aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2024-02-21 11:12:27 +0000
committerRichard Sandiford <richard.sandiford@arm.com>2024-02-21 11:12:27 +0000
commit58930e9fd1816c2a71c4f4e54a82e870d3afe10a (patch)
treec86a7ac323fa2ad94e8c68801e18ebf615e3d283
parentad4df8cd080c9be738f61b5e91cc70a594c4419d (diff)
downloadgcc-58930e9fd1816c2a71c4f4e54a82e870d3afe10a.zip
gcc-58930e9fd1816c2a71c4f4e54a82e870d3afe10a.tar.gz
gcc-58930e9fd1816c2a71c4f4e54a82e870d3afe10a.tar.bz2
aarch64: Remove the aarch64_commit_lazy_save pattern
The main purpose of the aarch64_commit_lazy_save pattern was to defer insertion of a half-diamond until splitting, since splitting knew how to create the associated basic blocks. However, the fix for PR113220 means that mode-switching also knows how to do that. This patch therefore removes the pattern and emits the subinstructions directly. On its own, this is actually a slight regression, since it means we keep an unnecessary zero { za }. But the cases where that happens are wrong for a different reason, and this patch is a prerequisite to fixing it. gcc/ * config/aarch64/aarch64-sme.md (aarch64_commit_lazy_save): Remove, directly inserting the associated sequence * config/aarch64/aarch64.cc (aarch64_mode_emit_local_sme_state): ...here instead. gcc/testsuite/ * gcc.target/aarch64/sme/zt0_state_5.c (test3, test5): Expect zero { za }s.
-rw-r--r--gcc/config/aarch64/aarch64-sme.md45
-rw-r--r--gcc/config/aarch64/aarch64.cc13
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sme/zt0_state_5.c2
3 files changed, 11 insertions, 49 deletions
diff --git a/gcc/config/aarch64/aarch64-sme.md b/gcc/config/aarch64/aarch64-sme.md
index 81d9418..c95d4aa 100644
--- a/gcc/config/aarch64/aarch64-sme.md
+++ b/gcc/config/aarch64/aarch64-sme.md
@@ -455,51 +455,6 @@
[(set_attr "type" "no_insn")]
)
-;; This pseudo-instruction is emitted before a private-ZA function uses
-;; PSTATE.ZA state for the first time. The instruction checks whether
-;; ZA currently contains data belonging to a caller and commits the
-;; lazy save if so.
-;;
-;; Operand 0 is the incoming value of TPIDR2_EL0. Operand 1 is nonzero
-;; if ZA is live, and should therefore be zeroed after committing a save.
-;;
-;; The instruction is generated by the mode-switching pass. It is a
-;; define_insn_and_split rather than a define_expand because of the
-;; internal control flow.
-(define_insn_and_split "aarch64_commit_lazy_save"
- [(set (reg:DI ZA_FREE_REGNUM)
- (unspec:DI [(match_operand 0 "pmode_register_operand" "r")
- (match_operand 1 "const_int_operand")
- (reg:DI SME_STATE_REGNUM)
- (reg:DI TPIDR2_SETUP_REGNUM)
- (reg:VNx16QI ZA_REGNUM)] UNSPEC_COMMIT_LAZY_SAVE))
- (set (reg:DI ZA_REGNUM)
- (unspec:DI [(reg:DI SME_STATE_REGNUM)
- (reg:DI ZA_FREE_REGNUM)] UNSPEC_INITIAL_ZERO_ZA))
- (clobber (reg:DI R14_REGNUM))
- (clobber (reg:DI R15_REGNUM))
- (clobber (reg:DI R16_REGNUM))
- (clobber (reg:DI R17_REGNUM))
- (clobber (reg:DI R18_REGNUM))
- (clobber (reg:DI R30_REGNUM))
- (clobber (reg:CC CC_REGNUM))]
- ""
- "#"
- "true"
- [(const_int 0)]
- {
- auto label = gen_label_rtx ();
- auto jump = emit_jump_insn (gen_aarch64_cbeqdi1 (operands[0], label));
- JUMP_LABEL (jump) = label;
- emit_insn (gen_aarch64_tpidr2_save ());
- emit_insn (gen_aarch64_clear_tpidr2 ());
- if (INTVAL (operands[1]) != 0)
- emit_insn (gen_aarch64_initial_zero_za ());
- emit_label (label);
- DONE;
- }
-)
-
;; =========================================================================
;; == Loads, stores and moves
;; =========================================================================
diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index 6a39ed8..ed7fbca 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -29339,12 +29339,17 @@ aarch64_mode_emit_local_sme_state (aarch64_local_sme_state mode,
msr tpidr2_el0, xzr
zero { za } // Only if ZA is live
no_save: */
- bool is_active = (mode == aarch64_local_sme_state::ACTIVE_LIVE
- || mode == aarch64_local_sme_state::ACTIVE_DEAD);
auto tmp_reg = gen_reg_rtx (DImode);
- auto active_flag = gen_int_mode (is_active, DImode);
emit_insn (gen_aarch64_read_tpidr2 (tmp_reg));
- emit_insn (gen_aarch64_commit_lazy_save (tmp_reg, active_flag));
+ auto label = gen_label_rtx ();
+ auto jump = emit_jump_insn (gen_aarch64_cbeqdi1 (tmp_reg, label));
+ JUMP_LABEL (jump) = label;
+ emit_insn (gen_aarch64_tpidr2_save ());
+ emit_insn (gen_aarch64_clear_tpidr2 ());
+ if (mode == aarch64_local_sme_state::ACTIVE_LIVE
+ || mode == aarch64_local_sme_state::ACTIVE_DEAD)
+ emit_insn (gen_aarch64_initial_zero_za ());
+ emit_label (label);
}
if (mode == aarch64_local_sme_state::ACTIVE_LIVE
diff --git a/gcc/testsuite/gcc.target/aarch64/sme/zt0_state_5.c b/gcc/testsuite/gcc.target/aarch64/sme/zt0_state_5.c
index e18b395..0fba218 100644
--- a/gcc/testsuite/gcc.target/aarch64/sme/zt0_state_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sme/zt0_state_5.c
@@ -54,6 +54,7 @@ __arm_new("zt0") int test3()
** cbz x0, [^\n]+
** bl __arm_tpidr2_save
** msr tpidr2_el0, xzr
+** zero { za }
** smstart za
** bl in_zt0
** smstop za
@@ -101,6 +102,7 @@ __arm_new("zt0") void test5()
** cbz x0, [^\n]+
** bl __arm_tpidr2_save
** msr tpidr2_el0, xzr
+** zero { za }
** smstart za
** bl out_zt0
** ...