From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1666) id 86CFC385B1AC; Tue, 29 Nov 2022 13:30:49 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 86CFC385B1AC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1669728649; bh=3zDS3dhUtm2wdQHLWdlsYG2kkmbzJO16VJVroIVP9jM=; h=From:To:Subject:Date:From; b=Vm3qRPOVlDUCzAHWmPgqAs3UvDZzjbhhBeoipMAjEIXXMMKAr6WnxdSO4GX4lkaKI 1t1LlYnGNU3Ka3pFVmyXiXmmhkFFfxHqjN9A4oPHnc7v6tLkjTv2V34dNIcS+S+Xzy 1jaJkno+2pDnbf9A0C5lRcUkter0U+ANaUsCtBVk= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Richard Biener To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-4389] tree-optimization/107852 - missed optimization with PHIs X-Act-Checkin: gcc X-Git-Author: Richard Biener X-Git-Refname: refs/heads/master X-Git-Oldrev: 063ba138eaa15ceecf23a24906e0e19be98d509d X-Git-Newrev: fd8dd6c0384969170e594be34da278a072d5eb76 Message-Id: <20221129133049.86CFC385B1AC@sourceware.org> Date: Tue, 29 Nov 2022 13:30:49 +0000 (GMT) List-Id: https://gcc.gnu.org/g:fd8dd6c0384969170e594be34da278a072d5eb76 commit r13-4389-gfd8dd6c0384969170e594be34da278a072d5eb76 Author: Richard Biener Date: Tue Nov 29 12:56:22 2022 +0100 tree-optimization/107852 - missed optimization with PHIs The following deals with the situation where we have [local count: 1073741824]: _5 = bytes.D.25336._M_impl.D.24643._M_start; _6 = bytes.D.25336._M_impl.D.24643._M_finish; pretmp_66 = bytes.D.25336._M_impl.D.24643._M_end_of_storage; if (_5 != _6) goto ; [70.00%] else goto ; [30.00%] ... [local count: 329045359]: _89 = operator new (4); _43 = bytes.D.25336._M_impl.D.24643._M_start; _Num_44 = _137 - _43; if (_Num_44 != 0) but fail to see that _137 is equal to _5 and thus eventually _Num_44 is zero if not operator new would possibly clobber the global bytes variable. The following resolves this in value-numbering by using the predicated values for _5 == _6 recorded for the dominating condition. PR tree-optimization/107852 * tree-ssa-sccvn.cc (visit_phi): Use equivalences recorded as predicated values to elide more redundant PHIs. * gcc.dg/tree-ssa/ssa-fre-101.c: New testcase. Diff: --- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-101.c | 47 ++++++++++++++++++++++++++ gcc/tree-ssa-sccvn.cc | 51 ++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-101.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-101.c new file mode 100644 index 00000000000..c67f211dcf6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-101.c @@ -0,0 +1,47 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre1-details" } */ + +int test1 (int i, int j) +{ + int k; + if (i != j) + k = i; + else + k = j; + return k; +} + +int test2 (int i, int j) +{ + int k; + if (i != j) + k = j; + else + k = i; + return k; +} + +int test3 (int i, int j) +{ + int k; + if (i == j) + k = j; + else + k = i; + return k; +} + +int test4 (int i, int j) +{ + int k; + if (i == j) + k = i; + else + k = j; + return k; +} + +/* We'd expect 4 hits but since we only keep one forwarder the + VN predication machinery cannot record something for the entry + block since it doesn't work on edges but on their source. */ +/* { dg-final { scan-tree-dump-times "equal on edge" 2 "fre1" } } */ diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc index 37484403c56..1e7763baa38 100644 --- a/gcc/tree-ssa-sccvn.cc +++ b/gcc/tree-ssa-sccvn.cc @@ -5793,7 +5793,8 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) /* See if all non-TOP arguments have the same value. TOP is equivalent to everything, so we can ignore it. */ - FOR_EACH_EDGE (e, ei, gimple_bb (phi)->preds) + basic_block bb = gimple_bb (phi); + FOR_EACH_EDGE (e, ei, bb->preds) if (e->flags & EDGE_EXECUTABLE) { tree def = PHI_ARG_DEF_FROM_EDGE (phi, e); @@ -5838,6 +5839,54 @@ visit_phi (gimple *phi, bool *inserted, bool backedges_varying_p) && known_eq (soff, doff)) continue; } + /* There's also the possibility to use equivalences. */ + if (!FLOAT_TYPE_P (TREE_TYPE (def))) + { + vn_nary_op_t vnresult; + tree ops[2]; + ops[0] = def; + ops[1] = sameval; + tree val = vn_nary_op_lookup_pieces (2, EQ_EXPR, + boolean_type_node, + ops, &vnresult); + if (! val && vnresult && vnresult->predicated_values) + { + val = vn_nary_op_get_predicated_value (vnresult, e->src); + if (val && integer_truep (val)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Predication says "); + print_generic_expr (dump_file, def, TDF_NONE); + fprintf (dump_file, " and "); + print_generic_expr (dump_file, sameval, TDF_NONE); + fprintf (dump_file, " are equal on edge %d -> %d\n", + e->src->index, e->dest->index); + } + continue; + } + /* If on all previous edges the value was equal to def + we can change sameval to def. */ + if (EDGE_COUNT (bb->preds) == 2 + && (val = vn_nary_op_get_predicated_value + (vnresult, EDGE_PRED (bb, 0)->src)) + && integer_truep (val)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Predication says "); + print_generic_expr (dump_file, def, TDF_NONE); + fprintf (dump_file, " and "); + print_generic_expr (dump_file, sameval, TDF_NONE); + fprintf (dump_file, " are equal on edge %d -> %d\n", + EDGE_PRED (bb, 0)->src->index, + EDGE_PRED (bb, 0)->dest->index); + } + sameval = def; + continue; + } + } + } sameval = NULL_TREE; break; }