diff mbox series

[pushed] aarch64: Remove the aarch64_commit_lazy_save pattern

Message ID mpta5nukr1w.fsf@arm.com
State New
Headers show
Series [pushed] aarch64: Remove the aarch64_commit_lazy_save pattern | expand

Commit Message

Richard Sandiford Feb. 21, 2024, 11:14 a.m. UTC
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.

Tested on aarch64-linux-gnu & pushed.

Richard


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.
---
 gcc/config/aarch64/aarch64-sme.md             | 45 -------------------
 gcc/config/aarch64/aarch64.cc                 | 13 ++++--
 .../gcc.target/aarch64/sme/zt0_state_5.c      |  2 +
 3 files changed, 11 insertions(+), 49 deletions(-)
diff mbox series

Patch

diff --git a/gcc/config/aarch64/aarch64-sme.md b/gcc/config/aarch64/aarch64-sme.md
index 81d941871ac..c95d4aa696c 100644
--- a/gcc/config/aarch64/aarch64-sme.md
+++ b/gcc/config/aarch64/aarch64-sme.md
@@ -455,51 +455,6 @@  (define_insn "aarch64_end_private_za_call"
   [(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 6a39ed8eddf..ed7fbca512b 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 e18b395476c..0fba21868ed 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
 **	...