[gcc r17-2790] avoid-store-forwarding: Unshare load dest when re-applying extension [PR126434]
Philipp Tomsich via Gcc-cvs <[email protected]> Wed, 29 Jul 2026 14:34:45 +0000 (GMT)
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://gcc.gnu.org/g:91663770f795fd02688c1da004337a1e7c94e810 commit r17-2790-g91663770f795fd02688c1da004337a1e7c94e810 Author: Konstantinos Eleftheriou <[email protected]> Date: Tue Jul 28 11:27:38 2026 +0200 avoid-store-forwarding: Unshare load dest when re-applying extension [PR126434] When store forwarding is avoided without eliminating the load (the store only partially covers it), the extension wrapping the load's MEM is re-applied after the bit-insert sequence, reusing SET_DEST (load) as the move destination. As the load insn is kept here, that rtx is now shared between two insns. That is fine for a plain REG, but in the case that the dest is a SUBREG, it must not be shared (verify_rtx_sharing ICEs). Unshare the destination with copy_rtx when building the move. Bootstrapped/regtested on AArch64, x86-64 and PowerPC. PR rtl-optimization/126434 gcc/ChangeLog: * avoid-store-forwarding.cc (process_store_forwarding): Unshare the load destination when building the re-extension move. gcc/testsuite/ChangeLog: * gcc.dg/pr126434.c: New test. Diff: --- gcc/avoid-store-forwarding.cc | 4 +++- gcc/testsuite/gcc.dg/pr126434.c | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/gcc/avoid-store-forwarding.cc b/gcc/avoid-store-forwarding.cc index 67abd2e37bd6..141f96c3d848 100644 --- a/gcc/avoid-store-forwarding.cc +++ b/gcc/avoid-store-forwarding.cc @@ -444,7 +444,9 @@ process_store_forwarding (vec<store_fwd_info> &stores, rtx_insn *load_insn, else move_src = dest; - rtx move = gen_rtx_SET (SET_DEST (load), move_src); + /* In the non-elimination case the load insn is retained, so unshare + its destination to avoid sharing a SUBREG between two insns. */ + rtx move = gen_rtx_SET (copy_rtx (SET_DEST (load)), move_src); start_sequence (); rtx_insn *insn = emit_insn (move); diff --git a/gcc/testsuite/gcc.dg/pr126434.c b/gcc/testsuite/gcc.dg/pr126434.c new file mode 100644 index 000000000000..b039ad0dfee6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr126434.c @@ -0,0 +1,18 @@ +/* PR rtl-optimization/126434 */ +/* { dg-do compile } */ +/* { dg-require-effective-target int128 } */ +/* { dg-options "-O1 -favoid-store-forwarding --param=store-forwarding-max-distance=146" } */ + +/* The store partially covers the load, so the load is kept and its + zero-extension is re-applied over a SUBREG destination. */ + +unsigned x; +__int128 y; + +void +foo () +{ + __builtin_memset (&x, 0, 2); + y &= x; +} +