aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2025-01-03 18:12:07 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2025-01-03 18:12:07 +0000
commit355475e332f264107ef07555f7c379be7b85942f (patch)
tree050030ceb72dd814daddb01cae54dfa345067877 /gcc
parent92ad6d4ebfe5454b9299f295926517bd453bc4a2 (diff)
downloadgcc-355475e332f264107ef07555f7c379be7b85942f.zip
gcc-355475e332f264107ef07555f7c379be7b85942f.tar.gz
gcc-355475e332f264107ef07555f7c379be7b85942f.tar.bz2
rtlanal: Treat writes to sp as also writing to memory [PR117938]
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. 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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/rtlanal.cc14
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr117938.c36
2 files changed, 47 insertions, 3 deletions
diff --git a/gcc/rtlanal.cc b/gcc/rtlanal.cc
index e7efb48..8caffaf 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 0000000..5a3b6d2
--- /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();
+}