RFC: PR rtl-optimization/43360: [4.3/4.4/4.5 Regression] possible wrong code bug

H.J. Lu hjl.tools@gmail.com
Tue Mar 16 22:06:00 GMT 2010


On Tue, Mar 16, 2010 at 12:28 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Tue, Mar 16, 2010 at 12:05:41PM -0700, H.J. Lu wrote:
>> > I'd say preventing the insn from being optimized is not desirable, instead
>> > if the REG_EQUAL is not invariant, the note should be dropped.
>> >
>> >        Jakub
>> >
>>
>> Here is the updated patch.  OK for trunk/4.4/4.3?
>
> Is every invariant insn for which find_invariant_insn succeeds actually
> moved?  I very much doubt so.  Therefore, it would be IMHO better to
> run this check in say create_new_invariant, set a new bool field
> in struct invariant (say drop_reg_equal) and only if/when it is actually
> moved drop the invariant if this field is true?
>

How about this patch?


-- 
H.J.
-------------- next part --------------
gcc/

2010-03-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/43360
	* loop-invariant.c (move_invariant_reg): Bail if the REG_EQUAL
	note is not invariant.

gcc/testsuite/

2010-03-16  H.J. Lu  <hongjiu.lu@intel.com>

	PR rtl-optimization/43360
	* gcc.dg/torture/pr43360.c: New.

diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 82e1829..cd9c88f 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -1181,6 +1181,11 @@ move_invariant_reg (struct loop *loop, unsigned invno)
      the register used for the representative.  */
   if (inv == repr)
     {
+      /* Bail if the REG_EQUAL note is not invariant.  */
+      note = find_reg_note (inv->insn, REG_EQUAL, NULL_RTX);
+      if (note && !check_maybe_invariant (XEXP (note, 0)))
+	goto fail;
+
       if (inv->depends_on)
 	{
 	  EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, i, bi)
@@ -1213,8 +1218,7 @@ move_invariant_reg (struct loop *loop, unsigned invno)
 	 Note that uses in REG_EQUAL notes are taken into account in
 	 the computation of invariants.  Hence it is safe to retain the
 	 note even if the note contains register references.  */
-      if (! inv->always_executed
-	  && (note = find_reg_note (inv->insn, REG_EQUAL, NULL_RTX)))
+      if (note && ! inv->always_executed)
 	remove_note (inv->insn, note);
     }
   else
diff --git a/gcc/testsuite/gcc.dg/torture/pr43360.c b/gcc/testsuite/gcc.dg/torture/pr43360.c
new file mode 100644
index 0000000..9ed9872
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr43360.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+
+int l_5_5_2 = 4;
+int g_3[1][1];
+
+void func_1 (void)
+{
+  for (g_3[0][0] = 1; g_3[0][0] < 8; g_3[0][0] += 7) {
+    int *l_6 = &g_3[0][0];
+    *l_6 = l_5_5_2;
+  }
+}
+
+int main (void)
+{
+  func_1 ();
+  if (g_3[0][0] != 11)
+      __builtin_abort ();
+  return 0;
+}


More information about the Gcc-patches mailing list