Re: [PATCH] range-op.cc: add VREL_EQ relation effect for div and mod [PR126745]
Andrea Pinski <[email protected]>
| Newsgroups | gmane.comp.gcc.patches |
|---|---|
| Message-ID | <CALvbMcDimS1Y_v2fc3Y6NQpFg+bG1B+u5rucjE=mkJ=ts=1eAA@mail.gmail.com> |
On Tue, Aug 18, 2026 at 2:28 PM Daniel Barboza <[email protected]> wrote: > > For res = a / b and a == b, set 'res' to one. > > For res = a % b and a == b, set 'res' to zero. > > Both are done by dom2/dom3 already. With this change we're now > doing it earlier (with -O2) in evrp. > > Bootstrapped and regtested in x86_64. > > PR tree-optimization/126745 > > gcc/ChangeLog: > > * range-op.cc (operator_div::op1_op2_relation_effect): add > VREL_EQ range equal one for op1/op2 and op1%op2 if op1 == op2. > > gcc/testsuite/ChangeLog: > > * gcc.dg/tree-ssa/pr126745.c: New test. > --- > gcc/range-op.cc | 36 ++++++++++++++++++++++++ > gcc/testsuite/gcc.dg/tree-ssa/pr126745.c | 16 +++++++++++ > 2 files changed, 52 insertions(+) > create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr126745.c > > diff --git a/gcc/range-op.cc b/gcc/range-op.cc > index bb055623872..0311cef7d47 100644 > --- a/gcc/range-op.cc > +++ b/gcc/range-op.cc > @@ -2641,6 +2641,7 @@ operator_div::op1_op2_relation_effect (irange &lhs_range, > return false; > > int_range<2> rel_range; > + wide_int one; > > switch (rel) > { > @@ -2652,6 +2653,10 @@ operator_div::op1_op2_relation_effect (irange &lhs_range, > && wi::ge_p (op2_range.lower_bound (), 0, SIGNED))) > rel_range.set_zero (type); > break; > + case VREL_EQ: > + one = wi::one (TYPE_PRECISION (type)); > + rel_range.set (type, one, one); > + break; Move the declaration of one into here. That is do this: case VREL_EQ: { wide_int one = wi::one (TYPE_PRECISION (type)); rel_range.set (type, one, one); break; } Otherwise ok. > default: > return false; > } > @@ -4380,6 +4385,7 @@ class operator_trunc_mod : public range_operator > using range_operator::op1_range; > using range_operator::op2_range; > using range_operator::update_bitmask; > + using range_operator::op1_op2_relation_effect; > public: > virtual void wi_fold (irange &r, tree type, > const wide_int &lh_lb, > @@ -4396,6 +4402,11 @@ public: > relation_trio) const; > void update_bitmask (irange &r, const irange &lh, const irange &rh) const > { update_known_bitmask (r, TRUNC_MOD_EXPR, lh, rh); } > + bool op1_op2_relation_effect (irange &lhs_range, > + tree type, > + const irange &op1_range, > + const irange &op2_range, > + relation_kind rel) const final override; > } op_trunc_mod; > > void > @@ -4536,6 +4547,31 @@ operator_trunc_mod::op2_range (irange &r, tree type, > return false; > } > > +bool > +operator_trunc_mod::op1_op2_relation_effect (irange &lhs_range, > + tree type, > + const irange &, > + const irange &, > + relation_kind rel) const > +{ > + if (rel == VREL_VARYING) > + return false; > + > + int_range<2> rel_range; > + > + switch (rel) > + { > + case VREL_EQ: > + rel_range.set_zero (type); > + break; > + default: > + return false; > + } > + > + lhs_range.intersect (rel_range); > + return true; > +} > + > > class operator_logical_not : public range_operator > { > diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr126745.c b/gcc/testsuite/gcc.dg/tree-ssa/pr126745.c > new file mode 100644 > index 00000000000..77405653ba2 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr126745.c > @@ -0,0 +1,16 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -fdump-tree-evrp" } */ > + > +int f (int a, int b) > +{ > + if (a != b) __builtin_unreachable (); > + return a / b; > +} > +/* { dg-final { scan-tree-dump-times "return 1;" 1 "evrp" } } */ > + > +int f2 (int a, int b) > +{ > + if (a != b) __builtin_unreachable (); > + return a % b; > +} > +/* { dg-final { scan-tree-dump-times "return 0;" 1 "evrp" } } */ > -- > 2.43.0 >