Hi All, PR123055 showed a regression on power9 and power8 IEEE128 where gcc.target/powerpc/pr116030.c started emitting stxvd2x after r16-5947-ga6c50ec2c6ebcb.
The regression was caused by -ffuse-ops-with-volatile-access, which allows volatile memory to satisfy general_operand. This made vsx_stxvd2x4_le_const_<mode> match quad stores regardless of their actual alignment. Introduce quad_unaligned_memory_operand and restrict vsx_stxvd2x4_le_const_<mode> to unaligned quad memory only. This ensures stxvd2x is emitted only when required and aligned cases continue to use stvx. Bootstrapped and Regtested on powerpc64le-linux-gnu. 2026-01-22 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 16-byte aligned. * config/rs6000/vsx.md (vsx_stxvd2x4_le_const_<mode>): Check if quad_unaligned_memory_operand. gcc/testsuite/ChangeLog: PR target/123055 testsuite/gcc.target/powerpc/pr123055.c: New testcase. --- gcc/config/rs6000/predicates.md | 5 +++++ gcc/config/rs6000/vsx.md | 2 +- gcc/testsuite/gcc.target/powerpc/pr123055.c | 19 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr123055.c diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 54dbc8bcc95..6438227cb97 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -981,6 +981,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 cfad9b8c6d5..d01807dab70 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -3452,7 +3452,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 diff --git a/gcc/testsuite/gcc.target/powerpc/pr123055.c b/gcc/testsuite/gcc.target/powerpc/pr123055.c new file mode 100644 index 00000000000..c7dccf528e6 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr123055.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=power8 -O2" } */ + +/* { dg-final { scan-assembler-not "stvx" { target { le } } } } */ + +#pragma pack(1) +struct unaligned_wrapper { + __vector int v; +}; +#pragma pack() + +void +store_unaligned_pragma (struct unaligned_wrapper *ptr) +{ + /* Accessing a packed member tells GCC the alignment is 1 byte. + Triggers stxvd2x. */ + ptr->v = (__vector int) { -1, -1, -1, -1 }; +} + -- 2.47.3
