[llvm] [AArch64] Reorder ZPR stack spills to maximize ld1b/st1b pairings (PR #218950)

Kieran B via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 7 01:52:12 PDT 2026


================
@@ -461,104 +461,409 @@ define aarch64_sve_vector_pcs  void @test_clobbers_z_regs() {
 ;; It does not belong to the allowed calling conventions
 ;; NOPAIR and PAIR should have the same assembly
 define  void @test_clobbers_z_regs_negative() {
-; NOPAIR-LABEL: test_clobbers_z_regs_negative:
+; CHECK-LABEL: test_clobbers_z_regs_negative:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    stp d9, d8, [sp, #-16]! // 16-byte Folded Spill
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    .cfi_offset b8, -8
+; CHECK-NEXT:    .cfi_offset b9, -16
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    ldp d9, d8, [sp], #16 // 16-byte Folded Reload
+; CHECK-NEXT:    ret
+  call void asm sideeffect "", "~{z8},~{z9}"()
+  ret void
+}
+
+;; Do NOT save P8 and NOT group any Z8 and Z10 register
+define aarch64_sve_vector_pcs void @test_clobbers_2_z_regs_negative() {
+; CHECK-LABEL: test_clobbers_2_z_regs_negative:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    addvl sp, sp, #-2
+; CHECK-NEXT:    str z10, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    str z8, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .cfi_escape 0x0f, 0x08, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x40, 0x1e, 0x22 // sp + 16 + 16 * VG
+; CHECK-NEXT:    .cfi_offset w29, -16
+; CHECK-NEXT:    .cfi_escape 0x10, 0x48, 0x09, 0x92, 0x2e, 0x00, 0x11, 0x78, 0x1e, 0x22, 0x40, 0x1c // $d8 @ cfa - 8 * VG - 16
+; CHECK-NEXT:    .cfi_escape 0x10, 0x4a, 0x09, 0x92, 0x2e, 0x00, 0x11, 0x70, 0x1e, 0x22, 0x40, 0x1c // $d10 @ cfa - 16 * VG - 16
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    ldr z10, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    ldr z8, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    addvl sp, sp, #2
+; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT:    ret
+  call void asm sideeffect "", "~{z8},~{z10}"()
+  ret void
+}
+
+;; NOTHING TO DO HERE
+;; There is no ZReg pairs to save
+define aarch64_sve_vector_pcs  void @test_clobbers_p_reg_negative() {
+; CHECK-LABEL: test_clobbers_p_reg_negative:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    addvl sp, sp, #-1
+; CHECK-NEXT:    str p10, [sp, #7, mul vl] // 2-byte Spill
+; CHECK-NEXT:    .cfi_escape 0x0f, 0x08, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x38, 0x1e, 0x22 // sp + 16 + 8 * VG
+; CHECK-NEXT:    .cfi_offset w29, -16
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    ldr p10, [sp, #7, mul vl] // 2-byte Reload
+; CHECK-NEXT:    addvl sp, sp, #1
+; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT:    ret
+  call void asm sideeffect "", "~{p10}"()
+  ret void
+}
+
+; ZPR spill reordering tests
+
+; No legal pairing
+define aarch64_sve_vector_pcs void @reorder_z_spills_no_pairs() {
+; CHECK-LABEL: reorder_z_spills_no_pairs:
+; CHECK:       // %bb.0:
+; CHECK-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
+; CHECK-NEXT:    addvl sp, sp, #-3
+; CHECK-NEXT:    str z21, [sp] // 16-byte Folded Spill
+; CHECK-NEXT:    str z19, [sp, #1, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    str z17, [sp, #2, mul vl] // 16-byte Folded Spill
+; CHECK-NEXT:    .cfi_escape 0x0f, 0x08, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x48, 0x1e, 0x22 // sp + 16 + 24 * VG
+; CHECK-NEXT:    .cfi_offset w29, -16
+; CHECK-NEXT:    //APP
+; CHECK-NEXT:    //NO_APP
+; CHECK-NEXT:    ldr z21, [sp] // 16-byte Folded Reload
+; CHECK-NEXT:    ldr z19, [sp, #1, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    ldr z17, [sp, #2, mul vl] // 16-byte Folded Reload
+; CHECK-NEXT:    addvl sp, sp, #3
+; CHECK-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
+; CHECK-NEXT:    ret
+  call void asm sideeffect "", "~{z21},~{z17},~{z19}"()
+  ret void
+}
+
+; A single pair must remain unpaired at odd offset
+define aarch64_sve_vector_pcs void @z_pair_at_odd_offset() {
+; NOPAIR-LABEL: z_pair_at_odd_offset:
 ; NOPAIR:       // %bb.0:
-; NOPAIR-NEXT:    stp d9, d8, [sp, #-16]! // 16-byte Folded Spill
-; NOPAIR-NEXT:    .cfi_def_cfa_offset 16
-; NOPAIR-NEXT:    .cfi_offset b8, -8
-; NOPAIR-NEXT:    .cfi_offset b9, -16
+; NOPAIR-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
+; NOPAIR-NEXT:    addvl sp, sp, #-2
+; NOPAIR-NEXT:    str z19, [sp] // 16-byte Folded Spill
+; NOPAIR-NEXT:    str z18, [sp, #1, mul vl] // 16-byte Folded Spill
+; NOPAIR-NEXT:    .cfi_escape 0x0f, 0x08, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x40, 0x1e, 0x22 // sp + 16 + 16 * VG
+; NOPAIR-NEXT:    .cfi_offset w29, -16
 ; NOPAIR-NEXT:    //APP
 ; NOPAIR-NEXT:    //NO_APP
-; NOPAIR-NEXT:    ldp d9, d8, [sp], #16 // 16-byte Folded Reload
+; NOPAIR-NEXT:    ldr z19, [sp] // 16-byte Folded Reload
+; NOPAIR-NEXT:    ldr z18, [sp, #1, mul vl] // 16-byte Folded Reload
+; NOPAIR-NEXT:    addvl sp, sp, #2
+; NOPAIR-NEXT:    ldr x29, [sp], #16 // 8-byte Folded Reload
 ; NOPAIR-NEXT:    ret
 ;
-; PAIR-LABEL: test_clobbers_z_regs_negative:
+; PAIR-LABEL: z_pair_at_odd_offset:
 ; PAIR:       // %bb.0:
-; PAIR-NEXT:    stp d9, d8, [sp, #-16]! // 16-byte Folded Spill
-; PAIR-NEXT:    .cfi_def_cfa_offset 16
-; PAIR-NEXT:    .cfi_offset b8, -8
-; PAIR-NEXT:    .cfi_offset b9, -16
+; PAIR-NEXT:    str x29, [sp, #-16]! // 8-byte Folded Spill
+; PAIR-NEXT:    addvl sp, sp, #-3
+; PAIR-NEXT:    str p8, [sp, #7, mul vl] // 2-byte Spill
+; PAIR-NEXT:    str z19, [sp, #1, mul vl] // 16-byte Folded Spill
+; PAIR-NEXT:    str z18, [sp, #2, mul vl] // 16-byte Folded Spill
+; PAIR-NEXT:    .cfi_escape 0x0f, 0x08, 0x8f, 0x10, 0x92, 0x2e, 0x00, 0x48, 0x1e, 0x22 // sp + 16 + 24 * VG
+; PAIR-NEXT:    .cfi_offset w29, -16
 ; PAIR-NEXT:    //APP
 ; PAIR-NEXT:    //NO_APP
-; PAIR-NEXT:    ldp d9, d8, [sp], #16 // 16-byte Folded Reload
+; PAIR-NEXT:    ldr p8, [sp, #7, mul vl] // 2-byte Reload
----------------
kieroxide wrote:

Yes I will create a github issue for this too. 

https://github.com/llvm/llvm-project/pull/218950


More information about the llvm-commits mailing list