1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin | FileCheck %s --check-prefixes=ALL,V01
3 ; RUN: llc < %s -mtriple=thumbv7-apple-darwin -arm-default-it | FileCheck %s --check-prefixes=ALL,V01
4 ; RUN: llc < %s -mtriple=thumbv8 | FileCheck %s --check-prefixes=ALL,V23,V2
5 ; RUN: llc < %s -mtriple=thumbv8 -enable-tail-merge=0 | FileCheck %s --check-prefixes=ALL,V23,V3
7 define i32 @t1(i32 %a, i32 %b, i32 %c, i32 %d) nounwind {
10 ; ALL-NEXT: cmp r2, #1
12 ; ALL-NEXT: cmpne r2, #7
13 ; ALL-NEXT: addne r0, r1
14 ; ALL-NEXT: addeq r0, r1
15 ; ALL-NEXT: addeq r0, #1
17 switch i32 %c, label %cond_next [
18 i32 1, label %cond_true
19 i32 7, label %cond_true
23 %tmp12 = add i32 %a, 1
24 %tmp1518 = add i32 %tmp12, %b
28 %tmp15 = add i32 %b, %a
32 define i32 @t2(i32 %a, i32 %b) nounwind {
34 ; V01: @ %bb.0: @ %entry
35 ; V01-NEXT: cmp r0, r1
38 ; V01-NEXT: LBB1_1: @ %bb
39 ; V01-NEXT: @ =>This Inner Loop Header: Depth=1
40 ; V01-NEXT: cmp r0, r1
42 ; V01-NEXT: subgt r0, r0, r1
43 ; V01-NEXT: suble r1, r1, r0
44 ; V01-NEXT: cmp r1, r0
45 ; V01-NEXT: bne LBB1_1
46 ; V01-NEXT: @ %bb.2: @ %bb17
50 ; V2: @ %bb.0: @ %entry
54 ; V2-NEXT: .LBB1_1: @ %bb
55 ; V2-NEXT: @ =>This Inner Loop Header: Depth=1
58 ; V2-NEXT: subgt r0, r0, r1
59 ; V2-NEXT: suble r1, r1, r0
61 ; V2-NEXT: bne .LBB1_1
62 ; V2-NEXT: @ %bb.2: @ %bb17
66 ; V3: @ %bb.0: @ %entry
70 ; V3-NEXT: .LBB1_1: @ %bb
71 ; V3-NEXT: @ =>This Inner Loop Header: Depth=1
74 ; V3-NEXT: suble r1, r1, r0
75 ; V3-NEXT: subgt r0, r0, r1
77 ; V3-NEXT: bne .LBB1_1
78 ; V3-NEXT: @ %bb.2: @ %bb17
81 %tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1]
82 br i1 %tmp1434, label %bb17, label %bb.outer
84 bb.outer: ; preds = %cond_false, %entry
85 %b_addr.021.0.ph = phi i32 [ %b, %entry ], [ %tmp10, %cond_false ] ; <i32> [#uses=5]
86 %a_addr.026.0.ph = phi i32 [ %a, %entry ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1]
89 bb: ; preds = %cond_true, %bb.outer
90 %indvar = phi i32 [ 0, %bb.outer ], [ %indvar.next, %cond_true ] ; <i32> [#uses=2]
91 %tmp. = sub i32 0, %b_addr.021.0.ph ; <i32> [#uses=1]
92 %tmp.40 = mul i32 %indvar, %tmp. ; <i32> [#uses=1]
93 %a_addr.026.0 = add i32 %tmp.40, %a_addr.026.0.ph ; <i32> [#uses=6]
94 %tmp3 = icmp sgt i32 %a_addr.026.0, %b_addr.021.0.ph ; <i1> [#uses=1]
95 br i1 %tmp3, label %cond_true, label %cond_false
97 cond_true: ; preds = %bb
98 %tmp7 = sub i32 %a_addr.026.0, %b_addr.021.0.ph ; <i32> [#uses=2]
99 %tmp1437 = icmp eq i32 %tmp7, %b_addr.021.0.ph ; <i1> [#uses=1]
100 %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
101 br i1 %tmp1437, label %bb17, label %bb
103 cond_false: ; preds = %bb
104 %tmp10 = sub i32 %b_addr.021.0.ph, %a_addr.026.0 ; <i32> [#uses=2]
105 %tmp14 = icmp eq i32 %a_addr.026.0, %tmp10 ; <i1> [#uses=1]
106 br i1 %tmp14, label %bb17, label %bb.outer
108 bb17: ; preds = %cond_false, %cond_true, %entry
109 %a_addr.026.1 = phi i32 [ %a, %entry ], [ %tmp7, %cond_true ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1]
110 ret i32 %a_addr.026.1
113 define i32 @t2_nomerge(i32 %a, i32 %b) nounwind {
114 ; V01-LABEL: t2_nomerge:
115 ; V01: @ %bb.0: @ %entry
116 ; V01-NEXT: cmp r0, r1
119 ; V01-NEXT: LBB2_1: @ %bb
120 ; V01-NEXT: @ =>This Inner Loop Header: Depth=1
121 ; V01-NEXT: cmp r0, r1
122 ; V01-NEXT: ble LBB2_3
123 ; V01-NEXT: @ %bb.2: @ %cond_true
124 ; V01-NEXT: @ in Loop: Header=BB2_1 Depth=1
125 ; V01-NEXT: subs r0, r0, r1
126 ; V01-NEXT: cmp r1, r0
127 ; V01-NEXT: bne LBB2_1
129 ; V01-NEXT: LBB2_3: @ %cond_false
130 ; V01-NEXT: @ in Loop: Header=BB2_1 Depth=1
131 ; V01-NEXT: subs r1, r1, r0
132 ; V01-NEXT: cmp r0, #0
133 ; V01-NEXT: bne LBB2_1
134 ; V01-NEXT: LBB2_4: @ %bb17
137 ; V2-LABEL: t2_nomerge:
138 ; V2: @ %bb.0: @ %entry
139 ; V2-NEXT: cmp r0, r1
142 ; V2-NEXT: .LBB2_1: @ %bb
143 ; V2-NEXT: @ =>This Inner Loop Header: Depth=1
144 ; V2-NEXT: cmp r0, r1
145 ; V2-NEXT: ble .LBB2_3
146 ; V2-NEXT: @ %bb.2: @ %cond_true
147 ; V2-NEXT: @ in Loop: Header=BB2_1 Depth=1
148 ; V2-NEXT: subs r0, r0, r1
149 ; V2-NEXT: cmp r1, r0
150 ; V2-NEXT: bne .LBB2_1
152 ; V2-NEXT: .LBB2_3: @ %cond_false
153 ; V2-NEXT: @ in Loop: Header=BB2_1 Depth=1
154 ; V2-NEXT: subs r1, r1, r0
155 ; V2-NEXT: cmp r0, #0
156 ; V2-NEXT: bne .LBB2_1
157 ; V2-NEXT: .LBB2_4: @ %bb17
160 ; V3-LABEL: t2_nomerge:
161 ; V3: @ %bb.0: @ %entry
162 ; V3-NEXT: cmp r0, r1
163 ; V3-NEXT: beq .LBB2_4
165 ; V3-NEXT: .LBB2_1: @ %cond_true
166 ; V3-NEXT: @ in Loop: Header=BB2_2 Depth=1
167 ; V3-NEXT: subs r0, r0, r1
168 ; V3-NEXT: cmp r1, r0
171 ; V3-NEXT: .LBB2_2: @ %bb
172 ; V3-NEXT: @ =>This Inner Loop Header: Depth=1
173 ; V3-NEXT: cmp r0, r1
174 ; V3-NEXT: bgt .LBB2_1
175 ; V3-NEXT: @ %bb.3: @ %cond_false
176 ; V3-NEXT: @ in Loop: Header=BB2_2 Depth=1
177 ; V3-NEXT: subs r1, r1, r0
178 ; V3-NEXT: cmp r0, #0
179 ; V3-NEXT: bne .LBB2_2
180 ; V3-NEXT: .LBB2_4: @ %bb17
183 %tmp1434 = icmp eq i32 %a, %b ; <i1> [#uses=1]
184 br i1 %tmp1434, label %bb17, label %bb.outer
186 bb.outer: ; preds = %cond_false, %entry
187 %b_addr.021.0.ph = phi i32 [ %b, %entry ], [ %tmp10, %cond_false ] ; <i32> [#uses=5]
188 %a_addr.026.0.ph = phi i32 [ %a, %entry ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1]
191 bb: ; preds = %cond_true, %bb.outer
192 %indvar = phi i32 [ 0, %bb.outer ], [ %indvar.next, %cond_true ] ; <i32> [#uses=2]
193 %tmp. = sub i32 0, %b_addr.021.0.ph ; <i32> [#uses=1]
194 %tmp.40 = mul i32 %indvar, %tmp. ; <i32> [#uses=1]
195 %a_addr.026.0 = add i32 %tmp.40, %a_addr.026.0.ph ; <i32> [#uses=6]
196 %tmp3 = icmp sgt i32 %a_addr.026.0, %b_addr.021.0.ph ; <i1> [#uses=1]
197 br i1 %tmp3, label %cond_true, label %cond_false
199 cond_true: ; preds = %bb
200 %tmp7 = sub i32 %a_addr.026.0, %b_addr.021.0.ph ; <i32> [#uses=2]
201 %tmp1437 = icmp eq i32 %tmp7, %b_addr.021.0.ph ; <i1> [#uses=1]
202 %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
203 br i1 %tmp1437, label %bb17, label %bb
205 cond_false: ; preds = %bb
206 %tmp10 = sub i32 %b_addr.021.0.ph, %a_addr.026.0 ; <i32> [#uses=2]
207 %tmp14 = icmp eq i32 %b_addr.021.0.ph, %tmp10 ; <i1> [#uses=1]
208 br i1 %tmp14, label %bb17, label %bb.outer
210 bb17: ; preds = %cond_false, %cond_true, %entry
211 %a_addr.026.1 = phi i32 [ %a, %entry ], [ %tmp7, %cond_true ], [ %a_addr.026.0, %cond_false ] ; <i32> [#uses=1]
212 ret i32 %a_addr.026.1
215 @x = external global ptr ; <ptr> [#uses=1]
217 define void @foo(i32 %a) nounwind {
219 ; V01: @ %bb.0: @ %entry
220 ; V01-NEXT: movw r1, :lower16:(L_x$non_lazy_ptr-(LPC3_0+4))
221 ; V01-NEXT: movt r1, :upper16:(L_x$non_lazy_ptr-(LPC3_0+4))
223 ; V01-NEXT: add r1, pc
224 ; V01-NEXT: ldr r1, [r1]
225 ; V01-NEXT: ldr r1, [r1]
226 ; V01-NEXT: str r0, [r1]
230 ; V23: @ %bb.0: @ %entry
231 ; V23-NEXT: movw r1, :lower16:x
232 ; V23-NEXT: movt r1, :upper16:x
233 ; V23-NEXT: ldr r1, [r1]
234 ; V23-NEXT: str r0, [r1]
237 %tmp = load ptr, ptr @x ; <ptr> [#uses=1]
238 store i32 %a, ptr %tmp
242 define void @t3(i32 %a, i32 %b) nounwind {
244 ; V01: @ %bb.0: @ %entry
245 ; V01-NEXT: cmp r0, #10
248 ; V01-NEXT: LBB4_1: @ %cond_true
249 ; V01-NEXT: str lr, [sp, #-4]!
250 ; V01-NEXT: mov r0, r1
252 ; V01-NEXT: ldr lr, [sp], #4
256 ; V23: @ %bb.0: @ %entry
257 ; V23-NEXT: cmp r0, #10
260 ; V23-NEXT: .LBB4_1: @ %cond_true
261 ; V23-NEXT: push {r7, lr}
262 ; V23-NEXT: mov r0, r1
264 ; V23-NEXT: pop.w {r7, lr}
267 %tmp1 = icmp sgt i32 %a, 10 ; <i1> [#uses=1]
268 br i1 %tmp1, label %cond_true, label %UnifiedReturnBlock
270 cond_true: ; preds = %entry
271 call void @foo( i32 %b )
274 UnifiedReturnBlock: ; preds = %entry