I haven't checked this patch in yet. This implements a side effect that
the divisor cannot be 0 after a divide executes. This allows us to fold
the divide away:
a = b / c;
if (c == 0)
dead();
This bootstraps on x86_64-pc-linux-gnu with no regressions, but I first
wanted to check to see if there are some flags or conditions that should
e checked in order NOT to do this optimization. I am guessing there is
probably something :-) Anyway, this is how we straightforwardly add
side effects now.
Does the patch conditions need tweaking to apply the side effect?
Andrew
commit 3bbcccf2ddd4d50cc5febf630bd8b55a45688352
Author: Andrew MacLeod <amacl...@redhat.com>
Date: Mon Apr 4 16:13:57 2022 -0400
Add divide by zero side effect.
After a divide, we know the divisor is not zero.
gcc/
* gimple-range-side-effect.cc (stmt_side_effects::stmt_side_effects):
Add support for all divides.
gcc/testsuite/
* gcc.dg/tree-ssa/evrp-zero.c: New.
diff --git a/gcc/gimple-range-side-effect.cc b/gcc/gimple-range-side-effect.cc
index 2c8c77dc569..548e4bea313 100644
--- a/gcc/gimple-range-side-effect.cc
+++ b/gcc/gimple-range-side-effect.cc
@@ -116,6 +116,23 @@ stmt_side_effects::stmt_side_effects (gimple *s)
walk_stmt_load_store_ops (s, (void *)this, non_null_loadstore,
non_null_loadstore);
+ if (is_a<gassign *> (s))
+ {
+ switch (gimple_assign_rhs_code (s))
+ {
+ case TRUNC_DIV_EXPR:
+ case CEIL_DIV_EXPR:
+ case FLOOR_DIV_EXPR:
+ case ROUND_DIV_EXPR:
+ case EXACT_DIV_EXPR:
+ // Divide means operand 2 is not zero after this stmt.
+ if (gimple_range_ssa_p (gimple_assign_rhs2 (s)))
+ add_nonzero (gimple_assign_rhs2 (s));
+ break;
+ default:
+ break;
+ }
+ }
}
// -------------------------------------------------------------------------
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp-zero.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp-zero.c
new file mode 100644
index 00000000000..2b76e449c9b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp-zero.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp " } */
+
+/* Side effects of divide are that the divisor cannot be 0. */
+
+void dead (int);
+
+void
+f1 (int a, int c) {
+ int b = a;
+ if (a / c > 10)
+ b = c;
+
+ if (c == 0)
+ dead (b);
+}
+
+
+void
+f2 (int a, int c) {
+ int nz = c == 0;
+ int b = a / c;
+ if (nz)
+ dead (0);
+}
+
+
+/* { dg-final { scan-tree-dump-not "dead" "evrp" } } */