xref: /llvm-project/llvm/test/CodeGen/ARM/arm-shrink-wrapping.ll (revision e0ed0333f0fed2e73f805afd58b61176a87aa3ad)
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc %s -o - -enable-shrink-wrap=true -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=armv7-apple-ios \
3; RUN:      | FileCheck %s --check-prefix=ARM-ENABLE
4; RUN: llc %s -o - -enable-shrink-wrap=false -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=armv7-apple-ios \
5; RUN:      | FileCheck %s --check-prefix=ARM-DISABLE
6; RUN: llc %s -o - -enable-shrink-wrap=true -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=thumbv7-apple-ios \
7; RUN:      | FileCheck %s --check-prefix=THUMB-ENABLE
8; RUN: llc %s -o - -enable-shrink-wrap=false -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=thumbv7-apple-ios \
9; RUN:      | FileCheck %s --check-prefix=THUMB-DISABLE
10
11;
12; Note: Lots of tests use inline asm instead of regular calls.
13; This allows to have a better control on what the allocation will do.
14; Otherwise, we may have spill right in the entry block, defeating
15; shrink-wrapping. Moreover, some of the inline asm statements (nop)
16; are here to ensure that the related paths do not end up as critical
17; edges.
18; Also disable the late if-converter as it makes harder to reason on
19; the diffs.
20
21; Initial motivating example: Simple diamond with a call just on one side.
22; foo:
23;
24; Compare the arguments and jump to exit.
25; No prologue needed.
26; cmp r0, r1
27; bge [[EXIT_LABEL:LBB[0-9_]+]]
28;
29; Prologue code.
30; push {r7, lr}
31; mov r7, sp
32;;
33; Compare the arguments and jump to exit.
34; After the prologue is set.
35; sub sp
36; cmp r0, r1
37; bge [[EXIT_LABEL:LBB[0-9_]+]]
38;
39; Store %a in the alloca.
40; push {r0}
41; str r0, [sp, #-4]
42; str r0, [sp]
43; Set the alloca address in the second argument.
44; mov r1, sp
45; Set the first argument to zero.
46; mov{{s?}} r0, #0
47; bl{{x?}} _doSomething
48;
49; With shrink-wrapping, epilogue is just after the call.
50; mov sp, r7
51; add sp, #4
52; pop{{(\.w)?}} {r7, lr}
53;
54; [[EXIT_LABEL]]:
55;
56; Without shrink-wrapping, epilogue is in the exit block.
57; Epilogue code. (What we pop does not matter.)
58; mov sp, r7
59; add sp,
60; pop {r7, pc}
61;
62; bx lr
63define i32 @foo(i32 %a, i32 %b) "frame-pointer"="all" {
64; ARM-ENABLE-LABEL: foo:
65; ARM-ENABLE:       Lfunc_begin0:
66; ARM-ENABLE-NEXT:  @ %bb.0:
67; ARM-ENABLE-NEXT:    cmp r0, r1
68; ARM-ENABLE-NEXT:    bge LBB0_2
69; ARM-ENABLE-NEXT:  @ %bb.1: @ %true
70; ARM-ENABLE-NEXT:    push {r7, lr}
71; ARM-ENABLE-NEXT:    mov r7, sp
72; ARM-ENABLE-NEXT:    push {r0}
73; ARM-ENABLE-NEXT:    mov r1, sp
74; ARM-ENABLE-NEXT:    mov r0, #0
75; ARM-ENABLE-NEXT:    bl _doSomething
76; ARM-ENABLE-NEXT:    mov sp, r7
77; ARM-ENABLE-NEXT:    pop {r7, lr}
78; ARM-ENABLE-NEXT:  LBB0_2: @ %false
79; ARM-ENABLE-NEXT:    bx lr
80; ARM-ENABLE-NEXT:  Lfunc_end0:
81;
82; ARM-DISABLE-LABEL: foo:
83; ARM-DISABLE:       Lfunc_begin0:
84; ARM-DISABLE-NEXT:  @ %bb.0:
85; ARM-DISABLE-NEXT:    push {r7, lr}
86; ARM-DISABLE-NEXT:    mov r7, sp
87; ARM-DISABLE-NEXT:    sub sp, sp, #4
88; ARM-DISABLE-NEXT:    cmp r0, r1
89; ARM-DISABLE-NEXT:    bge LBB0_2
90; ARM-DISABLE-NEXT:  @ %bb.1: @ %true
91; ARM-DISABLE-NEXT:    str r0, [sp]
92; ARM-DISABLE-NEXT:    mov r1, sp
93; ARM-DISABLE-NEXT:    mov r0, #0
94; ARM-DISABLE-NEXT:    bl _doSomething
95; ARM-DISABLE-NEXT:  LBB0_2: @ %false
96; ARM-DISABLE-NEXT:    mov sp, r7
97; ARM-DISABLE-NEXT:    pop {r7, pc}
98; ARM-DISABLE-NEXT:  Lfunc_end0:
99;
100; THUMB-ENABLE-LABEL: foo:
101; THUMB-ENABLE:       Lfunc_begin0:
102; THUMB-ENABLE-NEXT:  @ %bb.0:
103; THUMB-ENABLE-NEXT:    cmp r0, r1
104; THUMB-ENABLE-NEXT:    bge LBB0_2
105; THUMB-ENABLE-NEXT:  @ %bb.1: @ %true
106; THUMB-ENABLE-NEXT:    push {r7, lr}
107; THUMB-ENABLE-NEXT:    mov r7, sp
108; THUMB-ENABLE-NEXT:    str r0, [sp, #-4]!
109; THUMB-ENABLE-NEXT:    mov r1, sp
110; THUMB-ENABLE-NEXT:    movs r0, #0
111; THUMB-ENABLE-NEXT:    bl _doSomething
112; THUMB-ENABLE-NEXT:    add sp, #4
113; THUMB-ENABLE-NEXT:    pop.w {r7, lr}
114; THUMB-ENABLE-NEXT:  LBB0_2: @ %false
115; THUMB-ENABLE-NEXT:    bx lr
116; THUMB-ENABLE-NEXT:  Lfunc_end0:
117;
118; THUMB-DISABLE-LABEL: foo:
119; THUMB-DISABLE:       Lfunc_begin0:
120; THUMB-DISABLE-NEXT:  @ %bb.0:
121; THUMB-DISABLE-NEXT:    push {r7, lr}
122; THUMB-DISABLE-NEXT:    mov r7, sp
123; THUMB-DISABLE-NEXT:    sub sp, #4
124; THUMB-DISABLE-NEXT:    cmp r0, r1
125; THUMB-DISABLE-NEXT:    bge LBB0_2
126; THUMB-DISABLE-NEXT:  @ %bb.1: @ %true
127; THUMB-DISABLE-NEXT:    str r0, [sp]
128; THUMB-DISABLE-NEXT:    mov r1, sp
129; THUMB-DISABLE-NEXT:    movs r0, #0
130; THUMB-DISABLE-NEXT:    bl _doSomething
131; THUMB-DISABLE-NEXT:  LBB0_2: @ %false
132; THUMB-DISABLE-NEXT:    add sp, #4
133; THUMB-DISABLE-NEXT:    pop {r7, pc}
134; THUMB-DISABLE-NEXT:  Lfunc_end0:
135  %tmp = alloca i32, align 4
136  %tmp2 = icmp slt i32 %a, %b
137  br i1 %tmp2, label %true, label %false
138
139true:
140  store i32 %a, ptr %tmp, align 4
141  %tmp4 = call i32 @doSomething(i32 0, ptr %tmp)
142  br label %false
143
144false:
145  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
146  ret i32 %tmp.0
147}
148
149; Function Attrs: optsize
150declare i32 @doSomething(i32, ptr)
151
152
153; Check that we do not perform the restore inside the loop whereas the save
154; is outside.
155; freqSaveAndRestoreOutsideLoop:
156;
157; Shrink-wrapping allows to skip the prologue in the else case.
158; cmp r0, #0
159; beq [[ELSE_LABEL:LBB[0-9_]+]]
160; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
161;
162; Prologue code.
163; Make sure we save the CSR used in the inline asm: r4.
164; push {r4, r7, lr}
165; add r7, sp, #4
166;
167; cmp r0, #0
168; beq [[ELSE_LABEL:LBB[0-9_]+]]
169; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
170;
171; SUM is in r0 because it is coalesced with the second
172; argument on the else path.
173; mov{{s?}} [[SUM:r0]], #0
174; mov{{s?}} [[IV:r[0-9]+]], #10
175;
176; Next BB.
177; [[LOOP:LBB[0-9_]+]]: @ %for.body
178; mov{{(\.w)?}} [[TMP:r[0-9]+]], #1
179; add [[SUM]], [[TMP]], [[SUM]]
180; add [[SUM]], [[TMP]]
181; subs [[IV]], [[IV]], #1
182; subs [[IV]], #1
183; bne [[LOOP]]
184;
185; Next BB.
186; SUM << 3.
187; lsl{{s?}} [[SUM]], [[SUM]], #3
188; pop {r4, r7, pc}
189;
190; Duplicated epilogue.
191; pop {r4, r7, pc}
192;
193; [[ELSE_LABEL]]: @ %if.else
194; Shift second argument by one and store into returned register.
195; lsl{{s?}} r0, r1, #1
196; pop {r4, r7, pc}
197;
198; bx lr
199define i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) "frame-pointer"="all" {
200; ARM-ENABLE-LABEL: freqSaveAndRestoreOutsideLoop:
201; ARM-ENABLE:       Lfunc_begin1:
202; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
203; ARM-ENABLE-NEXT:    cmp r0, #0
204; ARM-ENABLE-NEXT:    beq LBB1_4
205; ARM-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
206; ARM-ENABLE-NEXT:    push {r4, r7, lr}
207; ARM-ENABLE-NEXT:    add r7, sp, #4
208; ARM-ENABLE-NEXT:    mov r0, #0
209; ARM-ENABLE-NEXT:    mov r1, #10
210; ARM-ENABLE-NEXT:    @ InlineAsm Start
211; ARM-ENABLE-NEXT:    nop
212; ARM-ENABLE-NEXT:    @ InlineAsm End
213; ARM-ENABLE-NEXT:  LBB1_2: @ %for.body
214; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
215; ARM-ENABLE-NEXT:    @ InlineAsm Start
216; ARM-ENABLE-NEXT:    mov r2, #1
217; ARM-ENABLE-NEXT:    @ InlineAsm End
218; ARM-ENABLE-NEXT:    add r0, r2, r0
219; ARM-ENABLE-NEXT:    subs r1, r1, #1
220; ARM-ENABLE-NEXT:    bne LBB1_2
221; ARM-ENABLE-NEXT:  @ %bb.3: @ %for.end
222; ARM-ENABLE-NEXT:    lsl r0, r0, #3
223; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
224; ARM-ENABLE-NEXT:  LBB1_4: @ %if.else
225; ARM-ENABLE-NEXT:    lsl r0, r1, #1
226; ARM-ENABLE-NEXT:    bx lr
227; ARM-ENABLE-NEXT:  Lfunc_end1:
228;
229; ARM-DISABLE-LABEL: freqSaveAndRestoreOutsideLoop:
230; ARM-DISABLE:       Lfunc_begin1:
231; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
232; ARM-DISABLE-NEXT:    push {r4, r7, lr}
233; ARM-DISABLE-NEXT:    add r7, sp, #4
234; ARM-DISABLE-NEXT:    cmp r0, #0
235; ARM-DISABLE-NEXT:    beq LBB1_4
236; ARM-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
237; ARM-DISABLE-NEXT:    mov r0, #0
238; ARM-DISABLE-NEXT:    mov r1, #10
239; ARM-DISABLE-NEXT:    @ InlineAsm Start
240; ARM-DISABLE-NEXT:    nop
241; ARM-DISABLE-NEXT:    @ InlineAsm End
242; ARM-DISABLE-NEXT:  LBB1_2: @ %for.body
243; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
244; ARM-DISABLE-NEXT:    @ InlineAsm Start
245; ARM-DISABLE-NEXT:    mov r2, #1
246; ARM-DISABLE-NEXT:    @ InlineAsm End
247; ARM-DISABLE-NEXT:    add r0, r2, r0
248; ARM-DISABLE-NEXT:    subs r1, r1, #1
249; ARM-DISABLE-NEXT:    bne LBB1_2
250; ARM-DISABLE-NEXT:  @ %bb.3: @ %for.end
251; ARM-DISABLE-NEXT:    lsl r0, r0, #3
252; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
253; ARM-DISABLE-NEXT:  LBB1_4: @ %if.else
254; ARM-DISABLE-NEXT:    lsl r0, r1, #1
255; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
256; ARM-DISABLE-NEXT:  Lfunc_end1:
257;
258; THUMB-ENABLE-LABEL: freqSaveAndRestoreOutsideLoop:
259; THUMB-ENABLE:       Lfunc_begin1:
260; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
261; THUMB-ENABLE-NEXT:    cbz r0, LBB1_4
262; THUMB-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
263; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
264; THUMB-ENABLE-NEXT:    add r7, sp, #4
265; THUMB-ENABLE-NEXT:    movs r0, #0
266; THUMB-ENABLE-NEXT:    movs r1, #10
267; THUMB-ENABLE-NEXT:    @ InlineAsm Start
268; THUMB-ENABLE-NEXT:    nop
269; THUMB-ENABLE-NEXT:    @ InlineAsm End
270; THUMB-ENABLE-NEXT:  LBB1_2: @ %for.body
271; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
272; THUMB-ENABLE-NEXT:    @ InlineAsm Start
273; THUMB-ENABLE-NEXT:    mov.w r2, #1
274; THUMB-ENABLE-NEXT:    @ InlineAsm End
275; THUMB-ENABLE-NEXT:    add r0, r2
276; THUMB-ENABLE-NEXT:    subs r1, #1
277; THUMB-ENABLE-NEXT:    bne LBB1_2
278; THUMB-ENABLE-NEXT:  @ %bb.3: @ %for.end
279; THUMB-ENABLE-NEXT:    lsls r0, r0, #3
280; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
281; THUMB-ENABLE-NEXT:  LBB1_4: @ %if.else
282; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
283; THUMB-ENABLE-NEXT:    bx lr
284; THUMB-ENABLE-NEXT:  Lfunc_end1:
285;
286; THUMB-DISABLE-LABEL: freqSaveAndRestoreOutsideLoop:
287; THUMB-DISABLE:       Lfunc_begin1:
288; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
289; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
290; THUMB-DISABLE-NEXT:    add r7, sp, #4
291; THUMB-DISABLE-NEXT:    cbz r0, LBB1_4
292; THUMB-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
293; THUMB-DISABLE-NEXT:    movs r0, #0
294; THUMB-DISABLE-NEXT:    movs r1, #10
295; THUMB-DISABLE-NEXT:    @ InlineAsm Start
296; THUMB-DISABLE-NEXT:    nop
297; THUMB-DISABLE-NEXT:    @ InlineAsm End
298; THUMB-DISABLE-NEXT:  LBB1_2: @ %for.body
299; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
300; THUMB-DISABLE-NEXT:    @ InlineAsm Start
301; THUMB-DISABLE-NEXT:    mov.w r2, #1
302; THUMB-DISABLE-NEXT:    @ InlineAsm End
303; THUMB-DISABLE-NEXT:    add r0, r2
304; THUMB-DISABLE-NEXT:    subs r1, #1
305; THUMB-DISABLE-NEXT:    bne LBB1_2
306; THUMB-DISABLE-NEXT:  @ %bb.3: @ %for.end
307; THUMB-DISABLE-NEXT:    lsls r0, r0, #3
308; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
309; THUMB-DISABLE-NEXT:  LBB1_4: @ %if.else
310; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
311; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
312; THUMB-DISABLE-NEXT:  Lfunc_end1:
313entry:
314  %tobool = icmp eq i32 %cond, 0
315  br i1 %tobool, label %if.else, label %for.preheader
316
317for.preheader:
318  tail call void asm "nop", ""()
319  br label %for.body
320
321for.body:                                         ; preds = %entry, %for.body
322  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
323  %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
324  %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
325  %add = add nsw i32 %call, %sum.04
326  %inc = add nuw nsw i32 %i.05, 1
327  %exitcond = icmp eq i32 %inc, 10
328  br i1 %exitcond, label %for.end, label %for.body
329
330for.end:                                          ; preds = %for.body
331  %shl = shl i32 %add, 3
332  br label %if.end
333
334if.else:                                          ; preds = %entry
335  %mul = shl nsw i32 %N, 1
336  br label %if.end
337
338if.end:                                           ; preds = %if.else, %for.end
339  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
340  ret i32 %sum.1
341}
342
343declare i32 @something(...)
344
345; Check that we do not perform the shrink-wrapping inside the loop even
346; though that would be legal. The cost model must prevent that.
347; freqSaveAndRestoreOutsideLoop2:
348; Prologue code.
349; Make sure we save the CSR used in the inline asm: r4.
350; push {r4
351; mov{{s?}} [[SUM:r0]], #0
352; mov{{s?}} [[IV:r[0-9]+]], #10
353; nop
354; Next BB.
355; [[LOOP_LABEL:LBB[0-9_]+]]: @ %for.body
356; mov{{(\.w)?}} [[TMP:r[0-9]+]], #1
357; add [[SUM]], [[TMP]], [[SUM]]
358; add [[SUM]], [[TMP]]
359; subs [[IV]], [[IV]], #1
360; subs [[IV]], #1
361; bne [[LOOP_LABEL]]
362; Next BB.
363; @ %for.exit
364; nop
365; pop {r4
366define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) "frame-pointer"="all" {
367; ARM-LABEL: freqSaveAndRestoreOutsideLoop2:
368; ARM:       @ %bb.0: @ %entry
369; ARM-NEXT:    push {r4, r7, lr}
370; ARM-NEXT:    add r7, sp, #4
371; ARM-NEXT:    mov r0, #0
372; ARM-NEXT:    mov r1, #10
373; ARM-NEXT:    @ InlineAsm Start
374; ARM-NEXT:    nop
375; ARM-NEXT:    @ InlineAsm End
376; ARM-NEXT:  LBB2_1: @ %for.body
377; ARM-NEXT:    @ =>This Inner Loop Header: Depth=1
378; ARM-NEXT:    @ InlineAsm Start
379; ARM-NEXT:    mov r2, #1
380; ARM-NEXT:    @ InlineAsm End
381; ARM-NEXT:    add r0, r2, r0
382; ARM-NEXT:    subs r1, r1, #1
383; ARM-NEXT:    bne LBB2_1
384; ARM-NEXT:  @ %bb.2: @ %for.exit
385; ARM-NEXT:    @ InlineAsm Start
386; ARM-NEXT:    nop
387; ARM-NEXT:    @ InlineAsm End
388; ARM-NEXT:    pop {r4, r7, pc}
389;
390; THUMB-LABEL: freqSaveAndRestoreOutsideLoop2:
391; THUMB:       @ %bb.0: @ %entry
392; THUMB-NEXT:    push {r4, r7, lr}
393; THUMB-NEXT:    add r7, sp, #4
394; THUMB-NEXT:    movs r0, #0
395; THUMB-NEXT:    movs r1, #10
396; THUMB-NEXT:    @ InlineAsm Start
397; THUMB-NEXT:    nop
398; THUMB-NEXT:    @ InlineAsm End
399; THUMB-NEXT:  LBB2_1: @ %for.body
400; THUMB-NEXT:    @ =>This Inner Loop Header: Depth=1
401; THUMB-NEXT:    @ InlineAsm Start
402; THUMB-NEXT:    mov.w r2, #1
403; THUMB-NEXT:    @ InlineAsm End
404; THUMB-NEXT:    add r0, r2
405; THUMB-NEXT:    subs r1, #1
406; THUMB-NEXT:    bne LBB2_1
407; THUMB-NEXT:  @ %bb.2: @ %for.exit
408; THUMB-NEXT:    @ InlineAsm Start
409; THUMB-NEXT:    nop
410; THUMB-NEXT:    @ InlineAsm End
411; THUMB-NEXT:    pop {r4, r7, pc}
412; ARM-ENABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
413; ARM-ENABLE:       Lfunc_begin2:
414; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
415; ARM-ENABLE-NEXT:    push {r4, r7, lr}
416; ARM-ENABLE-NEXT:    add r7, sp, #4
417; ARM-ENABLE-NEXT:    mov r0, #0
418; ARM-ENABLE-NEXT:    mov r1, #10
419; ARM-ENABLE-NEXT:    @ InlineAsm Start
420; ARM-ENABLE-NEXT:    nop
421; ARM-ENABLE-NEXT:    @ InlineAsm End
422; ARM-ENABLE-NEXT:  LBB2_1: @ %for.body
423; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
424; ARM-ENABLE-NEXT:    @ InlineAsm Start
425; ARM-ENABLE-NEXT:    mov r2, #1
426; ARM-ENABLE-NEXT:    @ InlineAsm End
427; ARM-ENABLE-NEXT:    add r0, r2, r0
428; ARM-ENABLE-NEXT:    subs r1, r1, #1
429; ARM-ENABLE-NEXT:    bne LBB2_1
430; ARM-ENABLE-NEXT:  @ %bb.2: @ %for.exit
431; ARM-ENABLE-NEXT:    @ InlineAsm Start
432; ARM-ENABLE-NEXT:    nop
433; ARM-ENABLE-NEXT:    @ InlineAsm End
434; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
435; ARM-ENABLE-NEXT:  Lfunc_end2:
436;
437; ARM-DISABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
438; ARM-DISABLE:       Lfunc_begin2:
439; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
440; ARM-DISABLE-NEXT:    push {r4, r7, lr}
441; ARM-DISABLE-NEXT:    add r7, sp, #4
442; ARM-DISABLE-NEXT:    mov r0, #0
443; ARM-DISABLE-NEXT:    mov r1, #10
444; ARM-DISABLE-NEXT:    @ InlineAsm Start
445; ARM-DISABLE-NEXT:    nop
446; ARM-DISABLE-NEXT:    @ InlineAsm End
447; ARM-DISABLE-NEXT:  LBB2_1: @ %for.body
448; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
449; ARM-DISABLE-NEXT:    @ InlineAsm Start
450; ARM-DISABLE-NEXT:    mov r2, #1
451; ARM-DISABLE-NEXT:    @ InlineAsm End
452; ARM-DISABLE-NEXT:    add r0, r2, r0
453; ARM-DISABLE-NEXT:    subs r1, r1, #1
454; ARM-DISABLE-NEXT:    bne LBB2_1
455; ARM-DISABLE-NEXT:  @ %bb.2: @ %for.exit
456; ARM-DISABLE-NEXT:    @ InlineAsm Start
457; ARM-DISABLE-NEXT:    nop
458; ARM-DISABLE-NEXT:    @ InlineAsm End
459; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
460; ARM-DISABLE-NEXT:  Lfunc_end2:
461;
462; THUMB-ENABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
463; THUMB-ENABLE:       Lfunc_begin2:
464; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
465; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
466; THUMB-ENABLE-NEXT:    add r7, sp, #4
467; THUMB-ENABLE-NEXT:    movs r0, #0
468; THUMB-ENABLE-NEXT:    movs r1, #10
469; THUMB-ENABLE-NEXT:    @ InlineAsm Start
470; THUMB-ENABLE-NEXT:    nop
471; THUMB-ENABLE-NEXT:    @ InlineAsm End
472; THUMB-ENABLE-NEXT:  LBB2_1: @ %for.body
473; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
474; THUMB-ENABLE-NEXT:    @ InlineAsm Start
475; THUMB-ENABLE-NEXT:    mov.w r2, #1
476; THUMB-ENABLE-NEXT:    @ InlineAsm End
477; THUMB-ENABLE-NEXT:    add r0, r2
478; THUMB-ENABLE-NEXT:    subs r1, #1
479; THUMB-ENABLE-NEXT:    bne LBB2_1
480; THUMB-ENABLE-NEXT:  @ %bb.2: @ %for.exit
481; THUMB-ENABLE-NEXT:    @ InlineAsm Start
482; THUMB-ENABLE-NEXT:    nop
483; THUMB-ENABLE-NEXT:    @ InlineAsm End
484; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
485; THUMB-ENABLE-NEXT:  Lfunc_end2:
486;
487; THUMB-DISABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
488; THUMB-DISABLE:       Lfunc_begin2:
489; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
490; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
491; THUMB-DISABLE-NEXT:    add r7, sp, #4
492; THUMB-DISABLE-NEXT:    movs r0, #0
493; THUMB-DISABLE-NEXT:    movs r1, #10
494; THUMB-DISABLE-NEXT:    @ InlineAsm Start
495; THUMB-DISABLE-NEXT:    nop
496; THUMB-DISABLE-NEXT:    @ InlineAsm End
497; THUMB-DISABLE-NEXT:  LBB2_1: @ %for.body
498; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
499; THUMB-DISABLE-NEXT:    @ InlineAsm Start
500; THUMB-DISABLE-NEXT:    mov.w r2, #1
501; THUMB-DISABLE-NEXT:    @ InlineAsm End
502; THUMB-DISABLE-NEXT:    add r0, r2
503; THUMB-DISABLE-NEXT:    subs r1, #1
504; THUMB-DISABLE-NEXT:    bne LBB2_1
505; THUMB-DISABLE-NEXT:  @ %bb.2: @ %for.exit
506; THUMB-DISABLE-NEXT:    @ InlineAsm Start
507; THUMB-DISABLE-NEXT:    nop
508; THUMB-DISABLE-NEXT:    @ InlineAsm End
509; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
510; THUMB-DISABLE-NEXT:  Lfunc_end2:
511entry:
512  br label %for.preheader
513
514for.preheader:
515  tail call void asm "nop", ""()
516  br label %for.body
517
518for.body:                                         ; preds = %for.body, %entry
519  %i.04 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]
520  %sum.03 = phi i32 [ 0, %for.preheader ], [ %add, %for.body ]
521  %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
522  %add = add nsw i32 %call, %sum.03
523  %inc = add nuw nsw i32 %i.04, 1
524  %exitcond = icmp eq i32 %inc, 10
525  br i1 %exitcond, label %for.exit, label %for.body
526
527for.exit:
528  tail call void asm "nop", ""()
529  br label %for.end
530
531for.end:                                          ; preds = %for.body
532  ret i32 %add
533}
534
535; Check with a more complex case that we do not have save within the loop and
536; restore outside.
537; loopInfoSaveOutsideLoop:
538;
539; cmp r0, #0
540; beq [[ELSE_LABEL:LBB[0-9_]+]]
541; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
542;
543; Prologue code.
544; Make sure we save the CSR used in the inline asm: r4.
545; push {r4, r7, lr}
546; add r7, sp, #4
547;
548; cmp r0, #0
549; beq [[ELSE_LABEL:LBB[0-9_]+]]
550; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
551;
552; SUM is in r0 because it is coalesced with the second
553; argument on the else path.
554; mov{{s?}} [[SUM:r0]], #0
555; mov{{s?}} [[IV:r[0-9]+]], #10
556;
557; Next BB.
558; [[LOOP:LBB[0-9_]+]]: @ %for.body
559; mov{{(\.w)?}} [[TMP:r[0-9]+]], #1
560; add [[SUM]], [[TMP]], [[SUM]]
561; add [[SUM]], [[TMP]]
562; subs [[IV]], [[IV]], #1
563; subs [[IV]], #1
564; bne [[LOOP]]
565;
566; Next BB.
567; SUM << 3.
568; lsl{{s?}} [[SUM]], [[SUM]], #3
569; pop {r4, r7, pc}
570;
571; Duplicated epilogue.
572; pop {r4, r7, pc}
573;
574; [[ELSE_LABEL]]: @ %if.else
575; Shift second argument by one and store into returned register.
576; lsl{{s?}} r0, r1, #1
577; pop {r4, r7, pc}
578;
579; bx lr
580define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) "frame-pointer"="all" {
581; ARM-ENABLE-LABEL: loopInfoSaveOutsideLoop:
582; ARM-ENABLE:       Lfunc_begin3:
583; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
584; ARM-ENABLE-NEXT:    cmp r0, #0
585; ARM-ENABLE-NEXT:    beq LBB3_4
586; ARM-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
587; ARM-ENABLE-NEXT:    push {r4, r7, lr}
588; ARM-ENABLE-NEXT:    add r7, sp, #4
589; ARM-ENABLE-NEXT:    mov r0, #0
590; ARM-ENABLE-NEXT:    mov r1, #10
591; ARM-ENABLE-NEXT:    @ InlineAsm Start
592; ARM-ENABLE-NEXT:    nop
593; ARM-ENABLE-NEXT:    @ InlineAsm End
594; ARM-ENABLE-NEXT:  LBB3_2: @ %for.body
595; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
596; ARM-ENABLE-NEXT:    @ InlineAsm Start
597; ARM-ENABLE-NEXT:    mov r2, #1
598; ARM-ENABLE-NEXT:    @ InlineAsm End
599; ARM-ENABLE-NEXT:    add r0, r2, r0
600; ARM-ENABLE-NEXT:    subs r1, r1, #1
601; ARM-ENABLE-NEXT:    bne LBB3_2
602; ARM-ENABLE-NEXT:  @ %bb.3: @ %for.end
603; ARM-ENABLE-NEXT:    lsl r0, r0, #3
604; ARM-ENABLE-NEXT:    @ InlineAsm Start
605; ARM-ENABLE-NEXT:    nop
606; ARM-ENABLE-NEXT:    @ InlineAsm End
607; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
608; ARM-ENABLE-NEXT:  LBB3_4: @ %if.else
609; ARM-ENABLE-NEXT:    lsl r0, r1, #1
610; ARM-ENABLE-NEXT:    bx lr
611; ARM-ENABLE-NEXT:  Lfunc_end3:
612;
613; ARM-DISABLE-LABEL: loopInfoSaveOutsideLoop:
614; ARM-DISABLE:       Lfunc_begin3:
615; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
616; ARM-DISABLE-NEXT:    push {r4, r7, lr}
617; ARM-DISABLE-NEXT:    add r7, sp, #4
618; ARM-DISABLE-NEXT:    cmp r0, #0
619; ARM-DISABLE-NEXT:    beq LBB3_4
620; ARM-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
621; ARM-DISABLE-NEXT:    mov r0, #0
622; ARM-DISABLE-NEXT:    mov r1, #10
623; ARM-DISABLE-NEXT:    @ InlineAsm Start
624; ARM-DISABLE-NEXT:    nop
625; ARM-DISABLE-NEXT:    @ InlineAsm End
626; ARM-DISABLE-NEXT:  LBB3_2: @ %for.body
627; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
628; ARM-DISABLE-NEXT:    @ InlineAsm Start
629; ARM-DISABLE-NEXT:    mov r2, #1
630; ARM-DISABLE-NEXT:    @ InlineAsm End
631; ARM-DISABLE-NEXT:    add r0, r2, r0
632; ARM-DISABLE-NEXT:    subs r1, r1, #1
633; ARM-DISABLE-NEXT:    bne LBB3_2
634; ARM-DISABLE-NEXT:  @ %bb.3: @ %for.end
635; ARM-DISABLE-NEXT:    lsl r0, r0, #3
636; ARM-DISABLE-NEXT:    @ InlineAsm Start
637; ARM-DISABLE-NEXT:    nop
638; ARM-DISABLE-NEXT:    @ InlineAsm End
639; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
640; ARM-DISABLE-NEXT:  LBB3_4: @ %if.else
641; ARM-DISABLE-NEXT:    lsl r0, r1, #1
642; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
643; ARM-DISABLE-NEXT:  Lfunc_end3:
644;
645; THUMB-ENABLE-LABEL: loopInfoSaveOutsideLoop:
646; THUMB-ENABLE:       Lfunc_begin3:
647; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
648; THUMB-ENABLE-NEXT:    cbz r0, LBB3_4
649; THUMB-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
650; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
651; THUMB-ENABLE-NEXT:    add r7, sp, #4
652; THUMB-ENABLE-NEXT:    movs r0, #0
653; THUMB-ENABLE-NEXT:    movs r1, #10
654; THUMB-ENABLE-NEXT:    @ InlineAsm Start
655; THUMB-ENABLE-NEXT:    nop
656; THUMB-ENABLE-NEXT:    @ InlineAsm End
657; THUMB-ENABLE-NEXT:  LBB3_2: @ %for.body
658; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
659; THUMB-ENABLE-NEXT:    @ InlineAsm Start
660; THUMB-ENABLE-NEXT:    mov.w r2, #1
661; THUMB-ENABLE-NEXT:    @ InlineAsm End
662; THUMB-ENABLE-NEXT:    add r0, r2
663; THUMB-ENABLE-NEXT:    subs r1, #1
664; THUMB-ENABLE-NEXT:    bne LBB3_2
665; THUMB-ENABLE-NEXT:  @ %bb.3: @ %for.end
666; THUMB-ENABLE-NEXT:    lsls r0, r0, #3
667; THUMB-ENABLE-NEXT:    @ InlineAsm Start
668; THUMB-ENABLE-NEXT:    nop
669; THUMB-ENABLE-NEXT:    @ InlineAsm End
670; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
671; THUMB-ENABLE-NEXT:  LBB3_4: @ %if.else
672; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
673; THUMB-ENABLE-NEXT:    bx lr
674; THUMB-ENABLE-NEXT:  Lfunc_end3:
675;
676; THUMB-DISABLE-LABEL: loopInfoSaveOutsideLoop:
677; THUMB-DISABLE:       Lfunc_begin3:
678; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
679; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
680; THUMB-DISABLE-NEXT:    add r7, sp, #4
681; THUMB-DISABLE-NEXT:    cbz r0, LBB3_4
682; THUMB-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
683; THUMB-DISABLE-NEXT:    movs r0, #0
684; THUMB-DISABLE-NEXT:    movs r1, #10
685; THUMB-DISABLE-NEXT:    @ InlineAsm Start
686; THUMB-DISABLE-NEXT:    nop
687; THUMB-DISABLE-NEXT:    @ InlineAsm End
688; THUMB-DISABLE-NEXT:  LBB3_2: @ %for.body
689; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
690; THUMB-DISABLE-NEXT:    @ InlineAsm Start
691; THUMB-DISABLE-NEXT:    mov.w r2, #1
692; THUMB-DISABLE-NEXT:    @ InlineAsm End
693; THUMB-DISABLE-NEXT:    add r0, r2
694; THUMB-DISABLE-NEXT:    subs r1, #1
695; THUMB-DISABLE-NEXT:    bne LBB3_2
696; THUMB-DISABLE-NEXT:  @ %bb.3: @ %for.end
697; THUMB-DISABLE-NEXT:    lsls r0, r0, #3
698; THUMB-DISABLE-NEXT:    @ InlineAsm Start
699; THUMB-DISABLE-NEXT:    nop
700; THUMB-DISABLE-NEXT:    @ InlineAsm End
701; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
702; THUMB-DISABLE-NEXT:  LBB3_4: @ %if.else
703; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
704; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
705; THUMB-DISABLE-NEXT:  Lfunc_end3:
706entry:
707  %tobool = icmp eq i32 %cond, 0
708  br i1 %tobool, label %if.else, label %for.preheader
709
710for.preheader:
711  tail call void asm "nop", ""()
712  br label %for.body
713
714for.body:                                         ; preds = %entry, %for.body
715  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
716  %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
717  %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
718  %add = add nsw i32 %call, %sum.04
719  %inc = add nuw nsw i32 %i.05, 1
720  %exitcond = icmp eq i32 %inc, 10
721  br i1 %exitcond, label %for.end, label %for.body
722
723for.end:                                          ; preds = %for.body
724  tail call void asm "nop", "~{r4}"()
725  %shl = shl i32 %add, 3
726  br label %if.end
727
728if.else:                                          ; preds = %entry
729  %mul = shl nsw i32 %N, 1
730  br label %if.end
731
732if.end:                                           ; preds = %if.else, %for.end
733  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
734  ret i32 %sum.1
735}
736
737declare void @somethingElse(...)
738
739; Check with a more complex case that we do not have restore within the loop and
740; save outside.
741; loopInfoRestoreOutsideLoop:
742;
743; cmp r0, #0
744; beq [[ELSE_LABEL:LBB[0-9_]+]]
745; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
746;
747; Prologue code.
748; Make sure we save the CSR used in the inline asm: r4.
749; push {r4, r7, lr}
750; add r7, sp, #4
751;
752; cmp r0, #0
753; beq [[ELSE_LABEL:LBB[0-9_]+]]
754; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
755;
756; SUM is in r0 because it is coalesced with the second
757; argument on the else path.
758; mov{{s?}} [[SUM:r0]], #0
759; mov{{s?}} [[IV:r[0-9]+]], #10
760;
761; Next BB.
762; [[LOOP:LBB[0-9_]+]]: @ %for.body
763; mov{{(\.w)?}} [[TMP:r[0-9]+]], #1
764; add [[SUM]], [[TMP]], [[SUM]]
765; add [[SUM]], [[TMP]]
766; subs [[IV]], [[IV]], #1
767; subs [[IV]], #1
768; bne [[LOOP]]
769;
770; Next BB.
771; SUM << 3.
772; lsl{{s?}} [[SUM]], [[SUM]], #3
773; pop {r4, r7, pc}
774;
775; Duplicated epilogue.
776; pop {r4, r7, pc}
777;
778; [[ELSE_LABEL]]: @ %if.else
779; Shift second argument by one and store into returned register.
780; lsl{{s?}} r0, r1, #1
781; pop {r4, r7, pc}
782;
783; bx lr
784define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) "frame-pointer"="all" nounwind {
785; ARM-ENABLE-LABEL: loopInfoRestoreOutsideLoop:
786; ARM-ENABLE:       Lfunc_begin4:
787; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
788; ARM-ENABLE-NEXT:    cmp r0, #0
789; ARM-ENABLE-NEXT:    beq LBB4_4
790; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.then
791; ARM-ENABLE-NEXT:    push {r4, r7, lr}
792; ARM-ENABLE-NEXT:    add r7, sp, #4
793; ARM-ENABLE-NEXT:    mov r0, #0
794; ARM-ENABLE-NEXT:    mov r1, #10
795; ARM-ENABLE-NEXT:    @ InlineAsm Start
796; ARM-ENABLE-NEXT:    nop
797; ARM-ENABLE-NEXT:    @ InlineAsm End
798; ARM-ENABLE-NEXT:  LBB4_2: @ %for.body
799; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
800; ARM-ENABLE-NEXT:    @ InlineAsm Start
801; ARM-ENABLE-NEXT:    mov r2, #1
802; ARM-ENABLE-NEXT:    @ InlineAsm End
803; ARM-ENABLE-NEXT:    add r0, r2, r0
804; ARM-ENABLE-NEXT:    subs r1, r1, #1
805; ARM-ENABLE-NEXT:    bne LBB4_2
806; ARM-ENABLE-NEXT:  @ %bb.3: @ %for.end
807; ARM-ENABLE-NEXT:    lsl r0, r0, #3
808; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
809; ARM-ENABLE-NEXT:  LBB4_4: @ %if.else
810; ARM-ENABLE-NEXT:    lsl r0, r1, #1
811; ARM-ENABLE-NEXT:    bx lr
812; ARM-ENABLE-NEXT:  Lfunc_end4:
813;
814; ARM-DISABLE-LABEL: loopInfoRestoreOutsideLoop:
815; ARM-DISABLE:       Lfunc_begin4:
816; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
817; ARM-DISABLE-NEXT:    push {r4, r7, lr}
818; ARM-DISABLE-NEXT:    add r7, sp, #4
819; ARM-DISABLE-NEXT:    cmp r0, #0
820; ARM-DISABLE-NEXT:    beq LBB4_4
821; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.then
822; ARM-DISABLE-NEXT:    mov r0, #0
823; ARM-DISABLE-NEXT:    mov r1, #10
824; ARM-DISABLE-NEXT:    @ InlineAsm Start
825; ARM-DISABLE-NEXT:    nop
826; ARM-DISABLE-NEXT:    @ InlineAsm End
827; ARM-DISABLE-NEXT:  LBB4_2: @ %for.body
828; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
829; ARM-DISABLE-NEXT:    @ InlineAsm Start
830; ARM-DISABLE-NEXT:    mov r2, #1
831; ARM-DISABLE-NEXT:    @ InlineAsm End
832; ARM-DISABLE-NEXT:    add r0, r2, r0
833; ARM-DISABLE-NEXT:    subs r1, r1, #1
834; ARM-DISABLE-NEXT:    bne LBB4_2
835; ARM-DISABLE-NEXT:  @ %bb.3: @ %for.end
836; ARM-DISABLE-NEXT:    lsl r0, r0, #3
837; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
838; ARM-DISABLE-NEXT:  LBB4_4: @ %if.else
839; ARM-DISABLE-NEXT:    lsl r0, r1, #1
840; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
841; ARM-DISABLE-NEXT:  Lfunc_end4:
842;
843; THUMB-ENABLE-LABEL: loopInfoRestoreOutsideLoop:
844; THUMB-ENABLE:       Lfunc_begin4:
845; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
846; THUMB-ENABLE-NEXT:    cbz r0, LBB4_4
847; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.then
848; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
849; THUMB-ENABLE-NEXT:    add r7, sp, #4
850; THUMB-ENABLE-NEXT:    movs r0, #0
851; THUMB-ENABLE-NEXT:    movs r1, #10
852; THUMB-ENABLE-NEXT:    @ InlineAsm Start
853; THUMB-ENABLE-NEXT:    nop
854; THUMB-ENABLE-NEXT:    @ InlineAsm End
855; THUMB-ENABLE-NEXT:  LBB4_2: @ %for.body
856; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
857; THUMB-ENABLE-NEXT:    @ InlineAsm Start
858; THUMB-ENABLE-NEXT:    mov.w r2, #1
859; THUMB-ENABLE-NEXT:    @ InlineAsm End
860; THUMB-ENABLE-NEXT:    add r0, r2
861; THUMB-ENABLE-NEXT:    subs r1, #1
862; THUMB-ENABLE-NEXT:    bne LBB4_2
863; THUMB-ENABLE-NEXT:  @ %bb.3: @ %for.end
864; THUMB-ENABLE-NEXT:    lsls r0, r0, #3
865; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
866; THUMB-ENABLE-NEXT:  LBB4_4: @ %if.else
867; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
868; THUMB-ENABLE-NEXT:    bx lr
869; THUMB-ENABLE-NEXT:  Lfunc_end4:
870;
871; THUMB-DISABLE-LABEL: loopInfoRestoreOutsideLoop:
872; THUMB-DISABLE:       Lfunc_begin4:
873; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
874; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
875; THUMB-DISABLE-NEXT:    add r7, sp, #4
876; THUMB-DISABLE-NEXT:    cbz r0, LBB4_4
877; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.then
878; THUMB-DISABLE-NEXT:    movs r0, #0
879; THUMB-DISABLE-NEXT:    movs r1, #10
880; THUMB-DISABLE-NEXT:    @ InlineAsm Start
881; THUMB-DISABLE-NEXT:    nop
882; THUMB-DISABLE-NEXT:    @ InlineAsm End
883; THUMB-DISABLE-NEXT:  LBB4_2: @ %for.body
884; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
885; THUMB-DISABLE-NEXT:    @ InlineAsm Start
886; THUMB-DISABLE-NEXT:    mov.w r2, #1
887; THUMB-DISABLE-NEXT:    @ InlineAsm End
888; THUMB-DISABLE-NEXT:    add r0, r2
889; THUMB-DISABLE-NEXT:    subs r1, #1
890; THUMB-DISABLE-NEXT:    bne LBB4_2
891; THUMB-DISABLE-NEXT:  @ %bb.3: @ %for.end
892; THUMB-DISABLE-NEXT:    lsls r0, r0, #3
893; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
894; THUMB-DISABLE-NEXT:  LBB4_4: @ %if.else
895; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
896; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
897; THUMB-DISABLE-NEXT:  Lfunc_end4:
898entry:
899  %tobool = icmp eq i32 %cond, 0
900  br i1 %tobool, label %if.else, label %if.then
901
902if.then:                                          ; preds = %entry
903  tail call void asm "nop", "~{r4}"()
904  br label %for.body
905
906for.body:                                         ; preds = %for.body, %if.then
907  %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ]
908  %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
909  %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
910  %add = add nsw i32 %call, %sum.04
911  %inc = add nuw nsw i32 %i.05, 1
912  %exitcond = icmp eq i32 %inc, 10
913  br i1 %exitcond, label %for.end, label %for.body
914
915for.end:                                          ; preds = %for.body
916  %shl = shl i32 %add, 3
917  br label %if.end
918
919if.else:                                          ; preds = %entry
920  %mul = shl nsw i32 %N, 1
921  br label %if.end
922
923if.end:                                           ; preds = %if.else, %for.end
924  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
925  ret i32 %sum.1
926}
927
928; Check that we handle function with no frame information correctly.
929; emptyFrame:
930; @ %entry
931; mov{{s?}} r0, #0
932; bx lr
933define i32 @emptyFrame() {
934; ARM-LABEL: emptyFrame:
935; ARM:       @ %bb.0: @ %entry
936; ARM-NEXT:    mov r0, #0
937; ARM-NEXT:    bx lr
938;
939; THUMB-LABEL: emptyFrame:
940; THUMB:       @ %bb.0: @ %entry
941; THUMB-NEXT:    movs r0, #0
942; THUMB-NEXT:    bx lr
943; ARM-ENABLE-LABEL: emptyFrame:
944; ARM-ENABLE:       Lfunc_begin5:
945; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
946; ARM-ENABLE-NEXT:    mov r0, #0
947; ARM-ENABLE-NEXT:    bx lr
948; ARM-ENABLE-NEXT:  Lfunc_end5:
949;
950; ARM-DISABLE-LABEL: emptyFrame:
951; ARM-DISABLE:       Lfunc_begin5:
952; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
953; ARM-DISABLE-NEXT:    mov r0, #0
954; ARM-DISABLE-NEXT:    bx lr
955; ARM-DISABLE-NEXT:  Lfunc_end5:
956;
957; THUMB-ENABLE-LABEL: emptyFrame:
958; THUMB-ENABLE:       Lfunc_begin5:
959; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
960; THUMB-ENABLE-NEXT:    movs r0, #0
961; THUMB-ENABLE-NEXT:    bx lr
962; THUMB-ENABLE-NEXT:  Lfunc_end5:
963;
964; THUMB-DISABLE-LABEL: emptyFrame:
965; THUMB-DISABLE:       Lfunc_begin5:
966; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
967; THUMB-DISABLE-NEXT:    movs r0, #0
968; THUMB-DISABLE-NEXT:    bx lr
969; THUMB-DISABLE-NEXT:  Lfunc_end5:
970entry:
971  ret i32 0
972}
973
974; Check that we handle inline asm correctly.
975; inlineAsm:
976;
977; cmp r0, #0
978; beq [[ELSE_LABEL:LBB[0-9_]+]]
979; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
980;
981; Prologue code.
982; Make sure we save the CSR used in the inline asm: r4.
983; push {r4, r7, lr}
984; add r7, sp, #4
985;
986; cmp r0, #0
987; beq [[ELSE_LABEL:LBB[0-9_]+]]
988; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
989;
990; mov{{s?}} [[IV:r[0-9]+]], #10
991;
992; Next BB.
993; [[LOOP:LBB[0-9_]+]]: @ %for.body
994; subs [[IV]], [[IV]], #1
995; subs [[IV]], #1
996; add{{(\.w)?}} r4, r4, #1
997; bne [[LOOP]]
998;
999; Next BB.
1000; mov{{s?}} r0, #0
1001;
1002; Duplicated epilogue.
1003; pop {r4, r7, pc}
1004;
1005; [[ELSE_LABEL]]: @ %if.else
1006; Shift second argument by one and store into returned register.
1007; lsl{{s?}} r0, r1, #1
1008; pop {r4, r7, pc}
1009;
1010; bx lr
1011define i32 @inlineAsm(i32 %cond, i32 %N) "frame-pointer"="all" {
1012; ARM-ENABLE-LABEL: inlineAsm:
1013; ARM-ENABLE:       Lfunc_begin6:
1014; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
1015; ARM-ENABLE-NEXT:    cmp r0, #0
1016; ARM-ENABLE-NEXT:    beq LBB6_4
1017; ARM-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
1018; ARM-ENABLE-NEXT:    push {r4, r7, lr}
1019; ARM-ENABLE-NEXT:    add r7, sp, #4
1020; ARM-ENABLE-NEXT:    mov r0, #10
1021; ARM-ENABLE-NEXT:    @ InlineAsm Start
1022; ARM-ENABLE-NEXT:    nop
1023; ARM-ENABLE-NEXT:    @ InlineAsm End
1024; ARM-ENABLE-NEXT:  LBB6_2: @ %for.body
1025; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1026; ARM-ENABLE-NEXT:    subs r0, r0, #1
1027; ARM-ENABLE-NEXT:    @ InlineAsm Start
1028; ARM-ENABLE-NEXT:    add r4, r4, #1
1029; ARM-ENABLE-NEXT:    @ InlineAsm End
1030; ARM-ENABLE-NEXT:    bne LBB6_2
1031; ARM-ENABLE-NEXT:  @ %bb.3: @ %for.exit
1032; ARM-ENABLE-NEXT:    mov r0, #0
1033; ARM-ENABLE-NEXT:    @ InlineAsm Start
1034; ARM-ENABLE-NEXT:    nop
1035; ARM-ENABLE-NEXT:    @ InlineAsm End
1036; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
1037; ARM-ENABLE-NEXT:  LBB6_4: @ %if.else
1038; ARM-ENABLE-NEXT:    lsl r0, r1, #1
1039; ARM-ENABLE-NEXT:    bx lr
1040; ARM-ENABLE-NEXT:  Lfunc_end6:
1041;
1042; ARM-DISABLE-LABEL: inlineAsm:
1043; ARM-DISABLE:       Lfunc_begin6:
1044; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
1045; ARM-DISABLE-NEXT:    push {r4, r7, lr}
1046; ARM-DISABLE-NEXT:    add r7, sp, #4
1047; ARM-DISABLE-NEXT:    cmp r0, #0
1048; ARM-DISABLE-NEXT:    beq LBB6_4
1049; ARM-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
1050; ARM-DISABLE-NEXT:    mov r0, #10
1051; ARM-DISABLE-NEXT:    @ InlineAsm Start
1052; ARM-DISABLE-NEXT:    nop
1053; ARM-DISABLE-NEXT:    @ InlineAsm End
1054; ARM-DISABLE-NEXT:  LBB6_2: @ %for.body
1055; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1056; ARM-DISABLE-NEXT:    subs r0, r0, #1
1057; ARM-DISABLE-NEXT:    @ InlineAsm Start
1058; ARM-DISABLE-NEXT:    add r4, r4, #1
1059; ARM-DISABLE-NEXT:    @ InlineAsm End
1060; ARM-DISABLE-NEXT:    bne LBB6_2
1061; ARM-DISABLE-NEXT:  @ %bb.3: @ %for.exit
1062; ARM-DISABLE-NEXT:    mov r0, #0
1063; ARM-DISABLE-NEXT:    @ InlineAsm Start
1064; ARM-DISABLE-NEXT:    nop
1065; ARM-DISABLE-NEXT:    @ InlineAsm End
1066; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
1067; ARM-DISABLE-NEXT:  LBB6_4: @ %if.else
1068; ARM-DISABLE-NEXT:    lsl r0, r1, #1
1069; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
1070; ARM-DISABLE-NEXT:  Lfunc_end6:
1071;
1072; THUMB-ENABLE-LABEL: inlineAsm:
1073; THUMB-ENABLE:       Lfunc_begin6:
1074; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
1075; THUMB-ENABLE-NEXT:    cbz r0, LBB6_4
1076; THUMB-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
1077; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
1078; THUMB-ENABLE-NEXT:    add r7, sp, #4
1079; THUMB-ENABLE-NEXT:    movs r0, #10
1080; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1081; THUMB-ENABLE-NEXT:    nop
1082; THUMB-ENABLE-NEXT:    @ InlineAsm End
1083; THUMB-ENABLE-NEXT:  LBB6_2: @ %for.body
1084; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1085; THUMB-ENABLE-NEXT:    subs r0, #1
1086; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1087; THUMB-ENABLE-NEXT:    add.w r4, r4, #1
1088; THUMB-ENABLE-NEXT:    @ InlineAsm End
1089; THUMB-ENABLE-NEXT:    bne LBB6_2
1090; THUMB-ENABLE-NEXT:  @ %bb.3: @ %for.exit
1091; THUMB-ENABLE-NEXT:    movs r0, #0
1092; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1093; THUMB-ENABLE-NEXT:    nop
1094; THUMB-ENABLE-NEXT:    @ InlineAsm End
1095; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
1096; THUMB-ENABLE-NEXT:  LBB6_4: @ %if.else
1097; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
1098; THUMB-ENABLE-NEXT:    bx lr
1099; THUMB-ENABLE-NEXT:  Lfunc_end6:
1100;
1101; THUMB-DISABLE-LABEL: inlineAsm:
1102; THUMB-DISABLE:       Lfunc_begin6:
1103; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
1104; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
1105; THUMB-DISABLE-NEXT:    add r7, sp, #4
1106; THUMB-DISABLE-NEXT:    cbz r0, LBB6_4
1107; THUMB-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
1108; THUMB-DISABLE-NEXT:    movs r0, #10
1109; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1110; THUMB-DISABLE-NEXT:    nop
1111; THUMB-DISABLE-NEXT:    @ InlineAsm End
1112; THUMB-DISABLE-NEXT:  LBB6_2: @ %for.body
1113; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1114; THUMB-DISABLE-NEXT:    subs r0, #1
1115; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1116; THUMB-DISABLE-NEXT:    add.w r4, r4, #1
1117; THUMB-DISABLE-NEXT:    @ InlineAsm End
1118; THUMB-DISABLE-NEXT:    bne LBB6_2
1119; THUMB-DISABLE-NEXT:  @ %bb.3: @ %for.exit
1120; THUMB-DISABLE-NEXT:    movs r0, #0
1121; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1122; THUMB-DISABLE-NEXT:    nop
1123; THUMB-DISABLE-NEXT:    @ InlineAsm End
1124; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
1125; THUMB-DISABLE-NEXT:  LBB6_4: @ %if.else
1126; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
1127; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
1128; THUMB-DISABLE-NEXT:  Lfunc_end6:
1129entry:
1130  %tobool = icmp eq i32 %cond, 0
1131  br i1 %tobool, label %if.else, label %for.preheader
1132
1133for.preheader:
1134  tail call void asm "nop", ""()
1135  br label %for.body
1136
1137for.body:                                         ; preds = %entry, %for.body
1138  %i.03 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
1139  tail call void asm sideeffect "add r4, #1", "~{r4}"()
1140  %inc = add nuw nsw i32 %i.03, 1
1141  %exitcond = icmp eq i32 %inc, 10
1142  br i1 %exitcond, label %for.exit, label %for.body
1143
1144for.exit:
1145  tail call void asm "nop", ""()
1146  br label %if.end
1147
1148if.else:                                          ; preds = %entry
1149  %mul = shl nsw i32 %N, 1
1150  br label %if.end
1151
1152if.end:                                           ; preds = %for.body, %if.else
1153  %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.exit ]
1154  ret i32 %sum.0
1155}
1156
1157; Check that we handle calls to variadic functions correctly.
1158; callVariadicFunc:
1159;
1160; cmp r0, #0
1161; beq [[ELSE_LABEL:LBB[0-9_]+]]
1162; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
1163;
1164; Prologue code.
1165; push {r7, lr}
1166; mov r7, sp
1167; sub sp, {{(sp, )?}}#12
1168;
1169; cmp r0, #0
1170; beq [[ELSE_LABEL:LBB[0-9_]+]]
1171; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
1172;
1173; Setup of the varags.
1174; mov r0, r1
1175; mov r2, r1
1176; mov r3, r1
1177; str r1, [sp]
1178; str r1, [sp, #4]
1179; strd r1, r1, [sp]
1180; str r1, [sp, #8]
1181; bl{{x?}} _someVariadicFunc
1182; lsl{{s?}} r0, r0, #3
1183; mov sp, r7
1184; add sp, #12
1185; pop {r7, pc}
1186;
1187; [[ELSE_LABEL]]: @ %if.else
1188; Shift second argument by one and store into returned register.
1189; lsl{{s?}} r0, r1, #1
1190;
1191; Epilogue code.
1192; bx lr
1193;
1194; mov sp, r7
1195; add sp, #12
1196; pop {r7, pc}
1197define i32 @callVariadicFunc(i32 %cond, i32 %N) "frame-pointer"="all" {
1198; ARM-ENABLE-LABEL: callVariadicFunc:
1199; ARM-ENABLE:       Lfunc_begin7:
1200; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
1201; ARM-ENABLE-NEXT:    cmp r0, #0
1202; ARM-ENABLE-NEXT:    beq LBB7_2
1203; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.then
1204; ARM-ENABLE-NEXT:    push {r7, lr}
1205; ARM-ENABLE-NEXT:    mov r7, sp
1206; ARM-ENABLE-NEXT:    sub sp, sp, #12
1207; ARM-ENABLE-NEXT:    mov r0, r1
1208; ARM-ENABLE-NEXT:    mov r2, r1
1209; ARM-ENABLE-NEXT:    mov r3, r1
1210; ARM-ENABLE-NEXT:    str r1, [sp]
1211; ARM-ENABLE-NEXT:    str r1, [sp, #4]
1212; ARM-ENABLE-NEXT:    str r1, [sp, #8]
1213; ARM-ENABLE-NEXT:    bl _someVariadicFunc
1214; ARM-ENABLE-NEXT:    lsl r0, r0, #3
1215; ARM-ENABLE-NEXT:    mov sp, r7
1216; ARM-ENABLE-NEXT:    pop {r7, pc}
1217; ARM-ENABLE-NEXT:  LBB7_2: @ %if.else
1218; ARM-ENABLE-NEXT:    lsl r0, r1, #1
1219; ARM-ENABLE-NEXT:    bx lr
1220; ARM-ENABLE-NEXT:  Lfunc_end7:
1221;
1222; ARM-DISABLE-LABEL: callVariadicFunc:
1223; ARM-DISABLE:       Lfunc_begin7:
1224; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
1225; ARM-DISABLE-NEXT:    push {r7, lr}
1226; ARM-DISABLE-NEXT:    mov r7, sp
1227; ARM-DISABLE-NEXT:    sub sp, sp, #12
1228; ARM-DISABLE-NEXT:    cmp r0, #0
1229; ARM-DISABLE-NEXT:    beq LBB7_2
1230; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.then
1231; ARM-DISABLE-NEXT:    mov r0, r1
1232; ARM-DISABLE-NEXT:    mov r2, r1
1233; ARM-DISABLE-NEXT:    mov r3, r1
1234; ARM-DISABLE-NEXT:    str r1, [sp]
1235; ARM-DISABLE-NEXT:    str r1, [sp, #4]
1236; ARM-DISABLE-NEXT:    str r1, [sp, #8]
1237; ARM-DISABLE-NEXT:    bl _someVariadicFunc
1238; ARM-DISABLE-NEXT:    lsl r0, r0, #3
1239; ARM-DISABLE-NEXT:    mov sp, r7
1240; ARM-DISABLE-NEXT:    pop {r7, pc}
1241; ARM-DISABLE-NEXT:  LBB7_2: @ %if.else
1242; ARM-DISABLE-NEXT:    lsl r0, r1, #1
1243; ARM-DISABLE-NEXT:    mov sp, r7
1244; ARM-DISABLE-NEXT:    pop {r7, pc}
1245; ARM-DISABLE-NEXT:  Lfunc_end7:
1246;
1247; THUMB-ENABLE-LABEL: callVariadicFunc:
1248; THUMB-ENABLE:       Lfunc_begin7:
1249; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
1250; THUMB-ENABLE-NEXT:    cbz r0, LBB7_2
1251; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.then
1252; THUMB-ENABLE-NEXT:    push {r7, lr}
1253; THUMB-ENABLE-NEXT:    mov r7, sp
1254; THUMB-ENABLE-NEXT:    sub sp, #12
1255; THUMB-ENABLE-NEXT:    mov r0, r1
1256; THUMB-ENABLE-NEXT:    mov r2, r1
1257; THUMB-ENABLE-NEXT:    mov r3, r1
1258; THUMB-ENABLE-NEXT:    strd r1, r1, [sp]
1259; THUMB-ENABLE-NEXT:    str r1, [sp, #8]
1260; THUMB-ENABLE-NEXT:    bl _someVariadicFunc
1261; THUMB-ENABLE-NEXT:    lsls r0, r0, #3
1262; THUMB-ENABLE-NEXT:    add sp, #12
1263; THUMB-ENABLE-NEXT:    pop {r7, pc}
1264; THUMB-ENABLE-NEXT:  LBB7_2: @ %if.else
1265; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
1266; THUMB-ENABLE-NEXT:    bx lr
1267; THUMB-ENABLE-NEXT:  Lfunc_end7:
1268;
1269; THUMB-DISABLE-LABEL: callVariadicFunc:
1270; THUMB-DISABLE:       Lfunc_begin7:
1271; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
1272; THUMB-DISABLE-NEXT:    push {r7, lr}
1273; THUMB-DISABLE-NEXT:    mov r7, sp
1274; THUMB-DISABLE-NEXT:    sub sp, #12
1275; THUMB-DISABLE-NEXT:    cbz r0, LBB7_2
1276; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.then
1277; THUMB-DISABLE-NEXT:    mov r0, r1
1278; THUMB-DISABLE-NEXT:    mov r2, r1
1279; THUMB-DISABLE-NEXT:    mov r3, r1
1280; THUMB-DISABLE-NEXT:    strd r1, r1, [sp]
1281; THUMB-DISABLE-NEXT:    str r1, [sp, #8]
1282; THUMB-DISABLE-NEXT:    bl _someVariadicFunc
1283; THUMB-DISABLE-NEXT:    lsls r0, r0, #3
1284; THUMB-DISABLE-NEXT:    add sp, #12
1285; THUMB-DISABLE-NEXT:    pop {r7, pc}
1286; THUMB-DISABLE-NEXT:  LBB7_2: @ %if.else
1287; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
1288; THUMB-DISABLE-NEXT:    add sp, #12
1289; THUMB-DISABLE-NEXT:    pop {r7, pc}
1290; THUMB-DISABLE-NEXT:  Lfunc_end7:
1291entry:
1292  %tobool = icmp eq i32 %cond, 0
1293  br i1 %tobool, label %if.else, label %if.then
1294
1295if.then:                                          ; preds = %entry
1296  %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N)
1297  %shl = shl i32 %call, 3
1298  br label %if.end
1299
1300if.else:                                          ; preds = %entry
1301  %mul = shl nsw i32 %N, 1
1302  br label %if.end
1303
1304if.end:                                           ; preds = %if.else, %if.then
1305  %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ]
1306  ret i32 %sum.0
1307}
1308
1309declare i32 @someVariadicFunc(i32, ...)
1310
1311; Make sure we do not insert unreachable code after noreturn function.
1312; Although this is not incorrect to insert such code, it is useless
1313; and it hurts the binary size.
1314;
1315; noreturn:
1316; push
1317; cmp r0, #0
1318; cmp r0, #0
1319; bne [[ABORT:LBB[0-9_]+]]
1320; bne [[ABORT:LBB[0-9_]+]]
1321; cbnz r0,  [[ABORT:LBB[0-9_]+]]
1322; cbnz r0,  [[ABORT:LBB[0-9_]+]]
1323
1324;
1325; mov{{s?}} r0, #42
1326;
1327; bx lr
1328;
1329; pop
1330;;
1331; [[ABORT]]: @ %if.abort
1332;
1333; push
1334;
1335; bl{{x?}} _abort
1336; pop
1337define i32 @noreturn(i8 signext %bad_thing) "frame-pointer"="all" {
1338; ARM-ENABLE-LABEL: noreturn:
1339; ARM-ENABLE:       Lfunc_begin8:
1340; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
1341; ARM-ENABLE-NEXT:    cmp r0, #0
1342; ARM-ENABLE-NEXT:    bne LBB8_2
1343; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.end
1344; ARM-ENABLE-NEXT:    mov r0, #42
1345; ARM-ENABLE-NEXT:    bx lr
1346; ARM-ENABLE-NEXT:  LBB8_2: @ %if.abort
1347; ARM-ENABLE-NEXT:    push {r4, r7, lr}
1348; ARM-ENABLE-NEXT:    add r7, sp, #4
1349; ARM-ENABLE-NEXT:    @ InlineAsm Start
1350; ARM-ENABLE-NEXT:    mov r0, #1
1351; ARM-ENABLE-NEXT:    @ InlineAsm End
1352; ARM-ENABLE-NEXT:    bl _abort
1353; ARM-ENABLE-NEXT:  Lfunc_end8:
1354;
1355; ARM-DISABLE-LABEL: noreturn:
1356; ARM-DISABLE:       Lfunc_begin8:
1357; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
1358; ARM-DISABLE-NEXT:    push {r4, r7, lr}
1359; ARM-DISABLE-NEXT:    add r7, sp, #4
1360; ARM-DISABLE-NEXT:    cmp r0, #0
1361; ARM-DISABLE-NEXT:    bne LBB8_2
1362; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.end
1363; ARM-DISABLE-NEXT:    mov r0, #42
1364; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
1365; ARM-DISABLE-NEXT:  LBB8_2: @ %if.abort
1366; ARM-DISABLE-NEXT:    @ InlineAsm Start
1367; ARM-DISABLE-NEXT:    mov r0, #1
1368; ARM-DISABLE-NEXT:    @ InlineAsm End
1369; ARM-DISABLE-NEXT:    bl _abort
1370; ARM-DISABLE-NEXT:  Lfunc_end8:
1371;
1372; THUMB-ENABLE-LABEL: noreturn:
1373; THUMB-ENABLE:       Lfunc_begin8:
1374; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
1375; THUMB-ENABLE-NEXT:    cbnz r0, LBB8_2
1376; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.end
1377; THUMB-ENABLE-NEXT:    movs r0, #42
1378; THUMB-ENABLE-NEXT:    bx lr
1379; THUMB-ENABLE-NEXT:  LBB8_2: @ %if.abort
1380; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
1381; THUMB-ENABLE-NEXT:    add r7, sp, #4
1382; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1383; THUMB-ENABLE-NEXT:    mov.w r0, #1
1384; THUMB-ENABLE-NEXT:    @ InlineAsm End
1385; THUMB-ENABLE-NEXT:    bl _abort
1386; THUMB-ENABLE-NEXT:  Lfunc_end8:
1387;
1388; THUMB-DISABLE-LABEL: noreturn:
1389; THUMB-DISABLE:       Lfunc_begin8:
1390; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
1391; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
1392; THUMB-DISABLE-NEXT:    add r7, sp, #4
1393; THUMB-DISABLE-NEXT:    cbnz r0, LBB8_2
1394; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.end
1395; THUMB-DISABLE-NEXT:    movs r0, #42
1396; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
1397; THUMB-DISABLE-NEXT:  LBB8_2: @ %if.abort
1398; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1399; THUMB-DISABLE-NEXT:    mov.w r0, #1
1400; THUMB-DISABLE-NEXT:    @ InlineAsm End
1401; THUMB-DISABLE-NEXT:    bl _abort
1402; THUMB-DISABLE-NEXT:  Lfunc_end8:
1403entry:
1404  %tobool = icmp eq i8 %bad_thing, 0
1405  br i1 %tobool, label %if.end, label %if.abort
1406
1407if.abort:
1408  %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
1409  tail call void @abort() #0
1410  unreachable
1411
1412if.end:
1413  ret i32 42
1414}
1415
1416declare void @abort() #0
1417
1418attributes #0 = { noreturn nounwind }
1419
1420; Make sure that we handle infinite loops properly When checking that the Save
1421; and Restore blocks are control flow equivalent, the loop searches for the
1422; immediate (post) dominator for the (restore) save blocks. When either the Save
1423; or Restore block is located in an infinite loop the only immediate (post)
1424; dominator is itself. In this case, we cannot perform shrink wrapping, but we
1425; should return gracefully and continue compilation.
1426; The only condition for this test is the compilation finishes correctly.
1427; infiniteloop
1428; pop
1429define void @infiniteloop() "frame-pointer"="all" {
1430; ARM-LABEL: infiniteloop:
1431; ARM:       @ %bb.0: @ %entry
1432; ARM-NEXT:    push {r4, r5, r7, lr}
1433; ARM-NEXT:    add r7, sp, #8
1434; ARM-NEXT:    mov r0, #0
1435; ARM-NEXT:    cmp r0, #0
1436; ARM-NEXT:    bne LBB9_3
1437; ARM-NEXT:  @ %bb.1: @ %if.then
1438; ARM-NEXT:    sub r1, sp, #16
1439; ARM-NEXT:    mov sp, r1
1440; ARM-NEXT:  LBB9_2: @ %for.body
1441; ARM-NEXT:    @ =>This Inner Loop Header: Depth=1
1442; ARM-NEXT:    @ InlineAsm Start
1443; ARM-NEXT:    mov r2, #1
1444; ARM-NEXT:    @ InlineAsm End
1445; ARM-NEXT:    add r0, r2, r0
1446; ARM-NEXT:    str r0, [r1]
1447; ARM-NEXT:    b LBB9_2
1448; ARM-NEXT:  LBB9_3: @ %if.end
1449; ARM-NEXT:    sub sp, r7, #8
1450; ARM-NEXT:    pop {r4, r5, r7, pc}
1451;
1452; THUMB-LABEL: infiniteloop:
1453; THUMB:       @ %bb.0: @ %entry
1454; THUMB-NEXT:    push {r4, r5, r7, lr}
1455; THUMB-NEXT:    add r7, sp, #8
1456; THUMB-NEXT:    movs r0, #0
1457; THUMB-NEXT:    cbnz r0, LBB9_3
1458; THUMB-NEXT:  @ %bb.1: @ %if.then
1459; THUMB-NEXT:    sub.w r0, sp, #16
1460; THUMB-NEXT:    mov sp, r0
1461; THUMB-NEXT:    movs r1, #0
1462; THUMB-NEXT:  LBB9_2: @ %for.body
1463; THUMB-NEXT:    @ =>This Inner Loop Header: Depth=1
1464; THUMB-NEXT:    @ InlineAsm Start
1465; THUMB-NEXT:    mov.w r2, #1
1466; THUMB-NEXT:    @ InlineAsm End
1467; THUMB-NEXT:    add r1, r2
1468; THUMB-NEXT:    str r1, [r0]
1469; THUMB-NEXT:    b LBB9_2
1470; THUMB-NEXT:  LBB9_3: @ %if.end
1471; THUMB-NEXT:    sub.w r4, r7, #8
1472; THUMB-NEXT:    mov sp, r4
1473; THUMB-NEXT:    pop {r4, r5, r7, pc}
1474; ARM-ENABLE-LABEL: infiniteloop:
1475; ARM-ENABLE:       Lfunc_begin9:
1476; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
1477; ARM-ENABLE-NEXT:    push {r4, r5, r7, lr}
1478; ARM-ENABLE-NEXT:    add r7, sp, #8
1479; ARM-ENABLE-NEXT:    mov r0, #0
1480; ARM-ENABLE-NEXT:    cmp r0, #0
1481; ARM-ENABLE-NEXT:    bne LBB9_3
1482; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.then
1483; ARM-ENABLE-NEXT:    sub r1, sp, #16
1484; ARM-ENABLE-NEXT:    mov sp, r1
1485; ARM-ENABLE-NEXT:  LBB9_2: @ %for.body
1486; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1487; ARM-ENABLE-NEXT:    @ InlineAsm Start
1488; ARM-ENABLE-NEXT:    mov r2, #1
1489; ARM-ENABLE-NEXT:    @ InlineAsm End
1490; ARM-ENABLE-NEXT:    add r0, r2, r0
1491; ARM-ENABLE-NEXT:    str r0, [r1]
1492; ARM-ENABLE-NEXT:    b LBB9_2
1493; ARM-ENABLE-NEXT:  LBB9_3: @ %if.end
1494; ARM-ENABLE-NEXT:    sub sp, r7, #8
1495; ARM-ENABLE-NEXT:    pop {r4, r5, r7, pc}
1496; ARM-ENABLE-NEXT:  Lfunc_end9:
1497;
1498; ARM-DISABLE-LABEL: infiniteloop:
1499; ARM-DISABLE:       Lfunc_begin9:
1500; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
1501; ARM-DISABLE-NEXT:    push {r4, r5, r7, lr}
1502; ARM-DISABLE-NEXT:    add r7, sp, #8
1503; ARM-DISABLE-NEXT:    mov r0, #0
1504; ARM-DISABLE-NEXT:    cmp r0, #0
1505; ARM-DISABLE-NEXT:    bne LBB9_3
1506; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.then
1507; ARM-DISABLE-NEXT:    sub r1, sp, #16
1508; ARM-DISABLE-NEXT:    mov sp, r1
1509; ARM-DISABLE-NEXT:  LBB9_2: @ %for.body
1510; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1511; ARM-DISABLE-NEXT:    @ InlineAsm Start
1512; ARM-DISABLE-NEXT:    mov r2, #1
1513; ARM-DISABLE-NEXT:    @ InlineAsm End
1514; ARM-DISABLE-NEXT:    add r0, r2, r0
1515; ARM-DISABLE-NEXT:    str r0, [r1]
1516; ARM-DISABLE-NEXT:    b LBB9_2
1517; ARM-DISABLE-NEXT:  LBB9_3: @ %if.end
1518; ARM-DISABLE-NEXT:    sub sp, r7, #8
1519; ARM-DISABLE-NEXT:    pop {r4, r5, r7, pc}
1520; ARM-DISABLE-NEXT:  Lfunc_end9:
1521;
1522; THUMB-ENABLE-LABEL: infiniteloop:
1523; THUMB-ENABLE:       Lfunc_begin9:
1524; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
1525; THUMB-ENABLE-NEXT:    push {r4, r5, r7, lr}
1526; THUMB-ENABLE-NEXT:    add r7, sp, #8
1527; THUMB-ENABLE-NEXT:    movs r0, #0
1528; THUMB-ENABLE-NEXT:    cbnz r0, LBB9_3
1529; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.then
1530; THUMB-ENABLE-NEXT:    sub.w r0, sp, #16
1531; THUMB-ENABLE-NEXT:    mov sp, r0
1532; THUMB-ENABLE-NEXT:    movs r1, #0
1533; THUMB-ENABLE-NEXT:  LBB9_2: @ %for.body
1534; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1535; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1536; THUMB-ENABLE-NEXT:    mov.w r2, #1
1537; THUMB-ENABLE-NEXT:    @ InlineAsm End
1538; THUMB-ENABLE-NEXT:    add r1, r2
1539; THUMB-ENABLE-NEXT:    str r1, [r0]
1540; THUMB-ENABLE-NEXT:    b LBB9_2
1541; THUMB-ENABLE-NEXT:  LBB9_3: @ %if.end
1542; THUMB-ENABLE-NEXT:    sub.w r4, r7, #8
1543; THUMB-ENABLE-NEXT:    mov sp, r4
1544; THUMB-ENABLE-NEXT:    pop {r4, r5, r7, pc}
1545; THUMB-ENABLE-NEXT:  Lfunc_end9:
1546;
1547; THUMB-DISABLE-LABEL: infiniteloop:
1548; THUMB-DISABLE:       Lfunc_begin9:
1549; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
1550; THUMB-DISABLE-NEXT:    push {r4, r5, r7, lr}
1551; THUMB-DISABLE-NEXT:    add r7, sp, #8
1552; THUMB-DISABLE-NEXT:    movs r0, #0
1553; THUMB-DISABLE-NEXT:    cbnz r0, LBB9_3
1554; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.then
1555; THUMB-DISABLE-NEXT:    sub.w r0, sp, #16
1556; THUMB-DISABLE-NEXT:    mov sp, r0
1557; THUMB-DISABLE-NEXT:    movs r1, #0
1558; THUMB-DISABLE-NEXT:  LBB9_2: @ %for.body
1559; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1560; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1561; THUMB-DISABLE-NEXT:    mov.w r2, #1
1562; THUMB-DISABLE-NEXT:    @ InlineAsm End
1563; THUMB-DISABLE-NEXT:    add r1, r2
1564; THUMB-DISABLE-NEXT:    str r1, [r0]
1565; THUMB-DISABLE-NEXT:    b LBB9_2
1566; THUMB-DISABLE-NEXT:  LBB9_3: @ %if.end
1567; THUMB-DISABLE-NEXT:    sub.w r4, r7, #8
1568; THUMB-DISABLE-NEXT:    mov sp, r4
1569; THUMB-DISABLE-NEXT:    pop {r4, r5, r7, pc}
1570; THUMB-DISABLE-NEXT:  Lfunc_end9:
1571entry:
1572  br i1 undef, label %if.then, label %if.end
1573
1574if.then:
1575  %ptr = alloca i32, i32 4
1576  br label %for.body
1577
1578for.body:                                         ; preds = %for.body, %entry
1579  %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
1580  %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
1581  %add = add nsw i32 %call, %sum.03
1582  store i32 %add, ptr %ptr
1583  br label %for.body
1584
1585if.end:
1586  ret void
1587}
1588
1589; Another infinite loop test this time with a body bigger than just one block.
1590; infiniteloop2
1591; pop
1592define void @infiniteloop2() "frame-pointer"="all" {
1593; ARM-ENABLE-LABEL: infiniteloop2:
1594; ARM-ENABLE:       Lfunc_begin10:
1595; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
1596; ARM-ENABLE-NEXT:    push {r4, r5, r7, lr}
1597; ARM-ENABLE-NEXT:    add r7, sp, #8
1598; ARM-ENABLE-NEXT:    mov r0, #0
1599; ARM-ENABLE-NEXT:    cmp r0, #0
1600; ARM-ENABLE-NEXT:    bne LBB10_3
1601; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.then
1602; ARM-ENABLE-NEXT:    sub r1, sp, #16
1603; ARM-ENABLE-NEXT:    mov sp, r1
1604; ARM-ENABLE-NEXT:    @ InlineAsm Start
1605; ARM-ENABLE-NEXT:    mov r2, #0
1606; ARM-ENABLE-NEXT:    @ InlineAsm End
1607; ARM-ENABLE-NEXT:  LBB10_2: @ %for.body
1608; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1609; ARM-ENABLE-NEXT:    add r0, r2, r0
1610; ARM-ENABLE-NEXT:    str r0, [r1]
1611; ARM-ENABLE-NEXT:    @ InlineAsm Start
1612; ARM-ENABLE-NEXT:    nop
1613; ARM-ENABLE-NEXT:    @ InlineAsm End
1614; ARM-ENABLE-NEXT:    mov r0, #1
1615; ARM-ENABLE-NEXT:    b LBB10_2
1616; ARM-ENABLE-NEXT:  LBB10_3: @ %if.end
1617; ARM-ENABLE-NEXT:    sub sp, r7, #8
1618; ARM-ENABLE-NEXT:    pop {r4, r5, r7, pc}
1619; ARM-ENABLE-NEXT:  Lfunc_end10:
1620;
1621; ARM-DISABLE-LABEL: infiniteloop2:
1622; ARM-DISABLE:       Lfunc_begin10:
1623; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
1624; ARM-DISABLE-NEXT:    push {r4, r5, r7, lr}
1625; ARM-DISABLE-NEXT:    add r7, sp, #8
1626; ARM-DISABLE-NEXT:    mov r0, #0
1627; ARM-DISABLE-NEXT:    cmp r0, #0
1628; ARM-DISABLE-NEXT:    bne LBB10_3
1629; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.then
1630; ARM-DISABLE-NEXT:    sub r1, sp, #16
1631; ARM-DISABLE-NEXT:    mov sp, r1
1632; ARM-DISABLE-NEXT:    @ InlineAsm Start
1633; ARM-DISABLE-NEXT:    mov r2, #0
1634; ARM-DISABLE-NEXT:    @ InlineAsm End
1635; ARM-DISABLE-NEXT:  LBB10_2: @ %for.body
1636; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1637; ARM-DISABLE-NEXT:    add r0, r2, r0
1638; ARM-DISABLE-NEXT:    str r0, [r1]
1639; ARM-DISABLE-NEXT:    @ InlineAsm Start
1640; ARM-DISABLE-NEXT:    nop
1641; ARM-DISABLE-NEXT:    @ InlineAsm End
1642; ARM-DISABLE-NEXT:    mov r0, #1
1643; ARM-DISABLE-NEXT:    b LBB10_2
1644; ARM-DISABLE-NEXT:  LBB10_3: @ %if.end
1645; ARM-DISABLE-NEXT:    sub sp, r7, #8
1646; ARM-DISABLE-NEXT:    pop {r4, r5, r7, pc}
1647; ARM-DISABLE-NEXT:  Lfunc_end10:
1648;
1649; THUMB-ENABLE-LABEL: infiniteloop2:
1650; THUMB-ENABLE:       Lfunc_begin10:
1651; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
1652; THUMB-ENABLE-NEXT:    push {r4, r5, r7, lr}
1653; THUMB-ENABLE-NEXT:    add r7, sp, #8
1654; THUMB-ENABLE-NEXT:    movs r0, #0
1655; THUMB-ENABLE-NEXT:    cbnz r0, LBB10_3
1656; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.then
1657; THUMB-ENABLE-NEXT:    sub.w r0, sp, #16
1658; THUMB-ENABLE-NEXT:    mov sp, r0
1659; THUMB-ENABLE-NEXT:    movs r1, #0
1660; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1661; THUMB-ENABLE-NEXT:    mov.w r2, #0
1662; THUMB-ENABLE-NEXT:    @ InlineAsm End
1663; THUMB-ENABLE-NEXT:  LBB10_2: @ %for.body
1664; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1665; THUMB-ENABLE-NEXT:    add r1, r2
1666; THUMB-ENABLE-NEXT:    str r1, [r0]
1667; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1668; THUMB-ENABLE-NEXT:    nop
1669; THUMB-ENABLE-NEXT:    @ InlineAsm End
1670; THUMB-ENABLE-NEXT:    movs r1, #1
1671; THUMB-ENABLE-NEXT:    b LBB10_2
1672; THUMB-ENABLE-NEXT:  LBB10_3: @ %if.end
1673; THUMB-ENABLE-NEXT:    sub.w r4, r7, #8
1674; THUMB-ENABLE-NEXT:    mov sp, r4
1675; THUMB-ENABLE-NEXT:    pop {r4, r5, r7, pc}
1676; THUMB-ENABLE-NEXT:  Lfunc_end10:
1677;
1678; THUMB-DISABLE-LABEL: infiniteloop2:
1679; THUMB-DISABLE:       Lfunc_begin10:
1680; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
1681; THUMB-DISABLE-NEXT:    push {r4, r5, r7, lr}
1682; THUMB-DISABLE-NEXT:    add r7, sp, #8
1683; THUMB-DISABLE-NEXT:    movs r0, #0
1684; THUMB-DISABLE-NEXT:    cbnz r0, LBB10_3
1685; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.then
1686; THUMB-DISABLE-NEXT:    sub.w r0, sp, #16
1687; THUMB-DISABLE-NEXT:    mov sp, r0
1688; THUMB-DISABLE-NEXT:    movs r1, #0
1689; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1690; THUMB-DISABLE-NEXT:    mov.w r2, #0
1691; THUMB-DISABLE-NEXT:    @ InlineAsm End
1692; THUMB-DISABLE-NEXT:  LBB10_2: @ %for.body
1693; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1694; THUMB-DISABLE-NEXT:    add r1, r2
1695; THUMB-DISABLE-NEXT:    str r1, [r0]
1696; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1697; THUMB-DISABLE-NEXT:    nop
1698; THUMB-DISABLE-NEXT:    @ InlineAsm End
1699; THUMB-DISABLE-NEXT:    movs r1, #1
1700; THUMB-DISABLE-NEXT:    b LBB10_2
1701; THUMB-DISABLE-NEXT:  LBB10_3: @ %if.end
1702; THUMB-DISABLE-NEXT:    sub.w r4, r7, #8
1703; THUMB-DISABLE-NEXT:    mov sp, r4
1704; THUMB-DISABLE-NEXT:    pop {r4, r5, r7, pc}
1705; THUMB-DISABLE-NEXT:  Lfunc_end10:
1706entry:
1707  br i1 undef, label %if.then, label %if.end
1708
1709if.then:
1710  %ptr = alloca i32, i32 4
1711  br label %for.body
1712
1713for.body:                                         ; preds = %for.body, %entry
1714  %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2]
1715  %call = tail call i32 asm "mov $0, #0", "=r,~{r4}"()
1716  %add = add nsw i32 %call, %sum.03
1717  store i32 %add, ptr %ptr
1718  br i1 undef, label %body1, label %body2
1719
1720body1:
1721  tail call void asm sideeffect "nop", "~{r4}"()
1722  br label %for.body
1723
1724body2:
1725  tail call void asm sideeffect "nop", "~{r4}"()
1726  br label %for.body
1727
1728if.end:
1729  ret void
1730}
1731
1732; Another infinite loop test this time with two nested infinite loop.
1733; infiniteloop3
1734; bx lr
1735define void @infiniteloop3() "frame-pointer"="none" {
1736; ARM-LABEL: infiniteloop3:
1737; ARM:       @ %bb.0: @ %entry
1738; ARM-NEXT:    mov r0, #0
1739; ARM-NEXT:    cmp r0, #0
1740; ARM-NEXT:    bne LBB11_5
1741; ARM-NEXT:  @ %bb.1: @ %loop2a.preheader
1742; ARM-NEXT:    mov r1, #0
1743; ARM-NEXT:    mov r2, r0
1744; ARM-NEXT:    b LBB11_3
1745; ARM-NEXT:  LBB11_2: @ %loop2b
1746; ARM-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1747; ARM-NEXT:    str r1, [r2]
1748; ARM-NEXT:    mov r2, r1
1749; ARM-NEXT:    mov r1, r3
1750; ARM-NEXT:  LBB11_3: @ %loop1
1751; ARM-NEXT:    @ =>This Inner Loop Header: Depth=1
1752; ARM-NEXT:    ldr r3, [r0]
1753; ARM-NEXT:    cmp r0, #0
1754; ARM-NEXT:    bne LBB11_2
1755; ARM-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1756; ARM-NEXT:    mov r0, r1
1757; ARM-NEXT:    mov r1, r3
1758; ARM-NEXT:    mov r2, r0
1759; ARM-NEXT:    b LBB11_3
1760; ARM-NEXT:  LBB11_5: @ %end
1761; ARM-NEXT:    bx lr
1762;
1763; THUMB-LABEL: infiniteloop3:
1764; THUMB:       @ %bb.0: @ %entry
1765; THUMB-NEXT:    movs r0, #0
1766; THUMB-NEXT:    cbnz r0, LBB11_5
1767; THUMB-NEXT:  @ %bb.1: @ %loop2a.preheader
1768; THUMB-NEXT:    movs r0, #0
1769; THUMB-NEXT:    movs r1, #0
1770; THUMB-NEXT:    mov r2, r0
1771; THUMB-NEXT:    b LBB11_3
1772; THUMB-NEXT:  LBB11_2: @ %loop2b
1773; THUMB-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1774; THUMB-NEXT:    str r1, [r2]
1775; THUMB-NEXT:    mov r2, r1
1776; THUMB-NEXT:    mov r1, r3
1777; THUMB-NEXT:  LBB11_3: @ %loop1
1778; THUMB-NEXT:    @ =>This Inner Loop Header: Depth=1
1779; THUMB-NEXT:    ldr r3, [r0]
1780; THUMB-NEXT:    cmp r0, #0
1781; THUMB-NEXT:    bne LBB11_2
1782; THUMB-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1783; THUMB-NEXT:    mov r0, r1
1784; THUMB-NEXT:    mov r1, r3
1785; THUMB-NEXT:    mov r2, r0
1786; THUMB-NEXT:    b LBB11_3
1787; THUMB-NEXT:  LBB11_5: @ %end
1788; THUMB-NEXT:    bx lr
1789; ARM-ENABLE-LABEL: infiniteloop3:
1790; ARM-ENABLE:       Lfunc_begin11:
1791; ARM-ENABLE-NEXT:  @ %bb.0: @ %entry
1792; ARM-ENABLE-NEXT:    mov r0, #0
1793; ARM-ENABLE-NEXT:    cmp r0, #0
1794; ARM-ENABLE-NEXT:    bne LBB11_5
1795; ARM-ENABLE-NEXT:  @ %bb.1: @ %loop2a.preheader
1796; ARM-ENABLE-NEXT:    mov r1, #0
1797; ARM-ENABLE-NEXT:    mov r2, r0
1798; ARM-ENABLE-NEXT:    b LBB11_3
1799; ARM-ENABLE-NEXT:  LBB11_2: @ %loop2b
1800; ARM-ENABLE-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1801; ARM-ENABLE-NEXT:    str r1, [r2]
1802; ARM-ENABLE-NEXT:    mov r2, r1
1803; ARM-ENABLE-NEXT:    mov r1, r3
1804; ARM-ENABLE-NEXT:  LBB11_3: @ %loop1
1805; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1806; ARM-ENABLE-NEXT:    ldr r3, [r0]
1807; ARM-ENABLE-NEXT:    cmp r0, #0
1808; ARM-ENABLE-NEXT:    bne LBB11_2
1809; ARM-ENABLE-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1810; ARM-ENABLE-NEXT:    mov r0, r1
1811; ARM-ENABLE-NEXT:    mov r1, r3
1812; ARM-ENABLE-NEXT:    mov r2, r0
1813; ARM-ENABLE-NEXT:    b LBB11_3
1814; ARM-ENABLE-NEXT:  LBB11_5: @ %end
1815; ARM-ENABLE-NEXT:    bx lr
1816; ARM-ENABLE-NEXT:  Lfunc_end11:
1817;
1818; ARM-DISABLE-LABEL: infiniteloop3:
1819; ARM-DISABLE:       Lfunc_begin11:
1820; ARM-DISABLE-NEXT:  @ %bb.0: @ %entry
1821; ARM-DISABLE-NEXT:    mov r0, #0
1822; ARM-DISABLE-NEXT:    cmp r0, #0
1823; ARM-DISABLE-NEXT:    bne LBB11_5
1824; ARM-DISABLE-NEXT:  @ %bb.1: @ %loop2a.preheader
1825; ARM-DISABLE-NEXT:    mov r1, #0
1826; ARM-DISABLE-NEXT:    mov r2, r0
1827; ARM-DISABLE-NEXT:    b LBB11_3
1828; ARM-DISABLE-NEXT:  LBB11_2: @ %loop2b
1829; ARM-DISABLE-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1830; ARM-DISABLE-NEXT:    str r1, [r2]
1831; ARM-DISABLE-NEXT:    mov r2, r1
1832; ARM-DISABLE-NEXT:    mov r1, r3
1833; ARM-DISABLE-NEXT:  LBB11_3: @ %loop1
1834; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1835; ARM-DISABLE-NEXT:    ldr r3, [r0]
1836; ARM-DISABLE-NEXT:    cmp r0, #0
1837; ARM-DISABLE-NEXT:    bne LBB11_2
1838; ARM-DISABLE-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1839; ARM-DISABLE-NEXT:    mov r0, r1
1840; ARM-DISABLE-NEXT:    mov r1, r3
1841; ARM-DISABLE-NEXT:    mov r2, r0
1842; ARM-DISABLE-NEXT:    b LBB11_3
1843; ARM-DISABLE-NEXT:  LBB11_5: @ %end
1844; ARM-DISABLE-NEXT:    bx lr
1845; ARM-DISABLE-NEXT:  Lfunc_end11:
1846;
1847; THUMB-ENABLE-LABEL: infiniteloop3:
1848; THUMB-ENABLE:       Lfunc_begin11:
1849; THUMB-ENABLE-NEXT:  @ %bb.0: @ %entry
1850; THUMB-ENABLE-NEXT:    movs r0, #0
1851; THUMB-ENABLE-NEXT:    cbnz r0, LBB11_5
1852; THUMB-ENABLE-NEXT:  @ %bb.1: @ %loop2a.preheader
1853; THUMB-ENABLE-NEXT:    movs r1, #0
1854; THUMB-ENABLE-NEXT:    mov r2, r0
1855; THUMB-ENABLE-NEXT:    b LBB11_3
1856; THUMB-ENABLE-NEXT:  LBB11_2: @ %loop2b
1857; THUMB-ENABLE-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1858; THUMB-ENABLE-NEXT:    str r1, [r2]
1859; THUMB-ENABLE-NEXT:    mov r2, r1
1860; THUMB-ENABLE-NEXT:    mov r1, r3
1861; THUMB-ENABLE-NEXT:  LBB11_3: @ %loop1
1862; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1863; THUMB-ENABLE-NEXT:    ldr r3, [r0]
1864; THUMB-ENABLE-NEXT:    cmp r0, #0
1865; THUMB-ENABLE-NEXT:    bne LBB11_2
1866; THUMB-ENABLE-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1867; THUMB-ENABLE-NEXT:    mov r0, r1
1868; THUMB-ENABLE-NEXT:    mov r1, r3
1869; THUMB-ENABLE-NEXT:    mov r2, r0
1870; THUMB-ENABLE-NEXT:    b LBB11_3
1871; THUMB-ENABLE-NEXT:  LBB11_5: @ %end
1872; THUMB-ENABLE-NEXT:    bx lr
1873; THUMB-ENABLE-NEXT:  Lfunc_end11:
1874;
1875; THUMB-DISABLE-LABEL: infiniteloop3:
1876; THUMB-DISABLE:       Lfunc_begin11:
1877; THUMB-DISABLE-NEXT:  @ %bb.0: @ %entry
1878; THUMB-DISABLE-NEXT:    movs r0, #0
1879; THUMB-DISABLE-NEXT:    cbnz r0, LBB11_5
1880; THUMB-DISABLE-NEXT:  @ %bb.1: @ %loop2a.preheader
1881; THUMB-DISABLE-NEXT:    movs r1, #0
1882; THUMB-DISABLE-NEXT:    mov r2, r0
1883; THUMB-DISABLE-NEXT:    b LBB11_3
1884; THUMB-DISABLE-NEXT:  LBB11_2: @ %loop2b
1885; THUMB-DISABLE-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1886; THUMB-DISABLE-NEXT:    str r1, [r2]
1887; THUMB-DISABLE-NEXT:    mov r2, r1
1888; THUMB-DISABLE-NEXT:    mov r1, r3
1889; THUMB-DISABLE-NEXT:  LBB11_3: @ %loop1
1890; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1891; THUMB-DISABLE-NEXT:    ldr r3, [r0]
1892; THUMB-DISABLE-NEXT:    cmp r0, #0
1893; THUMB-DISABLE-NEXT:    bne LBB11_2
1894; THUMB-DISABLE-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1895; THUMB-DISABLE-NEXT:    mov r0, r1
1896; THUMB-DISABLE-NEXT:    mov r1, r3
1897; THUMB-DISABLE-NEXT:    mov r2, r0
1898; THUMB-DISABLE-NEXT:    b LBB11_3
1899; THUMB-DISABLE-NEXT:  LBB11_5: @ %end
1900; THUMB-DISABLE-NEXT:    bx lr
1901; THUMB-DISABLE-NEXT:  Lfunc_end11:
1902entry:
1903  br i1 undef, label %loop2a, label %body
1904
1905body:                                             ; preds = %entry
1906  br i1 undef, label %loop2a, label %end
1907
1908loop1:                                            ; preds = %loop2a, %loop2b
1909  %var.phi = phi ptr [ %next.phi, %loop2b ], [ %var, %loop2a ]
1910  %next.phi = phi ptr [ %next.load, %loop2b ], [ %next.var, %loop2a ]
1911  %0 = icmp eq ptr %var, null
1912  %next.load = load ptr, ptr undef
1913  br i1 %0, label %loop2a, label %loop2b
1914
1915loop2a:                                           ; preds = %loop1, %body, %entry
1916  %var = phi ptr [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ]
1917  %next.var = phi ptr [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ]
1918  br label %loop1
1919
1920loop2b:                                           ; preds = %loop1
1921  store ptr %next.phi, ptr %var.phi
1922  br label %loop1
1923
1924end:
1925  ret void
1926}
1927
1928; Function Attrs: nounwind readnone
1929declare double @llvm.pow.f64(double, double)
1930
1931; This function needs to spill floating point registers to
1932; exercise the path where we were dereferencing the end iterator
1933; to access debug info location while inserting the spill code
1934; during PEI with shrink-wrapping enable.
1935; debug_info:
1936;
1937; {{tst  r2, #1|lsls r1, r2, #31}}
1938; beq      [[BB13:LBB[0-9_]+]]
1939;
1940; push
1941;
1942; {{tst  r2, #1|lsls r1, r2, #31}}
1943; beq      [[BB13:LBB[0-9_]+]]
1944;
1945; bl{{x?}} _pow
1946;
1947;
1948; pop
1949;
1950; [[BB13]]:
1951; vldr
1952;
1953; pop
1954;
1955; FIXME: This is flakey passing by finding 'bl' somewhere amongst the debug
1956; info (like labels named 'line_table) not because it's found a bl instruction.
1957;
1958; bl
1959define float @debug_info(float %gamma, float %slopeLimit, i1 %or.cond, double %tmp) "frame-pointer"="all" {
1960; ARM-ENABLE-LABEL: debug_info:
1961; ARM-ENABLE:       Lfunc_begin12:
1962; ARM-ENABLE-NEXT:  @ %bb.0: @ %bb
1963; ARM-ENABLE-NEXT:    tst r2, #1
1964; ARM-ENABLE-NEXT:    beq LBB12_2
1965; ARM-ENABLE-NEXT:  @ %bb.1: @ %bb3
1966; ARM-ENABLE-NEXT:    push {r4, r7, lr}
1967; ARM-ENABLE-NEXT:    add r7, sp, #4
1968; ARM-ENABLE-NEXT:    sub r4, sp, #24
1969; ARM-ENABLE-NEXT:    bfc r4, #0, #4
1970; ARM-ENABLE-NEXT:    mov sp, r4
1971; ARM-ENABLE-NEXT:    ldr r1, [r7, #8]
1972; ARM-ENABLE-NEXT:    vmov.f64 d16, #1.000000e+00
1973; ARM-ENABLE-NEXT:    mov r2, r3
1974; ARM-ENABLE-NEXT:    vst1.64 {d8, d9}, [r4:128]
1975; ARM-ENABLE-NEXT:    vmov d9, r3, r1
1976; ARM-ENABLE-NEXT:    vmov s16, r0
1977; ARM-ENABLE-NEXT:    mov r0, r3
1978; ARM-ENABLE-NEXT:    mov r3, r1
1979; ARM-ENABLE-NEXT:    vstr d10, [r4, #16]
1980; ARM-ENABLE-NEXT:    vadd.f64 d10, d9, d16
1981; ARM-ENABLE-NEXT:    bl _pow
1982; ARM-ENABLE-NEXT:    vmov.f32 s0, #1.000000e+00
1983; ARM-ENABLE-NEXT:    mov r4, sp
1984; ARM-ENABLE-NEXT:    vmov.f64 d17, d9
1985; ARM-ENABLE-NEXT:    vmov d16, r0, r1
1986; ARM-ENABLE-NEXT:    vcmp.f32 s16, s0
1987; ARM-ENABLE-NEXT:    vmrs APSR_nzcv, fpscr
1988; ARM-ENABLE-NEXT:    vadd.f64 d16, d16, d16
1989; ARM-ENABLE-NEXT:    vmovgt.f64 d17, d10
1990; ARM-ENABLE-NEXT:    vcmp.f64 d17, d9
1991; ARM-ENABLE-NEXT:    vmrs APSR_nzcv, fpscr
1992; ARM-ENABLE-NEXT:    vmovne.f64 d9, d16
1993; ARM-ENABLE-NEXT:    vcvt.f32.f64 s0, d9
1994; ARM-ENABLE-NEXT:    vld1.64 {d8, d9}, [r4:128]
1995; ARM-ENABLE-NEXT:    vldr d10, [r4, #16]
1996; ARM-ENABLE-NEXT:    sub sp, r7, #4
1997; ARM-ENABLE-NEXT:    pop {r4, r7, lr}
1998; ARM-ENABLE-NEXT:    vmov r0, s0
1999; ARM-ENABLE-NEXT:    bx lr
2000; ARM-ENABLE-NEXT:  LBB12_2:
2001; ARM-ENABLE-NEXT:    vldr s0, LCPI12_0
2002; ARM-ENABLE-NEXT:    vmov r0, s0
2003; ARM-ENABLE-NEXT:    bx lr
2004; ARM-ENABLE-NEXT:    .p2align 2
2005; ARM-ENABLE-NEXT:  @ %bb.3:
2006; ARM-ENABLE-NEXT:    .data_region
2007; ARM-ENABLE-NEXT:  LCPI12_0:
2008; ARM-ENABLE-NEXT:    .long 0x00000000 @ float 0
2009; ARM-ENABLE-NEXT:    .end_data_region
2010; ARM-ENABLE-NEXT:  Lfunc_end12:
2011;
2012; ARM-DISABLE-LABEL: debug_info:
2013; ARM-DISABLE:       Lfunc_begin12:
2014; ARM-DISABLE-NEXT:  @ %bb.0: @ %bb
2015; ARM-DISABLE-NEXT:    push {r4, r7, lr}
2016; ARM-DISABLE-NEXT:    add r7, sp, #4
2017; ARM-DISABLE-NEXT:    sub r4, sp, #24
2018; ARM-DISABLE-NEXT:    bfc r4, #0, #4
2019; ARM-DISABLE-NEXT:    mov sp, r4
2020; ARM-DISABLE-NEXT:    tst r2, #1
2021; ARM-DISABLE-NEXT:    vst1.64 {d8, d9}, [r4:128]
2022; ARM-DISABLE-NEXT:    vstr d10, [r4, #16]
2023; ARM-DISABLE-NEXT:    beq LBB12_2
2024; ARM-DISABLE-NEXT:  @ %bb.1: @ %bb3
2025; ARM-DISABLE-NEXT:    ldr r1, [r7, #8]
2026; ARM-DISABLE-NEXT:    vmov.f64 d16, #1.000000e+00
2027; ARM-DISABLE-NEXT:    mov r2, r3
2028; ARM-DISABLE-NEXT:    vmov d9, r3, r1
2029; ARM-DISABLE-NEXT:    vmov s16, r0
2030; ARM-DISABLE-NEXT:    mov r0, r3
2031; ARM-DISABLE-NEXT:    mov r3, r1
2032; ARM-DISABLE-NEXT:    vadd.f64 d10, d9, d16
2033; ARM-DISABLE-NEXT:    bl _pow
2034; ARM-DISABLE-NEXT:    vmov.f32 s0, #1.000000e+00
2035; ARM-DISABLE-NEXT:    vmov.f64 d17, d9
2036; ARM-DISABLE-NEXT:    vmov d16, r0, r1
2037; ARM-DISABLE-NEXT:    vcmp.f32 s16, s0
2038; ARM-DISABLE-NEXT:    vmrs APSR_nzcv, fpscr
2039; ARM-DISABLE-NEXT:    vadd.f64 d16, d16, d16
2040; ARM-DISABLE-NEXT:    vmovgt.f64 d17, d10
2041; ARM-DISABLE-NEXT:    vcmp.f64 d17, d9
2042; ARM-DISABLE-NEXT:    vmrs APSR_nzcv, fpscr
2043; ARM-DISABLE-NEXT:    vmovne.f64 d9, d16
2044; ARM-DISABLE-NEXT:    vcvt.f32.f64 s0, d9
2045; ARM-DISABLE-NEXT:    b LBB12_3
2046; ARM-DISABLE-NEXT:  LBB12_2:
2047; ARM-DISABLE-NEXT:    vldr s0, LCPI12_0
2048; ARM-DISABLE-NEXT:  LBB12_3: @ %bb13
2049; ARM-DISABLE-NEXT:    mov r4, sp
2050; ARM-DISABLE-NEXT:    vld1.64 {d8, d9}, [r4:128]
2051; ARM-DISABLE-NEXT:    vmov r0, s0
2052; ARM-DISABLE-NEXT:    vldr d10, [r4, #16]
2053; ARM-DISABLE-NEXT:    sub sp, r7, #4
2054; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
2055; ARM-DISABLE-NEXT:    .p2align 2
2056; ARM-DISABLE-NEXT:  @ %bb.4:
2057; ARM-DISABLE-NEXT:    .data_region
2058; ARM-DISABLE-NEXT:  LCPI12_0:
2059; ARM-DISABLE-NEXT:    .long 0x00000000 @ float 0
2060; ARM-DISABLE-NEXT:    .end_data_region
2061; ARM-DISABLE-NEXT:  Lfunc_end12:
2062;
2063; THUMB-ENABLE-LABEL: debug_info:
2064; THUMB-ENABLE:       Lfunc_begin12:
2065; THUMB-ENABLE-NEXT:  @ %bb.0: @ %bb
2066; THUMB-ENABLE-NEXT:    lsls r1, r2, #31
2067; THUMB-ENABLE-NEXT:    beq LBB12_2
2068; THUMB-ENABLE-NEXT:  @ %bb.1: @ %bb3
2069; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
2070; THUMB-ENABLE-NEXT:    add r7, sp, #4
2071; THUMB-ENABLE-NEXT:    sub.w r4, sp, #24
2072; THUMB-ENABLE-NEXT:    bfc r4, #0, #4
2073; THUMB-ENABLE-NEXT:    mov sp, r4
2074; THUMB-ENABLE-NEXT:    ldr r1, [r7, #8]
2075; THUMB-ENABLE-NEXT:    vmov.f64 d16, #1.000000e+00
2076; THUMB-ENABLE-NEXT:    mov r2, r3
2077; THUMB-ENABLE-NEXT:    vst1.64 {d8, d9}, [r4:128]
2078; THUMB-ENABLE-NEXT:    vmov d9, r3, r1
2079; THUMB-ENABLE-NEXT:    vmov s16, r0
2080; THUMB-ENABLE-NEXT:    mov r0, r3
2081; THUMB-ENABLE-NEXT:    mov r3, r1
2082; THUMB-ENABLE-NEXT:    vstr d10, [r4, #16]
2083; THUMB-ENABLE-NEXT:    vadd.f64 d10, d9, d16
2084; THUMB-ENABLE-NEXT:    bl _pow
2085; THUMB-ENABLE-NEXT:    vmov.f32 s0, #1.000000e+00
2086; THUMB-ENABLE-NEXT:    mov r4, sp
2087; THUMB-ENABLE-NEXT:    vmov.f64 d17, d9
2088; THUMB-ENABLE-NEXT:    vmov d16, r0, r1
2089; THUMB-ENABLE-NEXT:    vcmp.f32 s16, s0
2090; THUMB-ENABLE-NEXT:    vmrs APSR_nzcv, fpscr
2091; THUMB-ENABLE-NEXT:    it gt
2092; THUMB-ENABLE-NEXT:    vmovgt.f64 d17, d10
2093; THUMB-ENABLE-NEXT:    vcmp.f64 d17, d9
2094; THUMB-ENABLE-NEXT:    vadd.f64 d16, d16, d16
2095; THUMB-ENABLE-NEXT:    vmrs APSR_nzcv, fpscr
2096; THUMB-ENABLE-NEXT:    it ne
2097; THUMB-ENABLE-NEXT:    vmovne.f64 d9, d16
2098; THUMB-ENABLE-NEXT:    vcvt.f32.f64 s0, d9
2099; THUMB-ENABLE-NEXT:    vld1.64 {d8, d9}, [r4:128]
2100; THUMB-ENABLE-NEXT:    vldr d10, [r4, #16]
2101; THUMB-ENABLE-NEXT:    subs r4, r7, #4
2102; THUMB-ENABLE-NEXT:    mov sp, r4
2103; THUMB-ENABLE-NEXT:    pop.w {r4, r7, lr}
2104; THUMB-ENABLE-NEXT:    vmov r0, s0
2105; THUMB-ENABLE-NEXT:    bx lr
2106; THUMB-ENABLE-NEXT:  LBB12_2:
2107; THUMB-ENABLE-NEXT:    vldr s0, LCPI12_0
2108; THUMB-ENABLE-NEXT:    vmov r0, s0
2109; THUMB-ENABLE-NEXT:    bx lr
2110; THUMB-ENABLE-NEXT:    .p2align 2
2111; THUMB-ENABLE-NEXT:  @ %bb.3:
2112; THUMB-ENABLE-NEXT:    .data_region
2113; THUMB-ENABLE-NEXT:  LCPI12_0:
2114; THUMB-ENABLE-NEXT:    .long 0x00000000 @ float 0
2115; THUMB-ENABLE-NEXT:    .end_data_region
2116; THUMB-ENABLE-NEXT:  Lfunc_end12:
2117;
2118; THUMB-DISABLE-LABEL: debug_info:
2119; THUMB-DISABLE:       Lfunc_begin12:
2120; THUMB-DISABLE-NEXT:  @ %bb.0: @ %bb
2121; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
2122; THUMB-DISABLE-NEXT:    add r7, sp, #4
2123; THUMB-DISABLE-NEXT:    sub.w r4, sp, #24
2124; THUMB-DISABLE-NEXT:    bfc r4, #0, #4
2125; THUMB-DISABLE-NEXT:    mov sp, r4
2126; THUMB-DISABLE-NEXT:    lsls r1, r2, #31
2127; THUMB-DISABLE-NEXT:    vst1.64 {d8, d9}, [r4:128]
2128; THUMB-DISABLE-NEXT:    vstr d10, [r4, #16]
2129; THUMB-DISABLE-NEXT:    beq LBB12_2
2130; THUMB-DISABLE-NEXT:  @ %bb.1: @ %bb3
2131; THUMB-DISABLE-NEXT:    ldr r1, [r7, #8]
2132; THUMB-DISABLE-NEXT:    vmov.f64 d16, #1.000000e+00
2133; THUMB-DISABLE-NEXT:    mov r2, r3
2134; THUMB-DISABLE-NEXT:    vmov d9, r3, r1
2135; THUMB-DISABLE-NEXT:    vmov s16, r0
2136; THUMB-DISABLE-NEXT:    mov r0, r3
2137; THUMB-DISABLE-NEXT:    mov r3, r1
2138; THUMB-DISABLE-NEXT:    vadd.f64 d10, d9, d16
2139; THUMB-DISABLE-NEXT:    bl _pow
2140; THUMB-DISABLE-NEXT:    vmov.f32 s0, #1.000000e+00
2141; THUMB-DISABLE-NEXT:    vmov.f64 d17, d9
2142; THUMB-DISABLE-NEXT:    vmov d16, r0, r1
2143; THUMB-DISABLE-NEXT:    vcmp.f32 s16, s0
2144; THUMB-DISABLE-NEXT:    vmrs APSR_nzcv, fpscr
2145; THUMB-DISABLE-NEXT:    it gt
2146; THUMB-DISABLE-NEXT:    vmovgt.f64 d17, d10
2147; THUMB-DISABLE-NEXT:    vcmp.f64 d17, d9
2148; THUMB-DISABLE-NEXT:    vadd.f64 d16, d16, d16
2149; THUMB-DISABLE-NEXT:    vmrs APSR_nzcv, fpscr
2150; THUMB-DISABLE-NEXT:    it ne
2151; THUMB-DISABLE-NEXT:    vmovne.f64 d9, d16
2152; THUMB-DISABLE-NEXT:    vcvt.f32.f64 s0, d9
2153; THUMB-DISABLE-NEXT:    b LBB12_3
2154; THUMB-DISABLE-NEXT:  LBB12_2:
2155; THUMB-DISABLE-NEXT:    vldr s0, LCPI12_0
2156; THUMB-DISABLE-NEXT:  LBB12_3: @ %bb13
2157; THUMB-DISABLE-NEXT:    mov r4, sp
2158; THUMB-DISABLE-NEXT:    vld1.64 {d8, d9}, [r4:128]
2159; THUMB-DISABLE-NEXT:    vmov r0, s0
2160; THUMB-DISABLE-NEXT:    vldr d10, [r4, #16]
2161; THUMB-DISABLE-NEXT:    subs r4, r7, #4
2162; THUMB-DISABLE-NEXT:    mov sp, r4
2163; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
2164; THUMB-DISABLE-NEXT:    .p2align 2
2165; THUMB-DISABLE-NEXT:  @ %bb.4:
2166; THUMB-DISABLE-NEXT:    .data_region
2167; THUMB-DISABLE-NEXT:  LCPI12_0:
2168; THUMB-DISABLE-NEXT:    .long 0x00000000 @ float 0
2169; THUMB-DISABLE-NEXT:    .end_data_region
2170; THUMB-DISABLE-NEXT:  Lfunc_end12:
2171bb:
2172  br i1 %or.cond, label %bb3, label %bb13
2173
2174bb3:                                              ; preds = %bb
2175  %tmp4 = fcmp ogt float %gamma, 1.000000e+00
2176  %tmp5 = fadd double 1.000000e+00, %tmp
2177  %tmp6 = select i1 %tmp4, double %tmp5, double %tmp
2178  %tmp10 = tail call double @llvm.pow.f64(double %tmp, double %tmp)
2179  %tmp11 = fcmp une double %tmp6, %tmp
2180  %tmp12 = fadd double %tmp10, %tmp10
2181  %cutoff.0 = select i1 %tmp11, double %tmp12, double %tmp
2182  %phitmp = fptrunc double %cutoff.0 to float
2183  br label %bb13
2184
2185bb13:                                             ; preds = %bb3, %bb
2186  %cutoff.1 = phi float [ 0.000000e+00, %bb ], [ %phitmp, %bb3 ]
2187  ret float %cutoff.1
2188}
2189
2190
2191!llvm.dbg.cu = !{!0}
2192!llvm.module.flags = !{!3}
2193
2194!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "LLVM", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !4, globals: !2, imports: !2)
2195!1 = !DIFile(filename: "a.cpp", directory: "b")
2196!2 = !{}
2197!3 = !{i32 2, !"Debug Info Version", i32 3}
2198!4 = !{!5}
2199!5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
2200