diff options
author | Andrew MacLeod <amacleod@redhat.com> | 2023-01-17 11:39:47 -0500 |
---|---|---|
committer | Andrew MacLeod <amacleod@redhat.com> | 2023-01-31 09:56:27 -0500 |
commit | 1626ec53e8c1b9c245572417d380e3ed84990cff (patch) | |
tree | 6d7ae16ee9d8774a96a6d0d75c80e5b2b8460584 /gcc/range-op.cc | |
parent | 809d661aff99ae0287baf4a52269425de62381e6 (diff) | |
download | gcc-1626ec53e8c1b9c245572417d380e3ed84990cff.zip gcc-1626ec53e8c1b9c245572417d380e3ed84990cff.tar.gz gcc-1626ec53e8c1b9c245572417d380e3ed84990cff.tar.bz2 |
Add op2_range to pointer_plus.
Implement op2_range for pointer_plus to determine the offset (operand 2) is
zero or non-zero based on equality/inequality between the LHS and op1.
Also allow GORI computations to continue if the LHS is VARYING and there
is also a relation.
PR tree-optimization/108385
gcc/
* gimple-range-gori.cc (gori_compute::compute_operand_range):
Allow VARYING computations to continue if there is a relation.
* range-op.cc (pointer_plus_operator::op2_range): New.
gcc/testsuite/
* gcc.dg/pr108385.c: New.
Diffstat (limited to 'gcc/range-op.cc')
-rw-r--r-- | gcc/range-op.cc | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/range-op.cc b/gcc/range-op.cc index f7c1e84..136b709 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -4212,6 +4212,10 @@ public: const wide_int &lh_ub, const wide_int &rh_lb, const wide_int &rh_ub) const; + virtual bool op2_range (irange &r, tree type, + const irange &lhs, + const irange &op1, + relation_trio = TRIO_VARYING) const; } op_pointer_plus; void @@ -4258,6 +4262,25 @@ pointer_plus_operator::wi_fold (irange &r, tree type, r.set_varying (type); } +bool +pointer_plus_operator::op2_range (irange &r, tree type, + const irange &lhs ATTRIBUTE_UNUSED, + const irange &op1 ATTRIBUTE_UNUSED, + relation_trio trio) const +{ + relation_kind rel = trio.lhs_op1 (); + r.set_varying (type); + + // If the LHS and OP1 are equal, the op2 must be zero. + if (rel == VREL_EQ) + r.set_zero (type); + // If the LHS and OP1 are not equal, the offset must be non-zero. + else if (rel == VREL_NE) + r.set_nonzero (type); + else + return false; + return true; +} class pointer_min_max_operator : public range_operator { |