public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
From: Richard Sandiford <rsandifo@gcc.gnu.org>
To: gcc-cvs@gcc.gnu.org
Subject: [gcc r14-6387] aarch64: Fix invalid subregs for BE svread/write_za
Date: Sun, 10 Dec 2023 19:46:42 +0000 (GMT)	[thread overview]
Message-ID: <20231210194642.D4EE43858427@sourceware.org> (raw)

https://gcc.gnu.org/g:b3aed459634654d295a1d00e6c149565ced7a9a2

commit r14-6387-gb3aed459634654d295a1d00e6c149565ced7a9a2
Author: Richard Sandiford <richard.sandiford@arm.com>
Date:   Sun Dec 10 19:46:07 2023 +0000

    aarch64: Fix invalid subregs for BE svread/write_za
    
    Multi-register svread_za and svwrite_za are implemented using one
    pattern per register count, with the register contents being bitcast
    on entry (for writes) or return (for reads).  Previously we relied
    on subregs for this, with the subreg for reads being handled by
    target-independent code.  But using subregs isn't correct for many
    big-endian cases, where following subreg rules often requires actual
    instructions.  The semantics are instead supposed to be those of
    svreinterpret.
    
    gcc/
            PR target/112931
            PR target/112933
            * config/aarch64/aarch64-protos.h (aarch64_sve_reinterpret): Declare.
            * config/aarch64/aarch64.cc (aarch64_sve_reinterpret): New function.
            * config/aarch64/aarch64-sve-builtins-sme.cc (svread_za_impl::expand)
            (svwrite_za_impl::expand): Use it to cast the SVE register to the
            right mode.

Diff:
---
 gcc/config/aarch64/aarch64-protos.h            |  1 +
 gcc/config/aarch64/aarch64-sve-builtins-sme.cc |  5 +++--
 gcc/config/aarch64/aarch64.cc                  | 22 ++++++++++++++++++++++
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index d1af7f40891..eaf74a725e7 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -789,6 +789,7 @@ bool aarch64_mask_and_shift_for_ubfiz_p (scalar_int_mode, rtx, rtx);
 bool aarch64_masks_and_shift_for_bfi_p (scalar_int_mode, unsigned HOST_WIDE_INT,
 					unsigned HOST_WIDE_INT,
 					unsigned HOST_WIDE_INT);
+rtx aarch64_sve_reinterpret (machine_mode, rtx);
 bool aarch64_zero_extend_const_eq (machine_mode, rtx, machine_mode, rtx);
 bool aarch64_move_imm (unsigned HOST_WIDE_INT, machine_mode);
 machine_mode aarch64_sve_int_mode (machine_mode);
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-sme.cc b/gcc/config/aarch64/aarch64-sve-builtins-sme.cc
index 8d06a72f384..047a333ef47 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-sme.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-sme.cc
@@ -365,7 +365,8 @@ public:
   expand (function_expander &e) const override
   {
     machine_mode mode = e.vectors_per_tuple () == 4 ? VNx8DImode : VNx4DImode;
-    return e.use_exact_insn (code_for_aarch64_sme_read (mode));
+    rtx res = e.use_exact_insn (code_for_aarch64_sme_read (mode));
+    return aarch64_sve_reinterpret (e.result_mode (), res);
   }
 };
 
@@ -457,7 +458,7 @@ public:
   expand (function_expander &e) const override
   {
     machine_mode mode = e.vectors_per_tuple () == 4 ? VNx8DImode : VNx4DImode;
-    e.args[1] = lowpart_subreg (mode, e.args[1], e.tuple_mode (1));
+    e.args[1] = aarch64_sve_reinterpret (mode, e.args[1]);
     return e.use_exact_insn (code_for_aarch64_sme_write (mode));
   }
 };
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 2a64053f675..0889ceb7db1 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -3226,6 +3226,28 @@ aarch64_split_simd_move (rtx dst, rtx src)
     }
 }
 
+/* Return a register that contains SVE value X reinterpreted as SVE mode MODE.
+   The semantics of those of svreinterpret rather than those of subregs;
+   see the comment at the head of aarch64-sve.md for details about the
+   difference.  */
+
+rtx
+aarch64_sve_reinterpret (machine_mode mode, rtx x)
+{
+  if (GET_MODE (x) == mode)
+    return x;
+
+  /* can_change_mode_class must only return true if subregs and svreinterprets
+     have the same semantics.  */
+  if (targetm.can_change_mode_class (GET_MODE (x), mode, FP_REGS))
+    return lowpart_subreg (mode, x, GET_MODE (x));
+
+  rtx res = gen_reg_rtx (mode);
+  x = force_reg (GET_MODE (x), x);
+  emit_insn (gen_aarch64_sve_reinterpret (mode, res, x));
+  return res;
+}
+
 bool
 aarch64_zero_extend_const_eq (machine_mode xmode, rtx x,
 			      machine_mode ymode, rtx y)

                 reply	other threads:[~2023-12-10 19:46 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231210194642.D4EE43858427@sourceware.org \
    --to=rsandifo@gcc.gnu.org \
    --cc=gcc-cvs@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).