diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2025-01-03 18:12:07 +0000 |
---|---|---|
committer | Richard Sandiford <richard.sandiford@arm.com> | 2025-01-03 18:12:07 +0000 |
commit | 355475e332f264107ef07555f7c379be7b85942f (patch) | |
tree | 050030ceb72dd814daddb01cae54dfa345067877 | |
parent | 92ad6d4ebfe5454b9299f295926517bd453bc4a2 (diff) | |
download | gcc-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.
-rw-r--r-- | gcc/rtlanal.cc | 14 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/pr117938.c | 36 |
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(); +} |