On 11/17/20 11:01 PM, Andrew MacLeod wrote:
PR 91029 observes when

  a % b > 0 && b >= 0,

then a has an implied range of  a >=0.  likewise

Shouldn't that be && b > 0?  b == 0 is undefined.


a % b < 0 implies a range of a <= 0.

This patch is a good example of how range-ops can be leveraged to solve problems. It simply implements operator_trunc_mod::op1_range()  to solve for 'A' when the LHS and 'b' are known to be within the specified ranges.    I also added a a test case to show folding of conditions based on that.

Bootstrapped on x86_64-pc-linux-gnu, no regressions.  pushed.

Andrew


diff --git a/gcc/range-op.cc b/gcc/range-op.cc
index d0adc95527a..f37796cac70 100644
--- a/gcc/range-op.cc
+++ b/gcc/range-op.cc
@@ -2634,6 +2634,9 @@ public:
                        const wide_int &lh_ub,
                        const wide_int &rh_lb,
                        const wide_int &rh_ub) const;
+  virtual bool op1_range (irange &r, tree type,
+                         const irange &lhs,
+                         const irange &op2) const;
 } op_trunc_mod;
void
@@ -2680,6 +2683,31 @@ operator_trunc_mod::wi_fold (irange &r, tree type,
   value_range_with_overflow (r, type, new_lb, new_ub);
 }
+bool
+operator_trunc_mod::op1_range (irange &r, tree type,
+                              const irange &lhs,
+                              const irange &op2) const
+{
+  // PR 91029.  Check for signed truncation with op2 >= 0.
+  if (TYPE_SIGN (type) == SIGNED && wi::ge_p (op2.lower_bound (), 0, SIGNED))
+    {
+      unsigned prec = TYPE_PRECISION (type);
+      // if a & b >=0 , then a >= 0.

Shouldn't comment be %, not & ??.

+      if (wi::ge_p (lhs.lower_bound (), 0, SIGNED))
+       {
+         r = value_range (type, wi::zero (prec), wi::max_value (prec, SIGNED));
+         return true;
+       }
+      // if a & b < 0 , then a <= 0.

Similarly here.

+      if (wi::lt_p (lhs.upper_bound (), 0, SIGNED))
+       {
+         r = value_range (type, wi::min_value (prec, SIGNED), wi::zero (prec));
+         return true;
+       }
+    }
+  return false;
+}
+

Thanks for doing this BTW.
Aldy

Reply via email to