This PR was about a case in which late-combine moved a stack
deallocation across an earlier stack access.  This was possible
because the deallocation was missing the RTL-SSA equivalent of
a vop, which in turn was because rtl_properties didn't treat
the deallocation as writing to memory.  I think the bug was
ultimately there.

Tested on x86_64-linux-gnu (which the PR was reported against)
and aarch64-linux-gnu.  OK to install?

I don't think any earlier users of RTL-SSA are likely to be
affected by this, so I'm not sure it's worth a backport.

Richard


gcc/
        PR rtl-optimization/117938
        * rtlanal.cc (rtx_properties::try_to_add_dest): Treat writes
        to the stack pointer as also writing to memory.

gcc/testsuite/
        PR rtl-optimization/117938
        * gcc.dg/torture/pr117938.c: New test.
---
 gcc/rtlanal.cc                          | 14 +++++++---
 gcc/testsuite/gcc.dg/torture/pr117938.c | 36 +++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr117938.c

diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc
index e7efb48c398..8caffafdaa4 100644
--- a/gcc/rtlanal.cc
+++ b/gcc/rtlanal.cc
@@ -2163,10 +2163,18 @@ rtx_properties::try_to_add_dest (const_rtx x, unsigned 
int flags)
 
   if (LIKELY (REG_P (x)))
     {
-      /* We want to keep sp alive everywhere -  by making all
-        writes to sp also use sp. */
       if (REGNO (x) == STACK_POINTER_REGNUM)
-       flags |= rtx_obj_flags::IS_READ;
+       {
+         /* Stack accesses are dependent on previous allocations and
+            anti-dependent on later deallocations, so both types of
+            stack operation are akin to a memory write.  */
+         if (ref_iter != ref_end)
+           *ref_iter++ = rtx_obj_reference (MEM_REGNO, flags, BLKmode);
+
+         /* We want to keep sp alive everywhere - by making all
+            writes to sp also use sp.  */
+         flags |= rtx_obj_flags::IS_READ;
+       }
       try_to_add_reg (x, flags);
       return;
     }
diff --git a/gcc/testsuite/gcc.dg/torture/pr117938.c 
b/gcc/testsuite/gcc.dg/torture/pr117938.c
new file mode 100644
index 00000000000..5a3b6d2156c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr117938.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target { int32 && int128 } } } */
+/* { dg-additional-options "-Wno-psabi --param=max-cse-insns=1" } */
+
+typedef unsigned V __attribute__((__vector_size__(64)));
+typedef unsigned __int128 W __attribute__((__vector_size__(64)));
+unsigned a;
+W b;
+V c;
+W d;
+
+__attribute__((__noinline__))
+W
+bar (unsigned u, V z, W w)
+{
+  u *= z[5];
+  return u + w;
+}
+
+W
+foo (V v)
+{
+  unsigned g = a ? 1 : -1;
+  v ^= 0 <= v;
+  v <<= ((V){ bar (0, c, b)[0] } & 1);
+  v >>= ((V){ g, bar (1, c, b)[0] } & 1);
+  return a + b + (W) v + d;
+}
+
+int
+main ()
+{
+  V x = (V) foo ((V) { });
+  for (unsigned i = 0; i < sizeof(x)/sizeof(x[0]); i++)
+    if (x[i] != (i ? 0xffffffff : 0x7fffffff))
+      __builtin_abort();
+}
-- 
2.25.1

Reply via email to