]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: Fix gcs save/restore_stack_nonlocal
authorRichard Henderson <richard.henderson@linaro.org>
Thu, 7 Aug 2025 09:37:36 +0000 (09:37 +0000)
committerRichard Henderson <richard.henderson@linaro.org>
Mon, 11 Aug 2025 23:25:08 +0000 (23:25 +0000)
The save/restore_stack_nonlocal patterns passed a DImode rtx to
gen_tbranch_neqi3 for a QImode compare.  But since we're seeding
r16 with 1, GCSEnabled will clear the only set bit in r16, so we
can use CBNZ instead of TBNZ.

gcc:
* config/aarch64/aarch64.md (tbranch_<EQL><SHORT>3): Remove.
(save_stack_nonlocal): Use aarch64_gen_compare_zero_and_branch.
(restore_stack_nonlocal): Likewise.

gcc/testsuite:
* gcc.target/aarch64/gcs-nonlocal-3.c: Match cbnz.

gcc/config/aarch64/aarch64.md
gcc/testsuite/gcc.target/aarch64/gcs-nonlocal-3.c

index 3da5bc2122dfb68df26a61281b8f56a3247cddfc..7fbd07ebfc3a00c63e3f7506635c0fb0078d93bf 100644 (file)
       /* Save GCS with code like
                mov     x16, 1
                chkfeat x16
-               tbnz    x16, 0, .L_done
+               cbnz    x16, .L_done
                mrs     tmp, gcspr_el0
                str     tmp, [%0, 8]
        .L_done:  */
 
-      rtx done_label = gen_label_rtx ();
+      auto done_label = gen_label_rtx ();
       rtx r16 = gen_rtx_REG (DImode, R16_REGNUM);
       emit_move_insn (r16, const1_rtx);
       emit_insn (gen_aarch64_chkfeat ());
-      emit_insn (gen_tbranch_neqi3 (r16, const0_rtx, done_label));
+      emit_jump_insn (aarch64_gen_compare_zero_and_branch (NE, r16, done_label));
       rtx gcs_slot = adjust_address (operands[0], Pmode, GET_MODE_SIZE (Pmode));
       rtx gcs = gen_reg_rtx (Pmode);
       emit_insn (gen_aarch64_load_gcspr (gcs));
       /* Restore GCS with code like
                mov     x16, 1
                chkfeat x16
-               tbnz    x16, 0, .L_done
+               cbnz    x16, .L_done
                ldr     tmp1, [%1, 8]
                mrs     tmp2, gcspr_el0
                subs    tmp2, tmp1, tmp2
                b.ne    .L_loop
        .L_done:  */
 
-      rtx loop_label = gen_label_rtx ();
-      rtx done_label = gen_label_rtx ();
+      auto loop_label = gen_label_rtx ();
+      auto done_label = gen_label_rtx ();
       rtx r16 = gen_rtx_REG (DImode, R16_REGNUM);
       emit_move_insn (r16, const1_rtx);
       emit_insn (gen_aarch64_chkfeat ());
-      emit_insn (gen_tbranch_neqi3 (r16, const0_rtx, done_label));
+      emit_jump_insn (aarch64_gen_compare_zero_and_branch (NE, r16, done_label));
       rtx gcs_slot = adjust_address (operands[1], Pmode, GET_MODE_SIZE (Pmode));
       rtx gcs_old = gen_reg_rtx (Pmode);
       emit_move_insn (gcs_old, gcs_slot);
index e2391555150b31de1b108f3af750f3f1f0e89682..7a76b14e1e7454066b15493313caa9ed151eb3c0 100644 (file)
@@ -7,7 +7,7 @@ void run (void (*)());
 ** bar.0:
 **     ...
 **     hint    40 // chkfeat x16
-**     tbnz    w16, 0, (\.L[0-9]+)
+**     cbnz    x16, (\.L[0-9]+)
 **     ...
 **     mrs     (x[0-9]+), s3_3_c2_c5_1 // gcspr_el0
 **     subs    x[0-9]+, x[0-9]+, \2