public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-6146] tree-ssa-dce: Fix up -fcompare-debug failures in make_forwarders_with_degenerate_phis [PR103742]
@ 2021-12-29 20:47 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2021-12-29 20:47 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:e5acfcad98f3fa33e141f4e6bc06f7d7c13496e1

commit r12-6146-ge5acfcad98f3fa33e141f4e6bc06f7d7c13496e1
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Dec 29 21:46:21 2021 +0100

    tree-ssa-dce: Fix up -fcompare-debug failures in make_forwarders_with_degenerate_phis [PR103742]
    
    make_forwarders_with_degenerate_phis causes a -fcompare-debug failure on the
    following testcase.
    The problem is that on:
      # iftmp.4_8 = PHI <&D.2582(6), &D.2583(4), &D.2582(7), &D.2583(5)>
    the exact DECL_UIDs are different between -g and -g0 (which is ok, with -g
    the decls can have larger gaps in between the uids), which means
    iterative_hash_expr is different and because there are 2 pairs of edges
    with matching phi arguments, the function processes them in different
    orders.
    The following patch fixes it by using the iterative_hash_expr order
    only to determine which arguments are the same, then replaces the hashes
    with the minimum dest_idx in the set of matching arguments and qsorts
    again (which makes it stable for -fcompare-debug) and only splits edges etc.
    on that stable order.
    As a small optimization, if no arguments are equal, it doesn't do the
    second qsort and continues, and if all arguments of the PHI are
    constants or SSA_NAMEs (I think that is a pretty common case for many
    PHIs), then it doesn't do the second qsort either, because in that case
    the hash values will be stable, only computed from the constant values or
    SSA_NAME_VERSIONs.
    
    2021-12-29  Jakub Jelinek  <jakub@redhat.com>
    
            PR debug/103742
            * tree-ssa-dce.c (make_forwarders_with_degenerate_phis): If any phi
            argument is not CONSTANT_CLASS_P or SSA_NAME and any arguments are
            equal, change second from hash value to lowest dest_idx from the
            edges which have equal argument and resort to ensure -fcompare-debug
            stability.
    
            * g++.dg/opt/pr103742.C: New test.

Diff:
---
 gcc/testsuite/g++.dg/opt/pr103742.C | 36 +++++++++++++++++++++++++++++++++++
 gcc/tree-ssa-dce.c                  | 38 +++++++++++++++++++++++++++++++++----
 2 files changed, 70 insertions(+), 4 deletions(-)

diff --git a/gcc/testsuite/g++.dg/opt/pr103742.C b/gcc/testsuite/g++.dg/opt/pr103742.C
new file mode 100644
index 00000000000..6155d2221bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr103742.C
@@ -0,0 +1,36 @@
+// PR debug/103742
+// { dg-do compile { target c++17 } }
+// { dg-options "-O2 -fnon-call-exceptions --param=early-inlining-insns=82 -fcompare-debug" }
+
+template <typename T> T max(T a, T b) { return a >= b ? a : b; }
+template <typename T> T abs(T);
+template <int T, int U> struct A {
+  long a;
+  A(A &x) { a = x.a; }
+  A(long);
+  A foo(A) {
+    if (abs(a) && a == a)
+      a = a ? U : T;
+    else
+      a += a;
+    return *this;
+  }
+  bool operator>=(A) { return a; }
+};
+struct B {};
+struct C {
+  A<2147483647, 0> c;
+};
+struct D {
+  A<2147483647, 0> d;
+  C e[];
+};
+struct E : D{} * f;
+A<2147483647, 0> bar() {
+  A<2147483647, 0> g = g.foo(f->d);
+  return max(g, (A<2147483647, 0>)1);
+}
+E *h;
+void baz() {
+  h->e[0].c = bar();
+}
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 1f817b95fab..6a6da0963b2 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -1671,6 +1671,7 @@ make_forwarders_with_degenerate_phis (function *fn)
 	continue;
       gphi *phi = gsi.phi ();
       auto_vec<std::pair<edge, hashval_t>, 8> args;
+      bool need_resort = false;
       for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
 	{
 	  edge e = gimple_phi_arg_edge (phi, i);
@@ -1682,12 +1683,42 @@ make_forwarders_with_degenerate_phis (function *fn)
 	  if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
 	      && loop_exit_edge_p (e->src->loop_father, e))
 	    continue;
-	  args.safe_push (std::make_pair (e, iterative_hash_expr
-					     (gimple_phi_arg_def (phi, i), 0)));
+
+	  tree arg = gimple_phi_arg_def (phi, i);
+	  if (!CONSTANT_CLASS_P (arg) && TREE_CODE (arg) != SSA_NAME)
+	    need_resort = true;
+	  args.safe_push (std::make_pair (e, iterative_hash_expr (arg, 0)));
 	}
       if (args.length () < 2)
 	continue;
       args.qsort (sort_phi_args);
+      /* The above sorting can be different between -g and -g0, as e.g. decls
+	 can have different uids (-g could have bigger gaps in between them).
+	 So, only use that to determine which args are equal, then change
+	 second from hash value to smallest dest_idx of the edges which have
+	 equal argument and sort again.  If all the phi arguments are
+	 constants or SSA_NAME, there is no need for the second sort, the hash
+	 values are stable in that case.  */
+      hashval_t hash = args[0].second;
+      args[0].second = args[0].first->dest_idx;
+      bool any_equal = false;
+      for (unsigned i = 1; i < args.length (); ++i)
+	if (hash == args[i].second
+	    && operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[i - 1].first),
+				PHI_ARG_DEF_FROM_EDGE (phi, args[i].first)))
+	  {
+	    args[i].second = args[i - 1].second;
+	    any_equal = true;
+	  }
+	else
+	  {
+	    hash = args[i].second;
+	    args[i].second = args[i].first->dest_idx;
+	  }
+      if (!any_equal)
+	continue;
+      if (need_resort)
+	args.qsort (sort_phi_args);
 
       /* From the candidates vector now verify true candidates for
 	 forwarders and create them.  */
@@ -1697,8 +1728,7 @@ make_forwarders_with_degenerate_phis (function *fn)
 	{
 	  unsigned i;
 	  for (i = start + 1; i < args.length (); ++i)
-	    if (!operand_equal_p (PHI_ARG_DEF_FROM_EDGE (phi, args[start].first),
-				  PHI_ARG_DEF_FROM_EDGE (phi, args[i].first)))
+	    if (args[start].second != args[i].second)
 	      break;
 	  /* args[start]..args[i-1] are equal.  */
 	  if (start != i - 1)


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-12-29 20:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-29 20:47 [gcc r12-6146] tree-ssa-dce: Fix up -fcompare-debug failures in make_forwarders_with_degenerate_phis [PR103742] Jakub Jelinek

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).