aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/fold-const.c24
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/fold-cond-2.c (renamed from gcc/testsuite/gcc.dg/fold-cond_expr-1.c)0
-rw-r--r--gcc/testsuite/gcc.dg/fold-cond-3.c35
5 files changed, 67 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5985d9e..796a7e8 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,11 @@
-2017-10-23 Jan Hubicka <hubicka@ucw.cz>
+2017-10-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR middle-end/82062
+ * fold-const.c (operand_equal_for_comparison_p): Also return true
+ if ARG0 is a simple variant of ARG1 with narrower precision.
+ (fold_ternary_loc): Always pass unstripped operands to the predicate.
+
+2017-10-25 Jan Hubicka <hubicka@ucw.cz>
* i386.c (ix86_builtin_vectorization_cost): Compute scatter/gather
cost correctly.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index c16959b..9db5aeb 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3366,7 +3366,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
#undef OP_SAME_WITH_NULL
}
-/* Similar to operand_equal_p, but strip nops first. */
+/* Similar to operand_equal_p, but see if ARG0 might be a variant of ARG1
+ with a different signedness or a narrower precision. */
static bool
operand_equal_for_comparison_p (tree arg0, tree arg1)
@@ -3381,9 +3382,20 @@ operand_equal_for_comparison_p (tree arg0, tree arg1)
/* Discard any conversions that don't change the modes of ARG0 and ARG1
and see if the inner values are the same. This removes any
signedness comparison, which doesn't matter here. */
- STRIP_NOPS (arg0);
- STRIP_NOPS (arg1);
- if (operand_equal_p (arg0, arg1, 0))
+ tree op0 = arg0;
+ tree op1 = arg1;
+ STRIP_NOPS (op0);
+ STRIP_NOPS (op1);
+ if (operand_equal_p (op0, op1, 0))
+ return true;
+
+ /* Discard a single widening conversion from ARG1 and see if the inner
+ value is the same as ARG0. */
+ if (CONVERT_EXPR_P (arg1)
+ && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (arg1, 0)))
+ && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (arg1, 0)))
+ < TYPE_PRECISION (TREE_TYPE (arg1))
+ && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
return true;
return false;
@@ -11169,8 +11181,8 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
Also try swapping the arguments and inverting the conditional. */
if (COMPARISON_CLASS_P (arg0)
- && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), arg1)
- && !HONOR_SIGNED_ZEROS (element_mode (arg1)))
+ && operand_equal_for_comparison_p (TREE_OPERAND (arg0, 0), op1)
+ && !HONOR_SIGNED_ZEROS (element_mode (op1)))
{
tem = fold_cond_expr_with_comparison (loc, type, arg0, op1, op2);
if (tem)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0e38439..443e7c7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2017-10-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/fold-cond_expr-1.c: Rename to...
+ * gcc.dg/fold-cond-2.c: ...this.
+ * gcc.dg/fold-cond-3.c: New test.
+
2017-10-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/82436
diff --git a/gcc/testsuite/gcc.dg/fold-cond_expr-1.c b/gcc/testsuite/gcc.dg/fold-cond-2.c
index 68ec754..68ec754 100644
--- a/gcc/testsuite/gcc.dg/fold-cond_expr-1.c
+++ b/gcc/testsuite/gcc.dg/fold-cond-2.c
diff --git a/gcc/testsuite/gcc.dg/fold-cond-3.c b/gcc/testsuite/gcc.dg/fold-cond-3.c
new file mode 100644
index 0000000..fe0ba65
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-cond-3.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-tree-original" } */
+
+unsigned long f1 (int x)
+{
+ return x > 0 ? (unsigned long) x : 0;
+}
+
+unsigned long f2 (int x, int y)
+{
+ return x > y ? (unsigned long) x : (unsigned long) y;
+}
+
+unsigned long f3 (int x)
+{
+ return x < 0 ? (unsigned long) x : 0;
+}
+
+unsigned long f4 (int x, int y)
+{
+ return x < y ? (unsigned long) x : (unsigned long) y;
+}
+
+unsigned long f5 (unsigned int x, unsigned int y)
+{
+ return x > y ? (unsigned long) x : (unsigned long) y;
+}
+
+unsigned long f6 (unsigned int x, unsigned int y)
+{
+ return x < y ? (unsigned long) x : (unsigned long) y;
+}
+
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 3 "original"} } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 3 "original"} } */