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
>
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.