From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1011) id 00F7B3853314; Tue, 31 Jan 2023 14:58:11 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 00F7B3853314 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1675177091; bh=Yozones/TVwljSGNIHJyZF4eCnIbg/rB2/p6l6cUkFE=; h=From:To:Subject:Date:From; b=nkc7EUOTWm/lvtUYS3BOCKe5pyddTqahO7brzSUAzAbb6kf32r2SU7DM39mw6AcXm O+xjj6mocg8MzryDQv28RYU+RJB/xbiv1r44ogwy3i77F+kRVUs0Tl0o7Ar3I8Si6Z +x2HbNAG84geJwsGrn5eXfdIfmVnh40qJcdaGMKc= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Andrew Macleod To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-5579] Add op2_range to pointer_plus. X-Act-Checkin: gcc X-Git-Author: Andrew MacLeod X-Git-Refname: refs/heads/master X-Git-Oldrev: 809d661aff99ae0287baf4a52269425de62381e6 X-Git-Newrev: 1626ec53e8c1b9c245572417d380e3ed84990cff Message-Id: <20230131145811.00F7B3853314@sourceware.org> Date: Tue, 31 Jan 2023 14:58:11 +0000 (GMT) List-Id: https://gcc.gnu.org/g:1626ec53e8c1b9c245572417d380e3ed84990cff commit r13-5579-g1626ec53e8c1b9c245572417d380e3ed84990cff Author: Andrew MacLeod Date: Tue Jan 17 11:39:47 2023 -0500 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. Diff: --- gcc/gimple-range-gori.cc | 13 +++++++++---- gcc/range-op.cc | 23 +++++++++++++++++++++++ gcc/testsuite/gcc.dg/pr108385.c | 39 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 3dc4576ff13..beb1c0064b9 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -607,10 +607,6 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, { value_relation vrel; value_relation *vrel_ptr = rel; - // If the lhs doesn't tell us anything, neither will unwinding further. - if (lhs.varying_p ()) - return false; - // Empty ranges are viral as they are on an unexecutable path. if (lhs.undefined_p ()) { @@ -657,10 +653,19 @@ gori_compute::compute_operand_range (vrange &r, gimple *stmt, if (!op1_in_chain && !op2_in_chain) return false; + // If the lhs doesn't tell us anything and there are no relations, there + // is nothing to be learned. + if (lhs.varying_p () && !vrel_ptr) + return false; + bool res; // Process logicals as they have special handling. if (is_gimple_logical_p (stmt)) { + // If the lhs doesn't tell us anything, neither will combining operands. + if (lhs.varying_p ()) + return false; + unsigned idx; if ((idx = tracer.header ("compute_operand "))) { diff --git a/gcc/range-op.cc b/gcc/range-op.cc index f7c1e84e0bd..136b709385c 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 { diff --git a/gcc/testsuite/gcc.dg/pr108385.c b/gcc/testsuite/gcc.dg/pr108385.c new file mode 100644 index 00000000000..13babf06d9a --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr108385.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" } */ + +void bar(char *); + +/* Ensure that PTR1 = PTR2 + OFF properly picks up the zero and non-zero + properties if PTR1 and PTR2 are known equal or non-equal. */ + +void foo1 (char *p, char *pp, int off) +{ + char *q = p + off; + if (q != p) + { + if (off == 0) + bar (q); + } + else + { + if (off != 0) + bar (p); + } +} + +void foo2 (char *p, char *pp, int off) +{ + char *q = p + off; + if (q == p) + { + if (off != 0) + bar (p); + } + else + { + if (off == 0) + bar (q); + } +} + +/* { dg-final { scan-tree-dump-not "bar" "evrp" } } */