]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Infer non-zero for integral division RHS.
authorAndrew MacLeod <amacleod@redhat.com>
Tue, 21 Jan 2025 16:49:12 +0000 (11:49 -0500)
committerAndrew MacLeod <amacleod@redhat.com>
Mon, 28 Apr 2025 21:17:30 +0000 (17:17 -0400)
Adding op2_range for operator_div allows ranger to notice the divisor
is non-zero after execution.

PR tree-optimization/95801
gcc/
* range-op.cc (operator_div::op2_range): New.

gcc/testsuite/
* gcc.dg/tree-ssa/pr95801.c: New.

gcc/range-op.cc
gcc/testsuite/gcc.dg/tree-ssa/pr95801.c [new file with mode: 0644]

index f72b4ae92cfd88ef46a4b0d98a71f0108f965aa5..5c0bcdc3b37d433c8334992ed31be554235930f8 100644 (file)
@@ -2415,8 +2415,11 @@ operator_widen_mult_unsigned::wi_fold (irange &r, tree type,
 class operator_div : public cross_product_operator
 {
   using range_operator::update_bitmask;
+  using range_operator::op2_range;
 public:
   operator_div (tree_code div_kind) { m_code = div_kind; }
+  bool op2_range (irange &r, tree type, const irange &lhs, const irange &,
+                 relation_trio) const;
   virtual void wi_fold (irange &r, tree type,
                        const wide_int &lh_lb,
                        const wide_int &lh_ub,
@@ -2436,6 +2439,19 @@ static operator_div op_floor_div (FLOOR_DIV_EXPR);
 static operator_div op_round_div (ROUND_DIV_EXPR);
 static operator_div op_ceil_div (CEIL_DIV_EXPR);
 
+// Set OP2 to non-zero if the LHS isn't UNDEFINED.
+bool
+operator_div::op2_range (irange &r, tree type, const irange &lhs,
+                        const irange &, relation_trio) const
+{
+  if (!lhs.undefined_p ())
+    {
+      r.set_nonzero (type);
+      return true;
+    }
+  return false;
+}
+
 bool
 operator_div::wi_op_overflows (wide_int &res, tree type,
                               const wide_int &w0, const wide_int &w1) const
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr95801.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95801.c
new file mode 100644 (file)
index 0000000..c3c80a0
--- /dev/null
@@ -0,0 +1,13 @@
+// { dg-do compile }
+// { dg-options "-O2 -fdump-tree-evrp" }
+
+int always1(int a, int b) {
+    if (a / b)
+        return b != 0;
+    return 1;
+}
+
+// If b != 0 is optimized by recognizing divide by 0 cannot happen,
+// there should be no PHI node.
+
+// { dg-final { scan-tree-dump-not "PHI" "evrp" } }