]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/70007 (wrong code with -mbmi2)
authorEric Botcazou <ebotcazou@adacore.com>
Tue, 1 Mar 2016 22:36:15 +0000 (22:36 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 1 Mar 2016 22:36:15 +0000 (22:36 +0000)
PR rtl-optimization/70007
* gcse.c (compute_ld_motion_mems): Tidy up and also invalidate memory
references present in REG_EQUAL notes attached to non-SET patterns.

From-SVN: r233869

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

index b8bd435ece37e29b797c936712eaa27e361b46a5..5b8275475006aa0372d3638e3c5ba4cdc88d5a0a 100644 (file)
@@ -1,3 +1,9 @@
+2016-03-01  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR rtl-optimization/70007
+       * gcse.c (compute_ld_motion_mems): Tidy up and also invalidate memory
+       references present in REG_EQUAL notes attached to non-SET patterns.
+
 2016-02-17  Bill Schmidt  <wschmidt@linux.vnet.ibm.com>
 
        Backport from mainline
index b852aa1bf22fd0d11a1080f0c913993efe7618c3..e59151621ae6d73bf91bbbe5c879533a2a141a39 100644 (file)
@@ -3958,10 +3958,8 @@ compute_ld_motion_mems (void)
                {
                  rtx src = SET_SRC (PATTERN (insn));
                  rtx dest = SET_DEST (PATTERN (insn));
-                 rtx note = find_reg_equal_equiv_note (insn);
-                 rtx src_eq;
 
-                 /* Check for a simple LOAD...  */
+                 /* Check for a simple load.  */
                  if (MEM_P (src) && simple_mem (src))
                    {
                      ptr = ldst_entry (src);
@@ -3976,12 +3974,11 @@ compute_ld_motion_mems (void)
                      invalidate_any_buried_refs (src);
                    }
 
-                 if (note != 0 && REG_NOTE_KIND (note) == REG_EQUAL)
-                   src_eq = XEXP (note, 0);
-                 else
-                   src_eq = NULL_RTX;
-
-                 if (src_eq != NULL_RTX
+                 /* Check for a simple load through a REG_EQUAL note.  */
+                 rtx note = find_reg_equal_equiv_note (insn), src_eq;
+                 if (note
+                     && REG_NOTE_KIND (note) == REG_EQUAL
+                     && (src_eq = XEXP (note, 0))
                      && !(MEM_P (src_eq) && simple_mem (src_eq)))
                    invalidate_any_buried_refs (src_eq);
 
@@ -4004,7 +4001,17 @@ compute_ld_motion_mems (void)
                    }
                }
              else
-               invalidate_any_buried_refs (PATTERN (insn));
+               {
+                 /* Invalidate all MEMs in the pattern and...  */
+                 invalidate_any_buried_refs (PATTERN (insn));
+
+                 /* ...in REG_EQUAL notes for PARALLELs with single SET.  */
+                 rtx note = find_reg_equal_equiv_note (insn), src_eq;
+                 if (note
+                     && REG_NOTE_KIND (note) == REG_EQUAL
+                     && (src_eq = XEXP (note, 0)))
+                   invalidate_any_buried_refs (src_eq);
+               }
            }
        }
     }
index cfdf7c3d4ad049831e2ef3dd994b75b194f76913..98da2eddf5fa19f152b9d8b7e07019812d5e673b 100644 (file)
@@ -1,3 +1,7 @@
+2016-03-01  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.target/i386/pr70007.c: New test.
+
 2016-02-29  Harald Anlauf  <anlauf@gmx.de>
 
        PR fortran/60126
diff --git a/gcc/testsuite/gcc.target/i386/pr70007.c b/gcc/testsuite/gcc.target/i386/pr70007.c
new file mode 100644 (file)
index 0000000..6b457ee
--- /dev/null
@@ -0,0 +1,29 @@
+/* PR rtl-optimization/70007 */
+/* { dg-do run } */
+/* { dg-options "-O -fgcse -mbmi2" } */
+/* { dg-require-effective-target bmi2 } */
+
+typedef unsigned short v32u16 __attribute__ ((vector_size (32)));
+typedef unsigned long long v32u64 __attribute__ ((vector_size (32)));
+typedef unsigned __int128 u128;
+typedef unsigned __int128 v32u128 __attribute__ ((vector_size (32)));
+
+u128
+foo (v32u16 v32u16_0, v32u64 v32u64_0, v32u64 v32u64_1)
+{
+  do {
+    v32u16_0[13] |= v32u64_1[3] = (v32u64_1[3] >> 19) | (v32u64_1[3] << 45);
+    v32u64_1 %= ~v32u64_1;
+    v32u64_0 *= (v32u64) v32u16_0;
+  } while (v32u64_0[0]);
+  return v32u64_1[3];
+}
+
+int
+main (void)
+{
+  u128 x = foo((v32u16){~0xba31, 0x47c6}, (v32u64){64}, (v32u64){0, 0x8b217e2514d23242, 0xac569b6dff9f82, 0x9d4cffe03c139c});
+  if (x != 0x3c74da5ca328d09)
+    __builtin_abort();
+  return 0;
+}