-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.
#undef OP_SAME_WITH_NULL
}
\f
-/* 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)
/* 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;
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)
+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
--- /dev/null
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int
+min1 (signed char op1, signed char op2)
+{
+ return (op1 < 25) ? (int)op1 : 24;
+}
+int
+min2 (signed char op1, signed char op2)
+{
+ return (op1 <= 24) ? (int)op1 : 25;
+}
+int
+min3 (unsigned char op1, unsigned char op2)
+{
+ return (op1 < 25) ? (unsigned int)op1 : 24;
+}
+int
+min4 (unsigned char op1, unsigned char op2)
+{
+ return (op1 <= 24) ? (unsigned int)op1 : 25;
+}
+int
+max1 (signed char op1, signed char op2)
+{
+ return (op1 > 24) ? (int)op1 : 25;
+}
+int
+max2 (signed char op1, signed char op2)
+{
+ return (op1 >= 25) ? (int)op1 : 24;
+}
+int
+max3 (unsigned char op1, unsigned char op2)
+{
+ return (op1 > 24) ? (unsigned int)op1 : 25;
+}
+int
+max4 (unsigned char op1, unsigned char op2)
+{
+ return (op1 >= 25) ? (unsigned int)op1 : 24;
+}
+
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 4 "optimized" } } */
+
--- /dev/null
+/* { 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"} } */
+++ /dev/null
-/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
-
-int
-min1 (signed char op1, signed char op2)
-{
- return (op1 < 25) ? (int)op1 : 24;
-}
-int
-min2 (signed char op1, signed char op2)
-{
- return (op1 <= 24) ? (int)op1 : 25;
-}
-int
-min3 (unsigned char op1, unsigned char op2)
-{
- return (op1 < 25) ? (unsigned int)op1 : 24;
-}
-int
-min4 (unsigned char op1, unsigned char op2)
-{
- return (op1 <= 24) ? (unsigned int)op1 : 25;
-}
-int
-max1 (signed char op1, signed char op2)
-{
- return (op1 > 24) ? (int)op1 : 25;
-}
-int
-max2 (signed char op1, signed char op2)
-{
- return (op1 >= 25) ? (int)op1 : 24;
-}
-int
-max3 (unsigned char op1, unsigned char op2)
-{
- return (op1 > 24) ? (unsigned int)op1 : 25;
-}
-int
-max4 (unsigned char op1, unsigned char op2)
-{
- return (op1 >= 25) ? (unsigned int)op1 : 24;
-}
-
-/* { dg-final { scan-tree-dump-times "MIN_EXPR" 4 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "MAX_EXPR" 4 "optimized" } } */
-