diff options
author | Andrew Pinski <quic_apinski@quicinc.com> | 2024-09-19 13:50:14 -0700 |
---|---|---|
committer | Andrew Pinski <quic_apinski@quicinc.com> | 2024-09-25 08:03:18 -0700 |
commit | 6c5543d3d9c4bbcd19f0ae2b7ed7e523c978a9a8 (patch) | |
tree | aad71a5a80ec8fec08fc8d7aab6ef44a3657cffd /gcc | |
parent | 7cf85d137ba8f83a54438f53f557225485c3f695 (diff) | |
download | gcc-6c5543d3d9c4bbcd19f0ae2b7ed7e523c978a9a8.zip gcc-6c5543d3d9c4bbcd19f0ae2b7ed7e523c978a9a8.tar.gz gcc-6c5543d3d9c4bbcd19f0ae2b7ed7e523c978a9a8.tar.bz2 |
match: Fix `a != 0 ? a * b : 0` patterns for things that trap [PR116772]
For generic, `a != 0 ? a * b : 0` would match where `b` would be an expression
which trap (in the case of the testcase, it was an integer division but it could be any).
This adds a new helper function, expr_no_side_effects_p which tests if there is no side effects
and the expression is not trapping which might be used in other locations.
Changes since v1:
* v2: Add move check to helper function instead of inlining it.
PR middle-end/116772
gcc/ChangeLog:
* generic-match-head.cc (expr_no_side_effects_p): New function
* gimple-match-head.cc (expr_no_side_effects_p): New function
* match.pd (`a != 0 ? a / b : 0`): Check expr_no_side_effects_p.
(`a != 0 ? a * b : 0`, `a != 0 ? a & b : 0`): Likewise.
gcc/testsuite/ChangeLog:
* gcc.dg/torture/pr116772-1.c: New test.
Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/generic-match-head.cc | 12 | ||||
-rw-r--r-- | gcc/gimple-match-head.cc | 10 | ||||
-rw-r--r-- | gcc/match.pd | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr116772-1.c | 24 |
4 files changed, 54 insertions, 2 deletions
diff --git a/gcc/generic-match-head.cc b/gcc/generic-match-head.cc index 641d8e9..42dee62 100644 --- a/gcc/generic-match-head.cc +++ b/gcc/generic-match-head.cc @@ -115,6 +115,18 @@ optimize_successive_divisions_p (tree, tree) return false; } +/* Returns true if the expression T has no side effects + including not trapping. */ +static inline bool +expr_no_side_effects_p (tree t) +{ + if (TREE_SIDE_EFFECTS (t)) + return false; + if (generic_expr_could_trap_p (t)) + return false; + return true; +} + /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily same type. The types can differ through nop conversions. */ diff --git a/gcc/gimple-match-head.cc b/gcc/gimple-match-head.cc index b5d4a71..4147a0e 100644 --- a/gcc/gimple-match-head.cc +++ b/gcc/gimple-match-head.cc @@ -145,6 +145,16 @@ optimize_vectors_before_lowering_p () return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0; } +/* Returns true if the expression T has no side effects + including not trapping. */ +static inline bool +expr_no_side_effects_p (tree t) +{ + /* For gimple, there should only be gimple val's here. */ + gcc_assert (is_gimple_val (t)); + return true; +} + /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x). As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...> diff --git a/gcc/match.pd b/gcc/match.pd index d10ac7d..cae3c5f 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4728,7 +4728,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (simplify (cond (ne @0 integer_zerop) (op@2 @3 @1) integer_zerop ) (if (bitwise_equal_p (@0, @3) - && tree_expr_nonzero_p (@1)) + && tree_expr_nonzero_p (@1) + /* Cannot make a expression with side effects + unconditional. */ + && expr_no_side_effects_p (@3)) @2))) /* Note we prefer the != case here @@ -4738,7 +4741,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (for op (mult bit_and) (simplify (cond (ne @0 integer_zerop) (op:c@2 @1 @3) integer_zerop) - (if (bitwise_equal_p (@0, @3)) + (if (bitwise_equal_p (@0, @3) + /* Cannot make a expression with side effects + unconditional. */ + && expr_no_side_effects_p (@1)) @2))) /* Simplifications of shift and rotates. */ diff --git a/gcc/testsuite/gcc.dg/torture/pr116772-1.c b/gcc/testsuite/gcc.dg/torture/pr116772-1.c new file mode 100644 index 0000000..eedd039 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr116772-1.c @@ -0,0 +1,24 @@ +/* { dg-do run } */ +/* PR middle-end/116772 */ +/* The division by `/b` should not + be made uncondtional. */ + +int mult0(int a,int b) __attribute__((noipa)); + +int mult0(int a,int b){ + return (b!=0 ? (a/b)*b : 0); +} + +int bit_and0(int a,int b) __attribute__((noipa)); + +int bit_and0(int a,int b){ + return (b!=0 ? (a/b)&b : 0); +} + +int main() { + if (mult0(3, 0) != 0) + __builtin_abort(); + if (bit_and0(3, 0) != 0) + __builtin_abort(); + return 0; +} |