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