On 4/28/25 17:26, Andrew MacLeod wrote:
I have committed this patch to trunk after bootstrap/regression testing again on trunk.

I'll get to gcc14/15 once I flush the current queue.

Andrew

On 1/23/25 04:39, Richard Biener wrote:
On Wed, Jan 22, 2025 at 12:49 AM Andrew MacLeod <amacl...@redhat.com> wrote:
This patch simply adds an op2_range to operator_div which returns
non-zero if the LHS is not undefined.  This means given and integral
division:

         x = y / z

'z' will have a range of   [-INF, -1] [1, +INF]  after execution of the
statement.

This is relatively straightforward and resolves the PR, but I also get
that we might not want to proliferate an inferred range of undefined
behavior at this late stage.

OK for trunk, or defer to stage 1?  Are there any flags that need to be
checked to make this valid?
Stage 1 please.  I don't think this needs any flags.

Richard.

Bootstrapped on x86_64-pc-linux-gnu with no regressions.

Andrew
This is now in trunk.   Attached are the patches for gcc15, gcc14, and gcc13.

Bootstrapped with no regressions on x86_64-pc-linux-gnu.

Do you want me to check it in for any or all of those branches?    I cant go back further than gcc13 due to a lack of inferred range processing.

Andrew
From 05ea5fd870eaa632eec6a90f1ea171bc0bc1f571 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@redhat.com>
Date: Tue, 21 Jan 2025 11:49:12 -0500
Subject: [PATCH 2/2] Infer non-zero for integral division RHS.

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                         | 16 ++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr95801.c | 13 +++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr95801.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index f72b4ae92cf..5c0bcdc3b37 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -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
index 00000000000..c3c80a045cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95801.c
@@ -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" } }
-- 
2.45.0

From e68da32b60f24c52179fb239620f8fc3f160f56c Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@redhat.com>
Date: Tue, 29 Apr 2025 10:27:29 -0400
Subject: [PATCH 3/3] Infer non-zero for integral division RHS.

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                         | 16 ++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr95801.c | 13 +++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr95801.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 6ea0d9935eb..b776e9da170 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2334,8 +2334,11 @@ operator_widen_mult_unsigned::wi_fold (irange &r, tree type,
 
 class operator_div : public cross_product_operator
 {
+  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,
@@ -2355,6 +2358,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
index 00000000000..c3c80a045cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95801.c
@@ -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" } }
-- 
2.45.0

From d1c1d8d86d860ecc55bd1f7ea46414d1927b5dae Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@redhat.com>
Date: Tue, 29 Apr 2025 10:31:34 -0400
Subject: [PATCH 3/3] Infer non-zero for integral division RHS.

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                         | 16 ++++++++++++++++
 gcc/testsuite/gcc.dg/tree-ssa/pr95801.c | 13 +++++++++++++
 2 files changed, 29 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr95801.c

diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index 275b3ae6891..97af0b3adc3 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2173,7 +2173,10 @@ operator_widen_mult_unsigned::wi_fold (irange &r, tree type,
 
 class operator_div : public cross_product_operator
 {
+  using range_operator::op2_range;
 public:
+  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,
@@ -2373,6 +2376,19 @@ operator_rshift::lhs_op1_relation (const irange &lhs ATTRIBUTE_UNUSED,
   return VREL_VARYING;
 }
 
+// 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_lshift::fold_range (irange &r, tree type,
 			     const irange &op1,
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr95801.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95801.c
new file mode 100644
index 00000000000..c3c80a045cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95801.c
@@ -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" } }
-- 
2.45.0

Reply via email to