PR rtl-optimization/56151
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Feb 2013 10:37:38 +0000 (10:37 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 12 Feb 2013 10:37:38 +0000 (10:37 +0000)
* optabs.c (add_equal_note): Don't return 0 if target is a MEM,
equal to op0 or op1, and last_insn pattern is CODE operation
with MEM dest and one of the operands matches that MEM.

* gcc.target/i386/pr56151.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@195972 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr56151.c [new file with mode: 0644]

index 360514e..d959c9c 100644 (file)
@@ -1,3 +1,11 @@
+2013-02-12  Jakub Jelinek  <jakub@redhat.com>
+           Steven Bosscher   <steven@gcc.gnu.org>
+
+       PR rtl-optimization/56151
+       * optabs.c (add_equal_note): Don't return 0 if target is a MEM,
+       equal to op0 or op1, and last_insn pattern is CODE operation
+       with MEM dest and one of the operands matches that MEM.
+
 2013-02-11  Sriraman Tallam  <tmsriramgoogle.com>
 
        * doc/extend.texi: Document Function Multiversioning and "default"
index 8a3d3a9..c1dacf4 100644 (file)
@@ -190,17 +190,40 @@ add_equal_note (rtx insns, rtx target, enum rtx_code code, rtx op0, rtx op1)
   if (GET_CODE (target) == ZERO_EXTRACT)
     return 1;
 
-  /* If TARGET is in OP0 or OP1, punt.  We'd end up with a note referencing
-     a value changing in the insn, so the note would be invalid for CSE.  */
-  if (reg_overlap_mentioned_p (target, op0)
-      || (op1 && reg_overlap_mentioned_p (target, op1)))
-    return 0;
-
   for (last_insn = insns;
        NEXT_INSN (last_insn) != NULL_RTX;
        last_insn = NEXT_INSN (last_insn))
     ;
 
+  /* If TARGET is in OP0 or OP1, punt.  We'd end up with a note referencing
+     a value changing in the insn, so the note would be invalid for CSE.  */
+  if (reg_overlap_mentioned_p (target, op0)
+      || (op1 && reg_overlap_mentioned_p (target, op1)))
+    {
+      if (MEM_P (target)
+         && (rtx_equal_p (target, op0)
+             || (op1 && rtx_equal_p (target, op1))))
+       {
+         /* For MEM target, with MEM = MEM op X, prefer no REG_EQUAL note
+            over expanding it as temp = MEM op X, MEM = temp.  If the target
+            supports MEM = MEM op X instructions, it is sometimes too hard
+            to reconstruct that form later, especially if X is also a memory,
+            and due to multiple occurrences of addresses the address might
+            be forced into register unnecessarily.
+            Note that not emitting the REG_EQUIV note might inhibit
+            CSE in some cases.  */
+         set = single_set (last_insn);
+         if (set
+             && GET_CODE (SET_SRC (set)) == code
+             && MEM_P (SET_DEST (set))
+             && (rtx_equal_p (SET_DEST (set), XEXP (SET_SRC (set), 0))
+                 || (op1 && rtx_equal_p (SET_DEST (set),
+                                         XEXP (SET_SRC (set), 1)))))
+           return 1;
+       }
+      return 0;
+    }
+
   set = single_set (last_insn);
   if (set == NULL_RTX)
     return 1;
index 4aa1b4c..e9ab329 100644 (file)
@@ -1,3 +1,8 @@
+2013-02-12  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/56151
+       * gcc.target/i386/pr56151.c: New test.
+
 2013-02-11  Sriraman Tallam  <tmsriramgoogle.com>
 
        * g++.dg/ext/mv12.C: New test.
diff --git a/gcc/testsuite/gcc.target/i386/pr56151.c b/gcc/testsuite/gcc.target/i386/pr56151.c
new file mode 100644 (file)
index 0000000..24a1b8a
--- /dev/null
@@ -0,0 +1,17 @@
+/* PR rtl-optimization/56151 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int vara, varb;
+
+void
+foo (int i, int j)
+{
+  vara = varb | vara;
+}
+
+/* Verify the above is compiled into movl varb, %reg; orl %reg, vara instead
+   of longer movl vara, %reg; orl varb, %reg; movl %reg, vara.  */
+/* { dg-final { scan-assembler-not "mov\[^\n\r]*vara" { target nonpic } } } */
+/* { dg-final { scan-assembler-times "mov\[^\n\r]*varb" 1 { target nonpic } } } */
+/* { dg-final { scan-assembler-times "or\[^\n\r]*vara" 1 { target nonpic } } } */