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
From 9697c02864fae26146e1a08d70753ae89919df52 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/9] 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