[ARM] More MVE compare vector splat combines for ANDs
[llvm-complete.git] / test / CodeGen / ARM / arm-shrink-wrapping.ll
blob4b043362afaf8bb358eff4fb8166c153b80d41e5
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
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.
21 ; Initial motivating example: Simple diamond with a call just on one side.
22 ; foo:
24 ; Compare the arguments and jump to exit.
25 ; No prologue needed.
26 ; cmp r0, r1
27 ; bge [[EXIT_LABEL:LBB[0-9_]+]]
29 ; Prologue code.
30 ; push {r7, lr}
31 ; mov r7, sp
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_]+]]
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
49 ; With shrink-wrapping, epilogue is just after the call.
50 ; mov sp, r7
51 ; add sp, #4
52 ; pop{{(\.w)?}} {r7, lr}
54 ; [[EXIT_LABEL]]:
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}
62 ; bx lr
63 define i32 @foo(i32 %a, i32 %b) "no-frame-pointer-elim"="true" {
64 ; ARM-ENABLE-LABEL: foo:
65 ; ARM-ENABLE:       @ %bb.0:
66 ; ARM-ENABLE-NEXT:    cmp r0, r1
67 ; ARM-ENABLE-NEXT:    bge LBB0_2
68 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %true
69 ; ARM-ENABLE-NEXT:    push {r7, lr}
70 ; ARM-ENABLE-NEXT:    mov r7, sp
71 ; ARM-ENABLE-NEXT:    push {r0}
72 ; ARM-ENABLE-NEXT:    mov r1, sp
73 ; ARM-ENABLE-NEXT:    mov r0, #0
74 ; ARM-ENABLE-NEXT:    bl _doSomething
75 ; ARM-ENABLE-NEXT:    mov sp, r7
76 ; ARM-ENABLE-NEXT:    pop {r7, lr}
77 ; ARM-ENABLE-NEXT:  LBB0_2: @ %false
78 ; ARM-ENABLE-NEXT:    bx lr
80 ; ARM-DISABLE-LABEL: foo:
81 ; ARM-DISABLE:       @ %bb.0:
82 ; ARM-DISABLE-NEXT:    push {r7, lr}
83 ; ARM-DISABLE-NEXT:    mov r7, sp
84 ; ARM-DISABLE-NEXT:    sub sp, sp, #4
85 ; ARM-DISABLE-NEXT:    cmp r0, r1
86 ; ARM-DISABLE-NEXT:    bge LBB0_2
87 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %true
88 ; ARM-DISABLE-NEXT:    str r0, [sp]
89 ; ARM-DISABLE-NEXT:    mov r1, sp
90 ; ARM-DISABLE-NEXT:    mov r0, #0
91 ; ARM-DISABLE-NEXT:    bl _doSomething
92 ; ARM-DISABLE-NEXT:  LBB0_2: @ %false
93 ; ARM-DISABLE-NEXT:    mov sp, r7
94 ; ARM-DISABLE-NEXT:    pop {r7, pc}
96 ; THUMB-ENABLE-LABEL: foo:
97 ; THUMB-ENABLE:       @ %bb.0:
98 ; THUMB-ENABLE-NEXT:    cmp r0, r1
99 ; THUMB-ENABLE-NEXT:    bge LBB0_2
100 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %true
101 ; THUMB-ENABLE-NEXT:    push {r7, lr}
102 ; THUMB-ENABLE-NEXT:    mov r7, sp
103 ; THUMB-ENABLE-NEXT:    str r0, [sp, #-4]!
104 ; THUMB-ENABLE-NEXT:    mov r1, sp
105 ; THUMB-ENABLE-NEXT:    movs r0, #0
106 ; THUMB-ENABLE-NEXT:    bl _doSomething
107 ; THUMB-ENABLE-NEXT:    add sp, #4
108 ; THUMB-ENABLE-NEXT:    pop.w {r7, lr}
109 ; THUMB-ENABLE-NEXT:  LBB0_2: @ %false
110 ; THUMB-ENABLE-NEXT:    bx lr
112 ; THUMB-DISABLE-LABEL: foo:
113 ; THUMB-DISABLE:       @ %bb.0:
114 ; THUMB-DISABLE-NEXT:    push {r7, lr}
115 ; THUMB-DISABLE-NEXT:    mov r7, sp
116 ; THUMB-DISABLE-NEXT:    sub sp, #4
117 ; THUMB-DISABLE-NEXT:    cmp r0, r1
118 ; THUMB-DISABLE-NEXT:    bge LBB0_2
119 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %true
120 ; THUMB-DISABLE-NEXT:    str r0, [sp]
121 ; THUMB-DISABLE-NEXT:    mov r1, sp
122 ; THUMB-DISABLE-NEXT:    movs r0, #0
123 ; THUMB-DISABLE-NEXT:    bl _doSomething
124 ; THUMB-DISABLE-NEXT:  LBB0_2: @ %false
125 ; THUMB-DISABLE-NEXT:    add sp, #4
126 ; THUMB-DISABLE-NEXT:    pop {r7, pc}
127   %tmp = alloca i32, align 4
128   %tmp2 = icmp slt i32 %a, %b
129   br i1 %tmp2, label %true, label %false
131 true:
132   store i32 %a, i32* %tmp, align 4
133   %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
134   br label %false
136 false:
137   %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
138   ret i32 %tmp.0
141 ; Function Attrs: optsize
142 declare i32 @doSomething(i32, i32*)
145 ; Check that we do not perform the restore inside the loop whereas the save
146 ; is outside.
147 ; freqSaveAndRestoreOutsideLoop:
149 ; Shrink-wrapping allows to skip the prologue in the else case.
150 ; cmp r0, #0
151 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
152 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
154 ; Prologue code.
155 ; Make sure we save the CSR used in the inline asm: r4.
156 ; push {r4, r7, lr}
157 ; add r7, sp, #4
159 ; cmp r0, #0
160 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
161 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
163 ; SUM is in r0 because it is coalesced with the second
164 ; argument on the else path.
165 ; mov{{s?}} [[SUM:r0]], #0
166 ; mov{{s?}} [[IV:r[0-9]+]], #10
168 ; Next BB.
169 ; [[LOOP:LBB[0-9_]+]]: @ %for.body
170 ; mov{{(\.w)?}} [[TMP:r[0-9]+]], #1
171 ; add [[SUM]], [[TMP]], [[SUM]]
172 ; add [[SUM]], [[TMP]]
173 ; subs [[IV]], [[IV]], #1
174 ; subs [[IV]], #1
175 ; bne [[LOOP]]
177 ; Next BB.
178 ; SUM << 3.
179 ; lsl{{s?}} [[SUM]], [[SUM]], #3
180 ; pop {r4, r7, pc}
182 ; Duplicated epilogue.
183 ; pop {r4, r7, pc}
185 ; [[ELSE_LABEL]]: @ %if.else
186 ; Shift second argument by one and store into returned register.
187 ; lsl{{s?}} r0, r1, #1
188 ; pop {r4, r7, pc}
190 ; bx lr
191 define i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) "no-frame-pointer-elim"="true" {
192 ; ARM-ENABLE-LABEL: freqSaveAndRestoreOutsideLoop:
193 ; ARM-ENABLE:       @ %bb.0: @ %entry
194 ; ARM-ENABLE-NEXT:    cmp r0, #0
195 ; ARM-ENABLE-NEXT:    beq LBB1_4
196 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
197 ; ARM-ENABLE-NEXT:    push {r4, r7, lr}
198 ; ARM-ENABLE-NEXT:    add r7, sp, #4
199 ; ARM-ENABLE-NEXT:    mov r0, #0
200 ; ARM-ENABLE-NEXT:    mov r1, #10
201 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
202 ; ARM-ENABLE-NEXT:    nop
203 ; ARM-ENABLE-NEXT:    @ InlineAsm End
204 ; ARM-ENABLE-NEXT:  LBB1_2: @ %for.body
205 ; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
206 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
207 ; ARM-ENABLE-NEXT:    mov r2, #1
208 ; ARM-ENABLE-NEXT:    @ InlineAsm End
209 ; ARM-ENABLE-NEXT:    add r0, r2, r0
210 ; ARM-ENABLE-NEXT:    subs r1, r1, #1
211 ; ARM-ENABLE-NEXT:    bne LBB1_2
212 ; ARM-ENABLE-NEXT:  @ %bb.3: @ %for.end
213 ; ARM-ENABLE-NEXT:    lsl r0, r0, #3
214 ; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
215 ; ARM-ENABLE-NEXT:  LBB1_4: @ %if.else
216 ; ARM-ENABLE-NEXT:    lsl r0, r1, #1
217 ; ARM-ENABLE-NEXT:    bx lr
219 ; ARM-DISABLE-LABEL: freqSaveAndRestoreOutsideLoop:
220 ; ARM-DISABLE:       @ %bb.0: @ %entry
221 ; ARM-DISABLE-NEXT:    push {r4, r7, lr}
222 ; ARM-DISABLE-NEXT:    add r7, sp, #4
223 ; ARM-DISABLE-NEXT:    cmp r0, #0
224 ; ARM-DISABLE-NEXT:    beq LBB1_4
225 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
226 ; ARM-DISABLE-NEXT:    mov r0, #0
227 ; ARM-DISABLE-NEXT:    mov r1, #10
228 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
229 ; ARM-DISABLE-NEXT:    nop
230 ; ARM-DISABLE-NEXT:    @ InlineAsm End
231 ; ARM-DISABLE-NEXT:  LBB1_2: @ %for.body
232 ; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
233 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
234 ; ARM-DISABLE-NEXT:    mov r2, #1
235 ; ARM-DISABLE-NEXT:    @ InlineAsm End
236 ; ARM-DISABLE-NEXT:    add r0, r2, r0
237 ; ARM-DISABLE-NEXT:    subs r1, r1, #1
238 ; ARM-DISABLE-NEXT:    bne LBB1_2
239 ; ARM-DISABLE-NEXT:  @ %bb.3: @ %for.end
240 ; ARM-DISABLE-NEXT:    lsl r0, r0, #3
241 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
242 ; ARM-DISABLE-NEXT:  LBB1_4: @ %if.else
243 ; ARM-DISABLE-NEXT:    lsl r0, r1, #1
244 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
246 ; THUMB-ENABLE-LABEL: freqSaveAndRestoreOutsideLoop:
247 ; THUMB-ENABLE:       @ %bb.0: @ %entry
248 ; THUMB-ENABLE-NEXT:    cbz r0, LBB1_4
249 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
250 ; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
251 ; THUMB-ENABLE-NEXT:    add r7, sp, #4
252 ; THUMB-ENABLE-NEXT:    movs r0, #0
253 ; THUMB-ENABLE-NEXT:    movs r1, #10
254 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
255 ; THUMB-ENABLE-NEXT:    nop
256 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
257 ; THUMB-ENABLE-NEXT:  LBB1_2: @ %for.body
258 ; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
259 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
260 ; THUMB-ENABLE-NEXT:    mov.w r2, #1
261 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
262 ; THUMB-ENABLE-NEXT:    add r0, r2
263 ; THUMB-ENABLE-NEXT:    subs r1, #1
264 ; THUMB-ENABLE-NEXT:    bne LBB1_2
265 ; THUMB-ENABLE-NEXT:  @ %bb.3: @ %for.end
266 ; THUMB-ENABLE-NEXT:    lsls r0, r0, #3
267 ; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
268 ; THUMB-ENABLE-NEXT:  LBB1_4: @ %if.else
269 ; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
270 ; THUMB-ENABLE-NEXT:    bx lr
272 ; THUMB-DISABLE-LABEL: freqSaveAndRestoreOutsideLoop:
273 ; THUMB-DISABLE:       @ %bb.0: @ %entry
274 ; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
275 ; THUMB-DISABLE-NEXT:    add r7, sp, #4
276 ; THUMB-DISABLE-NEXT:    cbz r0, LBB1_4
277 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
278 ; THUMB-DISABLE-NEXT:    movs r0, #0
279 ; THUMB-DISABLE-NEXT:    movs r1, #10
280 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
281 ; THUMB-DISABLE-NEXT:    nop
282 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
283 ; THUMB-DISABLE-NEXT:  LBB1_2: @ %for.body
284 ; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
285 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
286 ; THUMB-DISABLE-NEXT:    mov.w r2, #1
287 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
288 ; THUMB-DISABLE-NEXT:    add r0, r2
289 ; THUMB-DISABLE-NEXT:    subs r1, #1
290 ; THUMB-DISABLE-NEXT:    bne LBB1_2
291 ; THUMB-DISABLE-NEXT:  @ %bb.3: @ %for.end
292 ; THUMB-DISABLE-NEXT:    lsls r0, r0, #3
293 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
294 ; THUMB-DISABLE-NEXT:  LBB1_4: @ %if.else
295 ; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
296 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
297 entry:
298   %tobool = icmp eq i32 %cond, 0
299   br i1 %tobool, label %if.else, label %for.preheader
301 for.preheader:
302   tail call void asm "nop", ""()
303   br label %for.body
305 for.body:                                         ; preds = %entry, %for.body
306   %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
307   %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
308   %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
309   %add = add nsw i32 %call, %sum.04
310   %inc = add nuw nsw i32 %i.05, 1
311   %exitcond = icmp eq i32 %inc, 10
312   br i1 %exitcond, label %for.end, label %for.body
314 for.end:                                          ; preds = %for.body
315   %shl = shl i32 %add, 3
316   br label %if.end
318 if.else:                                          ; preds = %entry
319   %mul = shl nsw i32 %N, 1
320   br label %if.end
322 if.end:                                           ; preds = %if.else, %for.end
323   %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
324   ret i32 %sum.1
327 declare i32 @something(...)
329 ; Check that we do not perform the shrink-wrapping inside the loop even
330 ; though that would be legal. The cost model must prevent that.
331 ; freqSaveAndRestoreOutsideLoop2:
332 ; Prologue code.
333 ; Make sure we save the CSR used in the inline asm: r4.
334 ; push {r4
335 ; mov{{s?}} [[SUM:r0]], #0
336 ; mov{{s?}} [[IV:r[0-9]+]], #10
337 ; nop
338 ; Next BB.
339 ; [[LOOP_LABEL:LBB[0-9_]+]]: @ %for.body
340 ; mov{{(\.w)?}} [[TMP:r[0-9]+]], #1
341 ; add [[SUM]], [[TMP]], [[SUM]]
342 ; add [[SUM]], [[TMP]]
343 ; subs [[IV]], [[IV]], #1
344 ; subs [[IV]], #1
345 ; bne [[LOOP_LABEL]]
346 ; Next BB.
347 ; @ %for.exit
348 ; nop
349 ; pop {r4
350 define i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) "no-frame-pointer-elim"="true" {
351 ; ARM-LABEL: freqSaveAndRestoreOutsideLoop2:
352 ; ARM:       @ %bb.0: @ %entry
353 ; ARM-NEXT:    push {r4, r7, lr}
354 ; ARM-NEXT:    add r7, sp, #4
355 ; ARM-NEXT:    mov r0, #0
356 ; ARM-NEXT:    mov r1, #10
357 ; ARM-NEXT:    @ InlineAsm Start
358 ; ARM-NEXT:    nop
359 ; ARM-NEXT:    @ InlineAsm End
360 ; ARM-NEXT:  LBB2_1: @ %for.body
361 ; ARM-NEXT:    @ =>This Inner Loop Header: Depth=1
362 ; ARM-NEXT:    @ InlineAsm Start
363 ; ARM-NEXT:    mov r2, #1
364 ; ARM-NEXT:    @ InlineAsm End
365 ; ARM-NEXT:    add r0, r2, r0
366 ; ARM-NEXT:    subs r1, r1, #1
367 ; ARM-NEXT:    bne LBB2_1
368 ; ARM-NEXT:  @ %bb.2: @ %for.exit
369 ; ARM-NEXT:    @ InlineAsm Start
370 ; ARM-NEXT:    nop
371 ; ARM-NEXT:    @ InlineAsm End
372 ; ARM-NEXT:    pop {r4, r7, pc}
374 ; THUMB-LABEL: freqSaveAndRestoreOutsideLoop2:
375 ; THUMB:       @ %bb.0: @ %entry
376 ; THUMB-NEXT:    push {r4, r7, lr}
377 ; THUMB-NEXT:    add r7, sp, #4
378 ; THUMB-NEXT:    movs r0, #0
379 ; THUMB-NEXT:    movs r1, #10
380 ; THUMB-NEXT:    @ InlineAsm Start
381 ; THUMB-NEXT:    nop
382 ; THUMB-NEXT:    @ InlineAsm End
383 ; THUMB-NEXT:  LBB2_1: @ %for.body
384 ; THUMB-NEXT:    @ =>This Inner Loop Header: Depth=1
385 ; THUMB-NEXT:    @ InlineAsm Start
386 ; THUMB-NEXT:    mov.w r2, #1
387 ; THUMB-NEXT:    @ InlineAsm End
388 ; THUMB-NEXT:    add r0, r2
389 ; THUMB-NEXT:    subs r1, #1
390 ; THUMB-NEXT:    bne LBB2_1
391 ; THUMB-NEXT:  @ %bb.2: @ %for.exit
392 ; THUMB-NEXT:    @ InlineAsm Start
393 ; THUMB-NEXT:    nop
394 ; THUMB-NEXT:    @ InlineAsm End
395 ; THUMB-NEXT:    pop {r4, r7, pc}
396 ; ARM-ENABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
397 ; ARM-ENABLE:       @ %bb.0: @ %entry
398 ; ARM-ENABLE-NEXT:    push {r4, r7, lr}
399 ; ARM-ENABLE-NEXT:    add r7, sp, #4
400 ; ARM-ENABLE-NEXT:    mov r0, #0
401 ; ARM-ENABLE-NEXT:    mov r1, #10
402 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
403 ; ARM-ENABLE-NEXT:    nop
404 ; ARM-ENABLE-NEXT:    @ InlineAsm End
405 ; ARM-ENABLE-NEXT:  LBB2_1: @ %for.body
406 ; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
407 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
408 ; ARM-ENABLE-NEXT:    mov r2, #1
409 ; ARM-ENABLE-NEXT:    @ InlineAsm End
410 ; ARM-ENABLE-NEXT:    add r0, r2, r0
411 ; ARM-ENABLE-NEXT:    subs r1, r1, #1
412 ; ARM-ENABLE-NEXT:    bne LBB2_1
413 ; ARM-ENABLE-NEXT:  @ %bb.2: @ %for.exit
414 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
415 ; ARM-ENABLE-NEXT:    nop
416 ; ARM-ENABLE-NEXT:    @ InlineAsm End
417 ; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
419 ; ARM-DISABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
420 ; ARM-DISABLE:       @ %bb.0: @ %entry
421 ; ARM-DISABLE-NEXT:    push {r4, r7, lr}
422 ; ARM-DISABLE-NEXT:    add r7, sp, #4
423 ; ARM-DISABLE-NEXT:    mov r0, #0
424 ; ARM-DISABLE-NEXT:    mov r1, #10
425 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
426 ; ARM-DISABLE-NEXT:    nop
427 ; ARM-DISABLE-NEXT:    @ InlineAsm End
428 ; ARM-DISABLE-NEXT:  LBB2_1: @ %for.body
429 ; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
430 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
431 ; ARM-DISABLE-NEXT:    mov r2, #1
432 ; ARM-DISABLE-NEXT:    @ InlineAsm End
433 ; ARM-DISABLE-NEXT:    add r0, r2, r0
434 ; ARM-DISABLE-NEXT:    subs r1, r1, #1
435 ; ARM-DISABLE-NEXT:    bne LBB2_1
436 ; ARM-DISABLE-NEXT:  @ %bb.2: @ %for.exit
437 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
438 ; ARM-DISABLE-NEXT:    nop
439 ; ARM-DISABLE-NEXT:    @ InlineAsm End
440 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
442 ; THUMB-ENABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
443 ; THUMB-ENABLE:       @ %bb.0: @ %entry
444 ; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
445 ; THUMB-ENABLE-NEXT:    add r7, sp, #4
446 ; THUMB-ENABLE-NEXT:    movs r0, #0
447 ; THUMB-ENABLE-NEXT:    movs r1, #10
448 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
449 ; THUMB-ENABLE-NEXT:    nop
450 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
451 ; THUMB-ENABLE-NEXT:  LBB2_1: @ %for.body
452 ; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
453 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
454 ; THUMB-ENABLE-NEXT:    mov.w r2, #1
455 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
456 ; THUMB-ENABLE-NEXT:    add r0, r2
457 ; THUMB-ENABLE-NEXT:    subs r1, #1
458 ; THUMB-ENABLE-NEXT:    bne LBB2_1
459 ; THUMB-ENABLE-NEXT:  @ %bb.2: @ %for.exit
460 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
461 ; THUMB-ENABLE-NEXT:    nop
462 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
463 ; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
465 ; THUMB-DISABLE-LABEL: freqSaveAndRestoreOutsideLoop2:
466 ; THUMB-DISABLE:       @ %bb.0: @ %entry
467 ; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
468 ; THUMB-DISABLE-NEXT:    add r7, sp, #4
469 ; THUMB-DISABLE-NEXT:    movs r0, #0
470 ; THUMB-DISABLE-NEXT:    movs r1, #10
471 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
472 ; THUMB-DISABLE-NEXT:    nop
473 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
474 ; THUMB-DISABLE-NEXT:  LBB2_1: @ %for.body
475 ; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
476 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
477 ; THUMB-DISABLE-NEXT:    mov.w r2, #1
478 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
479 ; THUMB-DISABLE-NEXT:    add r0, r2
480 ; THUMB-DISABLE-NEXT:    subs r1, #1
481 ; THUMB-DISABLE-NEXT:    bne LBB2_1
482 ; THUMB-DISABLE-NEXT:  @ %bb.2: @ %for.exit
483 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
484 ; THUMB-DISABLE-NEXT:    nop
485 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
486 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
487 entry:
488   br label %for.preheader
490 for.preheader:
491   tail call void asm "nop", ""()
492   br label %for.body
494 for.body:                                         ; preds = %for.body, %entry
495   %i.04 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]
496   %sum.03 = phi i32 [ 0, %for.preheader ], [ %add, %for.body ]
497   %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
498   %add = add nsw i32 %call, %sum.03
499   %inc = add nuw nsw i32 %i.04, 1
500   %exitcond = icmp eq i32 %inc, 10
501   br i1 %exitcond, label %for.exit, label %for.body
503 for.exit:
504   tail call void asm "nop", ""()
505   br label %for.end
507 for.end:                                          ; preds = %for.body
508   ret i32 %add
511 ; Check with a more complex case that we do not have save within the loop and
512 ; restore outside.
513 ; loopInfoSaveOutsideLoop:
515 ; cmp r0, #0
516 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
517 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
519 ; Prologue code.
520 ; Make sure we save the CSR used in the inline asm: r4.
521 ; push {r4, r7, lr}
522 ; add r7, sp, #4
524 ; cmp r0, #0
525 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
526 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
528 ; SUM is in r0 because it is coalesced with the second
529 ; argument on the else path.
530 ; mov{{s?}} [[SUM:r0]], #0
531 ; mov{{s?}} [[IV:r[0-9]+]], #10
533 ; Next BB.
534 ; [[LOOP:LBB[0-9_]+]]: @ %for.body
535 ; mov{{(\.w)?}} [[TMP:r[0-9]+]], #1
536 ; add [[SUM]], [[TMP]], [[SUM]]
537 ; add [[SUM]], [[TMP]]
538 ; subs [[IV]], [[IV]], #1
539 ; subs [[IV]], #1
540 ; bne [[LOOP]]
542 ; Next BB.
543 ; SUM << 3.
544 ; lsl{{s?}} [[SUM]], [[SUM]], #3
545 ; pop {r4, r7, pc}
547 ; Duplicated epilogue.
548 ; pop {r4, r7, pc}
550 ; [[ELSE_LABEL]]: @ %if.else
551 ; Shift second argument by one and store into returned register.
552 ; lsl{{s?}} r0, r1, #1
553 ; pop {r4, r7, pc}
555 ; bx lr
556 define i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) "no-frame-pointer-elim"="true" {
557 ; ARM-ENABLE-LABEL: loopInfoSaveOutsideLoop:
558 ; ARM-ENABLE:       @ %bb.0: @ %entry
559 ; ARM-ENABLE-NEXT:    cmp r0, #0
560 ; ARM-ENABLE-NEXT:    beq LBB3_4
561 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
562 ; ARM-ENABLE-NEXT:    push {r4, r7, lr}
563 ; ARM-ENABLE-NEXT:    add r7, sp, #4
564 ; ARM-ENABLE-NEXT:    mov r0, #0
565 ; ARM-ENABLE-NEXT:    mov r1, #10
566 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
567 ; ARM-ENABLE-NEXT:    nop
568 ; ARM-ENABLE-NEXT:    @ InlineAsm End
569 ; ARM-ENABLE-NEXT:  LBB3_2: @ %for.body
570 ; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
571 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
572 ; ARM-ENABLE-NEXT:    mov r2, #1
573 ; ARM-ENABLE-NEXT:    @ InlineAsm End
574 ; ARM-ENABLE-NEXT:    add r0, r2, r0
575 ; ARM-ENABLE-NEXT:    subs r1, r1, #1
576 ; ARM-ENABLE-NEXT:    bne LBB3_2
577 ; ARM-ENABLE-NEXT:  @ %bb.3: @ %for.end
578 ; ARM-ENABLE-NEXT:    lsl r0, r0, #3
579 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
580 ; ARM-ENABLE-NEXT:    nop
581 ; ARM-ENABLE-NEXT:    @ InlineAsm End
582 ; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
583 ; ARM-ENABLE-NEXT:  LBB3_4: @ %if.else
584 ; ARM-ENABLE-NEXT:    lsl r0, r1, #1
585 ; ARM-ENABLE-NEXT:    bx lr
587 ; ARM-DISABLE-LABEL: loopInfoSaveOutsideLoop:
588 ; ARM-DISABLE:       @ %bb.0: @ %entry
589 ; ARM-DISABLE-NEXT:    push {r4, r7, lr}
590 ; ARM-DISABLE-NEXT:    add r7, sp, #4
591 ; ARM-DISABLE-NEXT:    cmp r0, #0
592 ; ARM-DISABLE-NEXT:    beq LBB3_4
593 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
594 ; ARM-DISABLE-NEXT:    mov r0, #0
595 ; ARM-DISABLE-NEXT:    mov r1, #10
596 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
597 ; ARM-DISABLE-NEXT:    nop
598 ; ARM-DISABLE-NEXT:    @ InlineAsm End
599 ; ARM-DISABLE-NEXT:  LBB3_2: @ %for.body
600 ; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
601 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
602 ; ARM-DISABLE-NEXT:    mov r2, #1
603 ; ARM-DISABLE-NEXT:    @ InlineAsm End
604 ; ARM-DISABLE-NEXT:    add r0, r2, r0
605 ; ARM-DISABLE-NEXT:    subs r1, r1, #1
606 ; ARM-DISABLE-NEXT:    bne LBB3_2
607 ; ARM-DISABLE-NEXT:  @ %bb.3: @ %for.end
608 ; ARM-DISABLE-NEXT:    lsl r0, r0, #3
609 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
610 ; ARM-DISABLE-NEXT:    nop
611 ; ARM-DISABLE-NEXT:    @ InlineAsm End
612 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
613 ; ARM-DISABLE-NEXT:  LBB3_4: @ %if.else
614 ; ARM-DISABLE-NEXT:    lsl r0, r1, #1
615 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
617 ; THUMB-ENABLE-LABEL: loopInfoSaveOutsideLoop:
618 ; THUMB-ENABLE:       @ %bb.0: @ %entry
619 ; THUMB-ENABLE-NEXT:    cbz r0, LBB3_4
620 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
621 ; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
622 ; THUMB-ENABLE-NEXT:    add r7, sp, #4
623 ; THUMB-ENABLE-NEXT:    movs r0, #0
624 ; THUMB-ENABLE-NEXT:    movs r1, #10
625 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
626 ; THUMB-ENABLE-NEXT:    nop
627 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
628 ; THUMB-ENABLE-NEXT:  LBB3_2: @ %for.body
629 ; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
630 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
631 ; THUMB-ENABLE-NEXT:    mov.w r2, #1
632 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
633 ; THUMB-ENABLE-NEXT:    add r0, r2
634 ; THUMB-ENABLE-NEXT:    subs r1, #1
635 ; THUMB-ENABLE-NEXT:    bne LBB3_2
636 ; THUMB-ENABLE-NEXT:  @ %bb.3: @ %for.end
637 ; THUMB-ENABLE-NEXT:    lsls r0, r0, #3
638 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
639 ; THUMB-ENABLE-NEXT:    nop
640 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
641 ; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
642 ; THUMB-ENABLE-NEXT:  LBB3_4: @ %if.else
643 ; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
644 ; THUMB-ENABLE-NEXT:    bx lr
646 ; THUMB-DISABLE-LABEL: loopInfoSaveOutsideLoop:
647 ; THUMB-DISABLE:       @ %bb.0: @ %entry
648 ; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
649 ; THUMB-DISABLE-NEXT:    add r7, sp, #4
650 ; THUMB-DISABLE-NEXT:    cbz r0, LBB3_4
651 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
652 ; THUMB-DISABLE-NEXT:    movs r0, #0
653 ; THUMB-DISABLE-NEXT:    movs r1, #10
654 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
655 ; THUMB-DISABLE-NEXT:    nop
656 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
657 ; THUMB-DISABLE-NEXT:  LBB3_2: @ %for.body
658 ; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
659 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
660 ; THUMB-DISABLE-NEXT:    mov.w r2, #1
661 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
662 ; THUMB-DISABLE-NEXT:    add r0, r2
663 ; THUMB-DISABLE-NEXT:    subs r1, #1
664 ; THUMB-DISABLE-NEXT:    bne LBB3_2
665 ; THUMB-DISABLE-NEXT:  @ %bb.3: @ %for.end
666 ; THUMB-DISABLE-NEXT:    lsls r0, r0, #3
667 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
668 ; THUMB-DISABLE-NEXT:    nop
669 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
670 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
671 ; THUMB-DISABLE-NEXT:  LBB3_4: @ %if.else
672 ; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
673 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
674 entry:
675   %tobool = icmp eq i32 %cond, 0
676   br i1 %tobool, label %if.else, label %for.preheader
678 for.preheader:
679   tail call void asm "nop", ""()
680   br label %for.body
682 for.body:                                         ; preds = %entry, %for.body
683   %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
684   %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
685   %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
686   %add = add nsw i32 %call, %sum.04
687   %inc = add nuw nsw i32 %i.05, 1
688   %exitcond = icmp eq i32 %inc, 10
689   br i1 %exitcond, label %for.end, label %for.body
691 for.end:                                          ; preds = %for.body
692   tail call void asm "nop", "~{r4}"()
693   %shl = shl i32 %add, 3
694   br label %if.end
696 if.else:                                          ; preds = %entry
697   %mul = shl nsw i32 %N, 1
698   br label %if.end
700 if.end:                                           ; preds = %if.else, %for.end
701   %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
702   ret i32 %sum.1
705 declare void @somethingElse(...)
707 ; Check with a more complex case that we do not have restore within the loop and
708 ; save outside.
709 ; loopInfoRestoreOutsideLoop:
711 ; cmp r0, #0
712 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
713 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
715 ; Prologue code.
716 ; Make sure we save the CSR used in the inline asm: r4.
717 ; push {r4, r7, lr}
718 ; add r7, sp, #4
720 ; cmp r0, #0
721 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
722 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
724 ; SUM is in r0 because it is coalesced with the second
725 ; argument on the else path.
726 ; mov{{s?}} [[SUM:r0]], #0
727 ; mov{{s?}} [[IV:r[0-9]+]], #10
729 ; Next BB.
730 ; [[LOOP:LBB[0-9_]+]]: @ %for.body
731 ; mov{{(\.w)?}} [[TMP:r[0-9]+]], #1
732 ; add [[SUM]], [[TMP]], [[SUM]]
733 ; add [[SUM]], [[TMP]]
734 ; subs [[IV]], [[IV]], #1
735 ; subs [[IV]], #1
736 ; bne [[LOOP]]
738 ; Next BB.
739 ; SUM << 3.
740 ; lsl{{s?}} [[SUM]], [[SUM]], #3
741 ; pop {r4, r7, pc}
743 ; Duplicated epilogue.
744 ; pop {r4, r7, pc}
746 ; [[ELSE_LABEL]]: @ %if.else
747 ; Shift second argument by one and store into returned register.
748 ; lsl{{s?}} r0, r1, #1
749 ; pop {r4, r7, pc}
751 ; bx lr
752 define i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) "no-frame-pointer-elim"="true" nounwind {
753 ; ARM-ENABLE-LABEL: loopInfoRestoreOutsideLoop:
754 ; ARM-ENABLE:       @ %bb.0: @ %entry
755 ; ARM-ENABLE-NEXT:    cmp r0, #0
756 ; ARM-ENABLE-NEXT:    beq LBB4_4
757 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.then
758 ; ARM-ENABLE-NEXT:    push {r4, r7, lr}
759 ; ARM-ENABLE-NEXT:    add r7, sp, #4
760 ; ARM-ENABLE-NEXT:    mov r0, #0
761 ; ARM-ENABLE-NEXT:    mov r1, #10
762 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
763 ; ARM-ENABLE-NEXT:    nop
764 ; ARM-ENABLE-NEXT:    @ InlineAsm End
765 ; ARM-ENABLE-NEXT:  LBB4_2: @ %for.body
766 ; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
767 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
768 ; ARM-ENABLE-NEXT:    mov r2, #1
769 ; ARM-ENABLE-NEXT:    @ InlineAsm End
770 ; ARM-ENABLE-NEXT:    add r0, r2, r0
771 ; ARM-ENABLE-NEXT:    subs r1, r1, #1
772 ; ARM-ENABLE-NEXT:    bne LBB4_2
773 ; ARM-ENABLE-NEXT:  @ %bb.3: @ %for.end
774 ; ARM-ENABLE-NEXT:    lsl r0, r0, #3
775 ; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
776 ; ARM-ENABLE-NEXT:  LBB4_4: @ %if.else
777 ; ARM-ENABLE-NEXT:    lsl r0, r1, #1
778 ; ARM-ENABLE-NEXT:    bx lr
780 ; ARM-DISABLE-LABEL: loopInfoRestoreOutsideLoop:
781 ; ARM-DISABLE:       @ %bb.0: @ %entry
782 ; ARM-DISABLE-NEXT:    push {r4, r7, lr}
783 ; ARM-DISABLE-NEXT:    add r7, sp, #4
784 ; ARM-DISABLE-NEXT:    cmp r0, #0
785 ; ARM-DISABLE-NEXT:    beq LBB4_4
786 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.then
787 ; ARM-DISABLE-NEXT:    mov r0, #0
788 ; ARM-DISABLE-NEXT:    mov r1, #10
789 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
790 ; ARM-DISABLE-NEXT:    nop
791 ; ARM-DISABLE-NEXT:    @ InlineAsm End
792 ; ARM-DISABLE-NEXT:  LBB4_2: @ %for.body
793 ; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
794 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
795 ; ARM-DISABLE-NEXT:    mov r2, #1
796 ; ARM-DISABLE-NEXT:    @ InlineAsm End
797 ; ARM-DISABLE-NEXT:    add r0, r2, r0
798 ; ARM-DISABLE-NEXT:    subs r1, r1, #1
799 ; ARM-DISABLE-NEXT:    bne LBB4_2
800 ; ARM-DISABLE-NEXT:  @ %bb.3: @ %for.end
801 ; ARM-DISABLE-NEXT:    lsl r0, r0, #3
802 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
803 ; ARM-DISABLE-NEXT:  LBB4_4: @ %if.else
804 ; ARM-DISABLE-NEXT:    lsl r0, r1, #1
805 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
807 ; THUMB-ENABLE-LABEL: loopInfoRestoreOutsideLoop:
808 ; THUMB-ENABLE:       @ %bb.0: @ %entry
809 ; THUMB-ENABLE-NEXT:    cbz r0, LBB4_4
810 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.then
811 ; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
812 ; THUMB-ENABLE-NEXT:    add r7, sp, #4
813 ; THUMB-ENABLE-NEXT:    movs r0, #0
814 ; THUMB-ENABLE-NEXT:    movs r1, #10
815 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
816 ; THUMB-ENABLE-NEXT:    nop
817 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
818 ; THUMB-ENABLE-NEXT:  LBB4_2: @ %for.body
819 ; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
820 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
821 ; THUMB-ENABLE-NEXT:    mov.w r2, #1
822 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
823 ; THUMB-ENABLE-NEXT:    add r0, r2
824 ; THUMB-ENABLE-NEXT:    subs r1, #1
825 ; THUMB-ENABLE-NEXT:    bne LBB4_2
826 ; THUMB-ENABLE-NEXT:  @ %bb.3: @ %for.end
827 ; THUMB-ENABLE-NEXT:    lsls r0, r0, #3
828 ; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
829 ; THUMB-ENABLE-NEXT:  LBB4_4: @ %if.else
830 ; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
831 ; THUMB-ENABLE-NEXT:    bx lr
833 ; THUMB-DISABLE-LABEL: loopInfoRestoreOutsideLoop:
834 ; THUMB-DISABLE:       @ %bb.0: @ %entry
835 ; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
836 ; THUMB-DISABLE-NEXT:    add r7, sp, #4
837 ; THUMB-DISABLE-NEXT:    cbz r0, LBB4_4
838 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.then
839 ; THUMB-DISABLE-NEXT:    movs r0, #0
840 ; THUMB-DISABLE-NEXT:    movs r1, #10
841 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
842 ; THUMB-DISABLE-NEXT:    nop
843 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
844 ; THUMB-DISABLE-NEXT:  LBB4_2: @ %for.body
845 ; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
846 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
847 ; THUMB-DISABLE-NEXT:    mov.w r2, #1
848 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
849 ; THUMB-DISABLE-NEXT:    add r0, r2
850 ; THUMB-DISABLE-NEXT:    subs r1, #1
851 ; THUMB-DISABLE-NEXT:    bne LBB4_2
852 ; THUMB-DISABLE-NEXT:  @ %bb.3: @ %for.end
853 ; THUMB-DISABLE-NEXT:    lsls r0, r0, #3
854 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
855 ; THUMB-DISABLE-NEXT:  LBB4_4: @ %if.else
856 ; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
857 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
858 entry:
859   %tobool = icmp eq i32 %cond, 0
860   br i1 %tobool, label %if.else, label %if.then
862 if.then:                                          ; preds = %entry
863   tail call void asm "nop", "~{r4}"()
864   br label %for.body
866 for.body:                                         ; preds = %for.body, %if.then
867   %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ]
868   %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
869   %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
870   %add = add nsw i32 %call, %sum.04
871   %inc = add nuw nsw i32 %i.05, 1
872   %exitcond = icmp eq i32 %inc, 10
873   br i1 %exitcond, label %for.end, label %for.body
875 for.end:                                          ; preds = %for.body
876   %shl = shl i32 %add, 3
877   br label %if.end
879 if.else:                                          ; preds = %entry
880   %mul = shl nsw i32 %N, 1
881   br label %if.end
883 if.end:                                           ; preds = %if.else, %for.end
884   %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
885   ret i32 %sum.1
888 ; Check that we handle function with no frame information correctly.
889 ; emptyFrame:
890 ; @ %entry
891 ; mov{{s?}} r0, #0
892 ; bx lr
893 define i32 @emptyFrame() {
894 ; ARM-LABEL: emptyFrame:
895 ; ARM:       @ %bb.0: @ %entry
896 ; ARM-NEXT:    mov r0, #0
897 ; ARM-NEXT:    bx lr
899 ; THUMB-LABEL: emptyFrame:
900 ; THUMB:       @ %bb.0: @ %entry
901 ; THUMB-NEXT:    movs r0, #0
902 ; THUMB-NEXT:    bx lr
903 ; ARM-ENABLE-LABEL: emptyFrame:
904 ; ARM-ENABLE:       @ %bb.0: @ %entry
905 ; ARM-ENABLE-NEXT:    mov r0, #0
906 ; ARM-ENABLE-NEXT:    bx lr
908 ; ARM-DISABLE-LABEL: emptyFrame:
909 ; ARM-DISABLE:       @ %bb.0: @ %entry
910 ; ARM-DISABLE-NEXT:    mov r0, #0
911 ; ARM-DISABLE-NEXT:    bx lr
913 ; THUMB-ENABLE-LABEL: emptyFrame:
914 ; THUMB-ENABLE:       @ %bb.0: @ %entry
915 ; THUMB-ENABLE-NEXT:    movs r0, #0
916 ; THUMB-ENABLE-NEXT:    bx lr
918 ; THUMB-DISABLE-LABEL: emptyFrame:
919 ; THUMB-DISABLE:       @ %bb.0: @ %entry
920 ; THUMB-DISABLE-NEXT:    movs r0, #0
921 ; THUMB-DISABLE-NEXT:    bx lr
922 entry:
923   ret i32 0
926 ; Check that we handle inline asm correctly.
927 ; inlineAsm:
929 ; cmp r0, #0
930 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
931 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
933 ; Prologue code.
934 ; Make sure we save the CSR used in the inline asm: r4.
935 ; push {r4, r7, lr}
936 ; add r7, sp, #4
938 ; cmp r0, #0
939 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
940 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
942 ; mov{{s?}} [[IV:r[0-9]+]], #10
944 ; Next BB.
945 ; [[LOOP:LBB[0-9_]+]]: @ %for.body
946 ; subs [[IV]], [[IV]], #1
947 ; subs [[IV]], #1
948 ; add{{(\.w)?}} r4, r4, #1
949 ; bne [[LOOP]]
951 ; Next BB.
952 ; mov{{s?}} r0, #0
954 ; Duplicated epilogue.
955 ; pop {r4, r7, pc}
957 ; [[ELSE_LABEL]]: @ %if.else
958 ; Shift second argument by one and store into returned register.
959 ; lsl{{s?}} r0, r1, #1
960 ; pop {r4, r7, pc}
962 ; bx lr
963 define i32 @inlineAsm(i32 %cond, i32 %N) "no-frame-pointer-elim"="true" {
964 ; ARM-ENABLE-LABEL: inlineAsm:
965 ; ARM-ENABLE:       @ %bb.0: @ %entry
966 ; ARM-ENABLE-NEXT:    cmp r0, #0
967 ; ARM-ENABLE-NEXT:    beq LBB6_4
968 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
969 ; ARM-ENABLE-NEXT:    push {r4, r7, lr}
970 ; ARM-ENABLE-NEXT:    add r7, sp, #4
971 ; ARM-ENABLE-NEXT:    mov r0, #10
972 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
973 ; ARM-ENABLE-NEXT:    nop
974 ; ARM-ENABLE-NEXT:    @ InlineAsm End
975 ; ARM-ENABLE-NEXT:  LBB6_2: @ %for.body
976 ; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
977 ; ARM-ENABLE-NEXT:    subs r0, r0, #1
978 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
979 ; ARM-ENABLE-NEXT:    add r4, r4, #1
980 ; ARM-ENABLE-NEXT:    @ InlineAsm End
981 ; ARM-ENABLE-NEXT:    bne LBB6_2
982 ; ARM-ENABLE-NEXT:  @ %bb.3: @ %for.exit
983 ; ARM-ENABLE-NEXT:    mov r0, #0
984 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
985 ; ARM-ENABLE-NEXT:    nop
986 ; ARM-ENABLE-NEXT:    @ InlineAsm End
987 ; ARM-ENABLE-NEXT:    pop {r4, r7, pc}
988 ; ARM-ENABLE-NEXT:  LBB6_4: @ %if.else
989 ; ARM-ENABLE-NEXT:    lsl r0, r1, #1
990 ; ARM-ENABLE-NEXT:    bx lr
992 ; ARM-DISABLE-LABEL: inlineAsm:
993 ; ARM-DISABLE:       @ %bb.0: @ %entry
994 ; ARM-DISABLE-NEXT:    push {r4, r7, lr}
995 ; ARM-DISABLE-NEXT:    add r7, sp, #4
996 ; ARM-DISABLE-NEXT:    cmp r0, #0
997 ; ARM-DISABLE-NEXT:    beq LBB6_4
998 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
999 ; ARM-DISABLE-NEXT:    mov r0, #10
1000 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
1001 ; ARM-DISABLE-NEXT:    nop
1002 ; ARM-DISABLE-NEXT:    @ InlineAsm End
1003 ; ARM-DISABLE-NEXT:  LBB6_2: @ %for.body
1004 ; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1005 ; ARM-DISABLE-NEXT:    subs r0, r0, #1
1006 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
1007 ; ARM-DISABLE-NEXT:    add r4, r4, #1
1008 ; ARM-DISABLE-NEXT:    @ InlineAsm End
1009 ; ARM-DISABLE-NEXT:    bne LBB6_2
1010 ; ARM-DISABLE-NEXT:  @ %bb.3: @ %for.exit
1011 ; ARM-DISABLE-NEXT:    mov r0, #0
1012 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
1013 ; ARM-DISABLE-NEXT:    nop
1014 ; ARM-DISABLE-NEXT:    @ InlineAsm End
1015 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
1016 ; ARM-DISABLE-NEXT:  LBB6_4: @ %if.else
1017 ; ARM-DISABLE-NEXT:    lsl r0, r1, #1
1018 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
1020 ; THUMB-ENABLE-LABEL: inlineAsm:
1021 ; THUMB-ENABLE:       @ %bb.0: @ %entry
1022 ; THUMB-ENABLE-NEXT:    cbz r0, LBB6_4
1023 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %for.preheader
1024 ; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
1025 ; THUMB-ENABLE-NEXT:    add r7, sp, #4
1026 ; THUMB-ENABLE-NEXT:    movs r0, #10
1027 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1028 ; THUMB-ENABLE-NEXT:    nop
1029 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
1030 ; THUMB-ENABLE-NEXT:  LBB6_2: @ %for.body
1031 ; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1032 ; THUMB-ENABLE-NEXT:    subs r0, #1
1033 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1034 ; THUMB-ENABLE-NEXT:    add.w r4, r4, #1
1035 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
1036 ; THUMB-ENABLE-NEXT:    bne LBB6_2
1037 ; THUMB-ENABLE-NEXT:  @ %bb.3: @ %for.exit
1038 ; THUMB-ENABLE-NEXT:    movs r0, #0
1039 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1040 ; THUMB-ENABLE-NEXT:    nop
1041 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
1042 ; THUMB-ENABLE-NEXT:    pop {r4, r7, pc}
1043 ; THUMB-ENABLE-NEXT:  LBB6_4: @ %if.else
1044 ; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
1045 ; THUMB-ENABLE-NEXT:    bx lr
1047 ; THUMB-DISABLE-LABEL: inlineAsm:
1048 ; THUMB-DISABLE:       @ %bb.0: @ %entry
1049 ; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
1050 ; THUMB-DISABLE-NEXT:    add r7, sp, #4
1051 ; THUMB-DISABLE-NEXT:    cbz r0, LBB6_4
1052 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %for.preheader
1053 ; THUMB-DISABLE-NEXT:    movs r0, #10
1054 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1055 ; THUMB-DISABLE-NEXT:    nop
1056 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
1057 ; THUMB-DISABLE-NEXT:  LBB6_2: @ %for.body
1058 ; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1059 ; THUMB-DISABLE-NEXT:    subs r0, #1
1060 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1061 ; THUMB-DISABLE-NEXT:    add.w r4, r4, #1
1062 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
1063 ; THUMB-DISABLE-NEXT:    bne LBB6_2
1064 ; THUMB-DISABLE-NEXT:  @ %bb.3: @ %for.exit
1065 ; THUMB-DISABLE-NEXT:    movs r0, #0
1066 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1067 ; THUMB-DISABLE-NEXT:    nop
1068 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
1069 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
1070 ; THUMB-DISABLE-NEXT:  LBB6_4: @ %if.else
1071 ; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
1072 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
1073 entry:
1074   %tobool = icmp eq i32 %cond, 0
1075   br i1 %tobool, label %if.else, label %for.preheader
1077 for.preheader:
1078   tail call void asm "nop", ""()
1079   br label %for.body
1081 for.body:                                         ; preds = %entry, %for.body
1082   %i.03 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
1083   tail call void asm sideeffect "add r4, #1", "~{r4}"()
1084   %inc = add nuw nsw i32 %i.03, 1
1085   %exitcond = icmp eq i32 %inc, 10
1086   br i1 %exitcond, label %for.exit, label %for.body
1088 for.exit:
1089   tail call void asm "nop", ""()
1090   br label %if.end
1092 if.else:                                          ; preds = %entry
1093   %mul = shl nsw i32 %N, 1
1094   br label %if.end
1096 if.end:                                           ; preds = %for.body, %if.else
1097   %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.exit ]
1098   ret i32 %sum.0
1101 ; Check that we handle calls to variadic functions correctly.
1102 ; callVariadicFunc:
1104 ; cmp r0, #0
1105 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
1106 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
1108 ; Prologue code.
1109 ; push {r7, lr}
1110 ; mov r7, sp
1111 ; sub sp, {{(sp, )?}}#12
1113 ; cmp r0, #0
1114 ; beq [[ELSE_LABEL:LBB[0-9_]+]]
1115 ; cbz r0, [[ELSE_LABEL:LBB[0-9_]+]]
1117 ; Setup of the varags.
1118 ; mov r0, r1
1119 ; mov r2, r1
1120 ; mov r3, r1
1121 ; str r1, [sp]
1122 ; str r1, [sp, #4]
1123 ; strd r1, r1, [sp]
1124 ; str r1, [sp, #8]
1125 ; bl{{x?}} _someVariadicFunc
1126 ; lsl{{s?}} r0, r0, #3
1127 ; mov sp, r7
1128 ; add sp, #12
1129 ; pop {r7, pc}
1131 ; [[ELSE_LABEL]]: @ %if.else
1132 ; Shift second argument by one and store into returned register.
1133 ; lsl{{s?}} r0, r1, #1
1135 ; Epilogue code.
1136 ; bx lr
1138 ; mov sp, r7
1139 ; add sp, #12
1140 ; pop {r7, pc}
1141 define i32 @callVariadicFunc(i32 %cond, i32 %N) "no-frame-pointer-elim"="true" {
1142 ; ARM-ENABLE-LABEL: callVariadicFunc:
1143 ; ARM-ENABLE:       @ %bb.0: @ %entry
1144 ; ARM-ENABLE-NEXT:    cmp r0, #0
1145 ; ARM-ENABLE-NEXT:    beq LBB7_2
1146 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.then
1147 ; ARM-ENABLE-NEXT:    push {r7, lr}
1148 ; ARM-ENABLE-NEXT:    mov r7, sp
1149 ; ARM-ENABLE-NEXT:    sub sp, sp, #12
1150 ; ARM-ENABLE-NEXT:    mov r0, r1
1151 ; ARM-ENABLE-NEXT:    mov r2, r1
1152 ; ARM-ENABLE-NEXT:    mov r3, r1
1153 ; ARM-ENABLE-NEXT:    str r1, [sp]
1154 ; ARM-ENABLE-NEXT:    str r1, [sp, #4]
1155 ; ARM-ENABLE-NEXT:    str r1, [sp, #8]
1156 ; ARM-ENABLE-NEXT:    bl _someVariadicFunc
1157 ; ARM-ENABLE-NEXT:    lsl r0, r0, #3
1158 ; ARM-ENABLE-NEXT:    mov sp, r7
1159 ; ARM-ENABLE-NEXT:    pop {r7, pc}
1160 ; ARM-ENABLE-NEXT:  LBB7_2: @ %if.else
1161 ; ARM-ENABLE-NEXT:    lsl r0, r1, #1
1162 ; ARM-ENABLE-NEXT:    bx lr
1164 ; ARM-DISABLE-LABEL: callVariadicFunc:
1165 ; ARM-DISABLE:       @ %bb.0: @ %entry
1166 ; ARM-DISABLE-NEXT:    push {r7, lr}
1167 ; ARM-DISABLE-NEXT:    mov r7, sp
1168 ; ARM-DISABLE-NEXT:    sub sp, sp, #12
1169 ; ARM-DISABLE-NEXT:    cmp r0, #0
1170 ; ARM-DISABLE-NEXT:    beq LBB7_2
1171 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.then
1172 ; ARM-DISABLE-NEXT:    mov r0, r1
1173 ; ARM-DISABLE-NEXT:    mov r2, r1
1174 ; ARM-DISABLE-NEXT:    mov r3, r1
1175 ; ARM-DISABLE-NEXT:    str r1, [sp]
1176 ; ARM-DISABLE-NEXT:    str r1, [sp, #4]
1177 ; ARM-DISABLE-NEXT:    str r1, [sp, #8]
1178 ; ARM-DISABLE-NEXT:    bl _someVariadicFunc
1179 ; ARM-DISABLE-NEXT:    lsl r0, r0, #3
1180 ; ARM-DISABLE-NEXT:    mov sp, r7
1181 ; ARM-DISABLE-NEXT:    pop {r7, pc}
1182 ; ARM-DISABLE-NEXT:  LBB7_2: @ %if.else
1183 ; ARM-DISABLE-NEXT:    lsl r0, r1, #1
1184 ; ARM-DISABLE-NEXT:    mov sp, r7
1185 ; ARM-DISABLE-NEXT:    pop {r7, pc}
1187 ; THUMB-ENABLE-LABEL: callVariadicFunc:
1188 ; THUMB-ENABLE:       @ %bb.0: @ %entry
1189 ; THUMB-ENABLE-NEXT:    cbz r0, LBB7_2
1190 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.then
1191 ; THUMB-ENABLE-NEXT:    push {r7, lr}
1192 ; THUMB-ENABLE-NEXT:    mov r7, sp
1193 ; THUMB-ENABLE-NEXT:    sub sp, #12
1194 ; THUMB-ENABLE-NEXT:    mov r0, r1
1195 ; THUMB-ENABLE-NEXT:    mov r2, r1
1196 ; THUMB-ENABLE-NEXT:    mov r3, r1
1197 ; THUMB-ENABLE-NEXT:    strd r1, r1, [sp]
1198 ; THUMB-ENABLE-NEXT:    str r1, [sp, #8]
1199 ; THUMB-ENABLE-NEXT:    bl _someVariadicFunc
1200 ; THUMB-ENABLE-NEXT:    lsls r0, r0, #3
1201 ; THUMB-ENABLE-NEXT:    add sp, #12
1202 ; THUMB-ENABLE-NEXT:    pop {r7, pc}
1203 ; THUMB-ENABLE-NEXT:  LBB7_2: @ %if.else
1204 ; THUMB-ENABLE-NEXT:    lsls r0, r1, #1
1205 ; THUMB-ENABLE-NEXT:    bx lr
1207 ; THUMB-DISABLE-LABEL: callVariadicFunc:
1208 ; THUMB-DISABLE:       @ %bb.0: @ %entry
1209 ; THUMB-DISABLE-NEXT:    push {r7, lr}
1210 ; THUMB-DISABLE-NEXT:    mov r7, sp
1211 ; THUMB-DISABLE-NEXT:    sub sp, #12
1212 ; THUMB-DISABLE-NEXT:    cbz r0, LBB7_2
1213 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.then
1214 ; THUMB-DISABLE-NEXT:    mov r0, r1
1215 ; THUMB-DISABLE-NEXT:    mov r2, r1
1216 ; THUMB-DISABLE-NEXT:    mov r3, r1
1217 ; THUMB-DISABLE-NEXT:    strd r1, r1, [sp]
1218 ; THUMB-DISABLE-NEXT:    str r1, [sp, #8]
1219 ; THUMB-DISABLE-NEXT:    bl _someVariadicFunc
1220 ; THUMB-DISABLE-NEXT:    lsls r0, r0, #3
1221 ; THUMB-DISABLE-NEXT:    add sp, #12
1222 ; THUMB-DISABLE-NEXT:    pop {r7, pc}
1223 ; THUMB-DISABLE-NEXT:  LBB7_2: @ %if.else
1224 ; THUMB-DISABLE-NEXT:    lsls r0, r1, #1
1225 ; THUMB-DISABLE-NEXT:    add sp, #12
1226 ; THUMB-DISABLE-NEXT:    pop {r7, pc}
1227 entry:
1228   %tobool = icmp eq i32 %cond, 0
1229   br i1 %tobool, label %if.else, label %if.then
1231 if.then:                                          ; preds = %entry
1232   %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N)
1233   %shl = shl i32 %call, 3
1234   br label %if.end
1236 if.else:                                          ; preds = %entry
1237   %mul = shl nsw i32 %N, 1
1238   br label %if.end
1240 if.end:                                           ; preds = %if.else, %if.then
1241   %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ]
1242   ret i32 %sum.0
1245 declare i32 @someVariadicFunc(i32, ...)
1247 ; Make sure we do not insert unreachable code after noreturn function.
1248 ; Although this is not incorrect to insert such code, it is useless
1249 ; and it hurts the binary size.
1251 ; noreturn:
1252 ; push
1253 ; cmp r0, #0
1254 ; cmp r0, #0
1255 ; bne [[ABORT:LBB[0-9_]+]]
1256 ; bne [[ABORT:LBB[0-9_]+]]
1257 ; cbnz r0,  [[ABORT:LBB[0-9_]+]]
1258 ; cbnz r0,  [[ABORT:LBB[0-9_]+]]
1261 ; mov{{s?}} r0, #42
1263 ; bx lr
1265 ; pop
1267 ; [[ABORT]]: @ %if.abort
1269 ; push
1271 ; bl{{x?}} _abort
1272 ; pop
1273 define i32 @noreturn(i8 signext %bad_thing) "no-frame-pointer-elim"="true" {
1274 ; ARM-ENABLE-LABEL: noreturn:
1275 ; ARM-ENABLE:       @ %bb.0: @ %entry
1276 ; ARM-ENABLE-NEXT:    cmp r0, #0
1277 ; ARM-ENABLE-NEXT:    bne LBB8_2
1278 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.end
1279 ; ARM-ENABLE-NEXT:    mov r0, #42
1280 ; ARM-ENABLE-NEXT:    bx lr
1281 ; ARM-ENABLE-NEXT:  LBB8_2: @ %if.abort
1282 ; ARM-ENABLE-NEXT:    push {r4, r7, lr}
1283 ; ARM-ENABLE-NEXT:    add r7, sp, #4
1284 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
1285 ; ARM-ENABLE-NEXT:    mov r0, #1
1286 ; ARM-ENABLE-NEXT:    @ InlineAsm End
1287 ; ARM-ENABLE-NEXT:    bl _abort
1289 ; ARM-DISABLE-LABEL: noreturn:
1290 ; ARM-DISABLE:       @ %bb.0: @ %entry
1291 ; ARM-DISABLE-NEXT:    push {r4, r7, lr}
1292 ; ARM-DISABLE-NEXT:    add r7, sp, #4
1293 ; ARM-DISABLE-NEXT:    cmp r0, #0
1294 ; ARM-DISABLE-NEXT:    bne LBB8_2
1295 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.end
1296 ; ARM-DISABLE-NEXT:    mov r0, #42
1297 ; ARM-DISABLE-NEXT:    pop {r4, r7, pc}
1298 ; ARM-DISABLE-NEXT:  LBB8_2: @ %if.abort
1299 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
1300 ; ARM-DISABLE-NEXT:    mov r0, #1
1301 ; ARM-DISABLE-NEXT:    @ InlineAsm End
1302 ; ARM-DISABLE-NEXT:    bl _abort
1304 ; THUMB-ENABLE-LABEL: noreturn:
1305 ; THUMB-ENABLE:       @ %bb.0: @ %entry
1306 ; THUMB-ENABLE-NEXT:    cbnz r0, LBB8_2
1307 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.end
1308 ; THUMB-ENABLE-NEXT:    movs r0, #42
1309 ; THUMB-ENABLE-NEXT:    bx lr
1310 ; THUMB-ENABLE-NEXT:  LBB8_2: @ %if.abort
1311 ; THUMB-ENABLE-NEXT:    push {r4, r7, lr}
1312 ; THUMB-ENABLE-NEXT:    add r7, sp, #4
1313 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1314 ; THUMB-ENABLE-NEXT:    mov.w r0, #1
1315 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
1316 ; THUMB-ENABLE-NEXT:    bl _abort
1318 ; THUMB-DISABLE-LABEL: noreturn:
1319 ; THUMB-DISABLE:       @ %bb.0: @ %entry
1320 ; THUMB-DISABLE-NEXT:    push {r4, r7, lr}
1321 ; THUMB-DISABLE-NEXT:    add r7, sp, #4
1322 ; THUMB-DISABLE-NEXT:    cbnz r0, LBB8_2
1323 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.end
1324 ; THUMB-DISABLE-NEXT:    movs r0, #42
1325 ; THUMB-DISABLE-NEXT:    pop {r4, r7, pc}
1326 ; THUMB-DISABLE-NEXT:  LBB8_2: @ %if.abort
1327 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1328 ; THUMB-DISABLE-NEXT:    mov.w r0, #1
1329 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
1330 ; THUMB-DISABLE-NEXT:    bl _abort
1331 entry:
1332   %tobool = icmp eq i8 %bad_thing, 0
1333   br i1 %tobool, label %if.end, label %if.abort
1335 if.abort:
1336   %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
1337   tail call void @abort() #0
1338   unreachable
1340 if.end:
1341   ret i32 42
1344 declare void @abort() #0
1346 attributes #0 = { noreturn nounwind }
1348 ; Make sure that we handle infinite loops properly When checking that the Save
1349 ; and Restore blocks are control flow equivalent, the loop searches for the
1350 ; immediate (post) dominator for the (restore) save blocks. When either the Save
1351 ; or Restore block is located in an infinite loop the only immediate (post)
1352 ; dominator is itself. In this case, we cannot perform shrink wrapping, but we
1353 ; should return gracefully and continue compilation.
1354 ; The only condition for this test is the compilation finishes correctly.
1355 ; infiniteloop
1356 ; pop
1357 define void @infiniteloop() "no-frame-pointer-elim"="true" {
1358 ; ARM-LABEL: infiniteloop:
1359 ; ARM:       @ %bb.0: @ %entry
1360 ; ARM-NEXT:    push {r4, r5, r7, lr}
1361 ; ARM-NEXT:    add r7, sp, #8
1362 ; ARM-NEXT:    mov r0, #0
1363 ; ARM-NEXT:    cmp r0, #0
1364 ; ARM-NEXT:    bne LBB9_3
1365 ; ARM-NEXT:  @ %bb.1: @ %if.then
1366 ; ARM-NEXT:    sub r1, sp, #16
1367 ; ARM-NEXT:    mov sp, r1
1368 ; ARM-NEXT:  LBB9_2: @ %for.body
1369 ; ARM-NEXT:    @ =>This Inner Loop Header: Depth=1
1370 ; ARM-NEXT:    @ InlineAsm Start
1371 ; ARM-NEXT:    mov r2, #1
1372 ; ARM-NEXT:    @ InlineAsm End
1373 ; ARM-NEXT:    add r0, r2, r0
1374 ; ARM-NEXT:    str r0, [r1]
1375 ; ARM-NEXT:    b LBB9_2
1376 ; ARM-NEXT:  LBB9_3: @ %if.end
1377 ; ARM-NEXT:    sub sp, r7, #8
1378 ; ARM-NEXT:    pop {r4, r5, r7, pc}
1380 ; THUMB-LABEL: infiniteloop:
1381 ; THUMB:       @ %bb.0: @ %entry
1382 ; THUMB-NEXT:    push {r4, r5, r7, lr}
1383 ; THUMB-NEXT:    add r7, sp, #8
1384 ; THUMB-NEXT:    movs r0, #0
1385 ; THUMB-NEXT:    cbnz r0, LBB9_3
1386 ; THUMB-NEXT:  @ %bb.1: @ %if.then
1387 ; THUMB-NEXT:    sub.w r0, sp, #16
1388 ; THUMB-NEXT:    mov sp, r0
1389 ; THUMB-NEXT:    movs r1, #0
1390 ; THUMB-NEXT:  LBB9_2: @ %for.body
1391 ; THUMB-NEXT:    @ =>This Inner Loop Header: Depth=1
1392 ; THUMB-NEXT:    @ InlineAsm Start
1393 ; THUMB-NEXT:    mov.w r2, #1
1394 ; THUMB-NEXT:    @ InlineAsm End
1395 ; THUMB-NEXT:    add r1, r2
1396 ; THUMB-NEXT:    str r1, [r0]
1397 ; THUMB-NEXT:    b LBB9_2
1398 ; THUMB-NEXT:  LBB9_3: @ %if.end
1399 ; THUMB-NEXT:    sub.w r4, r7, #8
1400 ; THUMB-NEXT:    mov sp, r4
1401 ; THUMB-NEXT:    pop {r4, r5, r7, pc}
1402 ; ARM-ENABLE-LABEL: infiniteloop:
1403 ; ARM-ENABLE:       @ %bb.0: @ %entry
1404 ; ARM-ENABLE-NEXT:    push {r4, r5, r7, lr}
1405 ; ARM-ENABLE-NEXT:    add r7, sp, #8
1406 ; ARM-ENABLE-NEXT:    mov r0, #0
1407 ; ARM-ENABLE-NEXT:    cmp r0, #0
1408 ; ARM-ENABLE-NEXT:    bne LBB9_3
1409 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %if.then
1410 ; ARM-ENABLE-NEXT:    sub r1, sp, #16
1411 ; ARM-ENABLE-NEXT:    mov sp, r1
1412 ; ARM-ENABLE-NEXT:  LBB9_2: @ %for.body
1413 ; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1414 ; ARM-ENABLE-NEXT:    @ InlineAsm Start
1415 ; ARM-ENABLE-NEXT:    mov r2, #1
1416 ; ARM-ENABLE-NEXT:    @ InlineAsm End
1417 ; ARM-ENABLE-NEXT:    add r0, r2, r0
1418 ; ARM-ENABLE-NEXT:    str r0, [r1]
1419 ; ARM-ENABLE-NEXT:    b LBB9_2
1420 ; ARM-ENABLE-NEXT:  LBB9_3: @ %if.end
1421 ; ARM-ENABLE-NEXT:    sub sp, r7, #8
1422 ; ARM-ENABLE-NEXT:    pop {r4, r5, r7, pc}
1424 ; ARM-DISABLE-LABEL: infiniteloop:
1425 ; ARM-DISABLE:       @ %bb.0: @ %entry
1426 ; ARM-DISABLE-NEXT:    push {r4, r5, r7, lr}
1427 ; ARM-DISABLE-NEXT:    add r7, sp, #8
1428 ; ARM-DISABLE-NEXT:    mov r0, #0
1429 ; ARM-DISABLE-NEXT:    cmp r0, #0
1430 ; ARM-DISABLE-NEXT:    bne LBB9_3
1431 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %if.then
1432 ; ARM-DISABLE-NEXT:    sub r1, sp, #16
1433 ; ARM-DISABLE-NEXT:    mov sp, r1
1434 ; ARM-DISABLE-NEXT:  LBB9_2: @ %for.body
1435 ; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1436 ; ARM-DISABLE-NEXT:    @ InlineAsm Start
1437 ; ARM-DISABLE-NEXT:    mov r2, #1
1438 ; ARM-DISABLE-NEXT:    @ InlineAsm End
1439 ; ARM-DISABLE-NEXT:    add r0, r2, r0
1440 ; ARM-DISABLE-NEXT:    str r0, [r1]
1441 ; ARM-DISABLE-NEXT:    b LBB9_2
1442 ; ARM-DISABLE-NEXT:  LBB9_3: @ %if.end
1443 ; ARM-DISABLE-NEXT:    sub sp, r7, #8
1444 ; ARM-DISABLE-NEXT:    pop {r4, r5, r7, pc}
1446 ; THUMB-ENABLE-LABEL: infiniteloop:
1447 ; THUMB-ENABLE:       @ %bb.0: @ %entry
1448 ; THUMB-ENABLE-NEXT:    push {r4, r5, r7, lr}
1449 ; THUMB-ENABLE-NEXT:    add r7, sp, #8
1450 ; THUMB-ENABLE-NEXT:    movs r0, #0
1451 ; THUMB-ENABLE-NEXT:    cbnz r0, LBB9_3
1452 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %if.then
1453 ; THUMB-ENABLE-NEXT:    sub.w r0, sp, #16
1454 ; THUMB-ENABLE-NEXT:    mov sp, r0
1455 ; THUMB-ENABLE-NEXT:    movs r1, #0
1456 ; THUMB-ENABLE-NEXT:  LBB9_2: @ %for.body
1457 ; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1458 ; THUMB-ENABLE-NEXT:    @ InlineAsm Start
1459 ; THUMB-ENABLE-NEXT:    mov.w r2, #1
1460 ; THUMB-ENABLE-NEXT:    @ InlineAsm End
1461 ; THUMB-ENABLE-NEXT:    add r1, r2
1462 ; THUMB-ENABLE-NEXT:    str r1, [r0]
1463 ; THUMB-ENABLE-NEXT:    b LBB9_2
1464 ; THUMB-ENABLE-NEXT:  LBB9_3: @ %if.end
1465 ; THUMB-ENABLE-NEXT:    sub.w r4, r7, #8
1466 ; THUMB-ENABLE-NEXT:    mov sp, r4
1467 ; THUMB-ENABLE-NEXT:    pop {r4, r5, r7, pc}
1469 ; THUMB-DISABLE-LABEL: infiniteloop:
1470 ; THUMB-DISABLE:       @ %bb.0: @ %entry
1471 ; THUMB-DISABLE-NEXT:    push {r4, r5, r7, lr}
1472 ; THUMB-DISABLE-NEXT:    add r7, sp, #8
1473 ; THUMB-DISABLE-NEXT:    movs r0, #0
1474 ; THUMB-DISABLE-NEXT:    cbnz r0, LBB9_3
1475 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %if.then
1476 ; THUMB-DISABLE-NEXT:    sub.w r0, sp, #16
1477 ; THUMB-DISABLE-NEXT:    mov sp, r0
1478 ; THUMB-DISABLE-NEXT:    movs r1, #0
1479 ; THUMB-DISABLE-NEXT:  LBB9_2: @ %for.body
1480 ; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1481 ; THUMB-DISABLE-NEXT:    @ InlineAsm Start
1482 ; THUMB-DISABLE-NEXT:    mov.w r2, #1
1483 ; THUMB-DISABLE-NEXT:    @ InlineAsm End
1484 ; THUMB-DISABLE-NEXT:    add r1, r2
1485 ; THUMB-DISABLE-NEXT:    str r1, [r0]
1486 ; THUMB-DISABLE-NEXT:    b LBB9_2
1487 ; THUMB-DISABLE-NEXT:  LBB9_3: @ %if.end
1488 ; THUMB-DISABLE-NEXT:    sub.w r4, r7, #8
1489 ; THUMB-DISABLE-NEXT:    mov sp, r4
1490 ; THUMB-DISABLE-NEXT:    pop {r4, r5, r7, pc}
1491 entry:
1492   br i1 undef, label %if.then, label %if.end
1494 if.then:
1495   %ptr = alloca i32, i32 4
1496   br label %for.body
1498 for.body:                                         ; preds = %for.body, %entry
1499   %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
1500   %call = tail call i32 asm sideeffect "mov $0, #1", "=r,~{r4}"()
1501   %add = add nsw i32 %call, %sum.03
1502   store i32 %add, i32* %ptr
1503   br label %for.body
1505 if.end:
1506   ret void
1509 ; Another infinite loop test this time with a body bigger than just one block.
1510 ; infiniteloop2
1511 ; pop
1512 define void @infiniteloop2() "no-frame-pointer-elim"="true" {
1513 entry:
1514   br i1 undef, label %if.then, label %if.end
1516 if.then:
1517   %ptr = alloca i32, i32 4
1518   br label %for.body
1520 for.body:                                         ; preds = %for.body, %entry
1521   %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2]
1522   %call = tail call i32 asm "mov $0, #0", "=r,~{r4}"()
1523   %add = add nsw i32 %call, %sum.03
1524   store i32 %add, i32* %ptr
1525   br i1 undef, label %body1, label %body2
1527 body1:
1528   tail call void asm sideeffect "nop", "~{r4}"()
1529   br label %for.body
1531 body2:
1532   tail call void asm sideeffect "nop", "~{r4}"()
1533   br label %for.body
1535 if.end:
1536   ret void
1539 ; Another infinite loop test this time with two nested infinite loop.
1540 ; infiniteloop3
1541 ; bx lr
1542 define void @infiniteloop3() "no-frame-pointer-elim"="true" {
1543 ; ARM-LABEL: infiniteloop3:
1544 ; ARM:       @ %bb.0: @ %entry
1545 ; ARM-NEXT:    mov r0, #0
1546 ; ARM-NEXT:    cmp r0, #0
1547 ; ARM-NEXT:    bne LBB11_5
1548 ; ARM-NEXT:  @ %bb.1: @ %loop2a.preheader
1549 ; ARM-NEXT:    mov r1, #0
1550 ; ARM-NEXT:    mov r2, r0
1551 ; ARM-NEXT:    b LBB11_3
1552 ; ARM-NEXT:  LBB11_2: @ %loop2b
1553 ; ARM-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1554 ; ARM-NEXT:    str r1, [r2]
1555 ; ARM-NEXT:    mov r2, r1
1556 ; ARM-NEXT:    mov r1, r3
1557 ; ARM-NEXT:  LBB11_3: @ %loop1
1558 ; ARM-NEXT:    @ =>This Inner Loop Header: Depth=1
1559 ; ARM-NEXT:    ldr r3, [r0]
1560 ; ARM-NEXT:    cmp r0, #0
1561 ; ARM-NEXT:    bne LBB11_2
1562 ; ARM-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1563 ; ARM-NEXT:    mov r0, r1
1564 ; ARM-NEXT:    mov r1, r3
1565 ; ARM-NEXT:    mov r2, r0
1566 ; ARM-NEXT:    b LBB11_3
1567 ; ARM-NEXT:  LBB11_5: @ %end
1568 ; ARM-NEXT:    bx lr
1570 ; THUMB-LABEL: infiniteloop3:
1571 ; THUMB:       @ %bb.0: @ %entry
1572 ; THUMB-NEXT:    movs r0, #0
1573 ; THUMB-NEXT:    cbnz r0, LBB11_5
1574 ; THUMB-NEXT:  @ %bb.1: @ %loop2a.preheader
1575 ; THUMB-NEXT:    movs r0, #0
1576 ; THUMB-NEXT:    movs r1, #0
1577 ; THUMB-NEXT:    mov r2, r0
1578 ; THUMB-NEXT:    b LBB11_3
1579 ; THUMB-NEXT:  LBB11_2: @ %loop2b
1580 ; THUMB-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1581 ; THUMB-NEXT:    str r1, [r2]
1582 ; THUMB-NEXT:    mov r2, r1
1583 ; THUMB-NEXT:    mov r1, r3
1584 ; THUMB-NEXT:  LBB11_3: @ %loop1
1585 ; THUMB-NEXT:    @ =>This Inner Loop Header: Depth=1
1586 ; THUMB-NEXT:    ldr r3, [r0]
1587 ; THUMB-NEXT:    cmp r0, #0
1588 ; THUMB-NEXT:    bne LBB11_2
1589 ; THUMB-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1590 ; THUMB-NEXT:    mov r0, r1
1591 ; THUMB-NEXT:    mov r1, r3
1592 ; THUMB-NEXT:    mov r2, r0
1593 ; THUMB-NEXT:    b LBB11_3
1594 ; THUMB-NEXT:  LBB11_5: @ %end
1595 ; THUMB-NEXT:    bx lr
1596 ; ARM-ENABLE-LABEL: infiniteloop3:
1597 ; ARM-ENABLE:       @ %bb.0: @ %entry
1598 ; ARM-ENABLE-NEXT:    mov r0, #0
1599 ; ARM-ENABLE-NEXT:    cmp r0, #0
1600 ; ARM-ENABLE-NEXT:    bne LBB11_5
1601 ; ARM-ENABLE-NEXT:  @ %bb.1: @ %loop2a.preheader
1602 ; ARM-ENABLE-NEXT:    mov r1, #0
1603 ; ARM-ENABLE-NEXT:    mov r2, r0
1604 ; ARM-ENABLE-NEXT:    b LBB11_3
1605 ; ARM-ENABLE-NEXT:  LBB11_2: @ %loop2b
1606 ; ARM-ENABLE-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1607 ; ARM-ENABLE-NEXT:    str r1, [r2]
1608 ; ARM-ENABLE-NEXT:    mov r2, r1
1609 ; ARM-ENABLE-NEXT:    mov r1, r3
1610 ; ARM-ENABLE-NEXT:  LBB11_3: @ %loop1
1611 ; ARM-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1612 ; ARM-ENABLE-NEXT:    ldr r3, [r0]
1613 ; ARM-ENABLE-NEXT:    cmp r0, #0
1614 ; ARM-ENABLE-NEXT:    bne LBB11_2
1615 ; ARM-ENABLE-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1616 ; ARM-ENABLE-NEXT:    mov r0, r1
1617 ; ARM-ENABLE-NEXT:    mov r1, r3
1618 ; ARM-ENABLE-NEXT:    mov r2, r0
1619 ; ARM-ENABLE-NEXT:    b LBB11_3
1620 ; ARM-ENABLE-NEXT:  LBB11_5: @ %end
1621 ; ARM-ENABLE-NEXT:    bx lr
1623 ; ARM-DISABLE-LABEL: infiniteloop3:
1624 ; ARM-DISABLE:       @ %bb.0: @ %entry
1625 ; ARM-DISABLE-NEXT:    mov r0, #0
1626 ; ARM-DISABLE-NEXT:    cmp r0, #0
1627 ; ARM-DISABLE-NEXT:    bne LBB11_5
1628 ; ARM-DISABLE-NEXT:  @ %bb.1: @ %loop2a.preheader
1629 ; ARM-DISABLE-NEXT:    mov r1, #0
1630 ; ARM-DISABLE-NEXT:    mov r2, r0
1631 ; ARM-DISABLE-NEXT:    b LBB11_3
1632 ; ARM-DISABLE-NEXT:  LBB11_2: @ %loop2b
1633 ; ARM-DISABLE-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1634 ; ARM-DISABLE-NEXT:    str r1, [r2]
1635 ; ARM-DISABLE-NEXT:    mov r2, r1
1636 ; ARM-DISABLE-NEXT:    mov r1, r3
1637 ; ARM-DISABLE-NEXT:  LBB11_3: @ %loop1
1638 ; ARM-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1639 ; ARM-DISABLE-NEXT:    ldr r3, [r0]
1640 ; ARM-DISABLE-NEXT:    cmp r0, #0
1641 ; ARM-DISABLE-NEXT:    bne LBB11_2
1642 ; ARM-DISABLE-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1643 ; ARM-DISABLE-NEXT:    mov r0, r1
1644 ; ARM-DISABLE-NEXT:    mov r1, r3
1645 ; ARM-DISABLE-NEXT:    mov r2, r0
1646 ; ARM-DISABLE-NEXT:    b LBB11_3
1647 ; ARM-DISABLE-NEXT:  LBB11_5: @ %end
1648 ; ARM-DISABLE-NEXT:    bx lr
1650 ; THUMB-ENABLE-LABEL: infiniteloop3:
1651 ; THUMB-ENABLE:       @ %bb.0: @ %entry
1652 ; THUMB-ENABLE-NEXT:    movs r0, #0
1653 ; THUMB-ENABLE-NEXT:    cbnz r0, LBB11_5
1654 ; THUMB-ENABLE-NEXT:  @ %bb.1: @ %loop2a.preheader
1655 ; THUMB-ENABLE-NEXT:    movs r0, #0
1656 ; THUMB-ENABLE-NEXT:    movs r1, #0
1657 ; THUMB-ENABLE-NEXT:    mov r2, r0
1658 ; THUMB-ENABLE-NEXT:    b LBB11_3
1659 ; THUMB-ENABLE-NEXT:  LBB11_2: @ %loop2b
1660 ; THUMB-ENABLE-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1661 ; THUMB-ENABLE-NEXT:    str r1, [r2]
1662 ; THUMB-ENABLE-NEXT:    mov r2, r1
1663 ; THUMB-ENABLE-NEXT:    mov r1, r3
1664 ; THUMB-ENABLE-NEXT:  LBB11_3: @ %loop1
1665 ; THUMB-ENABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1666 ; THUMB-ENABLE-NEXT:    ldr r3, [r0]
1667 ; THUMB-ENABLE-NEXT:    cmp r0, #0
1668 ; THUMB-ENABLE-NEXT:    bne LBB11_2
1669 ; THUMB-ENABLE-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1670 ; THUMB-ENABLE-NEXT:    mov r0, r1
1671 ; THUMB-ENABLE-NEXT:    mov r1, r3
1672 ; THUMB-ENABLE-NEXT:    mov r2, r0
1673 ; THUMB-ENABLE-NEXT:    b LBB11_3
1674 ; THUMB-ENABLE-NEXT:  LBB11_5: @ %end
1675 ; THUMB-ENABLE-NEXT:    bx lr
1677 ; THUMB-DISABLE-LABEL: infiniteloop3:
1678 ; THUMB-DISABLE:       @ %bb.0: @ %entry
1679 ; THUMB-DISABLE-NEXT:    movs r0, #0
1680 ; THUMB-DISABLE-NEXT:    cbnz r0, LBB11_5
1681 ; THUMB-DISABLE-NEXT:  @ %bb.1: @ %loop2a.preheader
1682 ; THUMB-DISABLE-NEXT:    movs r0, #0
1683 ; THUMB-DISABLE-NEXT:    movs r1, #0
1684 ; THUMB-DISABLE-NEXT:    mov r2, r0
1685 ; THUMB-DISABLE-NEXT:    b LBB11_3
1686 ; THUMB-DISABLE-NEXT:  LBB11_2: @ %loop2b
1687 ; THUMB-DISABLE-NEXT:    @ in Loop: Header=BB11_3 Depth=1
1688 ; THUMB-DISABLE-NEXT:    str r1, [r2]
1689 ; THUMB-DISABLE-NEXT:    mov r2, r1
1690 ; THUMB-DISABLE-NEXT:    mov r1, r3
1691 ; THUMB-DISABLE-NEXT:  LBB11_3: @ %loop1
1692 ; THUMB-DISABLE-NEXT:    @ =>This Inner Loop Header: Depth=1
1693 ; THUMB-DISABLE-NEXT:    ldr r3, [r0]
1694 ; THUMB-DISABLE-NEXT:    cmp r0, #0
1695 ; THUMB-DISABLE-NEXT:    bne LBB11_2
1696 ; THUMB-DISABLE-NEXT:  @ %bb.4: @ in Loop: Header=BB11_3 Depth=1
1697 ; THUMB-DISABLE-NEXT:    mov r0, r1
1698 ; THUMB-DISABLE-NEXT:    mov r1, r3
1699 ; THUMB-DISABLE-NEXT:    mov r2, r0
1700 ; THUMB-DISABLE-NEXT:    b LBB11_3
1701 ; THUMB-DISABLE-NEXT:  LBB11_5: @ %end
1702 ; THUMB-DISABLE-NEXT:    bx lr
1703 entry:
1704   br i1 undef, label %loop2a, label %body
1706 body:                                             ; preds = %entry
1707   br i1 undef, label %loop2a, label %end
1709 loop1:                                            ; preds = %loop2a, %loop2b
1710   %var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ]
1711   %next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ]
1712   %0 = icmp eq i32* %var, null
1713   %next.load = load i32*, i32** undef
1714   br i1 %0, label %loop2a, label %loop2b
1716 loop2a:                                           ; preds = %loop1, %body, %entry
1717   %var = phi i32* [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ]
1718   %next.var = phi i32* [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ]
1719   br label %loop1
1721 loop2b:                                           ; preds = %loop1
1722   %gep1 = bitcast i32* %var.phi to i32*
1723   %next.ptr = bitcast i32* %gep1 to i32**
1724   store i32* %next.phi, i32** %next.ptr
1725   br label %loop1
1727 end:
1728   ret void
1731 ; Function Attrs: nounwind readnone
1732 declare double @llvm.pow.f64(double, double)
1734 ; This function needs to spill floating point registers to
1735 ; exercise the path where we were dereferencing the end iterator
1736 ; to access debug info location while inserting the spill code
1737 ; during PEI with shrink-wrapping enable.
1738 ; debug_info:
1740 ; {{tst  r2, #1|lsls r1, r2, #31}}
1741 ; beq      [[BB13:LBB[0-9_]+]]
1743 ; push
1745 ; {{tst  r2, #1|lsls r1, r2, #31}}
1746 ; beq      [[BB13:LBB[0-9_]+]]
1748 ; bl{{x?}} _pow
1751 ; pop
1753 ; [[BB13]]:
1754 ; vldr
1756 ; pop
1758 ; FIXME: This is flakey passing by finding 'bl' somewhere amongst the debug
1759 ; info (like labels named 'line_table) not because it's found a bl instruction.
1761 ; bl
1762 define float @debug_info(float %gamma, float %slopeLimit, i1 %or.cond, double %tmp) "no-frame-pointer-elim"="true" {
1763 ; ARM-LABEL: debug_info:
1764 ; ARM:       @ %bb.0: @ %bb
1765 ; ARM-NEXT:    push {r4, r7, lr}
1766 ; ARM-NEXT:    add r7, sp, #4
1767 ; ARM-NEXT:    sub r4, sp, #16
1768 ; ARM-NEXT:    bfc r4, #0, #4
1769 ; ARM-NEXT:    mov sp, r4
1770 ; ARM-NEXT:    tst r2, #1
1771 ; ARM-NEXT:    vst1.64 {d8, d9}, [r4:128]
1772 ; ARM-NEXT:    beq LBB12_2
1773 ; ARM-NEXT:  @ %bb.1: @ %bb3
1774 ; ARM-NEXT:    ldr r1, [r7, #8]
1775 ; ARM-NEXT:    vmov s16, r0
1776 ; ARM-NEXT:    mov r0, r3
1777 ; ARM-NEXT:    mov r2, r3
1778 ; ARM-NEXT:    vmov d9, r3, r1
1779 ; ARM-NEXT:    mov r3, r1
1780 ; ARM-NEXT:    bl _pow
1781 ; ARM-NEXT:    vmov.f32 s0, #1.000000e+00
1782 ; ARM-NEXT:    vmov.f64 d16, #1.000000e+00
1783 ; ARM-NEXT:    vadd.f64 d16, d9, d16
1784 ; ARM-NEXT:    vcmpe.f32 s16, s0
1785 ; ARM-NEXT:    vmrs APSR_nzcv, fpscr
1786 ; ARM-NEXT:    vmov d17, r0, r1
1787 ; ARM-NEXT:    vmov.f64 d18, d9
1788 ; ARM-NEXT:    vadd.f64 d17, d17, d17
1789 ; ARM-NEXT:    vmovgt.f64 d18, d16
1790 ; ARM-NEXT:    vcmp.f64 d18, d9
1791 ; ARM-NEXT:    vmrs APSR_nzcv, fpscr
1792 ; ARM-NEXT:    vmovne.f64 d9, d17
1793 ; ARM-NEXT:    vcvt.f32.f64 s0, d9
1794 ; ARM-NEXT:    b LBB12_3
1795 ; ARM-NEXT:  LBB12_2:
1796 ; ARM-NEXT:    vldr s0, LCPI12_0
1797 ; ARM-NEXT:  LBB12_3: @ %bb13
1798 ; ARM-NEXT:    mov r4, sp
1799 ; ARM-NEXT:    vld1.64 {d8, d9}, [r4:128]
1800 ; ARM-NEXT:    vmov r0, s0
1801 ; ARM-NEXT:    sub sp, r7, #4
1802 ; ARM-NEXT:    pop {r4, r7, pc}
1803 ; ARM-NEXT:    .p2align 2
1804 ; ARM-NEXT:  @ %bb.4:
1805 ; ARM-NEXT:    .data_region
1806 ; ARM-NEXT:  LCPI12_0:
1807 ; ARM-NEXT:    .long 0 @ float 0
1808 ; ARM-NEXT:    .end_data_region
1810 ; THUMB-LABEL: debug_info:
1811 ; THUMB:       @ %bb.0: @ %bb
1812 ; THUMB-NEXT:    push {r4, r7, lr}
1813 ; THUMB-NEXT:    add r7, sp, #4
1814 ; THUMB-NEXT:    sub.w r4, sp, #16
1815 ; THUMB-NEXT:    bfc r4, #0, #4
1816 ; THUMB-NEXT:    mov sp, r4
1817 ; THUMB-NEXT:    lsls r1, r2, #31
1818 ; THUMB-NEXT:    vst1.64 {d8, d9}, [r4:128]
1819 ; THUMB-NEXT:    beq LBB12_2
1820 ; THUMB-NEXT:  @ %bb.1: @ %bb3
1821 ; THUMB-NEXT:    ldr r1, [r7, #8]
1822 ; THUMB-NEXT:    vmov s16, r0
1823 ; THUMB-NEXT:    mov r0, r3
1824 ; THUMB-NEXT:    mov r2, r3
1825 ; THUMB-NEXT:    vmov d9, r3, r1
1826 ; THUMB-NEXT:    mov r3, r1
1827 ; THUMB-NEXT:    bl _pow
1828 ; THUMB-NEXT:    vmov.f32 s0, #1.000000e+00
1829 ; THUMB-NEXT:    vmov.f64 d16, #1.000000e+00
1830 ; THUMB-NEXT:    vmov.f64 d18, d9
1831 ; THUMB-NEXT:    vcmpe.f32 s16, s0
1832 ; THUMB-NEXT:    vadd.f64 d16, d9, d16
1833 ; THUMB-NEXT:    vmrs APSR_nzcv, fpscr
1834 ; THUMB-NEXT:    it gt
1835 ; THUMB-NEXT:    vmovgt.f64 d18, d16
1836 ; THUMB-NEXT:    vcmp.f64 d18, d9
1837 ; THUMB-NEXT:    vmov d17, r0, r1
1838 ; THUMB-NEXT:    vmrs APSR_nzcv, fpscr
1839 ; THUMB-NEXT:    vadd.f64 d17, d17, d17
1840 ; THUMB-NEXT:    it ne
1841 ; THUMB-NEXT:    vmovne.f64 d9, d17
1842 ; THUMB-NEXT:    vcvt.f32.f64 s0, d9
1843 ; THUMB-NEXT:    b LBB12_3
1844 ; THUMB-NEXT:  LBB12_2:
1845 ; THUMB-NEXT:    vldr s0, LCPI12_0
1846 ; THUMB-NEXT:  LBB12_3: @ %bb13
1847 ; THUMB-NEXT:    mov r4, sp
1848 ; THUMB-NEXT:    vld1.64 {d8, d9}, [r4:128]
1849 ; THUMB-NEXT:    subs r4, r7, #4
1850 ; THUMB-NEXT:    vmov r0, s0
1851 ; THUMB-NEXT:    mov sp, r4
1852 ; THUMB-NEXT:    pop {r4, r7, pc}
1853 ; THUMB-NEXT:    .p2align 2
1854 ; THUMB-NEXT:  @ %bb.4:
1855 ; THUMB-NEXT:    .data_region
1856 ; THUMB-NEXT:  LCPI12_0:
1857 ; THUMB-NEXT:    .long 0 @ float 0
1858 ; THUMB-NEXT:    .end_data_region
1860   br i1 %or.cond, label %bb3, label %bb13
1862 bb3:                                              ; preds = %bb
1863   %tmp4 = fcmp ogt float %gamma, 1.000000e+00
1864   %tmp5 = fadd double 1.000000e+00, %tmp
1865   %tmp6 = select i1 %tmp4, double %tmp5, double %tmp
1866   %tmp10 = tail call double @llvm.pow.f64(double %tmp, double %tmp)
1867   %tmp11 = fcmp une double %tmp6, %tmp
1868   %tmp12 = fadd double %tmp10, %tmp10
1869   %cutoff.0 = select i1 %tmp11, double %tmp12, double %tmp
1870   %phitmp = fptrunc double %cutoff.0 to float
1871   br label %bb13
1873 bb13:                                             ; preds = %bb3, %bb
1874   %cutoff.1 = phi float [ 0.000000e+00, %bb ], [ %phitmp, %bb3 ]
1875   ret float %cutoff.1
1879 !llvm.dbg.cu = !{!0}
1880 !llvm.module.flags = !{!3}
1882 !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)
1883 !1 = !DIFile(filename: "a.cpp", directory: "b")
1884 !2 = !{}
1885 !3 = !{i32 2, !"Debug Info Version", i32 3}
1886 !4 = !{!5}
1887 !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)