xref: /llvm-project/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll (revision 7a0e222a17058a311b69153d0b6f1b4459414778)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -debugify-and-strip-all-safe %s -o - -mtriple=arm64-apple-ios -enable-shrink-wrap=true -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=ENABLE
3; RUN: llc -debugify-and-strip-all-safe %s -o - -enable-shrink-wrap=false -disable-post-ra -frame-pointer=non-leaf | FileCheck %s --check-prefix=DISABLE
4target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
5target triple = "arm64-apple-ios"
6
7
8; Initial motivating example: Simple diamond with a call just on one side.
9define i32 @foo(i32 %a, i32 %b) {
10; ENABLE-LABEL: foo:
11; ENABLE:       ; %bb.0:
12; ENABLE-NEXT:    cmp w0, w1
13; ENABLE-NEXT:    b.ge LBB0_2
14; ENABLE-NEXT:  ; %bb.1: ; %true
15; ENABLE-NEXT:    sub sp, sp, #32
16; ENABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
17; ENABLE-NEXT:    add x29, sp, #16
18; ENABLE-NEXT:    .cfi_def_cfa w29, 16
19; ENABLE-NEXT:    .cfi_offset w30, -8
20; ENABLE-NEXT:    .cfi_offset w29, -16
21; ENABLE-NEXT:    stur w0, [x29, #-4]
22; ENABLE-NEXT:    sub x1, x29, #4
23; ENABLE-NEXT:    mov w0, wzr
24; ENABLE-NEXT:    bl _doSomething
25; ENABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
26; ENABLE-NEXT:    add sp, sp, #32
27; ENABLE-NEXT:  LBB0_2: ; %false
28; ENABLE-NEXT:    ret
29;
30; DISABLE-LABEL: foo:
31; DISABLE:       ; %bb.0:
32; DISABLE-NEXT:    sub sp, sp, #32
33; DISABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
34; DISABLE-NEXT:    add x29, sp, #16
35; DISABLE-NEXT:    .cfi_def_cfa w29, 16
36; DISABLE-NEXT:    .cfi_offset w30, -8
37; DISABLE-NEXT:    .cfi_offset w29, -16
38; DISABLE-NEXT:    cmp w0, w1
39; DISABLE-NEXT:    b.ge LBB0_2
40; DISABLE-NEXT:  ; %bb.1: ; %true
41; DISABLE-NEXT:    stur w0, [x29, #-4]
42; DISABLE-NEXT:    sub x1, x29, #4
43; DISABLE-NEXT:    mov w0, wzr
44; DISABLE-NEXT:    bl _doSomething
45; DISABLE-NEXT:  LBB0_2: ; %false
46; DISABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
47; DISABLE-NEXT:    add sp, sp, #32
48; DISABLE-NEXT:    ret
49  %tmp = alloca i32, align 4
50  %tmp2 = icmp slt i32 %a, %b
51  br i1 %tmp2, label %true, label %false
52
53true:
54  store i32 %a, ptr %tmp, align 4
55  %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
56  br label %false
57
58false:
59  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
60  ret i32 %tmp.0
61}
62
63; Function Attrs: optsize
64declare i32 @doSomething(i32, ptr)
65
66
67; Check that we do not perform the restore inside the loop whereas the save
68; is outside.
69define i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) {
70; ENABLE-LABEL: freqSaveAndRestoreOutsideLoop:
71; ENABLE:       ; %bb.0: ; %entry
72; ENABLE-NEXT:    cbz w0, LBB1_4
73; ENABLE-NEXT:  ; %bb.1: ; %for.body.preheader
74; ENABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
75; ENABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
76; ENABLE-NEXT:    add x29, sp, #16
77; ENABLE-NEXT:    .cfi_def_cfa w29, 16
78; ENABLE-NEXT:    .cfi_offset w30, -8
79; ENABLE-NEXT:    .cfi_offset w29, -16
80; ENABLE-NEXT:    .cfi_offset w19, -24
81; ENABLE-NEXT:    .cfi_offset w20, -32
82; ENABLE-NEXT:    mov w19, wzr
83; ENABLE-NEXT:    mov w20, #10 ; =0xa
84; ENABLE-NEXT:  LBB1_2: ; %for.body
85; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
86; ENABLE-NEXT:    bl _something
87; ENABLE-NEXT:    subs w20, w20, #1
88; ENABLE-NEXT:    add w19, w0, w19
89; ENABLE-NEXT:    b.ne LBB1_2
90; ENABLE-NEXT:  ; %bb.3: ; %for.end
91; ENABLE-NEXT:    lsl w0, w19, #3
92; ENABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
93; ENABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
94; ENABLE-NEXT:    ret
95; ENABLE-NEXT:  LBB1_4: ; %if.else
96; ENABLE-NEXT:    lsl w0, w1, #1
97; ENABLE-NEXT:    ret
98;
99; DISABLE-LABEL: freqSaveAndRestoreOutsideLoop:
100; DISABLE:       ; %bb.0: ; %entry
101; DISABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
102; DISABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
103; DISABLE-NEXT:    add x29, sp, #16
104; DISABLE-NEXT:    .cfi_def_cfa w29, 16
105; DISABLE-NEXT:    .cfi_offset w30, -8
106; DISABLE-NEXT:    .cfi_offset w29, -16
107; DISABLE-NEXT:    .cfi_offset w19, -24
108; DISABLE-NEXT:    .cfi_offset w20, -32
109; DISABLE-NEXT:    cbz w0, LBB1_4
110; DISABLE-NEXT:  ; %bb.1: ; %for.body.preheader
111; DISABLE-NEXT:    mov w19, wzr
112; DISABLE-NEXT:    mov w20, #10 ; =0xa
113; DISABLE-NEXT:  LBB1_2: ; %for.body
114; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
115; DISABLE-NEXT:    bl _something
116; DISABLE-NEXT:    subs w20, w20, #1
117; DISABLE-NEXT:    add w19, w0, w19
118; DISABLE-NEXT:    b.ne LBB1_2
119; DISABLE-NEXT:  ; %bb.3: ; %for.end
120; DISABLE-NEXT:    lsl w0, w19, #3
121; DISABLE-NEXT:    b LBB1_5
122; DISABLE-NEXT:  LBB1_4: ; %if.else
123; DISABLE-NEXT:    lsl w0, w1, #1
124; DISABLE-NEXT:  LBB1_5: ; %if.end
125; DISABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
126; DISABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
127; DISABLE-NEXT:    ret
128entry:
129  %tobool = icmp eq i32 %cond, 0
130  br i1 %tobool, label %if.else, label %for.body
131
132for.body:                                         ; preds = %entry, %for.body
133  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
134  %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ]
135  %call = tail call i32 @something()
136  %add = add nsw i32 %call, %sum.04
137  %inc = add nuw nsw i32 %i.05, 1
138  %exitcond = icmp eq i32 %inc, 10
139  br i1 %exitcond, label %for.end, label %for.body
140
141for.end:                                          ; preds = %for.body
142  %shl = shl i32 %add, 3
143  br label %if.end
144
145if.else:                                          ; preds = %entry
146  %mul = shl nsw i32 %N, 1
147  br label %if.end
148
149if.end:                                           ; preds = %if.else, %for.end
150  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
151  ret i32 %sum.1
152}
153
154declare i32 @something(...)
155
156; Check that we do not perform the shrink-wrapping inside the loop even
157; though that would be legal. The cost model must prevent that.
158define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) {
159; ENABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
160; ENABLE:       ; %bb.0: ; %entry
161; ENABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
162; ENABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
163; ENABLE-NEXT:    add x29, sp, #16
164; ENABLE-NEXT:    .cfi_def_cfa w29, 16
165; ENABLE-NEXT:    .cfi_offset w30, -8
166; ENABLE-NEXT:    .cfi_offset w29, -16
167; ENABLE-NEXT:    .cfi_offset w19, -24
168; ENABLE-NEXT:    .cfi_offset w20, -32
169; ENABLE-NEXT:    mov w19, wzr
170; ENABLE-NEXT:    mov w20, #10 ; =0xa
171; ENABLE-NEXT:  LBB2_1: ; %for.body
172; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
173; ENABLE-NEXT:    bl _something
174; ENABLE-NEXT:    subs w20, w20, #1
175; ENABLE-NEXT:    add w19, w0, w19
176; ENABLE-NEXT:    b.ne LBB2_1
177; ENABLE-NEXT:  ; %bb.2: ; %for.end
178; ENABLE-NEXT:    mov w0, w19
179; ENABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
180; ENABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
181; ENABLE-NEXT:    ret
182;
183; DISABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
184; DISABLE:       ; %bb.0: ; %entry
185; DISABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
186; DISABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
187; DISABLE-NEXT:    add x29, sp, #16
188; DISABLE-NEXT:    .cfi_def_cfa w29, 16
189; DISABLE-NEXT:    .cfi_offset w30, -8
190; DISABLE-NEXT:    .cfi_offset w29, -16
191; DISABLE-NEXT:    .cfi_offset w19, -24
192; DISABLE-NEXT:    .cfi_offset w20, -32
193; DISABLE-NEXT:    mov w19, wzr
194; DISABLE-NEXT:    mov w20, #10 ; =0xa
195; DISABLE-NEXT:  LBB2_1: ; %for.body
196; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
197; DISABLE-NEXT:    bl _something
198; DISABLE-NEXT:    subs w20, w20, #1
199; DISABLE-NEXT:    add w19, w0, w19
200; DISABLE-NEXT:    b.ne LBB2_1
201; DISABLE-NEXT:  ; %bb.2: ; %for.end
202; DISABLE-NEXT:    mov w0, w19
203; DISABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
204; DISABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
205; DISABLE-NEXT:    ret
206entry:
207  br label %for.body
208
209for.body:                                         ; preds = %for.body, %entry
210  %i.04 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
211  %sum.03 = phi i32 [ 0, %entry ], [ %add, %for.body ]
212  %call = tail call i32 @something()
213  %add = add nsw i32 %call, %sum.03
214  %inc = add nuw nsw i32 %i.04, 1
215  %exitcond = icmp eq i32 %inc, 10
216  br i1 %exitcond, label %for.end, label %for.body
217
218for.end:                                          ; preds = %for.body
219  ret i32 %add
220}
221
222; Check with a more complex case that we do not have save within the loop and
223; restore outside.
224define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) {
225; ENABLE-LABEL: loopInfoSaveOutsideLoop:
226; ENABLE:       ; %bb.0: ; %entry
227; ENABLE-NEXT:    cbz w0, LBB3_4
228; ENABLE-NEXT:  ; %bb.1: ; %for.body.preheader
229; ENABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
230; ENABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
231; ENABLE-NEXT:    add x29, sp, #16
232; ENABLE-NEXT:    .cfi_def_cfa w29, 16
233; ENABLE-NEXT:    .cfi_offset w30, -8
234; ENABLE-NEXT:    .cfi_offset w29, -16
235; ENABLE-NEXT:    .cfi_offset w19, -24
236; ENABLE-NEXT:    .cfi_offset w20, -32
237; ENABLE-NEXT:    mov w19, wzr
238; ENABLE-NEXT:    mov w20, #10 ; =0xa
239; ENABLE-NEXT:  LBB3_2: ; %for.body
240; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
241; ENABLE-NEXT:    bl _something
242; ENABLE-NEXT:    subs w20, w20, #1
243; ENABLE-NEXT:    add w19, w0, w19
244; ENABLE-NEXT:    b.ne LBB3_2
245; ENABLE-NEXT:  ; %bb.3: ; %for.end
246; ENABLE-NEXT:    bl _somethingElse
247; ENABLE-NEXT:    lsl w0, w19, #3
248; ENABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
249; ENABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
250; ENABLE-NEXT:    ret
251; ENABLE-NEXT:  LBB3_4: ; %if.else
252; ENABLE-NEXT:    lsl w0, w1, #1
253; ENABLE-NEXT:    ret
254;
255; DISABLE-LABEL: loopInfoSaveOutsideLoop:
256; DISABLE:       ; %bb.0: ; %entry
257; DISABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
258; DISABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
259; DISABLE-NEXT:    add x29, sp, #16
260; DISABLE-NEXT:    .cfi_def_cfa w29, 16
261; DISABLE-NEXT:    .cfi_offset w30, -8
262; DISABLE-NEXT:    .cfi_offset w29, -16
263; DISABLE-NEXT:    .cfi_offset w19, -24
264; DISABLE-NEXT:    .cfi_offset w20, -32
265; DISABLE-NEXT:    cbz w0, LBB3_4
266; DISABLE-NEXT:  ; %bb.1: ; %for.body.preheader
267; DISABLE-NEXT:    mov w19, wzr
268; DISABLE-NEXT:    mov w20, #10 ; =0xa
269; DISABLE-NEXT:  LBB3_2: ; %for.body
270; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
271; DISABLE-NEXT:    bl _something
272; DISABLE-NEXT:    subs w20, w20, #1
273; DISABLE-NEXT:    add w19, w0, w19
274; DISABLE-NEXT:    b.ne LBB3_2
275; DISABLE-NEXT:  ; %bb.3: ; %for.end
276; DISABLE-NEXT:    bl _somethingElse
277; DISABLE-NEXT:    lsl w0, w19, #3
278; DISABLE-NEXT:    b LBB3_5
279; DISABLE-NEXT:  LBB3_4: ; %if.else
280; DISABLE-NEXT:    lsl w0, w1, #1
281; DISABLE-NEXT:  LBB3_5: ; %if.end
282; DISABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
283; DISABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
284; DISABLE-NEXT:    ret
285entry:
286  %tobool = icmp eq i32 %cond, 0
287  br i1 %tobool, label %if.else, label %for.body
288
289for.body:                                         ; preds = %entry, %for.body
290  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
291  %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ]
292  %call = tail call i32 @something()
293  %add = add nsw i32 %call, %sum.04
294  %inc = add nuw nsw i32 %i.05, 1
295  %exitcond = icmp eq i32 %inc, 10
296  br i1 %exitcond, label %for.end, label %for.body
297
298for.end:                                          ; preds = %for.body
299  tail call void @somethingElse()
300  %shl = shl i32 %add, 3
301  br label %if.end
302
303if.else:                                          ; preds = %entry
304  %mul = shl nsw i32 %N, 1
305  br label %if.end
306
307if.end:                                           ; preds = %if.else, %for.end
308  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
309  ret i32 %sum.1
310}
311
312declare void @somethingElse(...)
313
314; Check with a more complex case that we do not have restore within the loop and
315; save outside.
316define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) nounwind uwtable {
317; ENABLE-LABEL: loopInfoRestoreOutsideLoop:
318; ENABLE:       ; %bb.0: ; %entry
319; ENABLE-NEXT:    cbz w0, LBB4_4
320; ENABLE-NEXT:  ; %bb.1: ; %if.then
321; ENABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
322; ENABLE-NEXT:    .cfi_def_cfa_offset 32
323; ENABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
324; ENABLE-NEXT:    add x29, sp, #16
325; ENABLE-NEXT:    .cfi_def_cfa w29, 16
326; ENABLE-NEXT:    .cfi_offset w30, -8
327; ENABLE-NEXT:    .cfi_offset w29, -16
328; ENABLE-NEXT:    .cfi_offset w19, -24
329; ENABLE-NEXT:    .cfi_offset w20, -32
330; ENABLE-NEXT:    bl _somethingElse
331; ENABLE-NEXT:    mov w19, wzr
332; ENABLE-NEXT:    mov w20, #10 ; =0xa
333; ENABLE-NEXT:  LBB4_2: ; %for.body
334; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
335; ENABLE-NEXT:    bl _something
336; ENABLE-NEXT:    subs w20, w20, #1
337; ENABLE-NEXT:    add w19, w0, w19
338; ENABLE-NEXT:    b.ne LBB4_2
339; ENABLE-NEXT:  ; %bb.3: ; %for.end
340; ENABLE-NEXT:    lsl w0, w19, #3
341; ENABLE-NEXT:    .cfi_def_cfa wsp, 32
342; ENABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
343; ENABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
344; ENABLE-NEXT:    .cfi_def_cfa_offset 0
345; ENABLE-NEXT:    .cfi_restore w30
346; ENABLE-NEXT:    .cfi_restore w29
347; ENABLE-NEXT:    .cfi_restore w19
348; ENABLE-NEXT:    .cfi_restore w20
349; ENABLE-NEXT:    ret
350; ENABLE-NEXT:  LBB4_4: ; %if.else
351; ENABLE-NEXT:    lsl w0, w1, #1
352; ENABLE-NEXT:    ret
353;
354; DISABLE-LABEL: loopInfoRestoreOutsideLoop:
355; DISABLE:       ; %bb.0: ; %entry
356; DISABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
357; DISABLE-NEXT:    .cfi_def_cfa_offset 32
358; DISABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
359; DISABLE-NEXT:    add x29, sp, #16
360; DISABLE-NEXT:    .cfi_def_cfa w29, 16
361; DISABLE-NEXT:    .cfi_offset w30, -8
362; DISABLE-NEXT:    .cfi_offset w29, -16
363; DISABLE-NEXT:    .cfi_offset w19, -24
364; DISABLE-NEXT:    .cfi_offset w20, -32
365; DISABLE-NEXT:    cbz w0, LBB4_4
366; DISABLE-NEXT:  ; %bb.1: ; %if.then
367; DISABLE-NEXT:    bl _somethingElse
368; DISABLE-NEXT:    mov w19, wzr
369; DISABLE-NEXT:    mov w20, #10 ; =0xa
370; DISABLE-NEXT:  LBB4_2: ; %for.body
371; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
372; DISABLE-NEXT:    bl _something
373; DISABLE-NEXT:    subs w20, w20, #1
374; DISABLE-NEXT:    add w19, w0, w19
375; DISABLE-NEXT:    b.ne LBB4_2
376; DISABLE-NEXT:  ; %bb.3: ; %for.end
377; DISABLE-NEXT:    lsl w0, w19, #3
378; DISABLE-NEXT:    b LBB4_5
379; DISABLE-NEXT:  LBB4_4: ; %if.else
380; DISABLE-NEXT:    lsl w0, w1, #1
381; DISABLE-NEXT:  LBB4_5: ; %if.end
382; DISABLE-NEXT:    .cfi_def_cfa wsp, 32
383; DISABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
384; DISABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
385; DISABLE-NEXT:    .cfi_def_cfa_offset 0
386; DISABLE-NEXT:    .cfi_restore w30
387; DISABLE-NEXT:    .cfi_restore w29
388; DISABLE-NEXT:    .cfi_restore w19
389; DISABLE-NEXT:    .cfi_restore w20
390; DISABLE-NEXT:    ret
391entry:
392  %tobool = icmp eq i32 %cond, 0
393  br i1 %tobool, label %if.else, label %if.then
394
395if.then:                                          ; preds = %entry
396  tail call void @somethingElse()
397  br label %for.body
398
399for.body:                                         ; preds = %for.body, %if.then
400  %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ]
401  %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
402  %call = tail call i32 @something()
403  %add = add nsw i32 %call, %sum.04
404  %inc = add nuw nsw i32 %i.05, 1
405  %exitcond = icmp eq i32 %inc, 10
406  br i1 %exitcond, label %for.end, label %for.body
407
408for.end:                                          ; preds = %for.body
409  %shl = shl i32 %add, 3
410  br label %if.end
411
412if.else:                                          ; preds = %entry
413  %mul = shl nsw i32 %N, 1
414  br label %if.end
415
416if.end:                                           ; preds = %if.else, %for.end
417  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
418  ret i32 %sum.1
419}
420
421; Check that we handle function with no frame information correctly.
422define i32 @emptyFrame() {
423; ENABLE-LABEL: emptyFrame:
424; ENABLE:       ; %bb.0: ; %entry
425; ENABLE-NEXT:    mov w0, wzr
426; ENABLE-NEXT:    ret
427;
428; DISABLE-LABEL: emptyFrame:
429; DISABLE:       ; %bb.0: ; %entry
430; DISABLE-NEXT:    mov w0, wzr
431; DISABLE-NEXT:    ret
432entry:
433  ret i32 0
434}
435
436; Check that we handle variadic function correctly.
437define i32 @variadicFunc(i32 %cond, i32 %count, ...) nounwind uwtable {
438; ENABLE-LABEL: variadicFunc:
439; ENABLE:       ; %bb.0: ; %entry
440; ENABLE-NEXT:    cbz w0, LBB6_4
441; ENABLE-NEXT:  ; %bb.1: ; %if.then
442; ENABLE-NEXT:    sub sp, sp, #16
443; ENABLE-NEXT:    .cfi_def_cfa_offset 16
444; ENABLE-NEXT:    add x8, sp, #16
445; ENABLE-NEXT:    cmp w1, #1
446; ENABLE-NEXT:    str x8, [sp, #8]
447; ENABLE-NEXT:    mov w0, wzr
448; ENABLE-NEXT:    b.lt LBB6_3
449; ENABLE-NEXT:  LBB6_2: ; %for.body
450; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
451; ENABLE-NEXT:    ldr x8, [sp, #8]
452; ENABLE-NEXT:    add x9, x8, #8
453; ENABLE-NEXT:    str x9, [sp, #8]
454; ENABLE-NEXT:    ldr w8, [x8]
455; ENABLE-NEXT:    subs w1, w1, #1
456; ENABLE-NEXT:    add w0, w0, w8
457; ENABLE-NEXT:    b.ne LBB6_2
458; ENABLE-NEXT:  LBB6_3: ; %for.end
459; ENABLE-NEXT:    add sp, sp, #16
460; ENABLE-NEXT:    .cfi_def_cfa_offset 0
461; ENABLE-NEXT:    ret
462; ENABLE-NEXT:  LBB6_4: ; %if.else
463; ENABLE-NEXT:    lsl w0, w1, #1
464; ENABLE-NEXT:    ret
465;
466; DISABLE-LABEL: variadicFunc:
467; DISABLE:       ; %bb.0: ; %entry
468; DISABLE-NEXT:    sub sp, sp, #16
469; DISABLE-NEXT:    .cfi_def_cfa_offset 16
470; DISABLE-NEXT:    cbz w0, LBB6_3
471; DISABLE-NEXT:  ; %bb.1: ; %if.then
472; DISABLE-NEXT:    add x8, sp, #16
473; DISABLE-NEXT:    cmp w1, #1
474; DISABLE-NEXT:    str x8, [sp, #8]
475; DISABLE-NEXT:    mov w0, wzr
476; DISABLE-NEXT:    b.lt LBB6_4
477; DISABLE-NEXT:  LBB6_2: ; %for.body
478; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
479; DISABLE-NEXT:    ldr x8, [sp, #8]
480; DISABLE-NEXT:    add x9, x8, #8
481; DISABLE-NEXT:    str x9, [sp, #8]
482; DISABLE-NEXT:    ldr w8, [x8]
483; DISABLE-NEXT:    subs w1, w1, #1
484; DISABLE-NEXT:    add w0, w0, w8
485; DISABLE-NEXT:    b.ne LBB6_2
486; DISABLE-NEXT:    b LBB6_4
487; DISABLE-NEXT:  LBB6_3: ; %if.else
488; DISABLE-NEXT:    lsl w0, w1, #1
489; DISABLE-NEXT:  LBB6_4: ; %if.end
490; DISABLE-NEXT:    add sp, sp, #16
491; DISABLE-NEXT:    .cfi_def_cfa_offset 0
492; DISABLE-NEXT:    ret
493entry:
494  %ap = alloca ptr, align 8
495  %tobool = icmp eq i32 %cond, 0
496  br i1 %tobool, label %if.else, label %if.then
497
498if.then:                                          ; preds = %entry
499  call void @llvm.va_start(ptr %ap)
500  %cmp6 = icmp sgt i32 %count, 0
501  br i1 %cmp6, label %for.body, label %for.end
502
503for.body:                                         ; preds = %if.then, %for.body
504  %i.08 = phi i32 [ %inc, %for.body ], [ 0, %if.then ]
505  %sum.07 = phi i32 [ %add, %for.body ], [ 0, %if.then ]
506  %0 = va_arg ptr %ap, i32
507  %add = add nsw i32 %sum.07, %0
508  %inc = add nuw nsw i32 %i.08, 1
509  %exitcond = icmp eq i32 %inc, %count
510  br i1 %exitcond, label %for.end, label %for.body
511
512for.end:                                          ; preds = %for.body, %if.then
513  %sum.0.lcssa = phi i32 [ 0, %if.then ], [ %add, %for.body ]
514  call void @llvm.va_end(ptr %ap)
515  br label %if.end
516
517if.else:                                          ; preds = %entry
518  %mul = shl nsw i32 %count, 1
519  br label %if.end
520
521if.end:                                           ; preds = %if.else, %for.end
522  %sum.1 = phi i32 [ %sum.0.lcssa, %for.end ], [ %mul, %if.else ]
523  ret i32 %sum.1
524}
525
526declare void @llvm.va_start(ptr)
527
528declare void @llvm.va_end(ptr)
529
530; Check that we handle inline asm correctly.
531define i32 @inlineAsm(i32 %cond, i32 %N) {
532; ENABLE-LABEL: inlineAsm:
533; ENABLE:       ; %bb.0: ; %entry
534; ENABLE-NEXT:    cbz w0, LBB7_4
535; ENABLE-NEXT:  ; %bb.1: ; %for.body.preheader
536; ENABLE-NEXT:    stp x20, x19, [sp, #-16]! ; 16-byte Folded Spill
537; ENABLE-NEXT:    .cfi_def_cfa_offset 16
538; ENABLE-NEXT:    .cfi_offset w19, -8
539; ENABLE-NEXT:    .cfi_offset w20, -16
540; ENABLE-NEXT:    mov w8, #10 ; =0xa
541; ENABLE-NEXT:  LBB7_2: ; %for.body
542; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
543; ENABLE-NEXT:    subs w8, w8, #1
544; ENABLE-NEXT:    ; InlineAsm Start
545; ENABLE-NEXT:    add x19, x19, #1
546; ENABLE-NEXT:    ; InlineAsm End
547; ENABLE-NEXT:    b.ne LBB7_2
548; ENABLE-NEXT:  ; %bb.3:
549; ENABLE-NEXT:    mov w0, wzr
550; ENABLE-NEXT:    ldp x20, x19, [sp], #16 ; 16-byte Folded Reload
551; ENABLE-NEXT:    ret
552; ENABLE-NEXT:  LBB7_4: ; %if.else
553; ENABLE-NEXT:    lsl w0, w1, #1
554; ENABLE-NEXT:    ret
555;
556; DISABLE-LABEL: inlineAsm:
557; DISABLE:       ; %bb.0: ; %entry
558; DISABLE-NEXT:    stp x20, x19, [sp, #-16]! ; 16-byte Folded Spill
559; DISABLE-NEXT:    .cfi_def_cfa_offset 16
560; DISABLE-NEXT:    .cfi_offset w19, -8
561; DISABLE-NEXT:    .cfi_offset w20, -16
562; DISABLE-NEXT:    cbz w0, LBB7_4
563; DISABLE-NEXT:  ; %bb.1: ; %for.body.preheader
564; DISABLE-NEXT:    mov w8, #10 ; =0xa
565; DISABLE-NEXT:  LBB7_2: ; %for.body
566; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
567; DISABLE-NEXT:    subs w8, w8, #1
568; DISABLE-NEXT:    ; InlineAsm Start
569; DISABLE-NEXT:    add x19, x19, #1
570; DISABLE-NEXT:    ; InlineAsm End
571; DISABLE-NEXT:    b.ne LBB7_2
572; DISABLE-NEXT:  ; %bb.3:
573; DISABLE-NEXT:    mov w0, wzr
574; DISABLE-NEXT:    ldp x20, x19, [sp], #16 ; 16-byte Folded Reload
575; DISABLE-NEXT:    ret
576; DISABLE-NEXT:  LBB7_4: ; %if.else
577; DISABLE-NEXT:    lsl w0, w1, #1
578; DISABLE-NEXT:    ldp x20, x19, [sp], #16 ; 16-byte Folded Reload
579; DISABLE-NEXT:    ret
580entry:
581  %tobool = icmp eq i32 %cond, 0
582  br i1 %tobool, label %if.else, label %for.body
583
584for.body:                                         ; preds = %entry, %for.body
585  %i.03 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
586  tail call void asm sideeffect "add x19, x19, #1", "~{x19}"()
587  %inc = add nuw nsw i32 %i.03, 1
588  %exitcond = icmp eq i32 %inc, 10
589  br i1 %exitcond, label %if.end, label %for.body
590
591if.else:                                          ; preds = %entry
592  %mul = shl nsw i32 %N, 1
593  br label %if.end
594
595if.end:                                           ; preds = %for.body, %if.else
596  %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.body ]
597  ret i32 %sum.0
598}
599
600; Check that we handle calls to variadic functions correctly.
601define i32 @callVariadicFunc(i32 %cond, i32 %N) {
602; ENABLE-LABEL: callVariadicFunc:
603; ENABLE:       ; %bb.0: ; %entry
604; ENABLE-NEXT:    ; kill: def $w1 killed $w1 def $x1
605; ENABLE-NEXT:    cbz w0, LBB8_2
606; ENABLE-NEXT:  ; %bb.1: ; %if.then
607; ENABLE-NEXT:    sub sp, sp, #64
608; ENABLE-NEXT:    stp x29, x30, [sp, #48] ; 16-byte Folded Spill
609; ENABLE-NEXT:    add x29, sp, #48
610; ENABLE-NEXT:    .cfi_def_cfa w29, 16
611; ENABLE-NEXT:    .cfi_offset w30, -8
612; ENABLE-NEXT:    .cfi_offset w29, -16
613; ENABLE-NEXT:    stp x1, x1, [sp, #32]
614; ENABLE-NEXT:    stp x1, x1, [sp, #16]
615; ENABLE-NEXT:    stp x1, x1, [sp]
616; ENABLE-NEXT:    mov w0, w1
617; ENABLE-NEXT:    bl _someVariadicFunc
618; ENABLE-NEXT:    lsl w0, w0, #3
619; ENABLE-NEXT:    ldp x29, x30, [sp, #48] ; 16-byte Folded Reload
620; ENABLE-NEXT:    add sp, sp, #64
621; ENABLE-NEXT:    ret
622; ENABLE-NEXT:  LBB8_2: ; %if.else
623; ENABLE-NEXT:    lsl w0, w1, #1
624; ENABLE-NEXT:    ret
625;
626; DISABLE-LABEL: callVariadicFunc:
627; DISABLE:       ; %bb.0: ; %entry
628; DISABLE-NEXT:    sub sp, sp, #64
629; DISABLE-NEXT:    stp x29, x30, [sp, #48] ; 16-byte Folded Spill
630; DISABLE-NEXT:    add x29, sp, #48
631; DISABLE-NEXT:    .cfi_def_cfa w29, 16
632; DISABLE-NEXT:    .cfi_offset w30, -8
633; DISABLE-NEXT:    .cfi_offset w29, -16
634; DISABLE-NEXT:    ; kill: def $w1 killed $w1 def $x1
635; DISABLE-NEXT:    cbz w0, LBB8_2
636; DISABLE-NEXT:  ; %bb.1: ; %if.then
637; DISABLE-NEXT:    stp x1, x1, [sp, #32]
638; DISABLE-NEXT:    stp x1, x1, [sp, #16]
639; DISABLE-NEXT:    stp x1, x1, [sp]
640; DISABLE-NEXT:    mov w0, w1
641; DISABLE-NEXT:    bl _someVariadicFunc
642; DISABLE-NEXT:    lsl w0, w0, #3
643; DISABLE-NEXT:    b LBB8_3
644; DISABLE-NEXT:  LBB8_2: ; %if.else
645; DISABLE-NEXT:    lsl w0, w1, #1
646; DISABLE-NEXT:  LBB8_3: ; %if.end
647; DISABLE-NEXT:    ldp x29, x30, [sp, #48] ; 16-byte Folded Reload
648; DISABLE-NEXT:    add sp, sp, #64
649; DISABLE-NEXT:    ret
650entry:
651  %tobool = icmp eq i32 %cond, 0
652  br i1 %tobool, label %if.else, label %if.then
653
654if.then:                                          ; preds = %entry
655  %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N)
656  %shl = shl i32 %call, 3
657  br label %if.end
658
659if.else:                                          ; preds = %entry
660  %mul = shl nsw i32 %N, 1
661  br label %if.end
662
663if.end:                                           ; preds = %if.else, %if.then
664  %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ]
665  ret i32 %sum.0
666}
667
668declare i32 @someVariadicFunc(i32, ...)
669
670; Make sure we do not insert unreachable code after noreturn function.
671; Although this is not incorrect to insert such code, it is useless
672; and it hurts the binary size.
673;
674define i32 @noreturn(i8 signext %bad_thing) {
675; ENABLE-LABEL: noreturn:
676; ENABLE:       ; %bb.0: ; %entry
677; ENABLE-NEXT:    cbnz w0, LBB9_2
678; ENABLE-NEXT:  ; %bb.1: ; %if.end
679; ENABLE-NEXT:    mov w0, #42 ; =0x2a
680; ENABLE-NEXT:    ret
681; ENABLE-NEXT:  LBB9_2: ; %if.abort
682; ENABLE-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
683; ENABLE-NEXT:    mov x29, sp
684; ENABLE-NEXT:    .cfi_def_cfa w29, 16
685; ENABLE-NEXT:    .cfi_offset w30, -8
686; ENABLE-NEXT:    .cfi_offset w29, -16
687; ENABLE-NEXT:    bl _abort
688;
689; DISABLE-LABEL: noreturn:
690; DISABLE:       ; %bb.0: ; %entry
691; DISABLE-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
692; DISABLE-NEXT:    mov x29, sp
693; DISABLE-NEXT:    .cfi_def_cfa w29, 16
694; DISABLE-NEXT:    .cfi_offset w30, -8
695; DISABLE-NEXT:    .cfi_offset w29, -16
696; DISABLE-NEXT:    cbnz w0, LBB9_2
697; DISABLE-NEXT:  ; %bb.1: ; %if.end
698; DISABLE-NEXT:    mov w0, #42 ; =0x2a
699; DISABLE-NEXT:    ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
700; DISABLE-NEXT:    ret
701; DISABLE-NEXT:  LBB9_2: ; %if.abort
702; DISABLE-NEXT:    bl _abort
703entry:
704  %tobool = icmp eq i8 %bad_thing, 0
705  br i1 %tobool, label %if.end, label %if.abort
706
707if.abort:
708  tail call void @abort() #0
709  unreachable
710
711if.end:
712  ret i32 42
713}
714
715declare void @abort() #0
716
717attributes #0 = { noreturn nounwind }
718
719; Make sure that we handle infinite loops properly When checking that the Save
720; and Restore blocks are control flow equivalent, the loop searches for the
721; immediate (post) dominator for the (restore) save blocks. When either the Save
722; or Restore block is located in an infinite loop the only immediate (post)
723; dominator is itself. In this case, we cannot perform shrink wrapping, but we
724; should return gracefully and continue compilation.
725; The only condition for this test is the compilation finishes correctly.
726;
727define void @infiniteloop() {
728; ENABLE-LABEL: infiniteloop:
729; ENABLE:       ; %bb.0: ; %entry
730; ENABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
731; ENABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
732; ENABLE-NEXT:    add x29, sp, #16
733; ENABLE-NEXT:    .cfi_def_cfa w29, 16
734; ENABLE-NEXT:    .cfi_offset w30, -8
735; ENABLE-NEXT:    .cfi_offset w29, -16
736; ENABLE-NEXT:    .cfi_offset w19, -24
737; ENABLE-NEXT:    .cfi_offset w20, -32
738; ENABLE-NEXT:    cbnz wzr, LBB10_3
739; ENABLE-NEXT:  ; %bb.1: ; %if.then
740; ENABLE-NEXT:    sub x19, sp, #16
741; ENABLE-NEXT:    mov sp, x19
742; ENABLE-NEXT:    mov w20, wzr
743; ENABLE-NEXT:  LBB10_2: ; %for.body
744; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
745; ENABLE-NEXT:    bl _something
746; ENABLE-NEXT:    add w20, w0, w20
747; ENABLE-NEXT:    str w20, [x19]
748; ENABLE-NEXT:    b LBB10_2
749; ENABLE-NEXT:  LBB10_3: ; %if.end
750; ENABLE-NEXT:    sub sp, x29, #16
751; ENABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
752; ENABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
753; ENABLE-NEXT:    ret
754;
755; DISABLE-LABEL: infiniteloop:
756; DISABLE:       ; %bb.0: ; %entry
757; DISABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
758; DISABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
759; DISABLE-NEXT:    add x29, sp, #16
760; DISABLE-NEXT:    .cfi_def_cfa w29, 16
761; DISABLE-NEXT:    .cfi_offset w30, -8
762; DISABLE-NEXT:    .cfi_offset w29, -16
763; DISABLE-NEXT:    .cfi_offset w19, -24
764; DISABLE-NEXT:    .cfi_offset w20, -32
765; DISABLE-NEXT:    cbnz wzr, LBB10_3
766; DISABLE-NEXT:  ; %bb.1: ; %if.then
767; DISABLE-NEXT:    sub x19, sp, #16
768; DISABLE-NEXT:    mov sp, x19
769; DISABLE-NEXT:    mov w20, wzr
770; DISABLE-NEXT:  LBB10_2: ; %for.body
771; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
772; DISABLE-NEXT:    bl _something
773; DISABLE-NEXT:    add w20, w0, w20
774; DISABLE-NEXT:    str w20, [x19]
775; DISABLE-NEXT:    b LBB10_2
776; DISABLE-NEXT:  LBB10_3: ; %if.end
777; DISABLE-NEXT:    sub sp, x29, #16
778; DISABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
779; DISABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
780; DISABLE-NEXT:    ret
781entry:
782  br i1 undef, label %if.then, label %if.end
783
784if.then:
785  %ptr = alloca i32, i32 4
786  br label %for.body
787
788for.body:                                         ; preds = %for.body, %entry
789  %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
790  %call = tail call i32 @something()
791  %add = add nsw i32 %call, %sum.03
792  store i32 %add, ptr %ptr
793  br label %for.body
794
795if.end:
796  ret void
797}
798
799; Another infinite loop test this time with a body bigger than just one block.
800define void @infiniteloop2() {
801; ENABLE-LABEL: infiniteloop2:
802; ENABLE:       ; %bb.0: ; %entry
803; ENABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
804; ENABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
805; ENABLE-NEXT:    add x29, sp, #16
806; ENABLE-NEXT:    .cfi_def_cfa w29, 16
807; ENABLE-NEXT:    .cfi_offset w30, -8
808; ENABLE-NEXT:    .cfi_offset w29, -16
809; ENABLE-NEXT:    .cfi_offset w19, -24
810; ENABLE-NEXT:    .cfi_offset w20, -32
811; ENABLE-NEXT:    cbnz wzr, LBB11_3
812; ENABLE-NEXT:  ; %bb.1: ; %if.then
813; ENABLE-NEXT:    sub x8, sp, #16
814; ENABLE-NEXT:    mov sp, x8
815; ENABLE-NEXT:    mov w9, wzr
816; ENABLE-NEXT:  LBB11_2: ; %for.body
817; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
818; ENABLE-NEXT:    ; InlineAsm Start
819; ENABLE-NEXT:    mov x10, #0 ; =0x0
820; ENABLE-NEXT:    ; InlineAsm End
821; ENABLE-NEXT:    add w10, w10, w9
822; ENABLE-NEXT:    mov w9, #1 ; =0x1
823; ENABLE-NEXT:    str w10, [x8]
824; ENABLE-NEXT:    ; InlineAsm Start
825; ENABLE-NEXT:    nop
826; ENABLE-NEXT:    ; InlineAsm End
827; ENABLE-NEXT:    b LBB11_2
828; ENABLE-NEXT:  LBB11_3: ; %if.end
829; ENABLE-NEXT:    sub sp, x29, #16
830; ENABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
831; ENABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
832; ENABLE-NEXT:    ret
833;
834; DISABLE-LABEL: infiniteloop2:
835; DISABLE:       ; %bb.0: ; %entry
836; DISABLE-NEXT:    stp x20, x19, [sp, #-32]! ; 16-byte Folded Spill
837; DISABLE-NEXT:    stp x29, x30, [sp, #16] ; 16-byte Folded Spill
838; DISABLE-NEXT:    add x29, sp, #16
839; DISABLE-NEXT:    .cfi_def_cfa w29, 16
840; DISABLE-NEXT:    .cfi_offset w30, -8
841; DISABLE-NEXT:    .cfi_offset w29, -16
842; DISABLE-NEXT:    .cfi_offset w19, -24
843; DISABLE-NEXT:    .cfi_offset w20, -32
844; DISABLE-NEXT:    cbnz wzr, LBB11_3
845; DISABLE-NEXT:  ; %bb.1: ; %if.then
846; DISABLE-NEXT:    sub x8, sp, #16
847; DISABLE-NEXT:    mov sp, x8
848; DISABLE-NEXT:    mov w9, wzr
849; DISABLE-NEXT:  LBB11_2: ; %for.body
850; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
851; DISABLE-NEXT:    ; InlineAsm Start
852; DISABLE-NEXT:    mov x10, #0 ; =0x0
853; DISABLE-NEXT:    ; InlineAsm End
854; DISABLE-NEXT:    add w10, w10, w9
855; DISABLE-NEXT:    mov w9, #1 ; =0x1
856; DISABLE-NEXT:    str w10, [x8]
857; DISABLE-NEXT:    ; InlineAsm Start
858; DISABLE-NEXT:    nop
859; DISABLE-NEXT:    ; InlineAsm End
860; DISABLE-NEXT:    b LBB11_2
861; DISABLE-NEXT:  LBB11_3: ; %if.end
862; DISABLE-NEXT:    sub sp, x29, #16
863; DISABLE-NEXT:    ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
864; DISABLE-NEXT:    ldp x20, x19, [sp], #32 ; 16-byte Folded Reload
865; DISABLE-NEXT:    ret
866entry:
867  br i1 undef, label %if.then, label %if.end
868
869if.then:
870  %ptr = alloca i32, i32 4
871  br label %for.body
872
873for.body:                                         ; preds = %for.body, %entry
874  %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2]
875  %call = tail call i32 asm "mov $0, #0", "=r,~{x19}"()
876  %add = add nsw i32 %call, %sum.03
877  store i32 %add, ptr %ptr
878  br i1 undef, label %body1, label %body2
879
880body1:
881  tail call void asm sideeffect "nop", "~{x19}"()
882  br label %for.body
883
884body2:
885  tail call void asm sideeffect "nop", "~{x19}"()
886  br label %for.body
887
888if.end:
889  ret void
890}
891
892; Another infinite loop test this time with two nested infinite loop.
893define void @infiniteloop3() {
894; ENABLE-LABEL: infiniteloop3:
895; ENABLE:       ; %bb.0: ; %entry
896; ENABLE-NEXT:    cbnz wzr, LBB12_5
897; ENABLE-NEXT:  ; %bb.1: ; %loop2a.preheader
898; ENABLE-NEXT:    mov x8, xzr
899; ENABLE-NEXT:    mov x9, xzr
900; ENABLE-NEXT:    mov x11, xzr
901; ENABLE-NEXT:    b LBB12_3
902; ENABLE-NEXT:  LBB12_2: ; %loop2b
903; ENABLE-NEXT:    ; in Loop: Header=BB12_3 Depth=1
904; ENABLE-NEXT:    str x10, [x11]
905; ENABLE-NEXT:    mov x11, x10
906; ENABLE-NEXT:  LBB12_3: ; %loop1
907; ENABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
908; ENABLE-NEXT:    mov x10, x9
909; ENABLE-NEXT:    ldr x9, [x8]
910; ENABLE-NEXT:    cbnz x8, LBB12_2
911; ENABLE-NEXT:  ; %bb.4: ; in Loop: Header=BB12_3 Depth=1
912; ENABLE-NEXT:    mov x8, x10
913; ENABLE-NEXT:    mov x11, x10
914; ENABLE-NEXT:    b LBB12_3
915; ENABLE-NEXT:  LBB12_5: ; %end
916; ENABLE-NEXT:    ret
917;
918; DISABLE-LABEL: infiniteloop3:
919; DISABLE:       ; %bb.0: ; %entry
920; DISABLE-NEXT:    cbnz wzr, LBB12_5
921; DISABLE-NEXT:  ; %bb.1: ; %loop2a.preheader
922; DISABLE-NEXT:    mov x8, xzr
923; DISABLE-NEXT:    mov x9, xzr
924; DISABLE-NEXT:    mov x11, xzr
925; DISABLE-NEXT:    b LBB12_3
926; DISABLE-NEXT:  LBB12_2: ; %loop2b
927; DISABLE-NEXT:    ; in Loop: Header=BB12_3 Depth=1
928; DISABLE-NEXT:    str x10, [x11]
929; DISABLE-NEXT:    mov x11, x10
930; DISABLE-NEXT:  LBB12_3: ; %loop1
931; DISABLE-NEXT:    ; =>This Inner Loop Header: Depth=1
932; DISABLE-NEXT:    mov x10, x9
933; DISABLE-NEXT:    ldr x9, [x8]
934; DISABLE-NEXT:    cbnz x8, LBB12_2
935; DISABLE-NEXT:  ; %bb.4: ; in Loop: Header=BB12_3 Depth=1
936; DISABLE-NEXT:    mov x8, x10
937; DISABLE-NEXT:    mov x11, x10
938; DISABLE-NEXT:    b LBB12_3
939; DISABLE-NEXT:  LBB12_5: ; %end
940; DISABLE-NEXT:    ret
941entry:
942  br i1 undef, label %loop2a, label %body
943
944body:                                             ; preds = %entry
945  br i1 undef, label %loop2a, label %end
946
947loop1:                                            ; preds = %loop2a, %loop2b
948  %var.phi = phi ptr [ %next.phi, %loop2b ], [ %var, %loop2a ]
949  %next.phi = phi ptr [ %next.load, %loop2b ], [ %next.var, %loop2a ]
950  %0 = icmp eq ptr %var, null
951  %next.load = load ptr, ptr undef
952  br i1 %0, label %loop2a, label %loop2b
953
954loop2a:                                           ; preds = %loop1, %body, %entry
955  %var = phi ptr [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ]
956  %next.var = phi ptr [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ]
957  br label %loop1
958
959loop2b:                                           ; preds = %loop1
960  store ptr %next.phi, ptr %var.phi
961  br label %loop1
962
963end:
964  ret void
965}
966
967; Re-aligned stack pointer.  See bug 26642.  Avoid clobbering live
968; values in the prologue when re-aligning the stack pointer.
969define i32 @stack_realign(i32 %a, i32 %b, ptr %ptr1, ptr %ptr2) {
970; ENABLE-LABEL: stack_realign:
971; ENABLE:       ; %bb.0:
972; ENABLE-NEXT:    lsl w9, w0, w1
973; ENABLE-NEXT:    lsl w8, w1, w0
974; ENABLE-NEXT:    cmp w0, w1
975; ENABLE-NEXT:    b.ge LBB13_2
976; ENABLE-NEXT:  ; %bb.1: ; %true
977; ENABLE-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
978; ENABLE-NEXT:    mov x29, sp
979; ENABLE-NEXT:    sub x1, sp, #16
980; ENABLE-NEXT:    and sp, x1, #0xffffffffffffffe0
981; ENABLE-NEXT:    .cfi_def_cfa w29, 16
982; ENABLE-NEXT:    .cfi_offset w30, -8
983; ENABLE-NEXT:    .cfi_offset w29, -16
984; ENABLE-NEXT:    str w0, [sp]
985; ENABLE-NEXT:    mov sp, x29
986; ENABLE-NEXT:    ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
987; ENABLE-NEXT:  LBB13_2: ; %false
988; ENABLE-NEXT:    str w9, [x2]
989; ENABLE-NEXT:    str w8, [x3]
990; ENABLE-NEXT:    ret
991;
992; DISABLE-LABEL: stack_realign:
993; DISABLE:       ; %bb.0:
994; DISABLE-NEXT:    stp x29, x30, [sp, #-16]! ; 16-byte Folded Spill
995; DISABLE-NEXT:    mov x29, sp
996; DISABLE-NEXT:    sub x9, sp, #16
997; DISABLE-NEXT:    and sp, x9, #0xffffffffffffffe0
998; DISABLE-NEXT:    .cfi_def_cfa w29, 16
999; DISABLE-NEXT:    .cfi_offset w30, -8
1000; DISABLE-NEXT:    .cfi_offset w29, -16
1001; DISABLE-NEXT:    lsl w9, w0, w1
1002; DISABLE-NEXT:    lsl w8, w1, w0
1003; DISABLE-NEXT:    cmp w0, w1
1004; DISABLE-NEXT:    b.ge LBB13_2
1005; DISABLE-NEXT:  ; %bb.1: ; %true
1006; DISABLE-NEXT:    str w0, [sp]
1007; DISABLE-NEXT:  LBB13_2: ; %false
1008; DISABLE-NEXT:    str w9, [x2]
1009; DISABLE-NEXT:    str w8, [x3]
1010; DISABLE-NEXT:    mov sp, x29
1011; DISABLE-NEXT:    ldp x29, x30, [sp], #16 ; 16-byte Folded Reload
1012; DISABLE-NEXT:    ret
1013  %tmp = alloca i32, align 32
1014  %shl1 = shl i32 %a, %b
1015  %shl2 = shl i32 %b, %a
1016  %tmp2 = icmp slt i32 %a, %b
1017  br i1 %tmp2, label %true, label %false
1018
1019true:
1020  store i32 %a, ptr %tmp, align 4
1021  %tmp4 = load i32, ptr %tmp
1022  br label %false
1023
1024false:
1025  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
1026  store i32 %shl1, ptr %ptr1
1027  store i32 %shl2, ptr %ptr2
1028  ret i32 %tmp.0
1029}
1030
1031; Re-aligned stack pointer with all caller-save regs live.  See bug
1032; 26642.  In this case we currently avoid shrink wrapping because
1033; ensuring we have a scratch register to re-align the stack pointer is
1034; too complicated.  Output should be the same for both enabled and
1035; disabled shrink wrapping.
1036define void @stack_realign2(i32 %a, i32 %b, ptr %ptr1, ptr %ptr2, ptr %ptr3, ptr %ptr4, ptr %ptr5, ptr %ptr6) {
1037; ENABLE-LABEL: stack_realign2:
1038; ENABLE:       ; %bb.0:
1039; ENABLE-NEXT:    stp x28, x27, [sp, #-96]! ; 16-byte Folded Spill
1040; ENABLE-NEXT:    stp x26, x25, [sp, #16] ; 16-byte Folded Spill
1041; ENABLE-NEXT:    stp x24, x23, [sp, #32] ; 16-byte Folded Spill
1042; ENABLE-NEXT:    stp x22, x21, [sp, #48] ; 16-byte Folded Spill
1043; ENABLE-NEXT:    stp x20, x19, [sp, #64] ; 16-byte Folded Spill
1044; ENABLE-NEXT:    stp x29, x30, [sp, #80] ; 16-byte Folded Spill
1045; ENABLE-NEXT:    add x29, sp, #80
1046; ENABLE-NEXT:    sub x9, sp, #32
1047; ENABLE-NEXT:    and sp, x9, #0xffffffffffffffe0
1048; ENABLE-NEXT:    .cfi_def_cfa w29, 16
1049; ENABLE-NEXT:    .cfi_offset w30, -8
1050; ENABLE-NEXT:    .cfi_offset w29, -16
1051; ENABLE-NEXT:    .cfi_offset w19, -24
1052; ENABLE-NEXT:    .cfi_offset w20, -32
1053; ENABLE-NEXT:    .cfi_offset w21, -40
1054; ENABLE-NEXT:    .cfi_offset w22, -48
1055; ENABLE-NEXT:    .cfi_offset w23, -56
1056; ENABLE-NEXT:    .cfi_offset w24, -64
1057; ENABLE-NEXT:    .cfi_offset w25, -72
1058; ENABLE-NEXT:    .cfi_offset w26, -80
1059; ENABLE-NEXT:    .cfi_offset w27, -88
1060; ENABLE-NEXT:    .cfi_offset w28, -96
1061; ENABLE-NEXT:    lsl w8, w1, w0
1062; ENABLE-NEXT:    lsr w9, w0, w1
1063; ENABLE-NEXT:    lsl w14, w0, w1
1064; ENABLE-NEXT:    lsr w11, w1, w0
1065; ENABLE-NEXT:    add w15, w1, w0
1066; ENABLE-NEXT:    sub w10, w8, w9
1067; ENABLE-NEXT:    subs w17, w1, w0
1068; ENABLE-NEXT:    add w16, w14, w8
1069; ENABLE-NEXT:    add w12, w9, w11
1070; ENABLE-NEXT:    add w13, w11, w15
1071; ENABLE-NEXT:    b.le LBB14_2
1072; ENABLE-NEXT:  ; %bb.1: ; %true
1073; ENABLE-NEXT:    str w0, [sp]
1074; ENABLE-NEXT:    ; InlineAsm Start
1075; ENABLE-NEXT:    nop
1076; ENABLE-NEXT:    ; InlineAsm End
1077; ENABLE-NEXT:  LBB14_2: ; %false
1078; ENABLE-NEXT:    str w14, [x2]
1079; ENABLE-NEXT:    str w8, [x3]
1080; ENABLE-NEXT:    str w9, [x4]
1081; ENABLE-NEXT:    str w11, [x5]
1082; ENABLE-NEXT:    str w15, [x6]
1083; ENABLE-NEXT:    str w17, [x7]
1084; ENABLE-NEXT:    stp w0, w1, [x2, #4]
1085; ENABLE-NEXT:    stp w16, w10, [x2, #12]
1086; ENABLE-NEXT:    stp w12, w13, [x2, #20]
1087; ENABLE-NEXT:    sub sp, x29, #80
1088; ENABLE-NEXT:    ldp x29, x30, [sp, #80] ; 16-byte Folded Reload
1089; ENABLE-NEXT:    ldp x20, x19, [sp, #64] ; 16-byte Folded Reload
1090; ENABLE-NEXT:    ldp x22, x21, [sp, #48] ; 16-byte Folded Reload
1091; ENABLE-NEXT:    ldp x24, x23, [sp, #32] ; 16-byte Folded Reload
1092; ENABLE-NEXT:    ldp x26, x25, [sp, #16] ; 16-byte Folded Reload
1093; ENABLE-NEXT:    ldp x28, x27, [sp], #96 ; 16-byte Folded Reload
1094; ENABLE-NEXT:    ret
1095;
1096; DISABLE-LABEL: stack_realign2:
1097; DISABLE:       ; %bb.0:
1098; DISABLE-NEXT:    stp x28, x27, [sp, #-96]! ; 16-byte Folded Spill
1099; DISABLE-NEXT:    stp x26, x25, [sp, #16] ; 16-byte Folded Spill
1100; DISABLE-NEXT:    stp x24, x23, [sp, #32] ; 16-byte Folded Spill
1101; DISABLE-NEXT:    stp x22, x21, [sp, #48] ; 16-byte Folded Spill
1102; DISABLE-NEXT:    stp x20, x19, [sp, #64] ; 16-byte Folded Spill
1103; DISABLE-NEXT:    stp x29, x30, [sp, #80] ; 16-byte Folded Spill
1104; DISABLE-NEXT:    add x29, sp, #80
1105; DISABLE-NEXT:    sub x9, sp, #32
1106; DISABLE-NEXT:    and sp, x9, #0xffffffffffffffe0
1107; DISABLE-NEXT:    .cfi_def_cfa w29, 16
1108; DISABLE-NEXT:    .cfi_offset w30, -8
1109; DISABLE-NEXT:    .cfi_offset w29, -16
1110; DISABLE-NEXT:    .cfi_offset w19, -24
1111; DISABLE-NEXT:    .cfi_offset w20, -32
1112; DISABLE-NEXT:    .cfi_offset w21, -40
1113; DISABLE-NEXT:    .cfi_offset w22, -48
1114; DISABLE-NEXT:    .cfi_offset w23, -56
1115; DISABLE-NEXT:    .cfi_offset w24, -64
1116; DISABLE-NEXT:    .cfi_offset w25, -72
1117; DISABLE-NEXT:    .cfi_offset w26, -80
1118; DISABLE-NEXT:    .cfi_offset w27, -88
1119; DISABLE-NEXT:    .cfi_offset w28, -96
1120; DISABLE-NEXT:    lsl w8, w1, w0
1121; DISABLE-NEXT:    lsr w9, w0, w1
1122; DISABLE-NEXT:    lsl w14, w0, w1
1123; DISABLE-NEXT:    lsr w11, w1, w0
1124; DISABLE-NEXT:    add w15, w1, w0
1125; DISABLE-NEXT:    sub w10, w8, w9
1126; DISABLE-NEXT:    subs w17, w1, w0
1127; DISABLE-NEXT:    add w16, w14, w8
1128; DISABLE-NEXT:    add w12, w9, w11
1129; DISABLE-NEXT:    add w13, w11, w15
1130; DISABLE-NEXT:    b.le LBB14_2
1131; DISABLE-NEXT:  ; %bb.1: ; %true
1132; DISABLE-NEXT:    str w0, [sp]
1133; DISABLE-NEXT:    ; InlineAsm Start
1134; DISABLE-NEXT:    nop
1135; DISABLE-NEXT:    ; InlineAsm End
1136; DISABLE-NEXT:  LBB14_2: ; %false
1137; DISABLE-NEXT:    str w14, [x2]
1138; DISABLE-NEXT:    str w8, [x3]
1139; DISABLE-NEXT:    str w9, [x4]
1140; DISABLE-NEXT:    str w11, [x5]
1141; DISABLE-NEXT:    str w15, [x6]
1142; DISABLE-NEXT:    str w17, [x7]
1143; DISABLE-NEXT:    stp w0, w1, [x2, #4]
1144; DISABLE-NEXT:    stp w16, w10, [x2, #12]
1145; DISABLE-NEXT:    stp w12, w13, [x2, #20]
1146; DISABLE-NEXT:    sub sp, x29, #80
1147; DISABLE-NEXT:    ldp x29, x30, [sp, #80] ; 16-byte Folded Reload
1148; DISABLE-NEXT:    ldp x20, x19, [sp, #64] ; 16-byte Folded Reload
1149; DISABLE-NEXT:    ldp x22, x21, [sp, #48] ; 16-byte Folded Reload
1150; DISABLE-NEXT:    ldp x24, x23, [sp, #32] ; 16-byte Folded Reload
1151; DISABLE-NEXT:    ldp x26, x25, [sp, #16] ; 16-byte Folded Reload
1152; DISABLE-NEXT:    ldp x28, x27, [sp], #96 ; 16-byte Folded Reload
1153; DISABLE-NEXT:    ret
1154  %tmp = alloca i32, align 32
1155  %tmp1 = shl i32 %a, %b
1156  %tmp2 = shl i32 %b, %a
1157  %tmp3 = lshr i32 %a, %b
1158  %tmp4 = lshr i32 %b, %a
1159  %tmp5 = add i32 %b, %a
1160  %tmp6 = sub i32 %b, %a
1161  %tmp7 = add i32 %tmp1, %tmp2
1162  %tmp8 = sub i32 %tmp2, %tmp3
1163  %tmp9 = add i32 %tmp3, %tmp4
1164  %tmp10 = add i32 %tmp4, %tmp5
1165  %cmp = icmp slt i32 %a, %b
1166  br i1 %cmp, label %true, label %false
1167
1168true:
1169  store i32 %a, ptr %tmp, align 4
1170  call void asm sideeffect "nop", "~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28}"() nounwind
1171  br label %false
1172
1173false:
1174  store i32 %tmp1, ptr %ptr1, align 4
1175  store i32 %tmp2, ptr %ptr2, align 4
1176  store i32 %tmp3, ptr %ptr3, align 4
1177  store i32 %tmp4, ptr %ptr4, align 4
1178  store i32 %tmp5, ptr %ptr5, align 4
1179  store i32 %tmp6, ptr %ptr6, align 4
1180  %idx1 = getelementptr inbounds i32, ptr %ptr1, i64 1
1181  store i32 %a, ptr %idx1, align 4
1182  %idx2 = getelementptr inbounds i32, ptr %ptr1, i64 2
1183  store i32 %b, ptr %idx2, align 4
1184  %idx3 = getelementptr inbounds i32, ptr %ptr1, i64 3
1185  store i32 %tmp7, ptr %idx3, align 4
1186  %idx4 = getelementptr inbounds i32, ptr %ptr1, i64 4
1187  store i32 %tmp8, ptr %idx4, align 4
1188  %idx5 = getelementptr inbounds i32, ptr %ptr1, i64 5
1189  store i32 %tmp9, ptr %idx5, align 4
1190  %idx6 = getelementptr inbounds i32, ptr %ptr1, i64 6
1191  store i32 %tmp10, ptr %idx6, align 4
1192
1193  ret void
1194}
1195