Skip to content

Commit 4348e3d

Browse files
committed
[CodeGen][ARM] Bug fix InsertStackProtectors with EH_SJ_LJ
when exception handling with setjmp/longjmp (exception-mode=eh_sjlj is enabled, eh_sjlj_callsite intrinsic is inserted in same basic block as the throwing/exception instruction. This fix ensures stack protector insertion code does not split the block and move these apart into different basic blocks.
1 parent 0d7b34b commit 4348e3d

File tree

2 files changed

+175
-1
lines changed

2 files changed

+175
-1
lines changed

llvm/lib/CodeGen/StackProtector.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,14 +588,22 @@ bool InsertStackProtectors(const TargetMachine *TM, Function *F,
588588
continue;
589589
Instruction *CheckLoc = dyn_cast<ReturnInst>(BB.getTerminator());
590590
if (!CheckLoc && !DisableCheckNoReturn)
591-
for (auto &Inst : BB)
591+
for (auto &Inst : BB) {
592+
if(auto *IB = dyn_cast<IntrinsicInst>(&Inst) )
593+
if(IB->getIntrinsicID()==Intrinsic::eh_sjlj_callsite) {
594+
// eh_sjlj_callsite has to be in same BB as the
595+
// bb terminator. Dont insert within this range.
596+
CheckLoc = IB;
597+
break;
598+
}
592599
if (auto *CB = dyn_cast<CallBase>(&Inst))
593600
// Do stack check before noreturn calls that aren't nounwind (e.g:
594601
// __cxa_throw).
595602
if (CB->doesNotReturn() && !CB->doesNotThrow()) {
596603
CheckLoc = CB;
597604
break;
598605
}
606+
}
599607

600608
if (!CheckLoc)
601609
continue;
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
2+
; RUN: llc -O0 -mtriple=thumbv7s-apple-darwin < %s | FileCheck %s
3+
target datalayout = "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
4+
5+
; Function Attrs: mustprogress noinline optnone ssp
6+
define ptr @foo() #0 personality ptr @__gxx_personality_sj0 {
7+
; CHECK-LABEL: foo:
8+
; CHECK: Lfunc_begin0:
9+
; CHECK-NEXT: @ %bb.0:
10+
; CHECK-NEXT: push {r4, r5, r6, r7, lr}
11+
; CHECK-NEXT: add r7, sp, #12
12+
; CHECK-NEXT: push.w {r8, r10, r11}
13+
; CHECK-NEXT: sub.w r4, sp, #64
14+
; CHECK-NEXT: bfc r4, #0, #4
15+
; CHECK-NEXT: mov sp, r4
16+
; CHECK-NEXT: vst1.64 {d8, d9, d10, d11}, [r4:128]!
17+
; CHECK-NEXT: vst1.64 {d12, d13, d14, d15}, [r4:128]
18+
; CHECK-NEXT: sub sp, #96
19+
; CHECK-NEXT: movw r0, :lower16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_2+4))
20+
; CHECK-NEXT: movt r0, :upper16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_2+4))
21+
; CHECK-NEXT: LPC0_2:
22+
; CHECK-NEXT: add r0, pc
23+
; CHECK-NEXT: ldr r0, [r0]
24+
; CHECK-NEXT: ldr r0, [r0]
25+
; CHECK-NEXT: movw r0, :lower16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_3+4))
26+
; CHECK-NEXT: movt r0, :upper16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_3+4))
27+
; CHECK-NEXT: LPC0_3:
28+
; CHECK-NEXT: add r0, pc
29+
; CHECK-NEXT: ldr r0, [r0]
30+
; CHECK-NEXT: ldr r0, [r0]
31+
; CHECK-NEXT: str r0, [sp, #92]
32+
; CHECK-NEXT: movw r0, :lower16:(L___gxx_personality_sj0$non_lazy_ptr-(LPC0_4+4))
33+
; CHECK-NEXT: movt r0, :upper16:(L___gxx_personality_sj0$non_lazy_ptr-(LPC0_4+4))
34+
; CHECK-NEXT: LPC0_4:
35+
; CHECK-NEXT: add r0, pc
36+
; CHECK-NEXT: ldr r0, [r0]
37+
; CHECK-NEXT: str r0, [sp, #36]
38+
; CHECK-NEXT: ldr r0, LCPI0_0
39+
; CHECK-NEXT: LPC0_0:
40+
; CHECK-NEXT: add r0, pc
41+
; CHECK-NEXT: str r0, [sp, #40]
42+
; CHECK-NEXT: str r7, [sp, #44]
43+
; CHECK-NEXT: mov r0, sp
44+
; CHECK-NEXT: str r0, [sp, #52]
45+
; CHECK-NEXT: ldr r0, LCPI0_1
46+
; CHECK-NEXT: orr r0, r0, #1
47+
; CHECK-NEXT: LPC0_1:
48+
; CHECK-NEXT: add r0, pc
49+
; CHECK-NEXT: str r0, [sp, #48]
50+
; CHECK-NEXT: add r0, sp, #12
51+
; CHECK-NEXT: bl __Unwind_SjLj_Register
52+
; CHECK-NEXT: movs r0, #1
53+
; CHECK-NEXT: str r0, [sp, #16]
54+
; CHECK-NEXT: movw r0, :lower16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_5+4))
55+
; CHECK-NEXT: movt r0, :upper16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_5+4))
56+
; CHECK-NEXT: LPC0_5:
57+
; CHECK-NEXT: add r0, pc
58+
; CHECK-NEXT: ldr r0, [r0]
59+
; CHECK-NEXT: ldr r0, [r0]
60+
; CHECK-NEXT: ldr r1, [sp, #92]
61+
; CHECK-NEXT: cmp r0, r1
62+
; CHECK-NEXT: bne LBB0_7
63+
; CHECK-NEXT: @ %bb.1: @ %SP_return
64+
; CHECK-NEXT: Ltmp0:
65+
; CHECK-NEXT: movs r2, #0
66+
; CHECK-NEXT: mov r0, r2
67+
; CHECK-NEXT: mov r1, r2
68+
; CHECK-NEXT: blx r2
69+
; CHECK-NEXT: Ltmp1:
70+
; CHECK-NEXT: b LBB0_2
71+
; CHECK-NEXT: LBB0_2:
72+
; CHECK-NEXT: movs r0, #2
73+
; CHECK-NEXT: str r0, [sp, #16]
74+
; CHECK-NEXT: movw r0, :lower16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_6+4))
75+
; CHECK-NEXT: movt r0, :upper16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_6+4))
76+
; CHECK-NEXT: LPC0_6:
77+
; CHECK-NEXT: add r0, pc
78+
; CHECK-NEXT: ldr r0, [r0]
79+
; CHECK-NEXT: ldr r0, [r0]
80+
; CHECK-NEXT: ldr r1, [sp, #92]
81+
; CHECK-NEXT: cmp r0, r1
82+
; CHECK-NEXT: bne LBB0_7
83+
; CHECK-NEXT: @ %bb.3: @ %SP_return2
84+
; CHECK-NEXT: Ltmp2:
85+
; CHECK-NEXT: movs r3, #0
86+
; CHECK-NEXT: mov r0, r3
87+
; CHECK-NEXT: mov r1, r3
88+
; CHECK-NEXT: mov r2, r3
89+
; CHECK-NEXT: blx r3
90+
; CHECK-NEXT: Ltmp3:
91+
; CHECK-NEXT: b LBB0_6
92+
; CHECK-NEXT: LBB0_4:
93+
; CHECK-NEXT: Ltmp4:
94+
; CHECK-NEXT: ldr r0, [sp, #20]
95+
; CHECK-NEXT: ldr r0, [sp, #24]
96+
; CHECK-NEXT: add r0, sp, #12
97+
; CHECK-NEXT: bl __Unwind_SjLj_Unregister
98+
; CHECK-NEXT: movw r0, :lower16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_7+4))
99+
; CHECK-NEXT: movt r0, :upper16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_7+4))
100+
; CHECK-NEXT: LPC0_7:
101+
; CHECK-NEXT: add r0, pc
102+
; CHECK-NEXT: ldr r0, [r0]
103+
; CHECK-NEXT: ldr r0, [r0]
104+
; CHECK-NEXT: ldr r1, [sp, #92]
105+
; CHECK-NEXT: cmp r0, r1
106+
; CHECK-NEXT: bne LBB0_7
107+
; CHECK-NEXT: @ %bb.5: @ %SP_return3
108+
; CHECK-NEXT: movs r0, #0
109+
; CHECK-NEXT: add r4, sp, #96
110+
; CHECK-NEXT: vld1.64 {d8, d9, d10, d11}, [r4:128]!
111+
; CHECK-NEXT: vld1.64 {d12, d13, d14, d15}, [r4:128]
112+
; CHECK-NEXT: sub.w r4, r7, #24
113+
; CHECK-NEXT: mov sp, r4
114+
; CHECK-NEXT: pop.w {r8, r10, r11}
115+
; CHECK-NEXT: pop {r4, r5, r6, r7, pc}
116+
; CHECK-NEXT: LBB0_6:
117+
; CHECK-NEXT: trap
118+
; CHECK-NEXT: LBB0_7: @ %CallStackCheckFailBlk
119+
; CHECK-NEXT: bl ___stack_chk_fail
120+
; CHECK-NEXT: LBB0_8:
121+
; CHECK-NEXT: ldr r0, [sp, #16]
122+
; CHECK-NEXT: str r0, [sp, #8] @ 4-byte Spill
123+
; CHECK-NEXT: cmp r0, #2
124+
; CHECK-NEXT: bhi LBB0_12
125+
; CHECK-NEXT: @ %bb.9:
126+
; CHECK-NEXT: ldr r1, [sp, #8] @ 4-byte Reload
127+
; CHECK-NEXT: LCPI0_2:
128+
; CHECK-NEXT: tbb [pc, r1]
129+
; CHECK-NEXT: @ %bb.10:
130+
; CHECK-NEXT: LJTI0_0:
131+
; CHECK-NEXT: .data_region jt8
132+
; CHECK-NEXT: .byte (LBB0_11-(LCPI0_2+4))/2
133+
; CHECK-NEXT: .byte (LBB0_11-(LCPI0_2+4))/2
134+
; CHECK-NEXT: .end_data_region
135+
; CHECK-NEXT: .p2align 1
136+
; CHECK-NEXT: LBB0_11:
137+
; CHECK-NEXT: b LBB0_4
138+
; CHECK-NEXT: LBB0_12:
139+
; CHECK-NEXT: trap
140+
; CHECK-NEXT: .p2align 2
141+
; CHECK-NEXT: @ %bb.13:
142+
%1 = alloca [14 x i8], align 16
143+
%2 = invoke i32 null(ptr noundef null, ptr noundef null) #1
144+
to label %3 unwind label %4
145+
146+
3: ; preds = %0
147+
invoke void null(ptr null, ptr null, ptr null) #2
148+
to label %6 unwind label %4
149+
150+
4: ; preds = %3, %0
151+
%5 = landingpad { ptr, i32 }
152+
cleanup
153+
ret ptr null
154+
155+
6: ; preds = %3
156+
unreachable
157+
}
158+
159+
declare i32 @__gxx_personality_sj0(...)
160+
161+
; uselistorder directives
162+
uselistorder ptr null, { 2, 3, 4, 5, 0, 6, 7, 1, 8, 9 }
163+
164+
attributes #0 = { mustprogress ssp "frame-pointer"="all" "no-builtin-calloc" "no-builtin-stpcpy" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
165+
attributes #1 = { "no-builtin-calloc" "no-builtin-stpcpy" }
166+
attributes #2 = { noreturn }

0 commit comments

Comments
 (0)