xref: /aosp_15_r20/external/llvm/test/CodeGen/Thumb/thumb-shrink-wrapping.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=true -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=thumb-macho \
2*9880d681SAndroid Build Coastguard Worker; RUN:      | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE --check-prefix=ENABLE-V4T
3*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=true -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=thumbv5-macho \
4*9880d681SAndroid Build Coastguard Worker; RUN:      | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE --check-prefix=ENABLE-V5T
5*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=false -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=thumb-macho \
6*9880d681SAndroid Build Coastguard Worker; RUN:      | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE --check-prefix=DISABLE-V4T
7*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=false -ifcvt-fn-start=1 -ifcvt-fn-stop=0 -mtriple=thumbv5-macho \
8*9880d681SAndroid Build Coastguard Worker; RUN:      | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE --check-prefix=DISABLE-V5T
9*9880d681SAndroid Build Coastguard Worker;
10*9880d681SAndroid Build Coastguard Worker; Note: Lots of tests use inline asm instead of regular calls.
11*9880d681SAndroid Build Coastguard Worker; This allows to have a better control on what the allocation will do.
12*9880d681SAndroid Build Coastguard Worker; Otherwise, we may have spill right in the entry block, defeating
13*9880d681SAndroid Build Coastguard Worker; shrink-wrapping. Moreover, some of the inline asm statements (nop)
14*9880d681SAndroid Build Coastguard Worker; are here to ensure that the related paths do not end up as critical
15*9880d681SAndroid Build Coastguard Worker; edges.
16*9880d681SAndroid Build Coastguard Worker; Also disable the late if-converter as it makes harder to reason on
17*9880d681SAndroid Build Coastguard Worker; the diffs.
18*9880d681SAndroid Build Coastguard Worker
19*9880d681SAndroid Build Coastguard Worker; Initial motivating example: Simple diamond with a call just on one side.
20*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo:
21*9880d681SAndroid Build Coastguard Worker;
22*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
23*9880d681SAndroid Build Coastguard Worker; No prologue needed.
24*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp r0, r1
25*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bge [[EXIT_LABEL:LBB[0-9_]+]]
26*9880d681SAndroid Build Coastguard Worker;
27*9880d681SAndroid Build Coastguard Worker; Prologue code.
28*9880d681SAndroid Build Coastguard Worker; CHECK: push {r7, lr}
29*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, #8
30*9880d681SAndroid Build Coastguard Worker;
31*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
32*9880d681SAndroid Build Coastguard Worker; After the prologue is set.
33*9880d681SAndroid Build Coastguard Worker; DISABLE: cmp r0, r1
34*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: bge [[EXIT_LABEL:LBB[0-9_]+]]
35*9880d681SAndroid Build Coastguard Worker;
36*9880d681SAndroid Build Coastguard Worker; Store %a in the alloca.
37*9880d681SAndroid Build Coastguard Worker; CHECK: str r0, [sp, #4]
38*9880d681SAndroid Build Coastguard Worker; Set the alloca address in the second argument.
39*9880d681SAndroid Build Coastguard Worker; Set the first argument to zero.
40*9880d681SAndroid Build Coastguard Worker; CHECK: movs r0, #0
41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add r1, sp, #4
42*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bl
43*9880d681SAndroid Build Coastguard Worker;
44*9880d681SAndroid Build Coastguard Worker; With shrink-wrapping, epilogue is just after the call.
45*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: add sp, #8
46*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: pop {r7, pc}
47*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r7}
48*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r1}
49*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: mov lr, r1
50*9880d681SAndroid Build Coastguard Worker;
51*9880d681SAndroid Build Coastguard Worker; CHECK: [[EXIT_LABEL]]:
52*9880d681SAndroid Build Coastguard Worker;
53*9880d681SAndroid Build Coastguard Worker; Without shrink-wrapping, epilogue is in the exit block.
54*9880d681SAndroid Build Coastguard Worker; Epilogue code. (What we pop does not matter.)
55*9880d681SAndroid Build Coastguard Worker; DISABLE: add sp, #8
56*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {r7, pc}
57*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r7}
58*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
59*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
60*9880d681SAndroid Build Coastguard Worker;
61*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
62*9880d681SAndroid Build Coastguard Workerdefine i32 @foo(i32 %a, i32 %b) {
63*9880d681SAndroid Build Coastguard Worker  %tmp = alloca i32, align 4
64*9880d681SAndroid Build Coastguard Worker  %tmp2 = icmp slt i32 %a, %b
65*9880d681SAndroid Build Coastguard Worker  br i1 %tmp2, label %true, label %false
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Workertrue:
68*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %tmp, align 4
69*9880d681SAndroid Build Coastguard Worker  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
70*9880d681SAndroid Build Coastguard Worker  br label %false
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Workerfalse:
73*9880d681SAndroid Build Coastguard Worker  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
74*9880d681SAndroid Build Coastguard Worker  ret i32 %tmp.0
75*9880d681SAndroid Build Coastguard Worker}
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker; Same, but the final BB is non-trivial, so we don't duplicate the return inst.
79*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: bar:
80*9880d681SAndroid Build Coastguard Worker;
81*9880d681SAndroid Build Coastguard Worker; With shrink-wrapping, epilogue is just after the call.
82*9880d681SAndroid Build Coastguard Worker; CHECK: bl
83*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: add sp, #8
84*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: pop {r7}
85*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: pop {r0}
86*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: mov lr, r0
87*9880d681SAndroid Build Coastguard Worker;
88*9880d681SAndroid Build Coastguard Worker; CHECK: movs r0, #42
89*9880d681SAndroid Build Coastguard Worker;
90*9880d681SAndroid Build Coastguard Worker; Without shrink-wrapping, epilogue is in the exit block.
91*9880d681SAndroid Build Coastguard Worker; Epilogue code. (What we pop does not matter.)
92*9880d681SAndroid Build Coastguard Worker; DISABLE: add sp, #8
93*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {r7, pc}
94*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r7}
95*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
96*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
97*9880d681SAndroid Build Coastguard Worker;
98*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
99*9880d681SAndroid Build Coastguard Workerdefine i32 @bar(i32 %a, i32 %b) {
100*9880d681SAndroid Build Coastguard Worker  %tmp = alloca i32, align 4
101*9880d681SAndroid Build Coastguard Worker  %tmp2 = icmp slt i32 %a, %b
102*9880d681SAndroid Build Coastguard Worker  br i1 %tmp2, label %true, label %false
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Workertrue:
105*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %tmp, align 4
106*9880d681SAndroid Build Coastguard Worker  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
107*9880d681SAndroid Build Coastguard Worker  br label %false
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Workerfalse:
110*9880d681SAndroid Build Coastguard Worker  ret i32 42
111*9880d681SAndroid Build Coastguard Worker}
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker; Function Attrs: optsize
114*9880d681SAndroid Build Coastguard Workerdeclare i32 @doSomething(i32, i32*)
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker; Check that we do not perform the restore inside the loop whereas the save
118*9880d681SAndroid Build Coastguard Worker; is outside.
119*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: freqSaveAndRestoreOutsideLoop:
120*9880d681SAndroid Build Coastguard Worker;
121*9880d681SAndroid Build Coastguard Worker; Shrink-wrapping allows to skip the prologue in the else case.
122*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp r0, #0
123*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
124*9880d681SAndroid Build Coastguard Worker;
125*9880d681SAndroid Build Coastguard Worker; Prologue code.
126*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4.
127*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, lr}
128*9880d681SAndroid Build Coastguard Worker;
129*9880d681SAndroid Build Coastguard Worker; DISABLE: cmp r0, #0
130*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
131*9880d681SAndroid Build Coastguard Worker;
132*9880d681SAndroid Build Coastguard Worker; SUM is in r0 because it is coalesced with the second
133*9880d681SAndroid Build Coastguard Worker; argument on the else path.
134*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[SUM:r0]], #0
135*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movs [[IV:r[0-9]+]], #10
136*9880d681SAndroid Build Coastguard Worker;
137*9880d681SAndroid Build Coastguard Worker; Next BB.
138*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body
139*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[TMP:r[0-9]+]], #1
140*9880d681SAndroid Build Coastguard Worker; CHECK: adds [[SUM]], [[TMP]], [[SUM]]
141*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subs [[IV]], [[IV]], #1
142*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[IV]], #0
143*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP]]
144*9880d681SAndroid Build Coastguard Worker;
145*9880d681SAndroid Build Coastguard Worker; Next BB.
146*9880d681SAndroid Build Coastguard Worker; SUM << 3.
147*9880d681SAndroid Build Coastguard Worker; CHECK: lsls [[SUM]], [[SUM]], #3
148*9880d681SAndroid Build Coastguard Worker;
149*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue.
150*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T: pop {r4, pc}
151*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T: b [[END_LABEL:LBB[0-9_]+]]
152*9880d681SAndroid Build Coastguard Worker;
153*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else
154*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
155*9880d681SAndroid Build Coastguard Worker; CHECK: lsls r0, r1, #1
156*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {r4, pc}
157*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: [[END_LABEL]]: @ %if.end
158*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r4}
159*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
160*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
161*9880d681SAndroid Build Coastguard Worker;
162*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: {{LBB[0-9_]+}}: @ %if.end
163*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
164*9880d681SAndroid Build Coastguard Workerdefine i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) {
165*9880d681SAndroid Build Coastguard Workerentry:
166*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
167*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %for.preheader
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerfor.preheader:
170*9880d681SAndroid Build Coastguard Worker  tail call void asm "nop", ""()
171*9880d681SAndroid Build Coastguard Worker  br label %for.body
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.body
174*9880d681SAndroid Build Coastguard Worker  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
175*9880d681SAndroid Build Coastguard Worker  %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
176*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"()
177*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.04
178*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.05, 1
179*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
180*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
181*9880d681SAndroid Build Coastguard Worker
182*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
183*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %add, 3
184*9880d681SAndroid Build Coastguard Worker  br label %if.end
185*9880d681SAndroid Build Coastguard Worker
186*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
187*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
188*9880d681SAndroid Build Coastguard Worker  br label %if.end
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %for.end
191*9880d681SAndroid Build Coastguard Worker  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
192*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.1
193*9880d681SAndroid Build Coastguard Worker}
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Workerdeclare i32 @something(...)
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker; Check that we do not perform the shrink-wrapping inside the loop even
198*9880d681SAndroid Build Coastguard Worker; though that would be legal. The cost model must prevent that.
199*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: freqSaveAndRestoreOutsideLoop2:
200*9880d681SAndroid Build Coastguard Worker; Prologue code.
201*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4.
202*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4
203*9880d681SAndroid Build Coastguard Worker; This is the nop.
204*9880d681SAndroid Build Coastguard Worker; CHECK: mov r8, r8
205*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[SUM:r0]], #0
206*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movs [[IV:r[0-9]+]], #10
207*9880d681SAndroid Build Coastguard Worker; Next BB.
208*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: @ %for.body
209*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[TMP:r[0-9]+]], #1
210*9880d681SAndroid Build Coastguard Worker; CHECK: adds [[SUM]], [[TMP]], [[SUM]]
211*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subs [[IV]], [[IV]], #1
212*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[IV]], #0
213*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP_LABEL]]
214*9880d681SAndroid Build Coastguard Worker; Next BB.
215*9880d681SAndroid Build Coastguard Worker; CHECK: @ %for.exit
216*9880d681SAndroid Build Coastguard Worker; This is the nop.
217*9880d681SAndroid Build Coastguard Worker; CHECK: mov r8, r8
218*9880d681SAndroid Build Coastguard Worker; CHECK: pop {r4
219*9880d681SAndroid Build Coastguard Workerdefine i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) {
220*9880d681SAndroid Build Coastguard Workerentry:
221*9880d681SAndroid Build Coastguard Worker  br label %for.preheader
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Workerfor.preheader:
224*9880d681SAndroid Build Coastguard Worker  tail call void asm "nop", ""()
225*9880d681SAndroid Build Coastguard Worker  br label %for.body
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
228*9880d681SAndroid Build Coastguard Worker  %i.04 = phi i32 [ 0, %for.preheader ], [ %inc, %for.body ]
229*9880d681SAndroid Build Coastguard Worker  %sum.03 = phi i32 [ 0, %for.preheader ], [ %add, %for.body ]
230*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"()
231*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.03
232*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.04, 1
233*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
234*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.exit, label %for.body
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Workerfor.exit:
237*9880d681SAndroid Build Coastguard Worker  tail call void asm "nop", ""()
238*9880d681SAndroid Build Coastguard Worker  br label %for.end
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
241*9880d681SAndroid Build Coastguard Worker  ret i32 %add
242*9880d681SAndroid Build Coastguard Worker}
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker; Check with a more complex case that we do not have save within the loop and
245*9880d681SAndroid Build Coastguard Worker; restore outside.
246*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoSaveOutsideLoop:
247*9880d681SAndroid Build Coastguard Worker;
248*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp r0, #0
249*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
250*9880d681SAndroid Build Coastguard Worker;
251*9880d681SAndroid Build Coastguard Worker; Prologue code.
252*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4.
253*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, lr}
254*9880d681SAndroid Build Coastguard Worker;
255*9880d681SAndroid Build Coastguard Worker; DISABLE: cmp r0, #0
256*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
257*9880d681SAndroid Build Coastguard Worker;
258*9880d681SAndroid Build Coastguard Worker; SUM is in r0 because it is coalesced with the second
259*9880d681SAndroid Build Coastguard Worker; argument on the else path.
260*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[SUM:r0]], #0
261*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movs [[IV:r[0-9]+]], #10
262*9880d681SAndroid Build Coastguard Worker;
263*9880d681SAndroid Build Coastguard Worker; Next BB.
264*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body
265*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[TMP:r[0-9]+]], #1
266*9880d681SAndroid Build Coastguard Worker; CHECK: adds [[SUM]], [[TMP]], [[SUM]]
267*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subs [[IV]], [[IV]], #1
268*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[IV]], #0
269*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP]]
270*9880d681SAndroid Build Coastguard Worker;
271*9880d681SAndroid Build Coastguard Worker; Next BB.
272*9880d681SAndroid Build Coastguard Worker; SUM << 3.
273*9880d681SAndroid Build Coastguard Worker; CHECK: lsls [[SUM]], [[SUM]], #3
274*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: pop {r4, pc}
275*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r4}
276*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r1}
277*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: bx r1
278*9880d681SAndroid Build Coastguard Worker;
279*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue.
280*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T: pop {r4, pc}
281*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T: b [[END_LABEL:LBB[0-9_]+]]
282*9880d681SAndroid Build Coastguard Worker;
283*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else
284*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
285*9880d681SAndroid Build Coastguard Worker; CHECK: lsls r0, r1, #1
286*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {r4, pc}
287*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: [[END_LABEL]]: @ %if.end
288*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r4}
289*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
290*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
291*9880d681SAndroid Build Coastguard Worker;
292*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: {{LBB[0-9_]+}}: @ %if.end
293*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
294*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) {
295*9880d681SAndroid Build Coastguard Workerentry:
296*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
297*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %for.preheader
298*9880d681SAndroid Build Coastguard Worker
299*9880d681SAndroid Build Coastguard Workerfor.preheader:
300*9880d681SAndroid Build Coastguard Worker  tail call void asm "nop", ""()
301*9880d681SAndroid Build Coastguard Worker  br label %for.body
302*9880d681SAndroid Build Coastguard Worker
303*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.body
304*9880d681SAndroid Build Coastguard Worker  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
305*9880d681SAndroid Build Coastguard Worker  %sum.04 = phi i32 [ %add, %for.body ], [ 0, %for.preheader ]
306*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"()
307*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.04
308*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.05, 1
309*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
310*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
313*9880d681SAndroid Build Coastguard Worker  tail call void asm "nop", "~{r4}"()
314*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %add, 3
315*9880d681SAndroid Build Coastguard Worker  br label %if.end
316*9880d681SAndroid Build Coastguard Worker
317*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
318*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
319*9880d681SAndroid Build Coastguard Worker  br label %if.end
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %for.end
322*9880d681SAndroid Build Coastguard Worker  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
323*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.1
324*9880d681SAndroid Build Coastguard Worker}
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Workerdeclare void @somethingElse(...)
327*9880d681SAndroid Build Coastguard Worker
328*9880d681SAndroid Build Coastguard Worker; Check with a more complex case that we do not have restore within the loop and
329*9880d681SAndroid Build Coastguard Worker; save outside.
330*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoRestoreOutsideLoop:
331*9880d681SAndroid Build Coastguard Worker;
332*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp r0, #0
333*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
334*9880d681SAndroid Build Coastguard Worker;
335*9880d681SAndroid Build Coastguard Worker; Prologue code.
336*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4.
337*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, lr}
338*9880d681SAndroid Build Coastguard Worker;
339*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: cmp r0, #0
340*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
341*9880d681SAndroid Build Coastguard Worker;
342*9880d681SAndroid Build Coastguard Worker; SUM is in r0 because it is coalesced with the second
343*9880d681SAndroid Build Coastguard Worker; argument on the else path.
344*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[SUM:r0]], #0
345*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movs [[IV:r[0-9]+]], #10
346*9880d681SAndroid Build Coastguard Worker;
347*9880d681SAndroid Build Coastguard Worker; Next BB.
348*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body
349*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[TMP:r[0-9]+]], #1
350*9880d681SAndroid Build Coastguard Worker; CHECK: adds [[SUM]], [[TMP]], [[SUM]]
351*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: subs [[IV]], [[IV]], #1
352*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[IV]], #0
353*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP]]
354*9880d681SAndroid Build Coastguard Worker;
355*9880d681SAndroid Build Coastguard Worker; Next BB.
356*9880d681SAndroid Build Coastguard Worker; SUM << 3.
357*9880d681SAndroid Build Coastguard Worker; CHECK: lsls [[SUM]], [[SUM]], #3
358*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: pop {r4, pc}
359*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r4}
360*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r1}
361*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: bx r1
362*9880d681SAndroid Build Coastguard Worker;
363*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue.
364*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T: pop {r4, pc}
365*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T: b [[END_LABEL:LBB[0-9_]+]]
366*9880d681SAndroid Build Coastguard Worker;
367*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else
368*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
369*9880d681SAndroid Build Coastguard Worker; CHECK: lsls r0, r1, #1
370*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {r4, pc}
371*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: [[END_LABEL]]: @ %if.end
372*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r4}
373*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
374*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
375*9880d681SAndroid Build Coastguard Worker;
376*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: {{LBB[0-9_]+}}: @ %if.end
377*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
378*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 {
379*9880d681SAndroid Build Coastguard Workerentry:
380*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
381*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %if.then
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
384*9880d681SAndroid Build Coastguard Worker  tail call void asm "nop", "~{r4}"()
385*9880d681SAndroid Build Coastguard Worker  br label %for.body
386*9880d681SAndroid Build Coastguard Worker
387*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %if.then
388*9880d681SAndroid Build Coastguard Worker  %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ]
389*9880d681SAndroid Build Coastguard Worker  %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
390*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"()
391*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.04
392*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.05, 1
393*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
394*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
395*9880d681SAndroid Build Coastguard Worker
396*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
397*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %add, 3
398*9880d681SAndroid Build Coastguard Worker  br label %if.end
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
401*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
402*9880d681SAndroid Build Coastguard Worker  br label %if.end
403*9880d681SAndroid Build Coastguard Worker
404*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %for.end
405*9880d681SAndroid Build Coastguard Worker  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
406*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.1
407*9880d681SAndroid Build Coastguard Worker}
408*9880d681SAndroid Build Coastguard Worker
409*9880d681SAndroid Build Coastguard Worker; Check that we handle function with no frame information correctly.
410*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: emptyFrame:
411*9880d681SAndroid Build Coastguard Worker; CHECK: @ %entry
412*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movs r0, #0
413*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bx lr
414*9880d681SAndroid Build Coastguard Workerdefine i32 @emptyFrame() {
415*9880d681SAndroid Build Coastguard Workerentry:
416*9880d681SAndroid Build Coastguard Worker  ret i32 0
417*9880d681SAndroid Build Coastguard Worker}
418*9880d681SAndroid Build Coastguard Worker
419*9880d681SAndroid Build Coastguard Worker; Check that we handle inline asm correctly.
420*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: inlineAsm:
421*9880d681SAndroid Build Coastguard Worker;
422*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp r0, #0
423*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
424*9880d681SAndroid Build Coastguard Worker;
425*9880d681SAndroid Build Coastguard Worker; Prologue code.
426*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: r4.
427*9880d681SAndroid Build Coastguard Worker; CHECK: push {r4, lr}
428*9880d681SAndroid Build Coastguard Worker;
429*9880d681SAndroid Build Coastguard Worker; DISABLE: cmp r0, #0
430*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
431*9880d681SAndroid Build Coastguard Worker;
432*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[IV:r[0-9]+]], #10
433*9880d681SAndroid Build Coastguard Worker;
434*9880d681SAndroid Build Coastguard Worker; Next BB.
435*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: @ %for.body
436*9880d681SAndroid Build Coastguard Worker; CHECK: movs r4, #1
437*9880d681SAndroid Build Coastguard Worker; CHECK: subs [[IV]], [[IV]], #1
438*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp [[IV]], #0
439*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne [[LOOP]]
440*9880d681SAndroid Build Coastguard Worker;
441*9880d681SAndroid Build Coastguard Worker; Next BB.
442*9880d681SAndroid Build Coastguard Worker; CHECK: movs r0, #0
443*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: pop {r4, pc}
444*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r4}
445*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r1}
446*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: bx r1
447*9880d681SAndroid Build Coastguard Worker;
448*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue.
449*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {r4, pc}
450*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: b [[END_LABEL:LBB[0-9_]+]]
451*9880d681SAndroid Build Coastguard Worker;
452*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else
453*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
454*9880d681SAndroid Build Coastguard Worker; CHECK: lsls r0, r1, #1
455*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {r4, pc}
456*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: [[END_LABEL]]: @ %if.end
457*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r4}
458*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
459*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
460*9880d681SAndroid Build Coastguard Worker;
461*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: {{LBB[0-9_]+}}: @ %if.end
462*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
463*9880d681SAndroid Build Coastguard Workerdefine i32 @inlineAsm(i32 %cond, i32 %N) {
464*9880d681SAndroid Build Coastguard Workerentry:
465*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
466*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %for.preheader
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Workerfor.preheader:
469*9880d681SAndroid Build Coastguard Worker  tail call void asm "nop", ""()
470*9880d681SAndroid Build Coastguard Worker  br label %for.body
471*9880d681SAndroid Build Coastguard Worker
472*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.body
473*9880d681SAndroid Build Coastguard Worker  %i.03 = phi i32 [ %inc, %for.body ], [ 0, %for.preheader ]
474*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "movs r4, #1", "~{r4}"()
475*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.03, 1
476*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
477*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.exit, label %for.body
478*9880d681SAndroid Build Coastguard Worker
479*9880d681SAndroid Build Coastguard Workerfor.exit:
480*9880d681SAndroid Build Coastguard Worker  tail call void asm "nop", ""()
481*9880d681SAndroid Build Coastguard Worker  br label %if.end
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
484*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
485*9880d681SAndroid Build Coastguard Worker  br label %if.end
486*9880d681SAndroid Build Coastguard Worker
487*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %for.body, %if.else
488*9880d681SAndroid Build Coastguard Worker  %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.exit ]
489*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.0
490*9880d681SAndroid Build Coastguard Worker}
491*9880d681SAndroid Build Coastguard Worker
492*9880d681SAndroid Build Coastguard Worker; Check that we handle calls to variadic functions correctly.
493*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: callVariadicFunc:
494*9880d681SAndroid Build Coastguard Worker;
495*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp r0, #0
496*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
497*9880d681SAndroid Build Coastguard Worker;
498*9880d681SAndroid Build Coastguard Worker; Prologue code.
499*9880d681SAndroid Build Coastguard Worker; CHECK: push {[[TMP:r[0-9]+]], lr}
500*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, #16
501*9880d681SAndroid Build Coastguard Worker;
502*9880d681SAndroid Build Coastguard Worker; DISABLE: cmp r0, #0
503*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: beq [[ELSE_LABEL:LBB[0-9_]+]]
504*9880d681SAndroid Build Coastguard Worker;
505*9880d681SAndroid Build Coastguard Worker; Setup of the varags.
506*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[TMP_SP:r[0-9]+]], sp
507*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str r1, {{\[}}[[TMP_SP]]]
508*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str r1, {{\[}}[[TMP_SP]], #4]
509*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str r1, {{\[}}[[TMP_SP]], #8]
510*9880d681SAndroid Build Coastguard Worker; Thumb has quite a strange way for moving stuff
511*9880d681SAndroid Build Coastguard Worker; in around. Oh well, match the current sequence.
512*9880d681SAndroid Build Coastguard Worker; CHECK: push {r1}
513*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: pop {r0}
514*9880d681SAndroid Build Coastguard Worker; CHECK: push {r1}
515*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: pop {r2}
516*9880d681SAndroid Build Coastguard Worker; CHECK: push {r1}
517*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: pop {r3}
518*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bl
519*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsls r0, r0, #3
520*9880d681SAndroid Build Coastguard Worker;
521*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: add sp, #16
522*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: pop {[[TMP]], pc}
523*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {[[TMP]]}
524*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: pop {r1}
525*9880d681SAndroid Build Coastguard Worker; ENABLE-V4T-NEXT: bx r1
526*9880d681SAndroid Build Coastguard Worker;
527*9880d681SAndroid Build Coastguard Worker; Duplicated epilogue.
528*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: add sp, #16
529*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {[[TMP]], pc}
530*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: b [[END_LABEL:LBB[0-9_]+]]
531*9880d681SAndroid Build Coastguard Worker;
532*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else
533*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
534*9880d681SAndroid Build Coastguard Worker; CHECK: lsls r0, r1, #1
535*9880d681SAndroid Build Coastguard Worker;
536*9880d681SAndroid Build Coastguard Worker; Epilogue code.
537*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: {{LBB[0-9_]+}}: @ %if.end
538*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
539*9880d681SAndroid Build Coastguard Worker;
540*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: [[END_LABEL]]: @ %if.end
541*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: add sp, #16
542*9880d681SAndroid Build Coastguard Worker; DISABLE-V5T-NEXT: pop {[[TMP]], pc}
543*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {[[TMP]]}
544*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
545*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
546*9880d681SAndroid Build Coastguard Workerdefine i32 @callVariadicFunc(i32 %cond, i32 %N) {
547*9880d681SAndroid Build Coastguard Workerentry:
548*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
549*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %if.then
550*9880d681SAndroid Build Coastguard Worker
551*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
552*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N)
553*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %call, 3
554*9880d681SAndroid Build Coastguard Worker  br label %if.end
555*9880d681SAndroid Build Coastguard Worker
556*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
557*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
558*9880d681SAndroid Build Coastguard Worker  br label %if.end
559*9880d681SAndroid Build Coastguard Worker
560*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %if.then
561*9880d681SAndroid Build Coastguard Worker  %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ]
562*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.0
563*9880d681SAndroid Build Coastguard Worker}
564*9880d681SAndroid Build Coastguard Worker
565*9880d681SAndroid Build Coastguard Workerdeclare i32 @someVariadicFunc(i32, ...)
566*9880d681SAndroid Build Coastguard Worker
567*9880d681SAndroid Build Coastguard Worker; Make sure we do not insert unreachable code after noreturn function.
568*9880d681SAndroid Build Coastguard Worker; Although this is not incorrect to insert such code, it is useless
569*9880d681SAndroid Build Coastguard Worker; and it hurts the binary size.
570*9880d681SAndroid Build Coastguard Worker;
571*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: noreturn:
572*9880d681SAndroid Build Coastguard Worker; DISABLE: push
573*9880d681SAndroid Build Coastguard Worker;
574*9880d681SAndroid Build Coastguard Worker; CHECK: movs [[TMP:r[0-9]+]], #255
575*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: tst  r0, [[TMP]]
576*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bne      [[ABORT:LBB[0-9_]+]]
577*9880d681SAndroid Build Coastguard Worker;
578*9880d681SAndroid Build Coastguard Worker; CHECK: movs r0, #42
579*9880d681SAndroid Build Coastguard Worker;
580*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
581*9880d681SAndroid Build Coastguard Worker;
582*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: pop
583*9880d681SAndroid Build Coastguard Worker;;
584*9880d681SAndroid Build Coastguard Worker; CHECK: [[ABORT]]: @ %if.abort
585*9880d681SAndroid Build Coastguard Worker;
586*9880d681SAndroid Build Coastguard Worker; ENABLE: push
587*9880d681SAndroid Build Coastguard Worker;
588*9880d681SAndroid Build Coastguard Worker; CHECK: bl
589*9880d681SAndroid Build Coastguard Worker; ENABLE-NOT: pop
590*9880d681SAndroid Build Coastguard Workerdefine i32 @noreturn(i8 signext %bad_thing) {
591*9880d681SAndroid Build Coastguard Workerentry:
592*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i8 %bad_thing, 0
593*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.end, label %if.abort
594*9880d681SAndroid Build Coastguard Worker
595*9880d681SAndroid Build Coastguard Workerif.abort:
596*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 asm sideeffect "movs $0, #1", "=r,~{r4}"()
597*9880d681SAndroid Build Coastguard Worker  tail call void @abort() #0
598*9880d681SAndroid Build Coastguard Worker  unreachable
599*9880d681SAndroid Build Coastguard Worker
600*9880d681SAndroid Build Coastguard Workerif.end:
601*9880d681SAndroid Build Coastguard Worker  ret i32 42
602*9880d681SAndroid Build Coastguard Worker}
603*9880d681SAndroid Build Coastguard Worker
604*9880d681SAndroid Build Coastguard Workerdeclare void @abort() #0
605*9880d681SAndroid Build Coastguard Worker
606*9880d681SAndroid Build Coastguard Workerdefine i32 @b_to_bx(i32 %value) {
607*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: b_to_bx:
608*9880d681SAndroid Build Coastguard Worker; DISABLE: push {r7, lr}
609*9880d681SAndroid Build Coastguard Worker; CHECK: cmp r1, #49
610*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bgt [[ELSE_LABEL:LBB[0-9_]+]]
611*9880d681SAndroid Build Coastguard Worker; ENABLE: push {r7, lr}
612*9880d681SAndroid Build Coastguard Worker
613*9880d681SAndroid Build Coastguard Worker; CHECK: bl
614*9880d681SAndroid Build Coastguard Worker; DISABLE-V5-NEXT: pop {r7, pc}
615*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: b [[END_LABEL:LBB[0-9_]+]]
616*9880d681SAndroid Build Coastguard Worker
617*9880d681SAndroid Build Coastguard Worker; ENABLE-V5-NEXT: pop {r7, pc}
618*9880d681SAndroid Build Coastguard Worker; ENABLE-V4-NEXT: pop {r7}
619*9880d681SAndroid Build Coastguard Worker; ENABLE-V4-NEXT: pop {r1}
620*9880d681SAndroid Build Coastguard Worker; ENABLE-V4-NEXT: bx r1
621*9880d681SAndroid Build Coastguard Worker
622*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: @ %if.else
623*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsls r0, r1, #1
624*9880d681SAndroid Build Coastguard Worker; DISABLE-V5-NEXT: pop {r7, pc}
625*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: [[END_LABEL]]: @ %if.end
626*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r7}
627*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
628*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Worker; ENABLE-V5T-NEXT: {{LBB[0-9_]+}}: @ %if.end
631*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
632*9880d681SAndroid Build Coastguard Worker
633*9880d681SAndroid Build Coastguard Workerentry:
634*9880d681SAndroid Build Coastguard Worker  %cmp = icmp slt i32 %value, 50
635*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %if.then, label %if.else
636*9880d681SAndroid Build Coastguard Worker
637*9880d681SAndroid Build Coastguard Workerif.then:
638*9880d681SAndroid Build Coastguard Worker  %div = sdiv i32 5000, %value
639*9880d681SAndroid Build Coastguard Worker  br label %if.end
640*9880d681SAndroid Build Coastguard Worker
641*9880d681SAndroid Build Coastguard Workerif.else:
642*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %value, 1
643*9880d681SAndroid Build Coastguard Worker  br label %if.end
644*9880d681SAndroid Build Coastguard Worker
645*9880d681SAndroid Build Coastguard Workerif.end:
646*9880d681SAndroid Build Coastguard Worker  %value.addr.0 = phi i32 [ %div, %if.then ], [ %mul, %if.else ]
647*9880d681SAndroid Build Coastguard Worker  ret i32 %value.addr.0
648*9880d681SAndroid Build Coastguard Worker}
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Workerdefine i1 @beq_to_bx(i32* %y, i32 %head) {
651*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: beq_to_bx:
652*9880d681SAndroid Build Coastguard Worker; DISABLE: push {r4, lr}
653*9880d681SAndroid Build Coastguard Worker; CHECK: cmp r2, #0
654*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: beq [[EXIT_LABEL:LBB[0-9_]+]]
655*9880d681SAndroid Build Coastguard Worker; ENABLE: push {r4, lr}
656*9880d681SAndroid Build Coastguard Worker
657*9880d681SAndroid Build Coastguard Worker; CHECK: tst r3, r4
658*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: pop {r4}
659*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: pop {r3}
660*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: mov lr, r3
661*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: beq [[EXIT_LABEL]]
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Worker; CHECK: str r1, [r2]
664*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: movs r0, #0
665*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: [[EXIT_LABEL]]: @ %cleanup
666*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: bx lr
667*9880d681SAndroid Build Coastguard Worker; DISABLE-V5-NEXT: pop {r4, pc}
668*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r4}
669*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: pop {r1}
670*9880d681SAndroid Build Coastguard Worker; DISABLE-V4T-NEXT: bx r1
671*9880d681SAndroid Build Coastguard Worker
672*9880d681SAndroid Build Coastguard Workerentry:
673*9880d681SAndroid Build Coastguard Worker  %cmp = icmp eq i32* %y, null
674*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %cleanup, label %if.end
675*9880d681SAndroid Build Coastguard Worker
676*9880d681SAndroid Build Coastguard Workerif.end:
677*9880d681SAndroid Build Coastguard Worker  %z = load i32, i32* %y, align 4
678*9880d681SAndroid Build Coastguard Worker  %and = and i32 %z, 2
679*9880d681SAndroid Build Coastguard Worker  %cmp2 = icmp eq i32 %and, 0
680*9880d681SAndroid Build Coastguard Worker  br i1 %cmp2, label %cleanup, label %if.end4
681*9880d681SAndroid Build Coastguard Worker
682*9880d681SAndroid Build Coastguard Workerif.end4:
683*9880d681SAndroid Build Coastguard Worker  store i32 %head, i32* %y, align 4
684*9880d681SAndroid Build Coastguard Worker  br label %cleanup
685*9880d681SAndroid Build Coastguard Worker
686*9880d681SAndroid Build Coastguard Workercleanup:
687*9880d681SAndroid Build Coastguard Worker  %retval.0 = phi i1 [ 0, %if.end4 ], [ 1, %entry ], [ 1, %if.end ]
688*9880d681SAndroid Build Coastguard Worker  ret i1 %retval.0
689*9880d681SAndroid Build Coastguard Worker}
690*9880d681SAndroid Build Coastguard Worker
691*9880d681SAndroid Build Coastguard Workerattributes #0 = { noreturn nounwind }
692