Re: [PATCH] range-op: add VREL_LT relation effect for div [PR126748]

Daniel Henrique Barboza <[email protected]>
Newsgroups gmane.comp.gcc.patches
Message-ID <[email protected]>

On 8/14/2026 8:19 PM, Andrea Pinski wrote:
> 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 :).

Sure, I'll take a look.

Daniel

> 
> 
>>
>>          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
>>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.