• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: llc -mtriple=x86_64-apple-darwin10.6 < %s | FileCheck %s
2; RUN: llc -mtriple=x86_64-linux < %s | FileCheck %s --check-prefix=NOCOMPACTUNWIND
3;
4; Note: This test cannot be merged with the shrink-wrapping tests
5; because the booleans set on the command line take precedence on
6; the target logic that disable shrink-wrapping.
7
8; The current compact unwind scheme does not work when the prologue is not at
9; the start (the instructions before the prologue cannot be described).
10; Currently we choose to not perform shrink-wrapping for functions without FP
11; not marked as nounwind. PR25614
12;
13; No shrink-wrapping should occur here, until the CFI information are fixed.
14; CHECK-LABEL: framelessUnwind:
15;
16; Prologue code.
17; (What we push does not matter. It should be some random sratch register.)
18; CHECK: pushq
19;
20; Compare the arguments and jump to exit.
21; After the prologue is set.
22; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]]
23; CHECK-NEXT: cmpl %esi, %edi
24; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]]
25;
26; Store %a in the alloca.
27; CHECK: movl [[ARG0CPY]], 4(%rsp)
28; Set the alloca address in the second argument.
29; CHECK-NEXT: leaq 4(%rsp), %rsi
30; Set the first argument to zero.
31; CHECK-NEXT: xorl %edi, %edi
32; CHECK-NEXT: callq _doSomething
33;
34; CHECK: [[EXIT_LABEL]]:
35;
36; Without shrink-wrapping, epilogue is in the exit block.
37; Epilogue code. (What we pop does not matter.)
38; CHECK-NEXT: popq
39;
40; CHECK-NEXT: retq
41
42; On a platform which does not support compact unwind, shrink wrapping is enabled.
43; NOCOMPACTUNWIND-LABEL: framelessUnwind:
44; NOCOMPACTUNWIND-NOT:     pushq
45; NOCOMPACTUNWIND:       # %bb.1:
46; NOCOMPACTUNWIND-NEXT:    pushq %rax
47define i32 @framelessUnwind(i32 %a, i32 %b) #0 {
48  %tmp = alloca i32, align 4
49  %tmp2 = icmp slt i32 %a, %b
50  br i1 %tmp2, label %true, label %false
51
52true:
53  store i32 %a, i32* %tmp, align 4
54  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
55  br label %false
56
57false:
58  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
59  ret i32 %tmp.0
60}
61
62declare i32 @doSomething(i32, i32*)
63
64attributes #0 = { "frame-pointer"="none" }
65
66; Shrink-wrapping should occur here. We have a frame pointer.
67; CHECK-LABEL: frameUnwind:
68;
69; Compare the arguments and jump to exit.
70; No prologue needed.
71;
72; Compare the arguments and jump to exit.
73; After the prologue is set.
74; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]]
75; CHECK-NEXT: cmpl %esi, %edi
76; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]]
77;
78; Prologue code.
79; CHECK: pushq %rbp
80; CHECK: movq %rsp, %rbp
81;
82; Store %a in the alloca.
83; CHECK: movl [[ARG0CPY]], -4(%rbp)
84; Set the alloca address in the second argument.
85; CHECK-NEXT: leaq -4(%rbp), %rsi
86; Set the first argument to zero.
87; CHECK-NEXT: xorl %edi, %edi
88; CHECK-NEXT: callq _doSomething
89;
90; Epilogue code. (What we pop does not matter.)
91; CHECK: popq %rbp
92;
93; CHECK: [[EXIT_LABEL]]:
94; CHECK-NEXT: retq
95define i32 @frameUnwind(i32 %a, i32 %b) #1 {
96  %tmp = alloca i32, align 4
97  %tmp2 = icmp slt i32 %a, %b
98  br i1 %tmp2, label %true, label %false
99
100true:
101  store i32 %a, i32* %tmp, align 4
102  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
103  br label %false
104
105false:
106  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
107  ret i32 %tmp.0
108}
109
110attributes #1 = { "frame-pointer"="all" }
111
112; Shrink-wrapping should occur here. We do not have to unwind.
113; CHECK-LABEL: framelessnoUnwind:
114;
115; Compare the arguments and jump to exit.
116; No prologue needed.
117;
118; Compare the arguments and jump to exit.
119; After the prologue is set.
120; CHECK: movl %edi, [[ARG0CPY:%e[a-z]+]]
121; CHECK-NEXT: cmpl %esi, %edi
122; CHECK-NEXT: jge [[EXIT_LABEL:LBB[0-9_]+]]
123;
124; Prologue code.
125; (What we push does not matter. It should be some random sratch register.)
126; CHECK: pushq
127;
128; Store %a in the alloca.
129; CHECK: movl [[ARG0CPY]], 4(%rsp)
130; Set the alloca address in the second argument.
131; CHECK-NEXT: leaq 4(%rsp), %rsi
132; Set the first argument to zero.
133; CHECK-NEXT: xorl %edi, %edi
134; CHECK-NEXT: callq _doSomething
135;
136; Epilogue code.
137; CHECK-NEXT: addq
138;
139; CHECK: [[EXIT_LABEL]]:
140; CHECK-NEXT: retq
141define i32 @framelessnoUnwind(i32 %a, i32 %b) #2 {
142  %tmp = alloca i32, align 4
143  %tmp2 = icmp slt i32 %a, %b
144  br i1 %tmp2, label %true, label %false
145
146true:
147  store i32 %a, i32* %tmp, align 4
148  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
149  br label %false
150
151false:
152  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
153  ret i32 %tmp.0
154}
155
156attributes #2 = { "frame-pointer"="none" nounwind }
157
158
159; Check that we generate correct code for segmented stack.
160; We used to emit the code at the entry point of the function
161; instead of just before the prologue.
162; For now, shrink-wrapping is disabled on segmented stack functions: PR26107.
163;
164; CHECK-LABEL: segmentedStack:
165; CHECK: cmpq
166; CHECK-NEXT: jbe [[ENTRY_LABEL:LBB[0-9_]+]]
167;
168; In PR26107, we use to drop these two basic blocks, because
169; the segmentedStack entry block was jumping directly to
170; the place where the prologue is actually needed, which is
171; the call to memcmp.
172; Then, those two basic blocks did not have any predecessors
173; anymore and were removed.
174;
175; Check if vk1 is null
176; CHECK: testq %rdi, %rdi
177; CHECK-NEXT: je [[STRINGS_EQUAL:LBB[0-9_]+]]
178;
179; Check if vk2 is null
180; CHECK: testq %rsi, %rsi
181; CHECK-NEXT:  je [[STRINGS_EQUAL]]
182;
183; CHECK: [[STRINGS_EQUAL]]
184; CHECK: popq
185;
186; CHECK: [[ENTRY_LABEL]]:
187; CHECK: callq ___morestack
188; CHECK-NEXT: retq
189;
190
191define zeroext i1 @segmentedStack(i8* readonly %vk1, i8* readonly %vk2, i64 %key_size) #5 {
192entry:
193  %cmp.i = icmp eq i8* %vk1, null
194  %cmp1.i = icmp eq i8* %vk2, null
195  %brmerge.i = or i1 %cmp.i, %cmp1.i
196  %cmp1.mux.i = and i1 %cmp.i, %cmp1.i
197  br i1 %brmerge.i, label %__go_ptr_strings_equal.exit, label %if.end4.i
198
199if.end4.i:                                        ; preds = %entry
200  %tmp = getelementptr inbounds i8, i8* %vk1, i64 8
201  %tmp1 = bitcast i8* %tmp to i64*
202  %tmp2 = load i64, i64* %tmp1, align 8
203  %tmp3 = getelementptr inbounds i8, i8* %vk2, i64 8
204  %tmp4 = bitcast i8* %tmp3 to i64*
205  %tmp5 = load i64, i64* %tmp4, align 8
206  %cmp.i.i = icmp eq i64 %tmp2, %tmp5
207  br i1 %cmp.i.i, label %land.rhs.i.i, label %__go_ptr_strings_equal.exit
208
209land.rhs.i.i:                                     ; preds = %if.end4.i
210  %tmp6 = bitcast i8* %vk2 to i8**
211  %tmp7 = load i8*, i8** %tmp6, align 8
212  %tmp8 = bitcast i8* %vk1 to i8**
213  %tmp9 = load i8*, i8** %tmp8, align 8
214  %call.i.i = tail call i32 @memcmp(i8* %tmp9, i8* %tmp7, i64 %tmp2) #5
215  %cmp4.i.i = icmp eq i32 %call.i.i, 0
216  br label %__go_ptr_strings_equal.exit
217
218__go_ptr_strings_equal.exit:                      ; preds = %land.rhs.i.i, %if.end4.i, %entry
219  %retval.0.i = phi i1 [ %cmp1.mux.i, %entry ], [ false, %if.end4.i ], [ %cmp4.i.i, %land.rhs.i.i ]
220  ret i1 %retval.0.i
221}
222
223; Function Attrs: nounwind readonly
224declare i32 @memcmp(i8* nocapture, i8* nocapture, i64) #5
225
226attributes #5 = { nounwind readonly ssp uwtable "split-stack" }
227
228; Check that correctly take into account the jumps to landing pad.
229; We used to consider function that may throw like regular
230; function calls.
231; Therefore, in this example, we were happily inserting the epilogue
232; right after the call to throw_exception. Because of that we would not
233; execute the epilogue when an execption occur and bad things will
234; happen.
235; PR36513
236;
237; CHECK-LABEL: with_nounwind:
238; Prologue
239; CHECK: push
240;
241; Jump to throw_exception:
242; CHECK-NEXT: .cfi_def_cfa_offset
243; CHECK-NEXT: testb $1, %dil
244; CHECK-NEXT: jne [[THROW_LABEL:LBB[0-9_]+]]
245; Else return exit
246; CHECK: popq
247; CHECK-NEXT: retq
248;
249; CHECK-NEXT: [[THROW_LABEL]]:
250; CHECK: callq	_throw_exception
251; Unreachable block...
252;
253; Epilogue must be after the landing pad.
254; CHECK-NOT: popq
255;
256; Look for the landing pad label.
257; CHECK: LBB{{[0-9_]+}}:
258; Epilogue on the landing pad
259; CHECK: popq
260; CHECK-NEXT: retq
261define void @with_nounwind(i1 %cond) nounwind personality i32 (...)* @my_personality {
262entry:
263  br i1 %cond, label %throw, label %return
264
265throw:
266  invoke void @throw_exception()
267          to label %unreachable unwind label %landing
268
269unreachable:
270  unreachable
271
272landing:
273  %pad = landingpad { i8*, i32 }
274          catch i8* null
275  ret void
276
277return:
278  ret void
279}
280
281; Check landing pad again.
282; This time checks that we can shrink-wrap when the epilogue does not
283; span accross several blocks.
284;
285; CHECK-LABEL: with_nounwind_same_succ:
286;
287; Jump to throw_exception:
288; CHECK: testb $1, %dil
289; CHECK-NEXT: je [[RET_LABEL:LBB[0-9_]+]]
290;
291; Prologue
292; CHECK: push
293; CHECK: callq	_throw_exception
294;
295; Fallthrough label
296; CHECK: [[FALLTHROUGH_LABEL:LBB[0-9_]+]]
297; CHECK: nop
298; CHECK: popq
299;
300; CHECK: [[RET_LABEL]]
301; CHECK: retq
302;
303; Look for the landing pad label.
304; CHECK: LBB{{[0-9_]+}}:
305; Landing pad jumps to fallthrough
306; CHECK: jmp [[FALLTHROUGH_LABEL]]
307define void @with_nounwind_same_succ(i1 %cond) nounwind personality i32 (...)* @my_personality2 {
308entry:
309  br i1 %cond, label %throw, label %return
310
311throw:
312  invoke void @throw_exception()
313          to label %fallthrough unwind label %landing
314landing:
315  %pad = landingpad { i8*, i32 }
316          catch i8* null
317  br label %fallthrough
318
319fallthrough:
320  tail call void asm "nop", ""()
321  br label %return
322
323return:
324  ret void
325}
326
327declare void @throw_exception()
328declare i32 @my_personality(...)
329declare i32 @my_personality2(...)
330