xref: /aosp_15_r20/external/llvm/test/CodeGen/AArch64/arm64-shrink-wrapping.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=true -disable-post-ra -disable-fp-elim | FileCheck %s --check-prefix=CHECK --check-prefix=ENABLE
2*9880d681SAndroid Build Coastguard Worker; RUN: llc %s -o - -enable-shrink-wrap=false -disable-post-ra -disable-fp-elim | FileCheck %s --check-prefix=CHECK --check-prefix=DISABLE
3*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
4*9880d681SAndroid Build Coastguard Workertarget triple = "arm64-apple-ios"
5*9880d681SAndroid Build Coastguard Worker
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker; Initial motivating example: Simple diamond with a call just on one side.
8*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo:
9*9880d681SAndroid Build Coastguard Worker;
10*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
11*9880d681SAndroid Build Coastguard Worker; No prologue needed.
12*9880d681SAndroid Build Coastguard Worker; ENABLE: cmp w0, w1
13*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: b.ge [[EXIT_LABEL:LBB[0-9_]+]]
14*9880d681SAndroid Build Coastguard Worker;
15*9880d681SAndroid Build Coastguard Worker; Prologue code.
16*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #32
17*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[SAVE_SP:x[0-9]+]], [[CSR:x[0-9]+]], [sp, #16]
18*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SAVE_SP]], sp, #16
19*9880d681SAndroid Build Coastguard Worker;
20*9880d681SAndroid Build Coastguard Worker; Compare the arguments and jump to exit.
21*9880d681SAndroid Build Coastguard Worker; After the prologue is set.
22*9880d681SAndroid Build Coastguard Worker; DISABLE: cmp w0, w1
23*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: b.ge [[EXIT_LABEL:LBB[0-9_]+]]
24*9880d681SAndroid Build Coastguard Worker;
25*9880d681SAndroid Build Coastguard Worker; Store %a in the alloca.
26*9880d681SAndroid Build Coastguard Worker; CHECK: stur w0, {{\[}}[[SAVE_SP]], #-4]
27*9880d681SAndroid Build Coastguard Worker; Set the alloca address in the second argument.
28*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub x1, [[SAVE_SP]], #4
29*9880d681SAndroid Build Coastguard Worker; Set the first argument to zero.
30*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov w0, wzr
31*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bl _doSomething
32*9880d681SAndroid Build Coastguard Worker;
33*9880d681SAndroid Build Coastguard Worker; Without shrink-wrapping, epilogue is in the exit block.
34*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EXIT_LABEL]]:
35*9880d681SAndroid Build Coastguard Worker; Epilogue code.
36*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp x{{[0-9]+}}, [[CSR]], [sp, #16]
37*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add sp, sp, #32
38*9880d681SAndroid Build Coastguard Worker;
39*9880d681SAndroid Build Coastguard Worker; With shrink-wrapping, exit block is a simple return.
40*9880d681SAndroid Build Coastguard Worker; ENABLE: [[EXIT_LABEL]]:
41*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
42*9880d681SAndroid Build Coastguard Workerdefine i32 @foo(i32 %a, i32 %b) {
43*9880d681SAndroid Build Coastguard Worker  %tmp = alloca i32, align 4
44*9880d681SAndroid Build Coastguard Worker  %tmp2 = icmp slt i32 %a, %b
45*9880d681SAndroid Build Coastguard Worker  br i1 %tmp2, label %true, label %false
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Workertrue:
48*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %tmp, align 4
49*9880d681SAndroid Build Coastguard Worker  %tmp4 = call i32 @doSomething(i32 0, i32* %tmp)
50*9880d681SAndroid Build Coastguard Worker  br label %false
51*9880d681SAndroid Build Coastguard Worker
52*9880d681SAndroid Build Coastguard Workerfalse:
53*9880d681SAndroid Build Coastguard Worker  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
54*9880d681SAndroid Build Coastguard Worker  ret i32 %tmp.0
55*9880d681SAndroid Build Coastguard Worker}
56*9880d681SAndroid Build Coastguard Worker
57*9880d681SAndroid Build Coastguard Worker; Function Attrs: optsize
58*9880d681SAndroid Build Coastguard Workerdeclare i32 @doSomething(i32, i32*)
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker; Check that we do not perform the restore inside the loop whereas the save
62*9880d681SAndroid Build Coastguard Worker; is outside.
63*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: freqSaveAndRestoreOutsideLoop:
64*9880d681SAndroid Build Coastguard Worker;
65*9880d681SAndroid Build Coastguard Worker; Shrink-wrapping allows to skip the prologue in the else case.
66*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
67*9880d681SAndroid Build Coastguard Worker;
68*9880d681SAndroid Build Coastguard Worker; Prologue code.
69*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]!
70*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16]
71*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16
72*9880d681SAndroid Build Coastguard Worker;
73*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
74*9880d681SAndroid Build Coastguard Worker;
75*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SUM:w[0-9]+]], wzr
76*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[IV:w[0-9]+]], #10
77*9880d681SAndroid Build Coastguard Worker;
78*9880d681SAndroid Build Coastguard Worker; Next BB.
79*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP:LBB[0-9_]+]]: ; %for.body
80*9880d681SAndroid Build Coastguard Worker; CHECK: bl _something
81*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], w0, [[SUM]]
82*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[IV]], [[IV]], #1
83*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP]]
84*9880d681SAndroid Build Coastguard Worker;
85*9880d681SAndroid Build Coastguard Worker; Next BB.
86*9880d681SAndroid Build Coastguard Worker; Copy SUM into the returned register + << 3.
87*9880d681SAndroid Build Coastguard Worker; CHECK: lsl w0, [[SUM]], #3
88*9880d681SAndroid Build Coastguard Worker;
89*9880d681SAndroid Build Coastguard Worker; Jump to epilogue.
90*9880d681SAndroid Build Coastguard Worker; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]]
91*9880d681SAndroid Build Coastguard Worker;
92*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else
93*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
94*9880d681SAndroid Build Coastguard Worker; DISABLE: lsl w0, w1, #1
95*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EPILOG_BB]]: ; %if.end
96*9880d681SAndroid Build Coastguard Worker;
97*9880d681SAndroid Build Coastguard Worker; Epilogue code.
98*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[CSR3]], [[CSR4]], [sp, #16]
99*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32
100*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
101*9880d681SAndroid Build Coastguard Worker;
102*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else
103*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
104*9880d681SAndroid Build Coastguard Worker; ENABLE: lsl w0, w1, #1
105*9880d681SAndroid Build Coastguard Worker; ENABLE: ret
106*9880d681SAndroid Build Coastguard Workerdefine i32 @freqSaveAndRestoreOutsideLoop(i32 %cond, i32 %N) {
107*9880d681SAndroid Build Coastguard Workerentry:
108*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
109*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %for.body
110*9880d681SAndroid Build Coastguard Worker
111*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.body
112*9880d681SAndroid Build Coastguard Worker  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
113*9880d681SAndroid Build Coastguard Worker  %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ]
114*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)()
115*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.04
116*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.05, 1
117*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
118*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
119*9880d681SAndroid Build Coastguard Worker
120*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
121*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %add, 3
122*9880d681SAndroid Build Coastguard Worker  br label %if.end
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
125*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
126*9880d681SAndroid Build Coastguard Worker  br label %if.end
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %for.end
129*9880d681SAndroid Build Coastguard Worker  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
130*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.1
131*9880d681SAndroid Build Coastguard Worker}
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Workerdeclare i32 @something(...)
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker; Check that we do not perform the shrink-wrapping inside the loop even
136*9880d681SAndroid Build Coastguard Worker; though that would be legal. The cost model must prevent that.
137*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: freqSaveAndRestoreOutsideLoop2:
138*9880d681SAndroid Build Coastguard Worker; Prologue code.
139*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]!
140*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16]
141*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16
142*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SUM:w[0-9]+]], wzr
143*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[IV:w[0-9]+]], #10
144*9880d681SAndroid Build Coastguard Worker; Next BB.
145*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body
146*9880d681SAndroid Build Coastguard Worker; CHECK: bl _something
147*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], w0, [[SUM]]
148*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[IV]], [[IV]], #1
149*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP_LABEL]]
150*9880d681SAndroid Build Coastguard Worker; Next BB.
151*9880d681SAndroid Build Coastguard Worker; CHECK: ; %for.end
152*9880d681SAndroid Build Coastguard Worker; CHECK: mov w0, [[SUM]]
153*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR3]], [[CSR4]], [sp, #16]
154*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32
155*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
156*9880d681SAndroid Build Coastguard Workerdefine i32 @freqSaveAndRestoreOutsideLoop2(i32 %cond) {
157*9880d681SAndroid Build Coastguard Workerentry:
158*9880d681SAndroid Build Coastguard Worker  br label %for.body
159*9880d681SAndroid Build Coastguard Worker
160*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
161*9880d681SAndroid Build Coastguard Worker  %i.04 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
162*9880d681SAndroid Build Coastguard Worker  %sum.03 = phi i32 [ 0, %entry ], [ %add, %for.body ]
163*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)()
164*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.03
165*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.04, 1
166*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
167*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
168*9880d681SAndroid Build Coastguard Worker
169*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
170*9880d681SAndroid Build Coastguard Worker  ret i32 %add
171*9880d681SAndroid Build Coastguard Worker}
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker; Check with a more complex case that we do not have save within the loop and
174*9880d681SAndroid Build Coastguard Worker; restore outside.
175*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoSaveOutsideLoop:
176*9880d681SAndroid Build Coastguard Worker;
177*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
178*9880d681SAndroid Build Coastguard Worker;
179*9880d681SAndroid Build Coastguard Worker; Prologue code.
180*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]!
181*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16]
182*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16
183*9880d681SAndroid Build Coastguard Worker;
184*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
185*9880d681SAndroid Build Coastguard Worker;
186*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SUM:w[0-9]+]], wzr
187*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[IV:w[0-9]+]], #10
188*9880d681SAndroid Build Coastguard Worker;
189*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body
190*9880d681SAndroid Build Coastguard Worker; CHECK: bl _something
191*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], w0, [[SUM]]
192*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[IV]], [[IV]], #1
193*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP_LABEL]]
194*9880d681SAndroid Build Coastguard Worker; Next BB.
195*9880d681SAndroid Build Coastguard Worker; CHECK: bl _somethingElse
196*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl w0, [[SUM]], #3
197*9880d681SAndroid Build Coastguard Worker;
198*9880d681SAndroid Build Coastguard Worker; Jump to epilogue.
199*9880d681SAndroid Build Coastguard Worker; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]]
200*9880d681SAndroid Build Coastguard Worker;
201*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else
202*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
203*9880d681SAndroid Build Coastguard Worker; DISABLE: lsl w0, w1, #1
204*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EPILOG_BB]]: ; %if.end
205*9880d681SAndroid Build Coastguard Worker; Epilogue code.
206*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR3]], [[CSR4]], [sp, #16]
207*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32
208*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
209*9880d681SAndroid Build Coastguard Worker;
210*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else
211*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
212*9880d681SAndroid Build Coastguard Worker; ENABLE: lsl w0, w1, #1
213*9880d681SAndroid Build Coastguard Worker; ENABLE: ret
214*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoSaveOutsideLoop(i32 %cond, i32 %N) {
215*9880d681SAndroid Build Coastguard Workerentry:
216*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
217*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %for.body
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.body
220*9880d681SAndroid Build Coastguard Worker  %i.05 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
221*9880d681SAndroid Build Coastguard Worker  %sum.04 = phi i32 [ %add, %for.body ], [ 0, %entry ]
222*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)()
223*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.04
224*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.05, 1
225*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
226*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
229*9880d681SAndroid Build Coastguard Worker  tail call void bitcast (void (...)* @somethingElse to void ()*)()
230*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %add, 3
231*9880d681SAndroid Build Coastguard Worker  br label %if.end
232*9880d681SAndroid Build Coastguard Worker
233*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
234*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
235*9880d681SAndroid Build Coastguard Worker  br label %if.end
236*9880d681SAndroid Build Coastguard Worker
237*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %for.end
238*9880d681SAndroid Build Coastguard Worker  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
239*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.1
240*9880d681SAndroid Build Coastguard Worker}
241*9880d681SAndroid Build Coastguard Worker
242*9880d681SAndroid Build Coastguard Workerdeclare void @somethingElse(...)
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker; Check with a more complex case that we do not have restore within the loop and
245*9880d681SAndroid Build Coastguard Worker; save outside.
246*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: loopInfoRestoreOutsideLoop:
247*9880d681SAndroid Build Coastguard Worker;
248*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
249*9880d681SAndroid Build Coastguard Worker;
250*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #-32]!
251*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR3:x[0-9]+]], [[CSR4:x[0-9]+]], [sp, #16]
252*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #16
253*9880d681SAndroid Build Coastguard Worker;
254*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
255*9880d681SAndroid Build Coastguard Worker;
256*9880d681SAndroid Build Coastguard Worker; CHECK: bl _somethingElse
257*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[SUM:w[0-9]+]], wzr
258*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov [[IV:w[0-9]+]], #10
259*9880d681SAndroid Build Coastguard Worker;
260*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body
261*9880d681SAndroid Build Coastguard Worker; CHECK: bl _something
262*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], w0, [[SUM]]
263*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub [[IV]], [[IV]], #1
264*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP_LABEL]]
265*9880d681SAndroid Build Coastguard Worker; Next BB.
266*9880d681SAndroid Build Coastguard Worker; CHECK: lsl w0, [[SUM]], #3
267*9880d681SAndroid Build Coastguard Worker;
268*9880d681SAndroid Build Coastguard Worker; Jump to epilogue.
269*9880d681SAndroid Build Coastguard Worker; DISABLE: b [[EPILOG_BB:LBB[0-9_]+]]
270*9880d681SAndroid Build Coastguard Worker;
271*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else
272*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
273*9880d681SAndroid Build Coastguard Worker; DISABLE: lsl w0, w1, #1
274*9880d681SAndroid Build Coastguard Worker; DISABLE: [[EPILOG_BB]]: ; %if.end
275*9880d681SAndroid Build Coastguard Worker; Epilogue code.
276*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[CSR3]], [[CSR4]], [sp, #16]
277*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #32
278*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
279*9880d681SAndroid Build Coastguard Worker;
280*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else
281*9880d681SAndroid Build Coastguard Worker; Shift second argument by one and store into returned register.
282*9880d681SAndroid Build Coastguard Worker; ENABLE: lsl w0, w1, #1
283*9880d681SAndroid Build Coastguard Worker; ENABLE: ret
284*9880d681SAndroid Build Coastguard Workerdefine i32 @loopInfoRestoreOutsideLoop(i32 %cond, i32 %N) #0 {
285*9880d681SAndroid Build Coastguard Workerentry:
286*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
287*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %if.then
288*9880d681SAndroid Build Coastguard Worker
289*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
290*9880d681SAndroid Build Coastguard Worker  tail call void bitcast (void (...)* @somethingElse to void ()*)()
291*9880d681SAndroid Build Coastguard Worker  br label %for.body
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %if.then
294*9880d681SAndroid Build Coastguard Worker  %i.05 = phi i32 [ 0, %if.then ], [ %inc, %for.body ]
295*9880d681SAndroid Build Coastguard Worker  %sum.04 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
296*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)()
297*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.04
298*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.05, 1
299*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
300*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body
303*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %add, 3
304*9880d681SAndroid Build Coastguard Worker  br label %if.end
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
307*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
308*9880d681SAndroid Build Coastguard Worker  br label %if.end
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %for.end
311*9880d681SAndroid Build Coastguard Worker  %sum.1 = phi i32 [ %shl, %for.end ], [ %mul, %if.else ]
312*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.1
313*9880d681SAndroid Build Coastguard Worker}
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker; Check that we handle function with no frame information correctly.
316*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: emptyFrame:
317*9880d681SAndroid Build Coastguard Worker; CHECK: ; %entry
318*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov w0, wzr
319*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
320*9880d681SAndroid Build Coastguard Workerdefine i32 @emptyFrame() {
321*9880d681SAndroid Build Coastguard Workerentry:
322*9880d681SAndroid Build Coastguard Worker  ret i32 0
323*9880d681SAndroid Build Coastguard Worker}
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker; Check that we handle variadic function correctly.
326*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: variadicFunc:
327*9880d681SAndroid Build Coastguard Worker;
328*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
329*9880d681SAndroid Build Coastguard Worker;
330*9880d681SAndroid Build Coastguard Worker; Prologue code.
331*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #16
332*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
333*9880d681SAndroid Build Coastguard Worker;
334*9880d681SAndroid Build Coastguard Worker; Sum is merged with the returned register.
335*9880d681SAndroid Build Coastguard Worker; CHECK: add [[VA_BASE:x[0-9]+]], sp, #16
336*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[VA_BASE]], [sp, #8]
337*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cmp w1, #1
338*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: b.lt [[IFEND_LABEL:LBB[0-9_]+]]
339*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[SUM:w0]], wzr
340*9880d681SAndroid Build Coastguard Worker;
341*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body
342*9880d681SAndroid Build Coastguard Worker; CHECK: ldr [[VA_ADDR:x[0-9]+]], [sp, #8]
343*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEXT_VA_ADDR:x[0-9]+]], [[VA_ADDR]], #8
344*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: str [[NEXT_VA_ADDR]], [sp, #8]
345*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldr [[VA_VAL:w[0-9]+]], {{\[}}[[VA_ADDR]]]
346*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[SUM]], [[SUM]], [[VA_VAL]]
347*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: sub w1, w1, #1
348*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz w1, [[LOOP_LABEL]]
349*9880d681SAndroid Build Coastguard Worker;
350*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: b
351*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else
352*9880d681SAndroid Build Coastguard Worker; DISABLE: lsl w0, w1, #1
353*9880d681SAndroid Build Coastguard Worker;
354*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else
355*9880d681SAndroid Build Coastguard Worker; ENABLE: lsl w0, w1, #1
356*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: ret
357*9880d681SAndroid Build Coastguard Worker;
358*9880d681SAndroid Build Coastguard Worker; CHECK: [[IFEND_LABEL]]:
359*9880d681SAndroid Build Coastguard Worker; Epilogue code.
360*9880d681SAndroid Build Coastguard Worker; CHECK: add sp, sp, #16
361*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
362*9880d681SAndroid Build Coastguard Workerdefine i32 @variadicFunc(i32 %cond, i32 %count, ...) #0 {
363*9880d681SAndroid Build Coastguard Workerentry:
364*9880d681SAndroid Build Coastguard Worker  %ap = alloca i8*, align 8
365*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
366*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %if.then
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
369*9880d681SAndroid Build Coastguard Worker  %ap1 = bitcast i8** %ap to i8*
370*9880d681SAndroid Build Coastguard Worker  call void @llvm.va_start(i8* %ap1)
371*9880d681SAndroid Build Coastguard Worker  %cmp6 = icmp sgt i32 %count, 0
372*9880d681SAndroid Build Coastguard Worker  br i1 %cmp6, label %for.body, label %for.end
373*9880d681SAndroid Build Coastguard Worker
374*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %if.then, %for.body
375*9880d681SAndroid Build Coastguard Worker  %i.08 = phi i32 [ %inc, %for.body ], [ 0, %if.then ]
376*9880d681SAndroid Build Coastguard Worker  %sum.07 = phi i32 [ %add, %for.body ], [ 0, %if.then ]
377*9880d681SAndroid Build Coastguard Worker  %0 = va_arg i8** %ap, i32
378*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %sum.07, %0
379*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.08, 1
380*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, %count
381*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %for.end, label %for.body
382*9880d681SAndroid Build Coastguard Worker
383*9880d681SAndroid Build Coastguard Workerfor.end:                                          ; preds = %for.body, %if.then
384*9880d681SAndroid Build Coastguard Worker  %sum.0.lcssa = phi i32 [ 0, %if.then ], [ %add, %for.body ]
385*9880d681SAndroid Build Coastguard Worker  call void @llvm.va_end(i8* %ap1)
386*9880d681SAndroid Build Coastguard Worker  br label %if.end
387*9880d681SAndroid Build Coastguard Worker
388*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
389*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %count, 1
390*9880d681SAndroid Build Coastguard Worker  br label %if.end
391*9880d681SAndroid Build Coastguard Worker
392*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %for.end
393*9880d681SAndroid Build Coastguard Worker  %sum.1 = phi i32 [ %sum.0.lcssa, %for.end ], [ %mul, %if.else ]
394*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.1
395*9880d681SAndroid Build Coastguard Worker}
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_start(i8*)
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.va_end(i8*)
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker; Check that we handle inline asm correctly.
402*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: inlineAsm:
403*9880d681SAndroid Build Coastguard Worker;
404*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
405*9880d681SAndroid Build Coastguard Worker;
406*9880d681SAndroid Build Coastguard Worker; Prologue code.
407*9880d681SAndroid Build Coastguard Worker; Make sure we save the CSR used in the inline asm: x19.
408*9880d681SAndroid Build Coastguard Worker; CHECK: stp [[CSR1:x[0-9]+]], [[CSR2:x19]], [sp, #-16]!
409*9880d681SAndroid Build Coastguard Worker;
410*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
411*9880d681SAndroid Build Coastguard Worker;
412*9880d681SAndroid Build Coastguard Worker; CHECK: mov [[IV:w[0-9]+]], #10
413*9880d681SAndroid Build Coastguard Worker;
414*9880d681SAndroid Build Coastguard Worker; CHECK: [[LOOP_LABEL:LBB[0-9_]+]]: ; %for.body
415*9880d681SAndroid Build Coastguard Worker; Inline asm statement.
416*9880d681SAndroid Build Coastguard Worker; CHECK: add x19, x19, #1
417*9880d681SAndroid Build Coastguard Worker; CHECK: sub [[IV]], [[IV]], #1
418*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[IV]], [[LOOP_LABEL]]
419*9880d681SAndroid Build Coastguard Worker; Next BB.
420*9880d681SAndroid Build Coastguard Worker; CHECK: mov w0, wzr
421*9880d681SAndroid Build Coastguard Worker; Epilogue code.
422*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #16
423*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
424*9880d681SAndroid Build Coastguard Worker; Next BB.
425*9880d681SAndroid Build Coastguard Worker; CHECK: [[ELSE_LABEL]]: ; %if.else
426*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl w0, w1, #1
427*9880d681SAndroid Build Coastguard Worker; Epilogue code.
428*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: ldp [[CSR1]], [[CSR2]], [sp], #16
429*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
430*9880d681SAndroid Build Coastguard Workerdefine i32 @inlineAsm(i32 %cond, i32 %N) {
431*9880d681SAndroid Build Coastguard Workerentry:
432*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
433*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %for.body
434*9880d681SAndroid Build Coastguard Worker
435*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %entry, %for.body
436*9880d681SAndroid Build Coastguard Worker  %i.03 = phi i32 [ %inc, %for.body ], [ 0, %entry ]
437*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "add x19, x19, #1", "~{x19}"()
438*9880d681SAndroid Build Coastguard Worker  %inc = add nuw nsw i32 %i.03, 1
439*9880d681SAndroid Build Coastguard Worker  %exitcond = icmp eq i32 %inc, 10
440*9880d681SAndroid Build Coastguard Worker  br i1 %exitcond, label %if.end, label %for.body
441*9880d681SAndroid Build Coastguard Worker
442*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
443*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
444*9880d681SAndroid Build Coastguard Worker  br label %if.end
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %for.body, %if.else
447*9880d681SAndroid Build Coastguard Worker  %sum.0 = phi i32 [ %mul, %if.else ], [ 0, %for.body ]
448*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.0
449*9880d681SAndroid Build Coastguard Worker}
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker; Check that we handle calls to variadic functions correctly.
452*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: callVariadicFunc:
453*9880d681SAndroid Build Coastguard Worker;
454*9880d681SAndroid Build Coastguard Worker; ENABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
455*9880d681SAndroid Build Coastguard Worker;
456*9880d681SAndroid Build Coastguard Worker; Prologue code.
457*9880d681SAndroid Build Coastguard Worker; CHECK: sub sp, sp, #64
458*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp [[CSR1:x[0-9]+]], [[CSR2:x[0-9]+]], [sp, #48]
459*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add [[NEW_SP:x[0-9]+]], sp, #48
460*9880d681SAndroid Build Coastguard Worker;
461*9880d681SAndroid Build Coastguard Worker; DISABLE: cbz w0, [[ELSE_LABEL:LBB[0-9_]+]]
462*9880d681SAndroid Build Coastguard Worker; Setup of the varags.
463*9880d681SAndroid Build Coastguard Worker; CHECK: stp x1, x1, [sp, #32]
464*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp x1, x1, [sp, #16]
465*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: stp x1, x1, [sp]
466*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: mov w0, w1
467*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: bl _someVariadicFunc
468*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: lsl w0, w0, #3
469*9880d681SAndroid Build Coastguard Worker;
470*9880d681SAndroid Build Coastguard Worker; DISABLE: b [[IFEND_LABEL:LBB[0-9_]+]]
471*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ELSE_LABEL]]: ; %if.else
472*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: lsl w0, w1, #1
473*9880d681SAndroid Build Coastguard Worker; DISABLE: [[IFEND_LABEL]]: ; %if.end
474*9880d681SAndroid Build Coastguard Worker;
475*9880d681SAndroid Build Coastguard Worker; Epilogue code.
476*9880d681SAndroid Build Coastguard Worker; CHECK: ldp [[CSR1]], [[CSR2]], [sp, #48]
477*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: add sp, sp, #64
478*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
479*9880d681SAndroid Build Coastguard Worker;
480*9880d681SAndroid Build Coastguard Worker; ENABLE: [[ELSE_LABEL]]: ; %if.else
481*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: lsl w0, w1, #1
482*9880d681SAndroid Build Coastguard Worker; ENABLE-NEXT: ret
483*9880d681SAndroid Build Coastguard Workerdefine i32 @callVariadicFunc(i32 %cond, i32 %N) {
484*9880d681SAndroid Build Coastguard Workerentry:
485*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i32 %cond, 0
486*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.else, label %if.then
487*9880d681SAndroid Build Coastguard Worker
488*9880d681SAndroid Build Coastguard Workerif.then:                                          ; preds = %entry
489*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 (i32, ...) @someVariadicFunc(i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N, i32 %N)
490*9880d681SAndroid Build Coastguard Worker  %shl = shl i32 %call, 3
491*9880d681SAndroid Build Coastguard Worker  br label %if.end
492*9880d681SAndroid Build Coastguard Worker
493*9880d681SAndroid Build Coastguard Workerif.else:                                          ; preds = %entry
494*9880d681SAndroid Build Coastguard Worker  %mul = shl nsw i32 %N, 1
495*9880d681SAndroid Build Coastguard Worker  br label %if.end
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Workerif.end:                                           ; preds = %if.else, %if.then
498*9880d681SAndroid Build Coastguard Worker  %sum.0 = phi i32 [ %shl, %if.then ], [ %mul, %if.else ]
499*9880d681SAndroid Build Coastguard Worker  ret i32 %sum.0
500*9880d681SAndroid Build Coastguard Worker}
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Workerdeclare i32 @someVariadicFunc(i32, ...)
503*9880d681SAndroid Build Coastguard Worker
504*9880d681SAndroid Build Coastguard Worker; Make sure we do not insert unreachable code after noreturn function.
505*9880d681SAndroid Build Coastguard Worker; Although this is not incorrect to insert such code, it is useless
506*9880d681SAndroid Build Coastguard Worker; and it hurts the binary size.
507*9880d681SAndroid Build Coastguard Worker;
508*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: noreturn:
509*9880d681SAndroid Build Coastguard Worker; DISABLE: stp
510*9880d681SAndroid Build Coastguard Worker;
511*9880d681SAndroid Build Coastguard Worker; CHECK: and [[TEST:w[0-9]+]], w0, #0xff
512*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: cbnz [[TEST]], [[ABORT:LBB[0-9_]+]]
513*9880d681SAndroid Build Coastguard Worker;
514*9880d681SAndroid Build Coastguard Worker; CHECK: mov w0, #42
515*9880d681SAndroid Build Coastguard Worker;
516*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: ldp
517*9880d681SAndroid Build Coastguard Worker;
518*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: ret
519*9880d681SAndroid Build Coastguard Worker;
520*9880d681SAndroid Build Coastguard Worker; CHECK: [[ABORT]]: ; %if.abort
521*9880d681SAndroid Build Coastguard Worker;
522*9880d681SAndroid Build Coastguard Worker; ENABLE: stp
523*9880d681SAndroid Build Coastguard Worker;
524*9880d681SAndroid Build Coastguard Worker; CHECK: bl _abort
525*9880d681SAndroid Build Coastguard Worker; ENABLE-NOT: ldp
526*9880d681SAndroid Build Coastguard Workerdefine i32 @noreturn(i8 signext %bad_thing) {
527*9880d681SAndroid Build Coastguard Workerentry:
528*9880d681SAndroid Build Coastguard Worker  %tobool = icmp eq i8 %bad_thing, 0
529*9880d681SAndroid Build Coastguard Worker  br i1 %tobool, label %if.end, label %if.abort
530*9880d681SAndroid Build Coastguard Worker
531*9880d681SAndroid Build Coastguard Workerif.abort:
532*9880d681SAndroid Build Coastguard Worker  tail call void @abort() #0
533*9880d681SAndroid Build Coastguard Worker  unreachable
534*9880d681SAndroid Build Coastguard Worker
535*9880d681SAndroid Build Coastguard Workerif.end:
536*9880d681SAndroid Build Coastguard Worker  ret i32 42
537*9880d681SAndroid Build Coastguard Worker}
538*9880d681SAndroid Build Coastguard Worker
539*9880d681SAndroid Build Coastguard Workerdeclare void @abort() #0
540*9880d681SAndroid Build Coastguard Worker
541*9880d681SAndroid Build Coastguard Workerattributes #0 = { noreturn nounwind }
542*9880d681SAndroid Build Coastguard Worker
543*9880d681SAndroid Build Coastguard Worker; Make sure that we handle infinite loops properly When checking that the Save
544*9880d681SAndroid Build Coastguard Worker; and Restore blocks are control flow equivalent, the loop searches for the
545*9880d681SAndroid Build Coastguard Worker; immediate (post) dominator for the (restore) save blocks. When either the Save
546*9880d681SAndroid Build Coastguard Worker; or Restore block is located in an infinite loop the only immediate (post)
547*9880d681SAndroid Build Coastguard Worker; dominator is itself. In this case, we cannot perform shrink wrapping, but we
548*9880d681SAndroid Build Coastguard Worker; should return gracefully and continue compilation.
549*9880d681SAndroid Build Coastguard Worker; The only condition for this test is the compilation finishes correctly.
550*9880d681SAndroid Build Coastguard Worker;
551*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop
552*9880d681SAndroid Build Coastguard Worker; CHECK: ret
553*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop() {
554*9880d681SAndroid Build Coastguard Workerentry:
555*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %if.then, label %if.end
556*9880d681SAndroid Build Coastguard Worker
557*9880d681SAndroid Build Coastguard Workerif.then:
558*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i32, i32 4
559*9880d681SAndroid Build Coastguard Worker  br label %for.body
560*9880d681SAndroid Build Coastguard Worker
561*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
562*9880d681SAndroid Build Coastguard Worker  %sum.03 = phi i32 [ 0, %if.then ], [ %add, %for.body ]
563*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 bitcast (i32 (...)* @something to i32 ()*)()
564*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.03
565*9880d681SAndroid Build Coastguard Worker  store i32 %add, i32* %ptr
566*9880d681SAndroid Build Coastguard Worker  br label %for.body
567*9880d681SAndroid Build Coastguard Worker
568*9880d681SAndroid Build Coastguard Workerif.end:
569*9880d681SAndroid Build Coastguard Worker  ret void
570*9880d681SAndroid Build Coastguard Worker}
571*9880d681SAndroid Build Coastguard Worker
572*9880d681SAndroid Build Coastguard Worker; Another infinite loop test this time with a body bigger than just one block.
573*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop2
574*9880d681SAndroid Build Coastguard Worker; CHECK: ret
575*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop2() {
576*9880d681SAndroid Build Coastguard Workerentry:
577*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %if.then, label %if.end
578*9880d681SAndroid Build Coastguard Worker
579*9880d681SAndroid Build Coastguard Workerif.then:
580*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i32, i32 4
581*9880d681SAndroid Build Coastguard Worker  br label %for.body
582*9880d681SAndroid Build Coastguard Worker
583*9880d681SAndroid Build Coastguard Workerfor.body:                                         ; preds = %for.body, %entry
584*9880d681SAndroid Build Coastguard Worker  %sum.03 = phi i32 [ 0, %if.then ], [ %add, %body1 ], [ 1, %body2]
585*9880d681SAndroid Build Coastguard Worker  %call = tail call i32 asm "mov $0, #0", "=r,~{x19}"()
586*9880d681SAndroid Build Coastguard Worker  %add = add nsw i32 %call, %sum.03
587*9880d681SAndroid Build Coastguard Worker  store i32 %add, i32* %ptr
588*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %body1, label %body2
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Workerbody1:
591*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "nop", "~{x19}"()
592*9880d681SAndroid Build Coastguard Worker  br label %for.body
593*9880d681SAndroid Build Coastguard Worker
594*9880d681SAndroid Build Coastguard Workerbody2:
595*9880d681SAndroid Build Coastguard Worker  tail call void asm sideeffect "nop", "~{x19}"()
596*9880d681SAndroid Build Coastguard Worker  br label %for.body
597*9880d681SAndroid Build Coastguard Worker
598*9880d681SAndroid Build Coastguard Workerif.end:
599*9880d681SAndroid Build Coastguard Worker  ret void
600*9880d681SAndroid Build Coastguard Worker}
601*9880d681SAndroid Build Coastguard Worker
602*9880d681SAndroid Build Coastguard Worker; Another infinite loop test this time with two nested infinite loop.
603*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: infiniteloop3
604*9880d681SAndroid Build Coastguard Worker; CHECK: ret
605*9880d681SAndroid Build Coastguard Workerdefine void @infiniteloop3() {
606*9880d681SAndroid Build Coastguard Workerentry:
607*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop2a, label %body
608*9880d681SAndroid Build Coastguard Worker
609*9880d681SAndroid Build Coastguard Workerbody:                                             ; preds = %entry
610*9880d681SAndroid Build Coastguard Worker  br i1 undef, label %loop2a, label %end
611*9880d681SAndroid Build Coastguard Worker
612*9880d681SAndroid Build Coastguard Workerloop1:                                            ; preds = %loop2a, %loop2b
613*9880d681SAndroid Build Coastguard Worker  %var.phi = phi i32* [ %next.phi, %loop2b ], [ %var, %loop2a ]
614*9880d681SAndroid Build Coastguard Worker  %next.phi = phi i32* [ %next.load, %loop2b ], [ %next.var, %loop2a ]
615*9880d681SAndroid Build Coastguard Worker  %0 = icmp eq i32* %var, null
616*9880d681SAndroid Build Coastguard Worker  %next.load = load i32*, i32** undef
617*9880d681SAndroid Build Coastguard Worker  br i1 %0, label %loop2a, label %loop2b
618*9880d681SAndroid Build Coastguard Worker
619*9880d681SAndroid Build Coastguard Workerloop2a:                                           ; preds = %loop1, %body, %entry
620*9880d681SAndroid Build Coastguard Worker  %var = phi i32* [ null, %body ], [ null, %entry ], [ %next.phi, %loop1 ]
621*9880d681SAndroid Build Coastguard Worker  %next.var = phi i32* [ undef, %body ], [ null, %entry ], [ %next.load, %loop1 ]
622*9880d681SAndroid Build Coastguard Worker  br label %loop1
623*9880d681SAndroid Build Coastguard Worker
624*9880d681SAndroid Build Coastguard Workerloop2b:                                           ; preds = %loop1
625*9880d681SAndroid Build Coastguard Worker  %gep1 = bitcast i32* %var.phi to i32*
626*9880d681SAndroid Build Coastguard Worker  %next.ptr = bitcast i32* %gep1 to i32**
627*9880d681SAndroid Build Coastguard Worker  store i32* %next.phi, i32** %next.ptr
628*9880d681SAndroid Build Coastguard Worker  br label %loop1
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Workerend:
631*9880d681SAndroid Build Coastguard Worker  ret void
632*9880d681SAndroid Build Coastguard Worker}
633*9880d681SAndroid Build Coastguard Worker
634*9880d681SAndroid Build Coastguard Worker; Re-aligned stack pointer.  See bug 26642.  Avoid clobbering live
635*9880d681SAndroid Build Coastguard Worker; values in the prologue when re-aligning the stack pointer.
636*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: stack_realign:
637*9880d681SAndroid Build Coastguard Worker; ENABLE-DAG: lsl w[[LSL1:[0-9]+]], w0, w1
638*9880d681SAndroid Build Coastguard Worker; ENABLE-DAG: lsl w[[LSL2:[0-9]+]], w1, w0
639*9880d681SAndroid Build Coastguard Worker; DISABLE-NOT: lsl w[[LSL1:[0-9]+]], w0, w1
640*9880d681SAndroid Build Coastguard Worker; DISABLE-NOT: lsl w[[LSL2:[0-9]+]], w1, w0
641*9880d681SAndroid Build Coastguard Worker; CHECK: stp x29, x30, [sp, #-16]!
642*9880d681SAndroid Build Coastguard Worker; CHECK: mov x29, sp
643*9880d681SAndroid Build Coastguard Worker; ENABLE-NOT: sub x[[LSL1]], sp, #16
644*9880d681SAndroid Build Coastguard Worker; ENABLE-NOT: sub x[[LSL2]], sp, #16
645*9880d681SAndroid Build Coastguard Worker; DISABLE: sub x{{[0-9]+}}, sp, #16
646*9880d681SAndroid Build Coastguard Worker; DISABLE-DAG: lsl w[[LSL1:[0-9]+]], w0, w1
647*9880d681SAndroid Build Coastguard Worker; DISABLE-DAG: lsl w[[LSL2:[0-9]+]], w1, w0
648*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: str w[[LSL1]],
649*9880d681SAndroid Build Coastguard Worker; CHECK-DAG: str w[[LSL2]],
650*9880d681SAndroid Build Coastguard Worker
651*9880d681SAndroid Build Coastguard Workerdefine i32 @stack_realign(i32 %a, i32 %b, i32* %ptr1, i32* %ptr2) {
652*9880d681SAndroid Build Coastguard Worker  %tmp = alloca i32, align 32
653*9880d681SAndroid Build Coastguard Worker  %shl1 = shl i32 %a, %b
654*9880d681SAndroid Build Coastguard Worker  %shl2 = shl i32 %b, %a
655*9880d681SAndroid Build Coastguard Worker  %tmp2 = icmp slt i32 %a, %b
656*9880d681SAndroid Build Coastguard Worker  br i1 %tmp2, label %true, label %false
657*9880d681SAndroid Build Coastguard Worker
658*9880d681SAndroid Build Coastguard Workertrue:
659*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %tmp, align 4
660*9880d681SAndroid Build Coastguard Worker  %tmp4 = load i32, i32* %tmp
661*9880d681SAndroid Build Coastguard Worker  br label %false
662*9880d681SAndroid Build Coastguard Worker
663*9880d681SAndroid Build Coastguard Workerfalse:
664*9880d681SAndroid Build Coastguard Worker  %tmp.0 = phi i32 [ %tmp4, %true ], [ %a, %0 ]
665*9880d681SAndroid Build Coastguard Worker  store i32 %shl1, i32* %ptr1
666*9880d681SAndroid Build Coastguard Worker  store i32 %shl2, i32* %ptr2
667*9880d681SAndroid Build Coastguard Worker  ret i32 %tmp.0
668*9880d681SAndroid Build Coastguard Worker}
669*9880d681SAndroid Build Coastguard Worker
670*9880d681SAndroid Build Coastguard Worker; Re-aligned stack pointer with all caller-save regs live.  See bug
671*9880d681SAndroid Build Coastguard Worker; 26642.  In this case we currently avoid shrink wrapping because
672*9880d681SAndroid Build Coastguard Worker; ensuring we have a scratch register to re-align the stack pointer is
673*9880d681SAndroid Build Coastguard Worker; too complicated.  Output should be the same for both enabled and
674*9880d681SAndroid Build Coastguard Worker; disabled shrink wrapping.
675*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: stack_realign2:
676*9880d681SAndroid Build Coastguard Worker; CHECK: stp {{x[0-9]+}}, {{x[0-9]+}}, [sp, #-{{[0-9]+}}]!
677*9880d681SAndroid Build Coastguard Worker; CHECK: add x29, sp, #{{[0-9]+}}
678*9880d681SAndroid Build Coastguard Worker; CHECK: lsl {{w[0-9]+}}, w0, w1
679*9880d681SAndroid Build Coastguard Worker
680*9880d681SAndroid Build Coastguard Workerdefine void @stack_realign2(i32 %a, i32 %b, i32* %ptr1, i32* %ptr2, i32* %ptr3, i32* %ptr4, i32* %ptr5, i32* %ptr6) {
681*9880d681SAndroid Build Coastguard Worker  %tmp = alloca i32, align 32
682*9880d681SAndroid Build Coastguard Worker  %tmp1 = shl i32 %a, %b
683*9880d681SAndroid Build Coastguard Worker  %tmp2 = shl i32 %b, %a
684*9880d681SAndroid Build Coastguard Worker  %tmp3 = lshr i32 %a, %b
685*9880d681SAndroid Build Coastguard Worker  %tmp4 = lshr i32 %b, %a
686*9880d681SAndroid Build Coastguard Worker  %tmp5 = add i32 %b, %a
687*9880d681SAndroid Build Coastguard Worker  %tmp6 = sub i32 %b, %a
688*9880d681SAndroid Build Coastguard Worker  %tmp7 = add i32 %tmp1, %tmp2
689*9880d681SAndroid Build Coastguard Worker  %tmp8 = sub i32 %tmp2, %tmp3
690*9880d681SAndroid Build Coastguard Worker  %tmp9 = add i32 %tmp3, %tmp4
691*9880d681SAndroid Build Coastguard Worker  %tmp10 = add i32 %tmp4, %tmp5
692*9880d681SAndroid Build Coastguard Worker  %cmp = icmp slt i32 %a, %b
693*9880d681SAndroid Build Coastguard Worker  br i1 %cmp, label %true, label %false
694*9880d681SAndroid Build Coastguard Worker
695*9880d681SAndroid Build Coastguard Workertrue:
696*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %tmp, align 4
697*9880d681SAndroid Build Coastguard Worker  call void asm sideeffect "nop", "~{x19},~{x20},~{x21},~{x22},~{x23},~{x24},~{x25},~{x26},~{x27},~{x28}"() nounwind
698*9880d681SAndroid Build Coastguard Worker  br label %false
699*9880d681SAndroid Build Coastguard Worker
700*9880d681SAndroid Build Coastguard Workerfalse:
701*9880d681SAndroid Build Coastguard Worker  store i32 %tmp1, i32* %ptr1, align 4
702*9880d681SAndroid Build Coastguard Worker  store i32 %tmp2, i32* %ptr2, align 4
703*9880d681SAndroid Build Coastguard Worker  store i32 %tmp3, i32* %ptr3, align 4
704*9880d681SAndroid Build Coastguard Worker  store i32 %tmp4, i32* %ptr4, align 4
705*9880d681SAndroid Build Coastguard Worker  store i32 %tmp5, i32* %ptr5, align 4
706*9880d681SAndroid Build Coastguard Worker  store i32 %tmp6, i32* %ptr6, align 4
707*9880d681SAndroid Build Coastguard Worker  %idx1 = getelementptr inbounds i32, i32* %ptr1, i64 1
708*9880d681SAndroid Build Coastguard Worker  store i32 %a, i32* %idx1, align 4
709*9880d681SAndroid Build Coastguard Worker  %idx2 = getelementptr inbounds i32, i32* %ptr1, i64 2
710*9880d681SAndroid Build Coastguard Worker  store i32 %b, i32* %idx2, align 4
711*9880d681SAndroid Build Coastguard Worker  %idx3 = getelementptr inbounds i32, i32* %ptr1, i64 3
712*9880d681SAndroid Build Coastguard Worker  store i32 %tmp7, i32* %idx3, align 4
713*9880d681SAndroid Build Coastguard Worker  %idx4 = getelementptr inbounds i32, i32* %ptr1, i64 4
714*9880d681SAndroid Build Coastguard Worker  store i32 %tmp8, i32* %idx4, align 4
715*9880d681SAndroid Build Coastguard Worker  %idx5 = getelementptr inbounds i32, i32* %ptr1, i64 5
716*9880d681SAndroid Build Coastguard Worker  store i32 %tmp9, i32* %idx5, align 4
717*9880d681SAndroid Build Coastguard Worker  %idx6 = getelementptr inbounds i32, i32* %ptr1, i64 6
718*9880d681SAndroid Build Coastguard Worker  store i32 %tmp10, i32* %idx6, align 4
719*9880d681SAndroid Build Coastguard Worker
720*9880d681SAndroid Build Coastguard Worker  ret void
721*9880d681SAndroid Build Coastguard Worker}
722