From 1e27e7a582a9b86bcf86f5c103cd947672746e97 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 17 Nov 2020 14:47:58 -0500 Subject: recognize implied ranges for modulo. implement op1_range for modulo with implied positive and negative ranges. gcc/ PR tree-optimization/91029 * range-op.cc (operator_trunc_mod::op1_range): New. gcc/testsuite/ * gcc.dg/pr91029.c: New. --- gcc/range-op.cc | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'gcc/range-op.cc') diff --git a/gcc/range-op.cc b/gcc/range-op.cc index d0adc95..f37796c 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. + 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. + 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; +} + class operator_logical_not : public range_operator { -- cgit v1.1