Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 425d25f

Browse files
authoredJan 24, 2025
[AArch64][WinCFI] Fix a crash due to missing seh directives (llvm#123993)
llvm#123808
1 parent b41987b commit 425d25f

File tree

3 files changed

+103
-9
lines changed

3 files changed

+103
-9
lines changed
 

‎llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1491,13 +1491,6 @@ static MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec(
14911491
NewOpc = AArch64::LDRQpost;
14921492
break;
14931493
}
1494-
// Get rid of the SEH code associated with the old instruction.
1495-
if (NeedsWinCFI) {
1496-
auto SEH = std::next(MBBI);
1497-
if (AArch64InstrInfo::isSEHInstruction(*SEH))
1498-
SEH->eraseFromParent();
1499-
}
1500-
15011494
TypeSize Scale = TypeSize::getFixed(1), Width = TypeSize::getFixed(0);
15021495
int64_t MinOffset, MaxOffset;
15031496
bool Success = static_cast<const AArch64InstrInfo *>(TII)->getMemOpInfo(
@@ -1512,16 +1505,27 @@ static MachineBasicBlock::iterator convertCalleeSaveRestoreToSPPrePostIncDec(
15121505
CSStackSizeInc > MaxOffset * (int64_t)Scale.getFixedValue()) {
15131506
// If we are destroying the frame, make sure we add the increment after the
15141507
// last frame operation.
1515-
if (FrameFlag == MachineInstr::FrameDestroy)
1508+
if (FrameFlag == MachineInstr::FrameDestroy) {
15161509
++MBBI;
1510+
// Also skip the SEH instruction, if needed
1511+
if (NeedsWinCFI && AArch64InstrInfo::isSEHInstruction(*MBBI))
1512+
++MBBI;
1513+
}
15171514
emitFrameOffset(MBB, MBBI, DL, AArch64::SP, AArch64::SP,
15181515
StackOffset::getFixed(CSStackSizeInc), TII, FrameFlag,
1519-
false, false, nullptr, EmitCFI,
1516+
false, NeedsWinCFI, HasWinCFI, EmitCFI,
15201517
StackOffset::getFixed(CFAOffset));
15211518

15221519
return std::prev(MBBI);
15231520
}
15241521

1522+
// Get rid of the SEH code associated with the old instruction.
1523+
if (NeedsWinCFI) {
1524+
auto SEH = std::next(MBBI);
1525+
if (AArch64InstrInfo::isSEHInstruction(*SEH))
1526+
SEH->eraseFromParent();
1527+
}
1528+
15251529
MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(NewOpc));
15261530
MIB.addReg(AArch64::SP, RegState::Define);
15271531

‎llvm/test/CodeGen/AArch64/stack-hazard-windows.ll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ define i32 @fpr_csr_stackobj(double %x) "aarch64_pstate_sm_compatible" "frame-po
7676
; CHECK1024: .seh_proc fpr_csr_stackobj
7777
; CHECK1024-NEXT: // %bb.0: // %entry
7878
; CHECK1024-NEXT: sub sp, sp, #1072
79+
; CHECK1024-NEXT: .seh_stackalloc 1072
7980
; CHECK1024-NEXT: str x23, [sp] // 8-byte Folded Spill
81+
; CHECK1024-NEXT: .seh_save_reg x23, 0
8082
; CHECK1024-NEXT: str x29, [sp, #8] // 8-byte Folded Spill
8183
; CHECK1024-NEXT: .seh_save_reg x29, 8
8284
; CHECK1024-NEXT: str x30, [sp, #16] // 8-byte Folded Spill
@@ -105,7 +107,9 @@ define i32 @fpr_csr_stackobj(double %x) "aarch64_pstate_sm_compatible" "frame-po
105107
; CHECK1024-NEXT: ldr x29, [sp, #8] // 8-byte Folded Reload
106108
; CHECK1024-NEXT: .seh_save_reg x29, 8
107109
; CHECK1024-NEXT: ldr x23, [sp] // 8-byte Folded Reload
110+
; CHECK1024-NEXT: .seh_save_reg x23, 0
108111
; CHECK1024-NEXT: add sp, sp, #1072
112+
; CHECK1024-NEXT: .seh_stackalloc 1072
109113
; CHECK1024-NEXT: .seh_endepilogue
110114
; CHECK1024-NEXT: ret
111115
; CHECK1024-NEXT: .seh_endfunclet
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
; RUN: llc -mtriple=aarch64-windows %s --filetype obj -o /dev/null
2+
; RUN: llc -mtriple=aarch64-windows %s --filetype asm -o - | FileCheck %s
3+
4+
; Check that it doesn't crash and that each instruction in the
5+
; prologue has a corresponding seh directive.
6+
;
7+
; CHECK-NOT: error: Incorrect size for
8+
; CHECK: foo:
9+
; CHECK: .seh_proc foo
10+
; CHECK: sub sp, sp, #288
11+
; CHECK: .seh_stackalloc 288
12+
; CHECK: str x19, [sp] // 8-byte Folded Spill
13+
; CHECK: .seh_save_reg x19, 0
14+
; CHECK: str x21, [sp, #8] // 8-byte Folded Spill
15+
; CHECK: .seh_save_reg x21, 8
16+
; CHECK: stp x23, x24, [sp, #16] // 16-byte Folded Spill
17+
; CHECK: .seh_save_regp x23, 16
18+
; CHECK: stp x25, x26, [sp, #32] // 16-byte Folded Spill
19+
; CHECK: .seh_save_regp x25, 32
20+
; CHECK: stp x27, x28, [sp, #48] // 16-byte Folded Spill
21+
; CHECK: .seh_save_regp x27, 48
22+
; CHECK: stp x29, x30, [sp, #64] // 16-byte Folded Spill
23+
; CHECK: .seh_save_fplr 64
24+
; CHECK: sub sp, sp, #224
25+
; CHECK: .seh_stackalloc 224
26+
; CHECK: .seh_endprologue
27+
28+
target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128-Fn32"
29+
target triple = "aarch64-unknown-windows-msvc19.42.34436"
30+
31+
%swift.refcounted = type { ptr, i64 }
32+
%TScA_pSg = type <{ [16 x i8] }>
33+
%T5repro4TestVSg = type <{ [32 x i8] }>
34+
%T5repro4TestV = type <{ %TSS, %TSS }>
35+
%TSS = type <{ %Ts11_StringGutsV }>
36+
%Ts11_StringGutsV = type <{ %Ts13_StringObjectV }>
37+
%Ts13_StringObjectV = type <{ %Ts6UInt64V, ptr }>
38+
%Ts6UInt64V = type <{ i64 }>
39+
40+
declare swiftcc ptr @swift_task_alloc()
41+
42+
declare swifttailcc void @bar(ptr, ptr, i64, i64, i64, ptr, i64, i64, i64, i64, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr, i64, ptr)
43+
44+
define swifttailcc void @foo(ptr %0, ptr swiftasync %1, ptr swiftself %2, ptr %3, ptr %._guts2._object._object, ptr %.rid4._guts._object._object, ptr %4, ptr %.idx8, ptr %.idx8._guts._object._object, ptr %5, ptr %.rid9._guts._object._object, ptr %6) {
45+
entry:
46+
%7 = load i64, ptr null, align 8
47+
%8 = load i64, ptr %3, align 8
48+
%9 = getelementptr <{ %swift.refcounted, %TScA_pSg, %TSS, %T5repro4TestVSg, %T5repro4TestV, %TSS, %TSS, %TSS, %T5repro4TestV, %TSS, %T5repro4TestV, %T5repro4TestV, %TSS }>, ptr %2, i32 0, i32 2
49+
%10 = load i64, ptr %9, align 8
50+
%11 = load ptr, ptr %1, align 8
51+
%12 = getelementptr <{ %swift.refcounted, %TScA_pSg, %TSS, %T5repro4TestVSg, %T5repro4TestV, %TSS, %TSS, %TSS, %T5repro4TestV, %TSS, %T5repro4TestV, %T5repro4TestV, %TSS }>, ptr %2, i32 0, i32 3
52+
%13 = load i64, ptr %.rid9._guts._object._object, align 8
53+
%14 = load i64, ptr %.idx8._guts._object._object, align 8
54+
%15 = load i64, ptr %5, align 8
55+
%16 = getelementptr { i64, i64, i64, i64 }, ptr %12, i32 0, i32 3
56+
%17 = load i64, ptr %16, align 8
57+
%18 = getelementptr <{ %swift.refcounted, %TScA_pSg, %TSS, %T5repro4TestVSg, %T5repro4TestV, %TSS, %TSS, %TSS, %T5repro4TestV, %TSS, %T5repro4TestV, %T5repro4TestV, %TSS }>, ptr %2, i32 0, i32 4
58+
%19 = load i64, ptr %18, align 8
59+
%.rid._guts._object._object = getelementptr %Ts13_StringObjectV, ptr %18, i32 0, i32 1
60+
%20 = load ptr, ptr %.rid._guts._object._object, align 8
61+
%21 = load i64, ptr %.rid4._guts._object._object, align 8
62+
%22 = load i64, ptr %0, align 8
63+
%23 = load ptr, ptr %6, align 8
64+
%24 = load i64, ptr %2, align 8
65+
%25 = load ptr, ptr %._guts2._object._object, align 8
66+
%26 = getelementptr <{ %swift.refcounted, %TScA_pSg, %TSS, %T5repro4TestVSg, %T5repro4TestV, %TSS, %TSS, %TSS, %T5repro4TestV, %TSS, %T5repro4TestV, %T5repro4TestV, %TSS }>, ptr %2, i32 0, i32 7
67+
%27 = load i64, ptr %26, align 8
68+
%._guts3._object._object = getelementptr %Ts13_StringObjectV, ptr %26, i32 0, i32 1
69+
%28 = load ptr, ptr %._guts3._object._object, align 8
70+
%29 = getelementptr <{ %swift.refcounted, %TScA_pSg, %TSS, %T5repro4TestVSg, %T5repro4TestV, %TSS, %TSS, %TSS, %T5repro4TestV, %TSS, %T5repro4TestV, %T5repro4TestV, %TSS }>, ptr %2, i32 0, i32 8
71+
%30 = load i64, ptr %29, align 8
72+
%.idx5 = getelementptr %T5repro4TestV, ptr %29, i32 0, i32 1
73+
%31 = load i64, ptr %.idx5, align 8
74+
%.idx5._guts._object._object = getelementptr %Ts13_StringObjectV, ptr %.idx5, i32 0, i32 1
75+
%32 = load ptr, ptr %.idx5._guts._object._object, align 8
76+
%33 = getelementptr <{ %swift.refcounted, %TScA_pSg, %TSS, %T5repro4TestVSg, %T5repro4TestV, %TSS, %TSS, %TSS, %T5repro4TestV, %TSS, %T5repro4TestV, %T5repro4TestV, %TSS }>, ptr %2, i32 0, i32 9
77+
%34 = load i64, ptr %33, align 8
78+
%35 = load i64, ptr %4, align 8
79+
%36 = load i64, ptr %.idx8, align 8
80+
%37 = load i64, ptr %1, align 8
81+
%38 = call swiftcc ptr @swift_task_alloc()
82+
store ptr null, ptr %3, align 8
83+
store ptr null, ptr %4, align 8
84+
musttail call swifttailcc void @bar(ptr null, ptr swiftasync %.rid4._guts._object._object, i64 %7, i64 %8, i64 %10, ptr %5, i64 %13, i64 %14, i64 %15, i64 %17, i64 %19, ptr %20, i64 %21, ptr %.idx8, i64 %22, ptr %23, i64 %24, ptr %25, i64 %27, ptr %28, i64 %30, ptr %.idx8._guts._object._object, i64 %31, ptr %32, i64 %34, ptr %._guts2._object._object, i64 %35, ptr %2, i64 %36, ptr %1, i64 %37, ptr %0, i64 0, ptr null, i64 0, ptr null)
85+
ret void
86+
}

0 commit comments

Comments
 (0)
Please sign in to comment.