Skip to content

Commit 0df6e25

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 0df6e25

File tree

2 files changed

+173
-1
lines changed

2 files changed

+173
-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: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
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 r1, #0
66+
; CHECK-NEXT: mov r0, r1
67+
; CHECK-NEXT: bl _foo2
68+
; CHECK-NEXT: Ltmp1:
69+
; CHECK-NEXT: b LBB0_2
70+
; CHECK-NEXT: LBB0_2:
71+
; CHECK-NEXT: movs r0, #2
72+
; CHECK-NEXT: str r0, [sp, #16]
73+
; CHECK-NEXT: movw r0, :lower16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_6+4))
74+
; CHECK-NEXT: movt r0, :upper16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_6+4))
75+
; CHECK-NEXT: LPC0_6:
76+
; CHECK-NEXT: add r0, pc
77+
; CHECK-NEXT: ldr r0, [r0]
78+
; CHECK-NEXT: ldr r0, [r0]
79+
; CHECK-NEXT: ldr r1, [sp, #92]
80+
; CHECK-NEXT: cmp r0, r1
81+
; CHECK-NEXT: bne LBB0_7
82+
; CHECK-NEXT: @ %bb.3: @ %SP_return2
83+
; CHECK-NEXT: Ltmp2:
84+
; CHECK-NEXT: movs r2, #0
85+
; CHECK-NEXT: mov r0, r2
86+
; CHECK-NEXT: mov r1, r2
87+
; CHECK-NEXT: bl _foo3
88+
; CHECK-NEXT: Ltmp3:
89+
; CHECK-NEXT: b LBB0_6
90+
; CHECK-NEXT: LBB0_4:
91+
; CHECK-NEXT: Ltmp4:
92+
; CHECK-NEXT: ldr r0, [sp, #20]
93+
; CHECK-NEXT: ldr r0, [sp, #24]
94+
; CHECK-NEXT: add r0, sp, #12
95+
; CHECK-NEXT: bl __Unwind_SjLj_Unregister
96+
; CHECK-NEXT: movw r0, :lower16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_7+4))
97+
; CHECK-NEXT: movt r0, :upper16:(L___stack_chk_guard$non_lazy_ptr-(LPC0_7+4))
98+
; CHECK-NEXT: LPC0_7:
99+
; CHECK-NEXT: add r0, pc
100+
; CHECK-NEXT: ldr r0, [r0]
101+
; CHECK-NEXT: ldr r0, [r0]
102+
; CHECK-NEXT: ldr r1, [sp, #92]
103+
; CHECK-NEXT: cmp r0, r1
104+
; CHECK-NEXT: bne LBB0_7
105+
; CHECK-NEXT: @ %bb.5: @ %SP_return3
106+
; CHECK-NEXT: movs r0, #0
107+
; CHECK-NEXT: add r4, sp, #96
108+
; CHECK-NEXT: vld1.64 {d8, d9, d10, d11}, [r4:128]!
109+
; CHECK-NEXT: vld1.64 {d12, d13, d14, d15}, [r4:128]
110+
; CHECK-NEXT: sub.w r4, r7, #24
111+
; CHECK-NEXT: mov sp, r4
112+
; CHECK-NEXT: pop.w {r8, r10, r11}
113+
; CHECK-NEXT: pop {r4, r5, r6, r7, pc}
114+
; CHECK-NEXT: LBB0_6:
115+
; CHECK-NEXT: trap
116+
; CHECK-NEXT: LBB0_7: @ %CallStackCheckFailBlk
117+
; CHECK-NEXT: bl ___stack_chk_fail
118+
; CHECK-NEXT: LBB0_8:
119+
; CHECK-NEXT: ldr r0, [sp, #16]
120+
; CHECK-NEXT: str r0, [sp, #8] @ 4-byte Spill
121+
; CHECK-NEXT: cmp r0, #2
122+
; CHECK-NEXT: bhi LBB0_12
123+
; CHECK-NEXT: @ %bb.9:
124+
; CHECK-NEXT: ldr r1, [sp, #8] @ 4-byte Reload
125+
; CHECK-NEXT: LCPI0_2:
126+
; CHECK-NEXT: tbb [pc, r1]
127+
; CHECK-NEXT: @ %bb.10:
128+
; CHECK-NEXT: LJTI0_0:
129+
; CHECK-NEXT: .data_region jt8
130+
; CHECK-NEXT: .byte (LBB0_11-(LCPI0_2+4))/2
131+
; CHECK-NEXT: .byte (LBB0_11-(LCPI0_2+4))/2
132+
; CHECK-NEXT: .end_data_region
133+
; CHECK-NEXT: .p2align 1
134+
; CHECK-NEXT: LBB0_11:
135+
; CHECK-NEXT: b LBB0_4
136+
; CHECK-NEXT: LBB0_12:
137+
; CHECK-NEXT: trap
138+
; CHECK-NEXT: .p2align 2
139+
; CHECK-NEXT: @ %bb.13:
140+
%1 = alloca [14 x i8], align 16
141+
%2 = invoke i32 @"foo2"(ptr noundef null, ptr noundef null) #1
142+
to label %3 unwind label %4
143+
144+
3: ; preds = %0
145+
invoke void @"foo3"(ptr null, ptr null, ptr null) #2
146+
to label %6 unwind label %4
147+
148+
4: ; preds = %3, %0
149+
%5 = landingpad { ptr, i32 }
150+
cleanup
151+
ret ptr null
152+
153+
6: ; preds = %3
154+
unreachable
155+
}
156+
157+
declare i32 @__gxx_personality_sj0(...)
158+
declare i32 @foo2(ptr,ptr)
159+
declare void @foo3(ptr,ptr,ptr)
160+
; uselistorder directives
161+
uselistorder ptr null, { 2, 3, 4, 5, 0, 6, 7, 1, 8, 9 }
162+
163+
attributes #0 = { mustprogress ssp "frame-pointer"="all" "no-builtin-calloc" "no-builtin-stpcpy" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
164+
attributes #2 = { noreturn }

0 commit comments

Comments
 (0)