From: Eric Botcazou Date: Wed, 25 Oct 2017 21:53:21 +0000 (+0000) Subject: re PR middle-end/82062 (simple conditional expressions no longer folded) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c0b24017eb8fee727bf1244e269e4b6b435e7952;p=gcc.git re PR middle-end/82062 (simple conditional expressions no longer folded) 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. From-SVN: r254089 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5985d9ed8c9..796a7e8cee9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,11 @@ -2017-10-23 Jan Hubicka +2017-10-25 Eric Botcazou + + 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 * i386.c (ix86_builtin_vectorization_cost): Compute scatter/gather cost correctly. diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c16959b84ac..9db5aeb8425 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 0e38439e12b..443e7c7df06 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-10-25 Eric Botcazou + + * 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 PR tree-optimization/82436 diff --git a/gcc/testsuite/gcc.dg/fold-cond-2.c b/gcc/testsuite/gcc.dg/fold-cond-2.c new file mode 100644 index 00000000000..68ec75480ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-cond-2.c @@ -0,0 +1,47 @@ +/* { 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" } } */ + 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 00000000000..fe0ba65ebac --- /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"} } */ diff --git a/gcc/testsuite/gcc.dg/fold-cond_expr-1.c b/gcc/testsuite/gcc.dg/fold-cond_expr-1.c deleted file mode 100644 index 68ec75480ad..00000000000 --- a/gcc/testsuite/gcc.dg/fold-cond_expr-1.c +++ /dev/null @@ -1,47 +0,0 @@ -/* { 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" } } */ -