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

Reply via email to