aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Pinski <quic_apinski@quicinc.com>2024-09-19 13:50:14 -0700
committerAndrew Pinski <quic_apinski@quicinc.com>2024-09-25 08:03:18 -0700
commit6c5543d3d9c4bbcd19f0ae2b7ed7e523c978a9a8 (patch)
treeaad71a5a80ec8fec08fc8d7aab6ef44a3657cffd /gcc
parent7cf85d137ba8f83a54438f53f557225485c3f695 (diff)
downloadgcc-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.cc12
-rw-r--r--gcc/gimple-match-head.cc10
-rw-r--r--gcc/match.pd10
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr116772-1.c24
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;
+}