From: Andrew Pinski <pinskia@gmail.com>
To: Richard Biener <richard.guenther@gmail.com>
Cc: Andrew Pinski <apinski@marvell.com>,
GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH 1/5] Fix 101256: Wrong code due to range incorrect from PHI-OPT
Date: Mon, 5 Jul 2021 15:54:39 -0700 [thread overview]
Message-ID: <CA+=Sn1muW9NGqE=3BrHVprbD6vNt+_OtEg9o-=ND4Zi85K=REw@mail.gmail.com> (raw)
In-Reply-To: <CAFiYyc2oL2jxPb6OMvWBt_SoqKtEL4BorEoRMPH+A09UjQfpxQ@mail.gmail.com>
On Mon, Jul 5, 2021 at 4:26 AM Richard Biener via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> On Sun, Jul 4, 2021 at 8:40 PM apinski--- via Gcc-patches
> <gcc-patches@gcc.gnu.org> wrote:
> >
> > From: Andrew Pinski <apinski@marvell.com>
> >
> > So the problem here is that replace_phi_edge_with_variable
> > will copy range information to a already (not newly) defined
> > ssa name. This causes wrong code later on.
>
> That's a bit too conservative I guess? Shouldn't it work for at least
> all defs defined in the same block as the original conditional (and
> thus then applying to the seq inserted there by the callers)?
Yes that even simplifies the change even further and still provide the
needed ranges
I should have a patch to submit later today.
Thanks,
Andrew Pinski
>
> I realize it's wrong for, say
>
> _1 = ..
> if (_1 != 0)
> {
> ...
> if (..)
> ;
> # _2 = PHI <_1, 1>
> ...
> }
>
> with _2 having range [1, +INF] but clearly not _1 at the point of its
> definition.
>
> Richard.
>
> > This patch fixes the problem by requiring there to be statements
> > that are to be placed before the conditional to be able to
> > copy the range info; this assumes the statements will define
> > the ssa name.
> >
> > gcc/ChangeLog:
> >
> > PR tree-optimization/101256
> > * dbgcnt.def (phiopt_edge_range): New counter.
> > * tree-ssa-phiopt.c (replace_phi_edge_with_variable):
> > Add optional sequence which will be added before the old
> > conditional. Check sequence for non-null if we want to
> > update the range.
> > (two_value_replacement): Instead of inserting the sequence,
> > update the call to replace_phi_edge_with_variable.
> > (match_simplify_replacement): Likewise.
> > (minmax_replacement): Likewise.
> > (value_replacement): Create a sequence of statements
> > which would have defined the ssa name. Update call
> > to replace_phi_edge_with_variable.
> >
> > gcc/testsuite/ChangeLog:
> >
> > PR tree-optimization/101256
> > * g++.dg/torture/pr101256.C: New test.
> > ---
> > gcc/dbgcnt.def | 1 +
> > gcc/testsuite/g++.dg/torture/pr101256.C | 28 +++++++++++++
> > gcc/tree-ssa-phiopt.c | 52 ++++++++++++++-----------
> > 3 files changed, 59 insertions(+), 22 deletions(-)
> > create mode 100644 gcc/testsuite/g++.dg/torture/pr101256.C
> >
> > diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def
> > index 93e7b4fd30e..2345899ba68 100644
> > --- a/gcc/dbgcnt.def
> > +++ b/gcc/dbgcnt.def
> > @@ -183,6 +183,7 @@ DEBUG_COUNTER (lim)
> > DEBUG_COUNTER (local_alloc_for_sched)
> > DEBUG_COUNTER (match)
> > DEBUG_COUNTER (merged_ipa_icf)
> > +DEBUG_COUNTER (phiopt_edge_range)
> > DEBUG_COUNTER (postreload_cse)
> > DEBUG_COUNTER (pre)
> > DEBUG_COUNTER (pre_insn)
> > diff --git a/gcc/testsuite/g++.dg/torture/pr101256.C b/gcc/testsuite/g++.dg/torture/pr101256.C
> > new file mode 100644
> > index 00000000000..973a8b4caf3
> > --- /dev/null
> > +++ b/gcc/testsuite/g++.dg/torture/pr101256.C
> > @@ -0,0 +1,28 @@
> > +// { dg-do run }
> > +
> > +template<class T>
> > +const T& max(const T& a, const T& b)
> > +{
> > + return (a < b) ? b : a;
> > +}
> > +
> > +signed char var_5 = -128;
> > +unsigned int var_11 = 2144479212U;
> > +unsigned long long int arr [22];
> > +
> > +void
> > +__attribute__((noipa))
> > +test(signed char var_5, unsigned var_11) {
> > + for (short i_61 = 0; i_61 < var_5 + 149; i_61 += 10000)
> > + arr[i_61] = max((signed char)0, var_5) ? max((signed char)1, var_5) : var_11;
> > +}
> > +
> > +int main() {
> > + for (int i_0 = 0; i_0 < 22; ++i_0)
> > + arr [i_0] = 11834725929543695741ULL;
> > +
> > + test(var_5, var_11);
> > + if (arr [0] != 2144479212ULL && arr [0] != 11834725929543695741ULL)
> > + __builtin_abort ();
> > + return 0;
> > +}
> > diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
> > index ab12e85569d..71f0019d877 100644
> > --- a/gcc/tree-ssa-phiopt.c
> > +++ b/gcc/tree-ssa-phiopt.c
> > @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see
> > #include "gimple-fold.h"
> > #include "internal-fn.h"
> > #include "gimple-range.h"
> > +#include "dbgcnt.h"
> >
> > static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
> > static bool two_value_replacement (basic_block, basic_block, edge, gphi *,
> > @@ -73,7 +74,8 @@ static bool cond_store_replacement (basic_block, basic_block, edge, edge,
> > hash_set<tree> *);
> > static bool cond_if_else_store_replacement (basic_block, basic_block, basic_block);
> > static hash_set<tree> * get_non_trapping ();
> > -static void replace_phi_edge_with_variable (basic_block, edge, gphi *, tree);
> > +static void replace_phi_edge_with_variable (basic_block, edge, gphi *, tree,
> > + gimple_seq = NULL);
> > static void hoist_adjacent_loads (basic_block, basic_block,
> > basic_block, basic_block);
> > static bool gate_hoist_loads (void);
> > @@ -382,18 +384,20 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads, bool early_p)
> >
> > /* Replace PHI node element whose edge is E in block BB with variable NEW.
> > Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
> > - is known to have two edges, one of which must reach BB). */
> > + is known to have two edges, one of which must reach BB).
> > + Optionally insert stmts before the old condition. */
> >
> > static void
> > replace_phi_edge_with_variable (basic_block cond_block,
> > - edge e, gphi *phi, tree new_tree)
> > + edge e, gphi *phi, tree new_tree,
> > + gimple_seq stmts)
> > {
> > basic_block bb = gimple_bb (phi);
> > basic_block block_to_remove;
> > gimple_stmt_iterator gsi;
> > tree phi_result = PHI_RESULT (phi);
> >
> > - /* Duplicate range info if we're the only things setting the target PHI.
> > + /* Duplicate range info if they are the only things setting the target PHI.
> > This is needed as later on, the new_tree will be replacing
> > The assignement of the PHI.
> > For an example:
> > @@ -401,19 +405,23 @@ replace_phi_edge_with_variable (basic_block cond_block,
> > _4 = min<a_1, 255>
> > goto bb2
> >
> > - range<-INF,255>
> > + # RANGE [-INF, 255]
> > a_3 = PHI<_4(1)>
> > bb3:
> >
> > use(a_3)
> > - And _4 gets prograted into the use of a_3 and losing the range info.
> > - This can't be done for more than 2 incoming edges as the progration
> > - won't happen. */
> > + And _4 gets propagated into the use of a_3 and losing the range info.
> > + This can't be done for more than 2 incoming edges as the propagation
> > + won't happen.
> > + This also cannot be done if the name is not defined by statements to
> > + be placed before the conditional. */
> > if (TREE_CODE (new_tree) == SSA_NAME
> > && EDGE_COUNT (gimple_bb (phi)->preds) == 2
> > && INTEGRAL_TYPE_P (TREE_TYPE (phi_result))
> > && !SSA_NAME_RANGE_INFO (new_tree)
> > - && SSA_NAME_RANGE_INFO (phi_result))
> > + && SSA_NAME_RANGE_INFO (phi_result)
> > + && stmts != NULL
> > + && dbg_cnt (phiopt_edge_range))
> > duplicate_ssa_name_range_info (new_tree,
> > SSA_NAME_RANGE_TYPE (phi_result),
> > SSA_NAME_RANGE_INFO (phi_result));
> > @@ -443,6 +451,8 @@ replace_phi_edge_with_variable (basic_block cond_block,
> >
> > /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
> > gsi = gsi_last_bb (cond_block);
> > + if (stmts)
> > + gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
> > gsi_remove (&gsi, true);
> >
> > statistics_counter_event (cfun, "Replace PHI with variable", 1);
> > @@ -802,10 +812,8 @@ two_value_replacement (basic_block cond_bb, basic_block middle_bb,
> > else
> > new_rhs = gimple_build (&stmts, MINUS_EXPR, type, arg, lhs);
> > new_rhs = gimple_convert (&stmts, TREE_TYPE (arg0), new_rhs);
> > - gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
> > - gsi_insert_seq_before (&gsi, stmts, GSI_SAME_STMT);
> >
> > - replace_phi_edge_with_variable (cond_bb, e1, phi, new_rhs);
> > + replace_phi_edge_with_variable (cond_bb, e1, phi, new_rhs, stmts);
> >
> > /* Note that we optimized this PHI. */
> > return true;
> > @@ -920,10 +928,8 @@ match_simplify_replacement (basic_block cond_bb, basic_block middle_bb,
> > gsi_move_before (&gsi1, &gsi);
> > reset_flow_sensitive_info (gimple_assign_lhs (stmt_to_move));
> > }
> > - if (seq)
> > - gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
> >
> > - replace_phi_edge_with_variable (cond_bb, e1, phi, result);
> > + replace_phi_edge_with_variable (cond_bb, e1, phi, result, seq);
> >
> > /* Add Statistic here even though replace_phi_edge_with_variable already
> > does it as we want to be able to count when match-simplify happens vs
> > @@ -1396,6 +1402,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
> > && absorbing_element_p (code_def,
> > cond_rhs, false, rhs2))))))
> > {
> > + gimple_seq stmts = NULL;
> > gsi = gsi_for_stmt (cond);
> > /* Moving ASSIGN might change VR of lhs, e.g. when moving u_6
> > def-stmt in:
> > @@ -1417,11 +1424,15 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
> > tree plhs = gimple_assign_lhs (prep_stmt[i]);
> > reset_flow_sensitive_info (plhs);
> > gsi_from = gsi_for_stmt (prep_stmt[i]);
> > - gsi_move_before (&gsi_from, &gsi);
> > + gsi_remove (&gsi_from, false);
> > +
> > + gimple_seq_add_stmt (&stmts, prep_stmt[i]);
> > }
> > gsi_from = gsi_for_stmt (assign);
> > - gsi_move_before (&gsi_from, &gsi);
> > - replace_phi_edge_with_variable (cond_bb, e1, phi, lhs);
> > + gsi_remove (&gsi_from, false);
> > + gimple_seq_add_stmt (&stmts, assign);
> > +
> > + replace_phi_edge_with_variable (cond_bb, e1, phi, lhs, stmts);
> > return 2;
> > }
> >
> > @@ -1811,10 +1822,7 @@ minmax_replacement (basic_block cond_bb, basic_block middle_bb,
> > tree phi_result = PHI_RESULT (phi);
> > result = gimple_build (&stmts, minmax, TREE_TYPE (phi_result), arg0, arg1);
> >
> > - gsi = gsi_last_bb (cond_bb);
> > - gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT);
> > -
> > - replace_phi_edge_with_variable (cond_bb, e1, phi, result);
> > + replace_phi_edge_with_variable (cond_bb, e1, phi, result, stmts);
> >
> > return true;
> > }
> > --
> > 2.27.0
> >
prev parent reply other threads:[~2021-07-05 22:54 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-04 18:37 apinski
2021-07-04 18:37 ` [PATCH 2/5] Fix PR 101237: Remove element_type call when used with the functions from real apinski
2021-07-05 11:18 ` Richard Biener
2021-07-04 18:37 ` [PATCH 3/5] Allow match-and-simplified phiopt to run in early phiopt apinski
2021-07-05 11:26 ` Richard Biener
2021-07-04 18:37 ` [PATCH 4/5] Try inverted comparison for match_simplify in phiopt apinski
2021-07-05 11:18 ` Richard Biener
2021-07-04 18:37 ` [PATCH 5/5] Port most of the A CMP 0 ? A : -A to match apinski
2021-07-05 11:26 ` Richard Biener
2021-07-05 11:25 ` [PATCH 1/5] Fix 101256: Wrong code due to range incorrect from PHI-OPT Richard Biener
2021-07-05 22:54 ` Andrew Pinski [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CA+=Sn1muW9NGqE=3BrHVprbD6vNt+_OtEg9o-=ND4Zi85K=REw@mail.gmail.com' \
--to=pinskia@gmail.com \
--cc=apinski@marvell.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=richard.guenther@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).