tree-optimization/109002 - partial PRE miscompilation

Message ID 20230303110643.1128D139D3@imap2.suse-dmz.suse.de
State Repeat Merge
Headers
Series tree-optimization/109002 - partial PRE miscompilation |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Richard Biener March 3, 2023, 11:06 a.m. UTC
  Partial PRE ends up miscompiling the testcase in PR109002, likely
involving a corner case when inifinite loops are involved.  The
following avoids the miscompilation by addressing a long-standing
oddity that manifests in odd partial partial redundancies eliminated
that are full redundancies.  The oddity is that while we properly
PHI translate the PA_IN set from the successors when computing
PA_OUT but we fail to do the same for ANTIC_IN which is supposed
to be unioned.  That results in expressions with wrong virtual
operands being placed in the PA_OUT/IN sets and the pruning
machinery to go wrong because it assumes the expressions in the
sets have virtual operands that are valid in the respective blocks.

Bootstrapped and tested on x86_64-unknown-linux-gnu, pushed.

	PR tree-optimization/109002
	* tree-ssa-pre.cc (compute_partial_antic_aux): Properly
	PHI-translate ANTIC_IN.

	* gcc.dg/torture/pr109002.c: New testcase.
---
 gcc/testsuite/gcc.dg/torture/pr109002.c | 27 +++++++++++++++++++++++++
 gcc/tree-ssa-pre.cc                     | 20 ++++++++++++------
 2 files changed, 41 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr109002.c
  

Patch

diff --git a/gcc/testsuite/gcc.dg/torture/pr109002.c b/gcc/testsuite/gcc.dg/torture/pr109002.c
new file mode 100644
index 00000000000..5575a4b9edc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr109002.c
@@ -0,0 +1,27 @@ 
+/* { dg-do run } */
+/* { dg-additional-options "-ftree-pre -ftree-partial-pre" } */
+
+extern void exit (int);
+
+int g;
+int h;
+
+void __attribute__((noipa)) bar ()
+{
+  if (g)
+    exit (0);
+}
+
+int main(void)
+{
+  for (int i = 0; ; i++) {
+      for (int j = 0; j < g; j++);
+      if (i & 1) {
+	  if (h)
+	    continue;
+	  if (g)
+	    bar ();
+	  g = 1;
+      }
+  }
+}
diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc
index f77732d75c3..37cad36f2de 100644
--- a/gcc/tree-ssa-pre.cc
+++ b/gcc/tree-ssa-pre.cc
@@ -2364,11 +2364,14 @@  compute_partial_antic_aux (basic_block block,
 	      unsigned int i;
 	      bitmap_iterator bi;
 
-	      FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (e->dest), i, bi)
-		bitmap_value_insert_into_set (PA_OUT,
-					      expression_for_id (i));
 	      if (!gimple_seq_empty_p (phi_nodes (e->dest)))
 		{
+		  bitmap_set_t antic_in = bitmap_set_new ();
+		  phi_translate_set (antic_in, ANTIC_IN (e->dest), e);
+		  FOR_EACH_EXPR_ID_IN_SET (antic_in, i, bi)
+		    bitmap_value_insert_into_set (PA_OUT,
+						  expression_for_id (i));
+		  bitmap_set_free (antic_in);
 		  bitmap_set_t pa_in = bitmap_set_new ();
 		  phi_translate_set (pa_in, PA_IN (e->dest), e);
 		  FOR_EACH_EXPR_ID_IN_SET (pa_in, i, bi)
@@ -2377,9 +2380,14 @@  compute_partial_antic_aux (basic_block block,
 		  bitmap_set_free (pa_in);
 		}
 	      else
-		FOR_EACH_EXPR_ID_IN_SET (PA_IN (e->dest), i, bi)
-		  bitmap_value_insert_into_set (PA_OUT,
-						expression_for_id (i));
+		{
+		  FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (e->dest), i, bi)
+		    bitmap_value_insert_into_set (PA_OUT,
+						  expression_for_id (i));
+		  FOR_EACH_EXPR_ID_IN_SET (PA_IN (e->dest), i, bi)
+		    bitmap_value_insert_into_set (PA_OUT,
+						  expression_for_id (i));
+		}
 	    }
 	}
     }