Skip to content

Commit 876d050

Browse files
sdesmalen-armtru
authored andcommitted
[AArch64][SME] Fix iterator to fixupCalleeSaveRestoreStackOffset (#110855)
The iterator passed to `fixupCalleeSaveRestoreStackOffset` may be incorrect when it tries to skip over the instructions that get the current value of 'vg', when there is a 'rdsvl' instruction straight after the prologue. That's because it doesn't check that the instruction is still a 'frame-setup' instruction.
1 parent 4716c47 commit 876d050

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

Diff for: llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

+3-6
Original file line numberDiff line numberDiff line change
@@ -1947,12 +1947,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
19471947
// pointer bump above.
19481948
while (MBBI != End && MBBI->getFlag(MachineInstr::FrameSetup) &&
19491949
!IsSVECalleeSave(MBBI)) {
1950-
// Move past instructions generated to calculate VG
1951-
if (requiresSaveVG(MF))
1952-
while (isVGInstruction(MBBI))
1953-
++MBBI;
1954-
1955-
if (CombineSPBump)
1950+
if (CombineSPBump &&
1951+
// Only fix-up frame-setup load/store instructions.
1952+
(!requiresSaveVG(MF) || !isVGInstruction(MBBI)))
19561953
fixupCalleeSaveRestoreStackOffset(*MBBI, AFI->getLocalStackSize(),
19571954
NeedsWinCFI, &HasWinCFI);
19581955
++MBBI;

Diff for: llvm/test/CodeGen/AArch64/sme-vg-to-stack.ll

+38
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,44 @@ define void @streaming_compatible_no_sve(i32 noundef %x) #4 {
11021102
ret void
11031103
}
11041104

1105+
; The algorithm that fixes up the offsets of the callee-save/restore
1106+
; instructions must jump over the instructions that instantiate the current
1107+
; 'VG' value. We must make sure that it doesn't consider any RDSVL in
1108+
; user-code as if it is part of the frame-setup when doing so.
1109+
define void @test_rdsvl_right_after_prologue(i64 %x0) nounwind {
1110+
; NO-SVE-CHECK-LABEL: test_rdsvl_right_after_prologue:
1111+
; NO-SVE-CHECK: // %bb.0:
1112+
; NO-SVE-CHECK-NEXT: stp d15, d14, [sp, #-96]! // 16-byte Folded Spill
1113+
; NO-SVE-CHECK-NEXT: stp d13, d12, [sp, #16] // 16-byte Folded Spill
1114+
; NO-SVE-CHECK-NEXT: mov x9, x0
1115+
; NO-SVE-CHECK-NEXT: stp d11, d10, [sp, #32] // 16-byte Folded Spill
1116+
; NO-SVE-CHECK-NEXT: stp d9, d8, [sp, #48] // 16-byte Folded Spill
1117+
; NO-SVE-CHECK-NEXT: stp x29, x30, [sp, #64] // 16-byte Folded Spill
1118+
; NO-SVE-CHECK-NEXT: bl __arm_get_current_vg
1119+
; NO-SVE-CHECK-NEXT: str x0, [sp, #80] // 8-byte Folded Spill
1120+
; NO-SVE-CHECK-NEXT: mov x0, x9
1121+
; NO-SVE-CHECK-NEXT: rdsvl x8, #1
1122+
; NO-SVE-CHECK-NEXT: add x29, sp, #64
1123+
; NO-SVE-CHECK-NEXT: lsr x8, x8, #3
1124+
; NO-SVE-CHECK-NEXT: mov x1, x0
1125+
; NO-SVE-CHECK-NEXT: smstart sm
1126+
; NO-SVE-CHECK-NEXT: mov x0, x8
1127+
; NO-SVE-CHECK-NEXT: bl bar
1128+
; NO-SVE-CHECK-NEXT: smstop sm
1129+
; NO-SVE-CHECK-NEXT: ldp x29, x30, [sp, #64] // 16-byte Folded Reload
1130+
; NO-SVE-CHECK-NEXT: ldp d9, d8, [sp, #48] // 16-byte Folded Reload
1131+
; NO-SVE-CHECK-NEXT: ldp d11, d10, [sp, #32] // 16-byte Folded Reload
1132+
; NO-SVE-CHECK-NEXT: ldp d13, d12, [sp, #16] // 16-byte Folded Reload
1133+
; NO-SVE-CHECK-NEXT: ldp d15, d14, [sp], #96 // 16-byte Folded Reload
1134+
; NO-SVE-CHECK-NEXT: ret
1135+
%some_alloc = alloca i64, align 8
1136+
%rdsvl = tail call i64 @llvm.aarch64.sme.cntsd()
1137+
call void @bar(i64 %rdsvl, i64 %x0) "aarch64_pstate_sm_enabled"
1138+
ret void
1139+
}
1140+
1141+
declare void @bar(i64, i64)
1142+
11051143
; Ensure we still emit async unwind information with -fno-asynchronous-unwind-tables
11061144
; if the function contains a streaming-mode change.
11071145

0 commit comments

Comments
 (0)