Re: [PATCH] range-op: add VREL_LT relation effect for div [PR126748]
Andrea Pinski <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CALvbMcDQ3=9QMEdJgo2CgUXB2DCSRee=D2xkpC24Z9YM8Cn2Aw@mail.gmail.com> |
On Wed, Aug 12, 2026 at 2:24 AM Daniel Barboza <[email protected]> wrote: > > Given A div B, if we know for certain that A and B are positive > and A < B, we can infer that A div B is zero. > > Bootstrapped and regression tested in x86_64, aarch64 and riscv64. Ok. You want to handle PR 126745 also? It is EQ for both division and mod. It was this week's easy issue but nobody has picked it up yet. Plus that is a step forward in the ability to remove dom since dom is the only pass that handles it so far :). > > PR tree-optimization/126748 > > gcc/ChangeLog: > > * range-op.cc (class operator_div): declarations. > (operator_div::op1_op2_relation_effect): add op1/op2 relation > range equal zero for op1/op2 if op1 < op2 and both op1 and op2 > are positives. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/pr126748.c: New test. > --- > gcc/range-op.cc | 35 ++++++++++++++++++++++++ > gcc/testsuite/gcc.dg/tree-ssa/pr126748.c | 26 ++++++++++++++++++ > 2 files changed, 61 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr126748.c > > diff --git a/gcc/range-op.cc b/gcc/range-op.cc > index b878a6052c6..85755ef679e 100644 > --- a/gcc/range-op.cc > +++ b/gcc/range-op.cc > @@ -2497,6 +2497,7 @@ class operator_div : public cross_product_operator > { > using range_operator::update_bitmask; > using range_operator::op2_range; > + using range_operator::op1_op2_relation_effect; > public: > operator_div (tree_code div_kind) { m_code = div_kind; } > bool op2_range (irange &r, tree type, const irange &lhs, const irange &, > @@ -2509,6 +2510,11 @@ public: > virtual bool wi_op_overflows (wide_int &res, tree type, > const wide_int &, const wide_int &) > const final override; > + bool op1_op2_relation_effect (irange &lhs_range, > + tree type, > + const irange &op1_range, > + const irange &op2_range, > + relation_kind rel) const final override; > void update_bitmask (irange &r, const irange &lh, const irange &rh) > const final override > { update_known_bitmask (r, m_code, lh, rh); } > @@ -2622,6 +2628,35 @@ operator_div::wi_fold (irange &r, tree type, > gcc_checking_assert (!r.undefined_p ()); > } > > +bool > +operator_div::op1_op2_relation_effect (irange &lhs_range, > + tree type, > + const irange &op1_range, > + const irange &op2_range, > + relation_kind rel) const > +{ > + if (rel == VREL_VARYING) > + return false; > + > + int_range<2> rel_range; > + > + switch (rel) > + { > + /* op1/op2 = 0 if op1 < op2 and both op1 and op2 > + are known positives. */ > + case VREL_LT: > + if (TYPE_UNSIGNED (type) > + || (wi::ge_p (op1_range.lower_bound (), 0, SIGNED) > + && wi::ge_p (op2_range.lower_bound (), 0, SIGNED))) > + rel_range.set_zero (type); > + break; > + default: > + return false; > + } > + > + lhs_range.intersect (rel_range); > + return true; > +} > > class operator_exact_divide : public operator_div > { > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126748.c b/gcc/testsuite/gcc.dg/tree-ssa/pr126748.c > new file mode 100644 > index 00000000000..063187a904c > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126748.c > @@ -0,0 +1,26 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-evrp" } */ > + > +unsigned f(unsigned a, unsigned b) > +{ > + if (b >= a) __builtin_unreachable(); > + return b / a; > +} > + > +int fs(int a, int b) > +{ > + a = __builtin_abs(a); > + b = __builtin_abs(b); > + if (b >= a) __builtin_unreachable(); > + return b / a; > +} > + > +/* This can't be simplified. */ > +int fs2(int a, int b) > +{ > + if (b >= a) __builtin_unreachable(); > + return b / a; > +} > + > +/* { dg-final { scan-tree-dump-times "return 0;" 2 "evrp" } } */ > +/* { dg-final { scan-tree-dump-times " / " 1 "evrp" } } */ > -- > 2.43.0 >