[PATCH] Fix PR66168: ICE due to incorrect invariant register info

Thomas Preud'homme thomas.preudhomme@arm.com
Tue May 19 10:27:00 GMT 2015


Hi,

r223113 made it possible for invariant to actually be moved rather than
moving the source to a new pseudoregister. However, when doing so
the inv->reg is not set up properly: in case of a subreg destination it
holds the inner register rather than the subreg expression.

This patch fixes that.


ChangeLog entries are as follow:

*** gcc/ChangeLog ***

2015-05-18  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        PR rtl-optimization/66168
        * loop-invariant.c (move_invariant_reg): Set inv->reg to destination
        of inv->insn when moving an invariant without introducing a temporary
        register.

*** gcc/testsuite/ChangeLog ***

2015-05-18  Thomas Preud'homme  <thomas.preudhomme@arm.com>

        PR rtl-optimization/66168
        * gcc.c-torture/compile/pr66168.c: New test.


diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 76a009f..30e1945 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -1642,9 +1642,13 @@ move_invariant_reg (struct loop *loop, unsigned invno)
 
 	  emit_insn_after (gen_move_insn (dest, reg), inv->insn);
 	}
-      else if (dump_file)
-	fprintf (dump_file, "Invariant %d moved without introducing a new "
-			    "temporary register\n", invno);
+      else
+	{
+	  reg = SET_DEST (set);
+	  if (dump_file)
+	    fprintf (dump_file, "Invariant %d moved without introducing a new "
+				"temporary register\n", invno);
+	}
       reorder_insns (inv->insn, inv->insn, BB_END (preheader));
 
       /* If there is a REG_EQUAL note on the insn we just moved, and the
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr66168.c b/gcc/testsuite/gcc.c-torture/compile/pr66168.c
new file mode 100644
index 0000000..d6bfc7b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr66168.c
@@ -0,0 +1,15 @@
+int a, b;
+
+void
+fn1 ()
+{
+  for (;;)
+    {
+      for (b = 0; b < 3; b++)
+	{
+	  char e[2];
+	  char f = e[1];
+	  a ^= f ? 1 / f : 0;
+	}
+    }
+}


Tested by bootstrapping on x86_64-linux-gnu and building an arm-none-eabi
cross-compiler. Testsuite run shows no regression for both of them.

Ok for trunk?

Best regards,

Thomas




More information about the Gcc-patches mailing list