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.
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
--
2.52.0