Hi, On 06/10/26 3:04 AM, Kishan Parmar wrote: > Hello All, > > Changes from v1: > - Dropped pr123055.c testcase from previsous patch. The > existing pr116030.c already carries scan-assembler-not > "stxvd2x" assertion that matches the regression, making a > separate pr123055.c redundant. > > Below patch is regtested and bootstrapped on power64le-linux-gnu. > > Thank You, > Kishan > > PR123055 reports a regression on power little-endian systems, > where gcc.target/powerpc/pr116030.c began emitting stxvd2x starting > from r16-5947-ga6c50ec2c6ebcb. > > Commit r16-5947 introduced -ffuse-ops-with-volatile-access (enabled by > default), which relaxes general_operand to accept volatile memory > references. As a side effect, the vsx_stxvd2x4_le_const_<mode> pattern > whose destination was the "memory_operand" predicate started > matching aligned volatile destinations such as the 16-byte-aligned > volatile union U128 in pr116030.c.
Why is it incorrect if the vsx_stxvd2x4_le_const_<mode> pattern starts matching now? vsx_stxvd2x4_le_const_<mode> ends up generating stxvd2x but stxvd2x is not worse than stvx. stxvd2x could require a swap instruction to get the correct element order, but in vsx_stxvd2x4_le_const_<mode>, we ensure that operand 1 is a splat constant (a vector constant with a duplicated element value). So we don't require a swap instruction. The fix to PR123055 would be to just modify the failing testcase. -Surya > > The fix introduces a new predicate quad_unaligned_memory_operand that > accepts memory operands with MEM_ALIGN < 128 bits (i.e. not naturally > 16-byte aligned). Restricting vsx_stxvd2x4_le_const_<mode> to this > predicate ensures stxvd2x is only emitted when the destination is > genuinely unaligned, while aligned destinations volatile or not > fall through to the stvx path as intended. > > The existing test gcc.target/powerpc/pr116030.c already carries the > scan-assembler-not "stxvd2x" assertion that captures this regression, > so no new testcase file is required. > > 2026-10-06 Kishan Parmar <[email protected]> > > gcc/ChangeLog: > PR target/123055 > * config/rs6000/predicates.md (quad_unaligned_memory_operand): New > predicate. Returns 1 if the operand is memory but not naturally > 16-byte (128-bit) aligned. > * config/rs6000/vsx.md (vsx_stxvd2x4_le_const_<mode>): Replace > memory_operand with quad_unaligned_memory_operand to prevent the > pattern from matching aligned volatile destinations. > > --- > gcc/config/rs6000/predicates.md | 5 +++++ > gcc/config/rs6000/vsx.md | 2 +- > 2 files changed, 6 insertions(+), 1 deletion(-) > > diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md > index a6ec04f5922..b441213af6c 100644 > --- a/gcc/config/rs6000/predicates.md > +++ b/gcc/config/rs6000/predicates.md > @@ -1023,6 +1023,11 @@ > return quad_address_p (XEXP (op, 0), mode, false); > }) > > +;; Return 1 if the operand is memory but not naturally 16-byte aligned. > +(define_predicate "quad_unaligned_memory_operand" > + (and (match_operand 0 "memory_operand") > + (match_test "MEM_ALIGN (op) < 128"))) > + > ;; Return 1 if the operand is suitable for load/store to vector registers > with > ;; d-form addressing (register+offset), which was added in ISA 3.0. > ;; Unlike quad_memory_operand, we do not have to check for alignment. > diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md > index dfb2485f2ec..eb735f22d93 100644 > --- a/gcc/config/rs6000/vsx.md > +++ b/gcc/config/rs6000/vsx.md > @@ -3483,7 +3483,7 @@ > [(set_attr "type" "vecstore")]) > > (define_insn_and_split "vsx_stxvd2x4_le_const_<mode>" > - [(set (match_operand:VSX_W 0 "memory_operand" "=Z") > + [(set (match_operand:VSX_W 0 "quad_unaligned_memory_operand" "=Z") > (match_operand:VSX_W 1 "immediate_operand" "W")) > (clobber (match_scratch:VSX_W 2 "=wa"))] > "!BYTES_BIG_ENDIAN
