1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=thumbv8.main -mcpu=cortex-m33 %s -arm-disable-cgp=false -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NODSP --check-prefix=CHECK-NODSP-V8
3 ; RUN: llc -mtriple=thumbv7-linux-android %s -arm-disable-cgp=false -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NODSP --check-prefix=CHECK-NODSP-V7
4 ; RUN: llc -mtriple=thumbv7em -mcpu=cortex-m7 %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DSP
5 ; RUN: llc -mtriple=thumbv8 %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -arm-enable-scalar-dsp-imms=true -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DSP-IMM
7 ; Transform will fail because the trunc is not a sink.
9 define i16 @dsp_trunc(i32 %arg0, i32 %arg1, i16* %gep0, i16* %gep1) {
10 ; CHECK-NODSP-V8-LABEL: dsp_trunc:
11 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
12 ; CHECK-NODSP-V8-NEXT: add r1, r0
13 ; CHECK-NODSP-V8-NEXT: ldrh r0, [r2]
14 ; CHECK-NODSP-V8-NEXT: ldrh r2, [r3]
15 ; CHECK-NODSP-V8-NEXT: add r0, r1
16 ; CHECK-NODSP-V8-NEXT: subs r1, r2, r1
17 ; CHECK-NODSP-V8-NEXT: uxth r3, r0
18 ; CHECK-NODSP-V8-NEXT: uxth r2, r1
19 ; CHECK-NODSP-V8-NEXT: cmp r3, r2
20 ; CHECK-NODSP-V8-NEXT: it lo
21 ; CHECK-NODSP-V8-NEXT: movlo r0, r1
22 ; CHECK-NODSP-V8-NEXT: bx lr
24 ; CHECK-NODSP-V7-LABEL: dsp_trunc:
25 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
26 ; CHECK-NODSP-V7-NEXT: ldrh r2, [r2]
27 ; CHECK-NODSP-V7-NEXT: add r1, r0
28 ; CHECK-NODSP-V7-NEXT: ldrh r3, [r3]
29 ; CHECK-NODSP-V7-NEXT: adds r0, r2, r1
30 ; CHECK-NODSP-V7-NEXT: subs r1, r3, r1
31 ; CHECK-NODSP-V7-NEXT: uxth r3, r0
32 ; CHECK-NODSP-V7-NEXT: uxth r2, r1
33 ; CHECK-NODSP-V7-NEXT: cmp r3, r2
34 ; CHECK-NODSP-V7-NEXT: it lo
35 ; CHECK-NODSP-V7-NEXT: movlo r0, r1
36 ; CHECK-NODSP-V7-NEXT: bx lr
38 ; CHECK-DSP-LABEL: dsp_trunc:
39 ; CHECK-DSP: @ %bb.0: @ %entry
40 ; CHECK-DSP-NEXT: add r0, r1
41 ; CHECK-DSP-NEXT: ldrh r1, [r3]
42 ; CHECK-DSP-NEXT: ldrh r2, [r2]
43 ; CHECK-DSP-NEXT: subs r1, r1, r0
44 ; CHECK-DSP-NEXT: add r0, r2
45 ; CHECK-DSP-NEXT: uxth r3, r1
46 ; CHECK-DSP-NEXT: uxth r2, r0
47 ; CHECK-DSP-NEXT: cmp r2, r3
48 ; CHECK-DSP-NEXT: it lo
49 ; CHECK-DSP-NEXT: movlo r0, r1
50 ; CHECK-DSP-NEXT: bx lr
52 ; CHECK-DSP-IMM-LABEL: dsp_trunc:
53 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
54 ; CHECK-DSP-IMM-NEXT: add r0, r1
55 ; CHECK-DSP-IMM-NEXT: movs r1, #0
56 ; CHECK-DSP-IMM-NEXT: uxth r0, r0
57 ; CHECK-DSP-IMM-NEXT: usub16 r1, r1, r0
58 ; CHECK-DSP-IMM-NEXT: ldrh r0, [r2]
59 ; CHECK-DSP-IMM-NEXT: ldrh r3, [r3]
60 ; CHECK-DSP-IMM-NEXT: usub16 r0, r0, r1
61 ; CHECK-DSP-IMM-NEXT: uadd16 r1, r3, r1
62 ; CHECK-DSP-IMM-NEXT: cmp r0, r1
63 ; CHECK-DSP-IMM-NEXT: it lo
64 ; CHECK-DSP-IMM-NEXT: movlo r0, r1
65 ; CHECK-DSP-IMM-NEXT: bx lr
67 %add0 = add i32 %arg0, %arg1
68 %conv0 = trunc i32 %add0 to i16
69 %sub0 = sub i16 0, %conv0
70 %load0 = load i16, i16* %gep0, align 2
71 %load1 = load i16, i16* %gep1, align 2
72 %sub1 = sub i16 %load0, %sub0
73 %add1 = add i16 %load1, %sub0
74 %cmp = icmp ult i16 %sub1, %add1
75 %res = select i1 %cmp, i16 %add1, i16 %sub1
79 define i8 @trunc_i16_i8(i16* %ptr, i16 zeroext %arg0, i8 zeroext %arg1) {
80 ; CHECK-LABEL: trunc_i16_i8:
81 ; CHECK: @ %bb.0: @ %entry
82 ; CHECK-NEXT: ldrh r0, [r0]
83 ; CHECK-NEXT: add r0, r1
84 ; CHECK-NEXT: uxtb r0, r0
85 ; CHECK-NEXT: cmp r0, r2
87 ; CHECK-NEXT: movls r0, r2
90 %0 = load i16, i16* %ptr
91 %1 = add i16 %0, %arg0
92 %2 = trunc i16 %1 to i8
93 %3 = icmp ugt i8 %2, %arg1
94 %4 = select i1 %3, i8 %2, i8 %arg1
98 ; The pass perform the transform, but a uxtb will still be inserted to handle
99 ; the zext to the icmp.
100 define i8 @icmp_i32_zext(i8* %ptr) {
101 ; CHECK-NODSP-V8-LABEL: icmp_i32_zext:
102 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
103 ; CHECK-NODSP-V8-NEXT: ldrb r2, [r0], #1
104 ; CHECK-NODSP-V8-NEXT: subs r1, r2, #1
105 ; CHECK-NODSP-V8-NEXT: .p2align 2
106 ; CHECK-NODSP-V8-NEXT: .LBB2_1: @ %body
107 ; CHECK-NODSP-V8-NEXT: @ =>This Inner Loop Header: Depth=1
108 ; CHECK-NODSP-V8-NEXT: uxtb r3, r1
109 ; CHECK-NODSP-V8-NEXT: cmp r2, r3
110 ; CHECK-NODSP-V8-NEXT: itt ne
111 ; CHECK-NODSP-V8-NEXT: movne r0, r1
112 ; CHECK-NODSP-V8-NEXT: bxne lr
113 ; CHECK-NODSP-V8-NEXT: ldrb r1, [r0, r2]
114 ; CHECK-NODSP-V8-NEXT: adds r2, #1
115 ; CHECK-NODSP-V8-NEXT: b .LBB2_1
117 ; CHECK-NODSP-V7-LABEL: icmp_i32_zext:
118 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
119 ; CHECK-NODSP-V7-NEXT: ldrb r2, [r0], #1
120 ; CHECK-NODSP-V7-NEXT: subs r1, r2, #1
121 ; CHECK-NODSP-V7-NEXT: .LBB2_1: @ %body
122 ; CHECK-NODSP-V7-NEXT: @ =>This Inner Loop Header: Depth=1
123 ; CHECK-NODSP-V7-NEXT: uxtb r3, r1
124 ; CHECK-NODSP-V7-NEXT: cmp r2, r3
125 ; CHECK-NODSP-V7-NEXT: itt ne
126 ; CHECK-NODSP-V7-NEXT: movne r0, r1
127 ; CHECK-NODSP-V7-NEXT: bxne lr
128 ; CHECK-NODSP-V7-NEXT: ldrb r1, [r0, r2]
129 ; CHECK-NODSP-V7-NEXT: adds r2, #1
130 ; CHECK-NODSP-V7-NEXT: b .LBB2_1
132 ; CHECK-DSP-LABEL: icmp_i32_zext:
133 ; CHECK-DSP: @ %bb.0: @ %entry
134 ; CHECK-DSP-NEXT: ldrb r2, [r0], #1
135 ; CHECK-DSP-NEXT: subs r1, r2, #1
136 ; CHECK-DSP-NEXT: .LBB2_1: @ %body
137 ; CHECK-DSP-NEXT: @ =>This Inner Loop Header: Depth=1
138 ; CHECK-DSP-NEXT: uxtb r3, r1
139 ; CHECK-DSP-NEXT: cmp r2, r3
140 ; CHECK-DSP-NEXT: itt ne
141 ; CHECK-DSP-NEXT: movne r0, r1
142 ; CHECK-DSP-NEXT: bxne lr
143 ; CHECK-DSP-NEXT: ldrb r1, [r0, r2]
144 ; CHECK-DSP-NEXT: adds r2, #1
145 ; CHECK-DSP-NEXT: b .LBB2_1
147 ; CHECK-DSP-IMM-LABEL: icmp_i32_zext:
148 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
149 ; CHECK-DSP-IMM-NEXT: ldrb r2, [r0], #1
150 ; CHECK-DSP-IMM-NEXT: subs r1, r2, #1
151 ; CHECK-DSP-IMM-NEXT: .LBB2_1: @ %body
152 ; CHECK-DSP-IMM-NEXT: @ =>This Inner Loop Header: Depth=1
153 ; CHECK-DSP-IMM-NEXT: uxtb r3, r1
154 ; CHECK-DSP-IMM-NEXT: cmp r2, r3
155 ; CHECK-DSP-IMM-NEXT: bne .LBB2_3
156 ; CHECK-DSP-IMM-NEXT: @ %bb.2: @ %if.end
157 ; CHECK-DSP-IMM-NEXT: @ in Loop: Header=BB2_1 Depth=1
158 ; CHECK-DSP-IMM-NEXT: ldrb r1, [r0, r2]
159 ; CHECK-DSP-IMM-NEXT: adds r2, #1
160 ; CHECK-DSP-IMM-NEXT: b .LBB2_1
161 ; CHECK-DSP-IMM-NEXT: .LBB2_3: @ %exit
162 ; CHECK-DSP-IMM-NEXT: mov r0, r1
163 ; CHECK-DSP-IMM-NEXT: bx lr
165 %gep = getelementptr inbounds i8, i8* %ptr, i32 0
166 %0 = load i8, i8* %gep, align 1
167 %1 = sub nuw nsw i8 %0, 1
168 %conv44 = zext i8 %0 to i32
175 %2 = phi i8 [ %1, %preheader ], [ %3, %if.end ]
176 %si.0274 = phi i32 [ %conv44, %preheader ], [ %inc, %if.end ]
177 %conv51266 = zext i8 %2 to i32
178 %cmp52267 = icmp eq i32 %si.0274, %conv51266
179 br i1 %cmp52267, label %if.end, label %exit
182 %inc = add i32 %si.0274, 1
183 %gep1 = getelementptr inbounds i8, i8* %ptr, i32 %inc
184 %3 = load i8, i8* %gep1, align 1
191 ; Won't don't handle sext
192 define i32 @icmp_sext_zext_store_i8_i16() {
193 ; CHECK-NODSP-V8-LABEL: icmp_sext_zext_store_i8_i16:
194 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
195 ; CHECK-NODSP-V8-NEXT: movw r0, :lower16:d_uch
196 ; CHECK-NODSP-V8-NEXT: movt r0, :upper16:d_uch
197 ; CHECK-NODSP-V8-NEXT: ldrb r1, [r0, #2]
198 ; CHECK-NODSP-V8-NEXT: movw r0, :lower16:d_sh
199 ; CHECK-NODSP-V8-NEXT: movt r0, :upper16:d_sh
200 ; CHECK-NODSP-V8-NEXT: ldrsh.w r0, [r0, #4]
201 ; CHECK-NODSP-V8-NEXT: movw r2, :lower16:sh1
202 ; CHECK-NODSP-V8-NEXT: subs r0, r1, r0
203 ; CHECK-NODSP-V8-NEXT: clz r0, r0
204 ; CHECK-NODSP-V8-NEXT: movt r2, :upper16:sh1
205 ; CHECK-NODSP-V8-NEXT: lsrs r0, r0, #5
206 ; CHECK-NODSP-V8-NEXT: strh r1, [r2]
207 ; CHECK-NODSP-V8-NEXT: bx lr
209 ; CHECK-NODSP-V7-LABEL: icmp_sext_zext_store_i8_i16:
210 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
211 ; CHECK-NODSP-V7-NEXT: movw r0, :lower16:d_sh
212 ; CHECK-NODSP-V7-NEXT: movw r1, :lower16:d_uch
213 ; CHECK-NODSP-V7-NEXT: movt r0, :upper16:d_sh
214 ; CHECK-NODSP-V7-NEXT: movt r1, :upper16:d_uch
215 ; CHECK-NODSP-V7-NEXT: ldrb r1, [r1, #2]
216 ; CHECK-NODSP-V7-NEXT: movw r2, :lower16:sh1
217 ; CHECK-NODSP-V7-NEXT: ldrsh.w r0, [r0, #4]
218 ; CHECK-NODSP-V7-NEXT: movt r2, :upper16:sh1
219 ; CHECK-NODSP-V7-NEXT: strh r1, [r2]
220 ; CHECK-NODSP-V7-NEXT: subs r0, r1, r0
221 ; CHECK-NODSP-V7-NEXT: clz r0, r0
222 ; CHECK-NODSP-V7-NEXT: lsrs r0, r0, #5
223 ; CHECK-NODSP-V7-NEXT: bx lr
225 ; CHECK-DSP-LABEL: icmp_sext_zext_store_i8_i16:
226 ; CHECK-DSP: @ %bb.0: @ %entry
227 ; CHECK-DSP-NEXT: movw r0, :lower16:d_uch
228 ; CHECK-DSP-NEXT: movw r1, :lower16:sh1
229 ; CHECK-DSP-NEXT: movt r0, :upper16:d_uch
230 ; CHECK-DSP-NEXT: movt r1, :upper16:sh1
231 ; CHECK-DSP-NEXT: ldrb r0, [r0, #2]
232 ; CHECK-DSP-NEXT: strh r0, [r1]
233 ; CHECK-DSP-NEXT: movw r1, :lower16:d_sh
234 ; CHECK-DSP-NEXT: movt r1, :upper16:d_sh
235 ; CHECK-DSP-NEXT: ldrsh.w r1, [r1, #4]
236 ; CHECK-DSP-NEXT: subs r0, r0, r1
237 ; CHECK-DSP-NEXT: clz r0, r0
238 ; CHECK-DSP-NEXT: lsrs r0, r0, #5
239 ; CHECK-DSP-NEXT: bx lr
241 ; CHECK-DSP-IMM-LABEL: icmp_sext_zext_store_i8_i16:
242 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
243 ; CHECK-DSP-IMM-NEXT: movw r0, :lower16:d_sh
244 ; CHECK-DSP-IMM-NEXT: movw r1, :lower16:d_uch
245 ; CHECK-DSP-IMM-NEXT: movt r0, :upper16:d_sh
246 ; CHECK-DSP-IMM-NEXT: movt r1, :upper16:d_uch
247 ; CHECK-DSP-IMM-NEXT: ldrb r1, [r1, #2]
248 ; CHECK-DSP-IMM-NEXT: movw r2, :lower16:sh1
249 ; CHECK-DSP-IMM-NEXT: ldrsh.w r0, [r0, #4]
250 ; CHECK-DSP-IMM-NEXT: movt r2, :upper16:sh1
251 ; CHECK-DSP-IMM-NEXT: strh r1, [r2]
252 ; CHECK-DSP-IMM-NEXT: subs r0, r1, r0
253 ; CHECK-DSP-IMM-NEXT: clz r0, r0
254 ; CHECK-DSP-IMM-NEXT: lsrs r0, r0, #5
255 ; CHECK-DSP-IMM-NEXT: bx lr
257 %0 = load i8, i8* getelementptr inbounds ([16 x i8], [16 x i8]* @d_uch, i32 0, i32 2), align 1
258 %conv = zext i8 %0 to i16
259 store i16 %conv, i16* @sh1, align 2
260 %conv1 = zext i8 %0 to i32
261 %1 = load i16, i16* getelementptr inbounds ([16 x i16], [16 x i16]* @d_sh, i32 0, i32 2), align 2
262 %conv2 = sext i16 %1 to i32
263 %cmp = icmp eq i32 %conv1, %conv2
264 %conv3 = zext i1 %cmp to i32
268 define i1 @or_icmp_ugt(i32 %arg, i8* %ptr) {
269 ; CHECK-NODSP-V8-LABEL: or_icmp_ugt:
270 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
271 ; CHECK-NODSP-V8-NEXT: ldrb r1, [r1]
272 ; CHECK-NODSP-V8-NEXT: adds r2, r1, #3
273 ; CHECK-NODSP-V8-NEXT: subs.w r0, r0, r2, lsl #1
274 ; CHECK-NODSP-V8-NEXT: it ne
275 ; CHECK-NODSP-V8-NEXT: movne r0, #1
276 ; CHECK-NODSP-V8-NEXT: subs r1, #1
277 ; CHECK-NODSP-V8-NEXT: movs r2, #0
278 ; CHECK-NODSP-V8-NEXT: cmp r1, #3
279 ; CHECK-NODSP-V8-NEXT: it hi
280 ; CHECK-NODSP-V8-NEXT: movhi r2, #1
281 ; CHECK-NODSP-V8-NEXT: orrs r0, r2
282 ; CHECK-NODSP-V8-NEXT: bx lr
284 ; CHECK-NODSP-V7-LABEL: or_icmp_ugt:
285 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
286 ; CHECK-NODSP-V7-NEXT: ldrb r1, [r1]
287 ; CHECK-NODSP-V7-NEXT: adds r2, r1, #3
288 ; CHECK-NODSP-V7-NEXT: subs r1, #1
289 ; CHECK-NODSP-V7-NEXT: subs.w r0, r0, r2, lsl #1
290 ; CHECK-NODSP-V7-NEXT: mov.w r2, #0
291 ; CHECK-NODSP-V7-NEXT: it ne
292 ; CHECK-NODSP-V7-NEXT: movne r0, #1
293 ; CHECK-NODSP-V7-NEXT: cmp r1, #3
294 ; CHECK-NODSP-V7-NEXT: it hi
295 ; CHECK-NODSP-V7-NEXT: movhi r2, #1
296 ; CHECK-NODSP-V7-NEXT: orrs r0, r2
297 ; CHECK-NODSP-V7-NEXT: bx lr
299 ; CHECK-DSP-LABEL: or_icmp_ugt:
300 ; CHECK-DSP: @ %bb.0: @ %entry
301 ; CHECK-DSP-NEXT: ldrb r1, [r1]
302 ; CHECK-DSP-NEXT: adds r2, r1, #3
303 ; CHECK-DSP-NEXT: subs r1, #1
304 ; CHECK-DSP-NEXT: subs.w r0, r0, r2, lsl #1
305 ; CHECK-DSP-NEXT: mov.w r2, #0
306 ; CHECK-DSP-NEXT: it ne
307 ; CHECK-DSP-NEXT: movne r0, #1
308 ; CHECK-DSP-NEXT: cmp r1, #3
309 ; CHECK-DSP-NEXT: it hi
310 ; CHECK-DSP-NEXT: movhi r2, #1
311 ; CHECK-DSP-NEXT: orrs r0, r2
312 ; CHECK-DSP-NEXT: bx lr
314 ; CHECK-DSP-IMM-LABEL: or_icmp_ugt:
315 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
316 ; CHECK-DSP-IMM-NEXT: ldrb r1, [r1]
317 ; CHECK-DSP-IMM-NEXT: adds r2, r1, #3
318 ; CHECK-DSP-IMM-NEXT: subs.w r0, r0, r2, lsl #1
319 ; CHECK-DSP-IMM-NEXT: it ne
320 ; CHECK-DSP-IMM-NEXT: movne r0, #1
321 ; CHECK-DSP-IMM-NEXT: subs r1, #1
322 ; CHECK-DSP-IMM-NEXT: movs r2, #0
323 ; CHECK-DSP-IMM-NEXT: cmp r1, #3
324 ; CHECK-DSP-IMM-NEXT: it hi
325 ; CHECK-DSP-IMM-NEXT: movhi r2, #1
326 ; CHECK-DSP-IMM-NEXT: orrs r0, r2
327 ; CHECK-DSP-IMM-NEXT: bx lr
329 %0 = load i8, i8* %ptr
330 %1 = zext i8 %0 to i32
331 %mul = shl nuw nsw i32 %1, 1
332 %add0 = add nuw nsw i32 %mul, 6
333 %cmp0 = icmp ne i32 %arg, %add0
334 %add1 = add i8 %0, -1
335 %cmp1 = icmp ugt i8 %add1, 3
336 %or = or i1 %cmp0, %cmp1
340 ; We currently only handle truncs as sinks, so a uxt will still be needed for
341 ; the icmp ugt instruction.
342 define void @urem_trunc_icmps(i16** %in, i32* %g, i32* %k) {
343 ; CHECK-NODSP-V8-LABEL: urem_trunc_icmps:
344 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
345 ; CHECK-NODSP-V8-NEXT: ldr r0, [r0]
346 ; CHECK-NODSP-V8-NEXT: ldrh r0, [r0]
347 ; CHECK-NODSP-V8-NEXT: cbz r0, .LBB5_3
348 ; CHECK-NODSP-V8-NEXT: @ %bb.1: @ %cond.false.i
349 ; CHECK-NODSP-V8-NEXT: movs r3, #5
350 ; CHECK-NODSP-V8-NEXT: udiv r3, r3, r0
351 ; CHECK-NODSP-V8-NEXT: muls r0, r3, r0
352 ; CHECK-NODSP-V8-NEXT: rsb.w r0, r0, #5
353 ; CHECK-NODSP-V8-NEXT: .p2align 2
354 ; CHECK-NODSP-V8-NEXT: .LBB5_2: @ %body
355 ; CHECK-NODSP-V8-NEXT: @ =>This Inner Loop Header: Depth=1
356 ; CHECK-NODSP-V8-NEXT: uxtb r3, r0
357 ; CHECK-NODSP-V8-NEXT: cmp r3, #7
358 ; CHECK-NODSP-V8-NEXT: mov.w r3, #0
359 ; CHECK-NODSP-V8-NEXT: it hi
360 ; CHECK-NODSP-V8-NEXT: movhi r3, #1
361 ; CHECK-NODSP-V8-NEXT: str r3, [r1]
362 ; CHECK-NODSP-V8-NEXT: ldr r3, [r2]
363 ; CHECK-NODSP-V8-NEXT: cmp r3, #0
364 ; CHECK-NODSP-V8-NEXT: it ne
365 ; CHECK-NODSP-V8-NEXT: bxne lr
366 ; CHECK-NODSP-V8-NEXT: adds r0, #1
367 ; CHECK-NODSP-V8-NEXT: b .LBB5_2
368 ; CHECK-NODSP-V8-NEXT: .LBB5_3: @ %exit
369 ; CHECK-NODSP-V8-NEXT: bx lr
371 ; CHECK-NODSP-V7-LABEL: urem_trunc_icmps:
372 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
373 ; CHECK-NODSP-V7-NEXT: .save {r4, r5, r7, lr}
374 ; CHECK-NODSP-V7-NEXT: push {r4, r5, r7, lr}
375 ; CHECK-NODSP-V7-NEXT: ldr r0, [r0]
376 ; CHECK-NODSP-V7-NEXT: mov r5, r1
377 ; CHECK-NODSP-V7-NEXT: ldrh r1, [r0]
378 ; CHECK-NODSP-V7-NEXT: cbz r1, .LBB5_4
379 ; CHECK-NODSP-V7-NEXT: @ %bb.1: @ %cond.false.i
380 ; CHECK-NODSP-V7-NEXT: movs r0, #5
381 ; CHECK-NODSP-V7-NEXT: mov r4, r2
382 ; CHECK-NODSP-V7-NEXT: bl __aeabi_uidivmod
383 ; CHECK-NODSP-V7-NEXT: .LBB5_2: @ %body
384 ; CHECK-NODSP-V7-NEXT: @ =>This Inner Loop Header: Depth=1
385 ; CHECK-NODSP-V7-NEXT: uxtb r0, r1
386 ; CHECK-NODSP-V7-NEXT: cmp r0, #7
387 ; CHECK-NODSP-V7-NEXT: mov.w r0, #0
388 ; CHECK-NODSP-V7-NEXT: it hi
389 ; CHECK-NODSP-V7-NEXT: movhi r0, #1
390 ; CHECK-NODSP-V7-NEXT: str r0, [r5]
391 ; CHECK-NODSP-V7-NEXT: ldr r0, [r4]
392 ; CHECK-NODSP-V7-NEXT: cbnz r0, .LBB5_4
393 ; CHECK-NODSP-V7-NEXT: @ %bb.3: @ %for.inc
394 ; CHECK-NODSP-V7-NEXT: @ in Loop: Header=BB5_2 Depth=1
395 ; CHECK-NODSP-V7-NEXT: adds r1, #1
396 ; CHECK-NODSP-V7-NEXT: b .LBB5_2
397 ; CHECK-NODSP-V7-NEXT: .LBB5_4: @ %exit
398 ; CHECK-NODSP-V7-NEXT: pop {r4, r5, r7, pc}
400 ; CHECK-DSP-LABEL: urem_trunc_icmps:
401 ; CHECK-DSP: @ %bb.0: @ %entry
402 ; CHECK-DSP-NEXT: ldr r0, [r0]
403 ; CHECK-DSP-NEXT: ldrh r0, [r0]
404 ; CHECK-DSP-NEXT: cbz r0, .LBB5_3
405 ; CHECK-DSP-NEXT: @ %bb.1: @ %cond.false.i
406 ; CHECK-DSP-NEXT: movs r3, #5
407 ; CHECK-DSP-NEXT: udiv r3, r3, r0
408 ; CHECK-DSP-NEXT: muls r0, r3, r0
409 ; CHECK-DSP-NEXT: rsb.w r0, r0, #5
410 ; CHECK-DSP-NEXT: .LBB5_2: @ %body
411 ; CHECK-DSP-NEXT: @ =>This Inner Loop Header: Depth=1
412 ; CHECK-DSP-NEXT: uxtb r3, r0
413 ; CHECK-DSP-NEXT: cmp r3, #7
414 ; CHECK-DSP-NEXT: mov.w r3, #0
415 ; CHECK-DSP-NEXT: it hi
416 ; CHECK-DSP-NEXT: movhi r3, #1
417 ; CHECK-DSP-NEXT: str r3, [r1]
418 ; CHECK-DSP-NEXT: ldr r3, [r2]
419 ; CHECK-DSP-NEXT: cmp r3, #0
420 ; CHECK-DSP-NEXT: it ne
421 ; CHECK-DSP-NEXT: bxne lr
422 ; CHECK-DSP-NEXT: adds r0, #1
423 ; CHECK-DSP-NEXT: b .LBB5_2
424 ; CHECK-DSP-NEXT: .LBB5_3: @ %exit
425 ; CHECK-DSP-NEXT: bx lr
427 ; CHECK-DSP-IMM-LABEL: urem_trunc_icmps:
428 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
429 ; CHECK-DSP-IMM-NEXT: ldr r0, [r0]
430 ; CHECK-DSP-IMM-NEXT: ldrh r0, [r0]
431 ; CHECK-DSP-IMM-NEXT: cbz r0, .LBB5_4
432 ; CHECK-DSP-IMM-NEXT: @ %bb.1: @ %cond.false.i
433 ; CHECK-DSP-IMM-NEXT: movs r3, #5
434 ; CHECK-DSP-IMM-NEXT: udiv r3, r3, r0
435 ; CHECK-DSP-IMM-NEXT: muls r0, r3, r0
436 ; CHECK-DSP-IMM-NEXT: rsb.w r0, r0, #5
437 ; CHECK-DSP-IMM-NEXT: .LBB5_2: @ %body
438 ; CHECK-DSP-IMM-NEXT: @ =>This Inner Loop Header: Depth=1
439 ; CHECK-DSP-IMM-NEXT: uxtb r3, r0
440 ; CHECK-DSP-IMM-NEXT: cmp r3, #7
441 ; CHECK-DSP-IMM-NEXT: mov.w r3, #0
442 ; CHECK-DSP-IMM-NEXT: it hi
443 ; CHECK-DSP-IMM-NEXT: movhi r3, #1
444 ; CHECK-DSP-IMM-NEXT: str r3, [r1]
445 ; CHECK-DSP-IMM-NEXT: ldr r3, [r2]
446 ; CHECK-DSP-IMM-NEXT: cbnz r3, .LBB5_4
447 ; CHECK-DSP-IMM-NEXT: @ %bb.3: @ %for.inc
448 ; CHECK-DSP-IMM-NEXT: @ in Loop: Header=BB5_2 Depth=1
449 ; CHECK-DSP-IMM-NEXT: adds r0, #1
450 ; CHECK-DSP-IMM-NEXT: b .LBB5_2
451 ; CHECK-DSP-IMM-NEXT: .LBB5_4: @ %exit
452 ; CHECK-DSP-IMM-NEXT: bx lr
454 %ptr = load i16*, i16** %in, align 4
455 %ld = load i16, i16* %ptr, align 2
456 %cmp.i = icmp eq i16 %ld, 0
457 br i1 %cmp.i, label %exit, label %cond.false.i
460 %rem = urem i16 5, %ld
461 %extract.t = trunc i16 %rem to i8
465 %cond.in.i.off0 = phi i8 [ %extract.t, %cond.false.i ], [ %add, %for.inc ]
466 %cmp = icmp ugt i8 %cond.in.i.off0, 7
467 %conv5 = zext i1 %cmp to i32
468 store i32 %conv5, i32* %g, align 4
469 %.pr = load i32, i32* %k, align 4
470 %tobool13150 = icmp eq i32 %.pr, 0
471 br i1 %tobool13150, label %for.inc, label %exit
474 %add = add nuw i8 %cond.in.i.off0, 1
481 ; Check that %exp requires uxth in all cases, and will also be required to
482 ; promote %1 for the call - unless we can generate a uadd16.
483 define i32 @zext_load_sink_call(i16* %ptr, i16 %exp) {
484 ; CHECK-NODSP-LABEL: zext_load_sink_call:
485 ; CHECK-NODSP: @ %bb.0: @ %entry
486 ; CHECK-NODSP-NEXT: ldrh r0, [r0]
487 ; CHECK-NODSP-NEXT: uxth r2, r1
488 ; CHECK-NODSP-NEXT: cmp r0, r2
489 ; CHECK-NODSP-NEXT: itt eq
490 ; CHECK-NODSP-NEXT: moveq r0, #0
491 ; CHECK-NODSP-NEXT: bxeq lr
492 ; CHECK-NODSP-NEXT: adds r1, #3
493 ; CHECK-NODSP-NEXT: uxth r1, r1
494 ; CHECK-NODSP-NEXT: b dummy
496 ; CHECK-DSP-LABEL: zext_load_sink_call:
497 ; CHECK-DSP: @ %bb.0: @ %entry
498 ; CHECK-DSP-NEXT: ldrh r0, [r0]
499 ; CHECK-DSP-NEXT: uxth r2, r1
500 ; CHECK-DSP-NEXT: cmp r0, r2
501 ; CHECK-DSP-NEXT: itt eq
502 ; CHECK-DSP-NEXT: moveq r0, #0
503 ; CHECK-DSP-NEXT: bxeq lr
504 ; CHECK-DSP-NEXT: adds r1, #3
505 ; CHECK-DSP-NEXT: uxth r1, r1
506 ; CHECK-DSP-NEXT: b dummy
508 ; CHECK-DSP-IMM-LABEL: zext_load_sink_call:
509 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
510 ; CHECK-DSP-IMM-NEXT: uxth r2, r1
511 ; CHECK-DSP-IMM-NEXT: ldrh r0, [r0]
512 ; CHECK-DSP-IMM-NEXT: movs r1, #3
513 ; CHECK-DSP-IMM-NEXT: uadd16 r1, r2, r1
514 ; CHECK-DSP-IMM-NEXT: cmp r0, r2
515 ; CHECK-DSP-IMM-NEXT: bne .LBB6_2
516 ; CHECK-DSP-IMM-NEXT: @ %bb.1: @ %exit
517 ; CHECK-DSP-IMM-NEXT: movs r0, #0
518 ; CHECK-DSP-IMM-NEXT: bx lr
519 ; CHECK-DSP-IMM-NEXT: .LBB6_2: @ %if.then
520 ; CHECK-DSP-IMM-NEXT: b dummy
522 %0 = load i16, i16* %ptr, align 4
524 %cmp = icmp eq i16 %0, %exp
525 br i1 %cmp, label %exit, label %if.then
528 %conv0 = zext i16 %0 to i32
529 %conv1 = zext i16 %1 to i32
530 %call = tail call arm_aapcs_vfpcc i32 @dummy(i32 %conv0, i32 %conv1)
534 %exitval = phi i32 [ %call, %if.then ], [ 0, %entry ]
538 define i16 @bitcast_i16(i16 zeroext %arg0, i16 zeroext %arg1) {
539 ; CHECK-NODSP-LABEL: bitcast_i16:
540 ; CHECK-NODSP: @ %bb.0: @ %entry
541 ; CHECK-NODSP-NEXT: adds r0, #1
542 ; CHECK-NODSP-NEXT: movw r2, #12345
543 ; CHECK-NODSP-NEXT: cmp r0, r2
544 ; CHECK-NODSP-NEXT: it hi
545 ; CHECK-NODSP-NEXT: movwhi r1, #32657
546 ; CHECK-NODSP-NEXT: mov r0, r1
547 ; CHECK-NODSP-NEXT: bx lr
549 ; CHECK-DSP-LABEL: bitcast_i16:
550 ; CHECK-DSP: @ %bb.0: @ %entry
551 ; CHECK-DSP-NEXT: adds r0, #1
552 ; CHECK-DSP-NEXT: movw r2, #12345
553 ; CHECK-DSP-NEXT: cmp r0, r2
554 ; CHECK-DSP-NEXT: it hi
555 ; CHECK-DSP-NEXT: movwhi r1, #32657
556 ; CHECK-DSP-NEXT: mov r0, r1
557 ; CHECK-DSP-NEXT: bx lr
559 ; CHECK-DSP-IMM-LABEL: bitcast_i16:
560 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
561 ; CHECK-DSP-IMM-NEXT: adds r2, r0, #1
562 ; CHECK-DSP-IMM-NEXT: movw r0, #32657
563 ; CHECK-DSP-IMM-NEXT: movw r3, #12345
564 ; CHECK-DSP-IMM-NEXT: cmp r2, r3
565 ; CHECK-DSP-IMM-NEXT: it ls
566 ; CHECK-DSP-IMM-NEXT: movls r0, r1
567 ; CHECK-DSP-IMM-NEXT: bx lr
569 %cast = bitcast i16 12345 to i16
570 %add = add nuw i16 %arg0, 1
571 %cmp = icmp ule i16 %add, %cast
572 %res = select i1 %cmp, i16 %arg1, i16 32657
576 define i8 @bitcast_i8(i8 zeroext %arg0, i8 zeroext %arg1) {
577 ; CHECK-LABEL: bitcast_i8:
578 ; CHECK: @ %bb.0: @ %entry
579 ; CHECK-NEXT: mvn r2, #127
580 ; CHECK-NEXT: cmp.w r1, r0, lsl #1
582 ; CHECK-NEXT: movls r2, #127
583 ; CHECK-NEXT: mov r0, r2
586 %cast = bitcast i8 127 to i8
587 %mul = shl nuw i8 %arg0, 1
588 %cmp = icmp uge i8 %mul, %arg1
589 %res = select i1 %cmp, i8 %cast, i8 128
593 define i16 @bitcast_i16_minus(i16 zeroext %arg0, i16 zeroext %arg1) {
594 ; CHECK-NODSP-LABEL: bitcast_i16_minus:
595 ; CHECK-NODSP: @ %bb.0: @ %entry
596 ; CHECK-NODSP-NEXT: eor r2, r0, #7
597 ; CHECK-NODSP-NEXT: movw r0, #32657
598 ; CHECK-NODSP-NEXT: cmp r2, r1
599 ; CHECK-NODSP-NEXT: itt eq
600 ; CHECK-NODSP-NEXT: movweq r0, #53191
601 ; CHECK-NODSP-NEXT: movteq r0, #65535
602 ; CHECK-NODSP-NEXT: bx lr
604 ; CHECK-DSP-LABEL: bitcast_i16_minus:
605 ; CHECK-DSP: @ %bb.0: @ %entry
606 ; CHECK-DSP-NEXT: eor r2, r0, #7
607 ; CHECK-DSP-NEXT: movw r0, #32657
608 ; CHECK-DSP-NEXT: cmp r2, r1
609 ; CHECK-DSP-NEXT: itt eq
610 ; CHECK-DSP-NEXT: movweq r0, #53191
611 ; CHECK-DSP-NEXT: movteq r0, #65535
612 ; CHECK-DSP-NEXT: bx lr
614 ; CHECK-DSP-IMM-LABEL: bitcast_i16_minus:
615 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
616 ; CHECK-DSP-IMM-NEXT: eor r2, r0, #7
617 ; CHECK-DSP-IMM-NEXT: movw r0, #32657
618 ; CHECK-DSP-IMM-NEXT: cmp r2, r1
619 ; CHECK-DSP-IMM-NEXT: it eq
620 ; CHECK-DSP-IMM-NEXT: movweq r0, #53191
621 ; CHECK-DSP-IMM-NEXT: it eq
622 ; CHECK-DSP-IMM-NEXT: movteq r0, #65535
623 ; CHECK-DSP-IMM-NEXT: bx lr
625 %cast = bitcast i16 -12345 to i16
626 %xor = xor i16 %arg0, 7
627 %cmp = icmp eq i16 %xor, %arg1
628 %res = select i1 %cmp, i16 %cast, i16 32657
632 define i8 @bitcast_i8_minus(i8 zeroext %arg0, i8 zeroext %arg1) {
633 ; CHECK-LABEL: bitcast_i8_minus:
634 ; CHECK: @ %bb.0: @ %entry
635 ; CHECK-NEXT: and r2, r0, #3
636 ; CHECK-NEXT: mvn r0, #127
637 ; CHECK-NEXT: cmp r2, r1
639 ; CHECK-NEXT: mvnne r0, #126
642 %cast = bitcast i8 -127 to i8
643 %and = and i8 %arg0, 3
644 %cmp = icmp ne i8 %and, %arg1
645 %res = select i1 %cmp, i8 %cast, i8 128
649 declare i32 @dummy(i32, i32)
651 @d_uch = hidden local_unnamed_addr global [16 x i8] zeroinitializer, align 1
652 @sh1 = hidden local_unnamed_addr global i16 0, align 2
653 @d_sh = hidden local_unnamed_addr global [16 x i16] zeroinitializer, align 2
655 define i8* @two_stage_zext_trunc_mix(i32* %this, i32 %__pos1, i32 %__n1, i32** %__str, i32 %__pos2, i32 %__n2) {
656 ; CHECK-NODSP-V8-LABEL: two_stage_zext_trunc_mix:
657 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
658 ; CHECK-NODSP-V8-NEXT: ldr.w r12, [sp]
659 ; CHECK-NODSP-V8-NEXT: ldrb r2, [r0]
660 ; CHECK-NODSP-V8-NEXT: add.w r0, r3, r12
661 ; CHECK-NODSP-V8-NEXT: lsls r2, r2, #31
662 ; CHECK-NODSP-V8-NEXT: it eq
663 ; CHECK-NODSP-V8-NEXT: addeq r0, r3, r1
664 ; CHECK-NODSP-V8-NEXT: bx lr
666 ; CHECK-NODSP-V7-LABEL: two_stage_zext_trunc_mix:
667 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
668 ; CHECK-NODSP-V7-NEXT: ldrb r2, [r0]
669 ; CHECK-NODSP-V7-NEXT: ldr.w r12, [sp]
670 ; CHECK-NODSP-V7-NEXT: add.w r0, r3, r12
671 ; CHECK-NODSP-V7-NEXT: lsls r2, r2, #31
672 ; CHECK-NODSP-V7-NEXT: it eq
673 ; CHECK-NODSP-V7-NEXT: addeq r0, r3, r1
674 ; CHECK-NODSP-V7-NEXT: bx lr
676 ; CHECK-DSP-LABEL: two_stage_zext_trunc_mix:
677 ; CHECK-DSP: @ %bb.0: @ %entry
678 ; CHECK-DSP-NEXT: ldr r2, [sp]
679 ; CHECK-DSP-NEXT: ldrb r0, [r0]
680 ; CHECK-DSP-NEXT: add r2, r3
681 ; CHECK-DSP-NEXT: lsls r0, r0, #31
682 ; CHECK-DSP-NEXT: it eq
683 ; CHECK-DSP-NEXT: addeq r2, r3, r1
684 ; CHECK-DSP-NEXT: mov r0, r2
685 ; CHECK-DSP-NEXT: bx lr
687 ; CHECK-DSP-IMM-LABEL: two_stage_zext_trunc_mix:
688 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
689 ; CHECK-DSP-IMM-NEXT: ldr.w r12, [sp]
690 ; CHECK-DSP-IMM-NEXT: ldrb r2, [r0]
691 ; CHECK-DSP-IMM-NEXT: adds r0, r3, r1
692 ; CHECK-DSP-IMM-NEXT: add r12, r3
693 ; CHECK-DSP-IMM-NEXT: lsls r1, r2, #31
694 ; CHECK-DSP-IMM-NEXT: it ne
695 ; CHECK-DSP-IMM-NEXT: movne r0, r12
696 ; CHECK-DSP-IMM-NEXT: bx lr
698 %__size_.i.i.i.i = bitcast i32** %__str to i8*
699 %0 = load i8, i8* %__size_.i.i.i.i, align 4
701 %tobool.i.i.i.i = icmp eq i8 %1, 0
702 %__size_.i5.i.i = getelementptr inbounds i32*, i32** %__str, i32 %__n1
703 %cast = bitcast i32** %__size_.i5.i.i to i32*
704 %2 = load i32, i32* %cast, align 4
706 %4 = zext i8 %3 to i32
707 %cond.i.i = select i1 %tobool.i.i.i.i, i32 %4, i32 %2
708 %__size_.i.i.i.i.i = bitcast i32* %this to i8*
709 %5 = load i8, i8* %__size_.i.i.i.i.i, align 4
711 %tobool.i.i.i.i.i = icmp eq i8 %6, 0
712 %7 = getelementptr inbounds i8, i8* %__size_.i.i.i.i, i32 %__pos1
713 %8 = getelementptr inbounds i8, i8* %__size_.i.i.i.i, i32 %__pos2
714 %res = select i1 %tobool.i.i.i.i.i, i8* %7, i8* %8
718 define i8 @search_through_zext_1(i8 zeroext %a, i8 zeroext %b, i16 zeroext %c) {
719 ; CHECK-NODSP-V8-LABEL: search_through_zext_1:
720 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
721 ; CHECK-NODSP-V8-NEXT: subs r3, r1, r0
722 ; CHECK-NODSP-V8-NEXT: add.w r12, r0, r1
723 ; CHECK-NODSP-V8-NEXT: cmp r3, r2
724 ; CHECK-NODSP-V8-NEXT: it ls
725 ; CHECK-NODSP-V8-NEXT: movls r0, r1
726 ; CHECK-NODSP-V8-NEXT: cmp r12, r2
727 ; CHECK-NODSP-V8-NEXT: it hs
728 ; CHECK-NODSP-V8-NEXT: movhs r0, #0
729 ; CHECK-NODSP-V8-NEXT: bx lr
731 ; CHECK-NODSP-V7-LABEL: search_through_zext_1:
732 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
733 ; CHECK-NODSP-V7-NEXT: subs r3, r1, r0
734 ; CHECK-NODSP-V7-NEXT: cmp r3, r2
735 ; CHECK-NODSP-V7-NEXT: mov r3, r1
736 ; CHECK-NODSP-V7-NEXT: it hi
737 ; CHECK-NODSP-V7-NEXT: movhi r3, r0
738 ; CHECK-NODSP-V7-NEXT: add r0, r1
739 ; CHECK-NODSP-V7-NEXT: cmp r0, r2
740 ; CHECK-NODSP-V7-NEXT: it hs
741 ; CHECK-NODSP-V7-NEXT: movhs r3, #0
742 ; CHECK-NODSP-V7-NEXT: mov r0, r3
743 ; CHECK-NODSP-V7-NEXT: bx lr
745 ; CHECK-DSP-LABEL: search_through_zext_1:
746 ; CHECK-DSP: @ %bb.0: @ %entry
747 ; CHECK-DSP-NEXT: subs r3, r1, r0
748 ; CHECK-DSP-NEXT: cmp r3, r2
749 ; CHECK-DSP-NEXT: mov r3, r1
750 ; CHECK-DSP-NEXT: it hi
751 ; CHECK-DSP-NEXT: movhi r3, r0
752 ; CHECK-DSP-NEXT: add r0, r1
753 ; CHECK-DSP-NEXT: cmp r0, r2
754 ; CHECK-DSP-NEXT: it hs
755 ; CHECK-DSP-NEXT: movhs r3, #0
756 ; CHECK-DSP-NEXT: mov r0, r3
757 ; CHECK-DSP-NEXT: bx lr
759 ; CHECK-DSP-IMM-LABEL: search_through_zext_1:
760 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
761 ; CHECK-DSP-IMM-NEXT: subs r3, r1, r0
762 ; CHECK-DSP-IMM-NEXT: cmp r3, r2
763 ; CHECK-DSP-IMM-NEXT: mov r3, r1
764 ; CHECK-DSP-IMM-NEXT: it hi
765 ; CHECK-DSP-IMM-NEXT: movhi r3, r0
766 ; CHECK-DSP-IMM-NEXT: add r1, r0
767 ; CHECK-DSP-IMM-NEXT: movs r0, #0
768 ; CHECK-DSP-IMM-NEXT: cmp r1, r2
769 ; CHECK-DSP-IMM-NEXT: it lo
770 ; CHECK-DSP-IMM-NEXT: movlo r0, r3
771 ; CHECK-DSP-IMM-NEXT: bx lr
773 %add = add nuw i8 %a, %b
774 %conv = zext i8 %add to i16
775 %cmp = icmp ult i16 %conv, %c
776 br i1 %cmp, label %if.then, label %if.end
779 %sub = sub nuw i8 %b, %a
780 %conv2 = zext i8 %sub to i16
781 %cmp2 = icmp ugt i16 %conv2, %c
782 %res = select i1 %cmp2, i8 %a, i8 %b
786 %retval = phi i8 [ 0, %entry ], [ %res, %if.then ]
790 ; TODO: We should be able to remove the uxtb here. The transform fails because
791 ; the icmp ugt uses an i32, which is too large... but this doesn't matter
792 ; because it won't be writing a large value to a register as a result.
793 define i8 @search_through_zext_2(i8 zeroext %a, i8 zeroext %b, i16 zeroext %c, i32 %d) {
794 ; CHECK-NODSP-V8-LABEL: search_through_zext_2:
795 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
796 ; CHECK-NODSP-V8-NEXT: push {r7, lr}
797 ; CHECK-NODSP-V8-NEXT: sub.w lr, r1, r0
798 ; CHECK-NODSP-V8-NEXT: add.w r12, r0, r1
799 ; CHECK-NODSP-V8-NEXT: uxtb.w lr, lr
800 ; CHECK-NODSP-V8-NEXT: uxtb.w r12, r12
801 ; CHECK-NODSP-V8-NEXT: cmp lr, r3
802 ; CHECK-NODSP-V8-NEXT: it ls
803 ; CHECK-NODSP-V8-NEXT: movls r0, r1
804 ; CHECK-NODSP-V8-NEXT: cmp r12, r2
805 ; CHECK-NODSP-V8-NEXT: it hs
806 ; CHECK-NODSP-V8-NEXT: movhs r0, #0
807 ; CHECK-NODSP-V8-NEXT: pop {r7, pc}
809 ; CHECK-NODSP-V7-LABEL: search_through_zext_2:
810 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
811 ; CHECK-NODSP-V7-NEXT: sub.w r12, r1, r0
812 ; CHECK-NODSP-V7-NEXT: uxtb.w r12, r12
813 ; CHECK-NODSP-V7-NEXT: cmp r12, r3
814 ; CHECK-NODSP-V7-NEXT: mov r3, r1
815 ; CHECK-NODSP-V7-NEXT: it hi
816 ; CHECK-NODSP-V7-NEXT: movhi r3, r0
817 ; CHECK-NODSP-V7-NEXT: add r0, r1
818 ; CHECK-NODSP-V7-NEXT: uxtb r0, r0
819 ; CHECK-NODSP-V7-NEXT: cmp r0, r2
820 ; CHECK-NODSP-V7-NEXT: it hs
821 ; CHECK-NODSP-V7-NEXT: movhs r3, #0
822 ; CHECK-NODSP-V7-NEXT: mov r0, r3
823 ; CHECK-NODSP-V7-NEXT: bx lr
825 ; CHECK-DSP-LABEL: search_through_zext_2:
826 ; CHECK-DSP: @ %bb.0: @ %entry
827 ; CHECK-DSP-NEXT: sub.w r12, r1, r0
828 ; CHECK-DSP-NEXT: uxtb.w r12, r12
829 ; CHECK-DSP-NEXT: cmp r12, r3
830 ; CHECK-DSP-NEXT: mov r3, r1
831 ; CHECK-DSP-NEXT: it hi
832 ; CHECK-DSP-NEXT: movhi r3, r0
833 ; CHECK-DSP-NEXT: add r0, r1
834 ; CHECK-DSP-NEXT: uxtb r0, r0
835 ; CHECK-DSP-NEXT: cmp r0, r2
836 ; CHECK-DSP-NEXT: it hs
837 ; CHECK-DSP-NEXT: movhs r3, #0
838 ; CHECK-DSP-NEXT: mov r0, r3
839 ; CHECK-DSP-NEXT: bx lr
841 ; CHECK-DSP-IMM-LABEL: search_through_zext_2:
842 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
843 ; CHECK-DSP-IMM-NEXT: sub.w r12, r1, r0
844 ; CHECK-DSP-IMM-NEXT: uxtb.w r12, r12
845 ; CHECK-DSP-IMM-NEXT: cmp r12, r3
846 ; CHECK-DSP-IMM-NEXT: mov r3, r1
847 ; CHECK-DSP-IMM-NEXT: it hi
848 ; CHECK-DSP-IMM-NEXT: movhi r3, r0
849 ; CHECK-DSP-IMM-NEXT: add r0, r1
850 ; CHECK-DSP-IMM-NEXT: uxtb r1, r0
851 ; CHECK-DSP-IMM-NEXT: movs r0, #0
852 ; CHECK-DSP-IMM-NEXT: cmp r1, r2
853 ; CHECK-DSP-IMM-NEXT: it lo
854 ; CHECK-DSP-IMM-NEXT: movlo r0, r3
855 ; CHECK-DSP-IMM-NEXT: bx lr
857 %add = add nuw i8 %a, %b
858 %conv = zext i8 %add to i16
859 %cmp = icmp ult i16 %conv, %c
860 br i1 %cmp, label %if.then, label %if.end
863 %sub = sub nuw i8 %b, %a
864 %conv2 = zext i8 %sub to i32
865 %cmp2 = icmp ugt i32 %conv2, %d
866 %res = select i1 %cmp2, i8 %a, i8 %b
870 %retval = phi i8 [ 0, %entry ], [ %res, %if.then ]
874 ; TODO: We should be able to remove the uxtb here as all the calculations are
875 ; performed on i8s. The promotion of i8 to i16 and then the later truncation
876 ; results in the uxtb.
877 define i8 @search_through_zext_3(i8 zeroext %a, i8 zeroext %b, i16 zeroext %c, i32 %d) {
878 ; CHECK-NODSP-LABEL: search_through_zext_3:
879 ; CHECK-NODSP: @ %bb.0: @ %entry
880 ; CHECK-NODSP-NEXT: add.w r12, r0, r1
881 ; CHECK-NODSP-NEXT: uxtb.w r12, r12
882 ; CHECK-NODSP-NEXT: cmp r12, r2
883 ; CHECK-NODSP-NEXT: itt hs
884 ; CHECK-NODSP-NEXT: movhs r0, #0
885 ; CHECK-NODSP-NEXT: bxhs lr
886 ; CHECK-NODSP-NEXT: sub.w r2, r1, r12
887 ; CHECK-NODSP-NEXT: uxtb r2, r2
888 ; CHECK-NODSP-NEXT: cmp r2, r3
889 ; CHECK-NODSP-NEXT: it ls
890 ; CHECK-NODSP-NEXT: movls r0, r1
891 ; CHECK-NODSP-NEXT: bx lr
893 ; CHECK-DSP-LABEL: search_through_zext_3:
894 ; CHECK-DSP: @ %bb.0: @ %entry
895 ; CHECK-DSP-NEXT: add.w r12, r0, r1
896 ; CHECK-DSP-NEXT: uxtb.w r12, r12
897 ; CHECK-DSP-NEXT: cmp r12, r2
898 ; CHECK-DSP-NEXT: itt hs
899 ; CHECK-DSP-NEXT: movhs r0, #0
900 ; CHECK-DSP-NEXT: bxhs lr
901 ; CHECK-DSP-NEXT: sub.w r2, r1, r12
902 ; CHECK-DSP-NEXT: uxtb r2, r2
903 ; CHECK-DSP-NEXT: cmp r2, r3
904 ; CHECK-DSP-NEXT: it ls
905 ; CHECK-DSP-NEXT: movls r0, r1
906 ; CHECK-DSP-NEXT: bx lr
908 ; CHECK-DSP-IMM-LABEL: search_through_zext_3:
909 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
910 ; CHECK-DSP-IMM-NEXT: add.w r12, r0, r1
911 ; CHECK-DSP-IMM-NEXT: uxtb.w r12, r12
912 ; CHECK-DSP-IMM-NEXT: cmp r12, r2
913 ; CHECK-DSP-IMM-NEXT: bhs .LBB14_2
914 ; CHECK-DSP-IMM-NEXT: @ %bb.1: @ %if.then
915 ; CHECK-DSP-IMM-NEXT: sub.w r2, r1, r12
916 ; CHECK-DSP-IMM-NEXT: uxtb r2, r2
917 ; CHECK-DSP-IMM-NEXT: cmp r2, r3
918 ; CHECK-DSP-IMM-NEXT: it ls
919 ; CHECK-DSP-IMM-NEXT: movls r0, r1
920 ; CHECK-DSP-IMM-NEXT: bx lr
921 ; CHECK-DSP-IMM-NEXT: .LBB14_2:
922 ; CHECK-DSP-IMM-NEXT: movs r0, #0
923 ; CHECK-DSP-IMM-NEXT: bx lr
925 %add = add nuw i8 %a, %b
926 %conv = zext i8 %add to i16
927 %cmp = icmp ult i16 %conv, %c
928 br i1 %cmp, label %if.then, label %if.end
931 %trunc = trunc i16 %conv to i8
932 %sub = sub nuw i8 %b, %trunc
933 %conv2 = zext i8 %sub to i32
934 %cmp2 = icmp ugt i32 %conv2, %d
935 %res = select i1 %cmp2, i8 %a, i8 %b
939 %retval = phi i8 [ 0, %entry ], [ %res, %if.then ]
943 ; TODO: We should be able to remove the uxt that gets introduced for %conv2
944 define i8 @search_through_zext_cmp(i8 zeroext %a, i8 zeroext %b, i16 zeroext %c) {
945 ; CHECK-NODSP-V8-LABEL: search_through_zext_cmp:
946 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
947 ; CHECK-NODSP-V8-NEXT: subs r3, r1, r0
948 ; CHECK-NODSP-V8-NEXT: subs.w r12, r1, r0
949 ; CHECK-NODSP-V8-NEXT: uxtb r3, r3
950 ; CHECK-NODSP-V8-NEXT: it ne
951 ; CHECK-NODSP-V8-NEXT: movne.w r12, #1
952 ; CHECK-NODSP-V8-NEXT: cmp r3, r2
953 ; CHECK-NODSP-V8-NEXT: it ls
954 ; CHECK-NODSP-V8-NEXT: movls r0, r1
955 ; CHECK-NODSP-V8-NEXT: cmp r12, r2
956 ; CHECK-NODSP-V8-NEXT: it hs
957 ; CHECK-NODSP-V8-NEXT: movhs r0, #0
958 ; CHECK-NODSP-V8-NEXT: bx lr
960 ; CHECK-NODSP-V7-LABEL: search_through_zext_cmp:
961 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
962 ; CHECK-NODSP-V7-NEXT: subs r3, r1, r0
963 ; CHECK-NODSP-V7-NEXT: subs.w r12, r1, r0
964 ; CHECK-NODSP-V7-NEXT: it ne
965 ; CHECK-NODSP-V7-NEXT: movne.w r12, #1
966 ; CHECK-NODSP-V7-NEXT: uxtb r3, r3
967 ; CHECK-NODSP-V7-NEXT: cmp r3, r2
968 ; CHECK-NODSP-V7-NEXT: it ls
969 ; CHECK-NODSP-V7-NEXT: movls r0, r1
970 ; CHECK-NODSP-V7-NEXT: cmp r12, r2
971 ; CHECK-NODSP-V7-NEXT: it hs
972 ; CHECK-NODSP-V7-NEXT: movhs r0, #0
973 ; CHECK-NODSP-V7-NEXT: bx lr
975 ; CHECK-DSP-LABEL: search_through_zext_cmp:
976 ; CHECK-DSP: @ %bb.0: @ %entry
977 ; CHECK-DSP-NEXT: subs r3, r1, r0
978 ; CHECK-DSP-NEXT: subs.w r12, r1, r0
979 ; CHECK-DSP-NEXT: uxtb r3, r3
980 ; CHECK-DSP-NEXT: it ne
981 ; CHECK-DSP-NEXT: movne.w r12, #1
982 ; CHECK-DSP-NEXT: cmp r3, r2
983 ; CHECK-DSP-NEXT: it ls
984 ; CHECK-DSP-NEXT: movls r0, r1
985 ; CHECK-DSP-NEXT: cmp r12, r2
986 ; CHECK-DSP-NEXT: it hs
987 ; CHECK-DSP-NEXT: movhs r0, #0
988 ; CHECK-DSP-NEXT: bx lr
990 ; CHECK-DSP-IMM-LABEL: search_through_zext_cmp:
991 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
992 ; CHECK-DSP-IMM-NEXT: subs.w r12, r1, r0
993 ; CHECK-DSP-IMM-NEXT: it ne
994 ; CHECK-DSP-IMM-NEXT: movne.w r12, #1
995 ; CHECK-DSP-IMM-NEXT: subs r3, r1, r0
996 ; CHECK-DSP-IMM-NEXT: uxtb r3, r3
997 ; CHECK-DSP-IMM-NEXT: cmp r3, r2
998 ; CHECK-DSP-IMM-NEXT: it hi
999 ; CHECK-DSP-IMM-NEXT: movhi r1, r0
1000 ; CHECK-DSP-IMM-NEXT: movs r0, #0
1001 ; CHECK-DSP-IMM-NEXT: cmp r12, r2
1002 ; CHECK-DSP-IMM-NEXT: it lo
1003 ; CHECK-DSP-IMM-NEXT: movlo r0, r1
1004 ; CHECK-DSP-IMM-NEXT: bx lr
1006 %cmp = icmp ne i8 %a, %b
1007 %conv = zext i1 %cmp to i16
1008 %cmp1 = icmp ult i16 %conv, %c
1009 br i1 %cmp1, label %if.then, label %if.end
1012 %sub = sub nuw i8 %b, %a
1013 %conv2 = zext i8 %sub to i16
1014 %cmp3 = icmp ugt i16 %conv2, %c
1015 %res = select i1 %cmp3, i8 %a, i8 %b
1019 %retval = phi i8 [ 0, %entry ], [ %res, %if.then ]
1023 define i8 @search_through_zext_load(i8* %a, i8 zeroext %b, i16 zeroext %c) {
1024 ; CHECK-NODSP-V8-LABEL: search_through_zext_load:
1025 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1026 ; CHECK-NODSP-V8-NEXT: ldrb r3, [r0]
1027 ; CHECK-NODSP-V8-NEXT: mov r0, r1
1028 ; CHECK-NODSP-V8-NEXT: subs r1, r1, r3
1029 ; CHECK-NODSP-V8-NEXT: cmp r1, r2
1030 ; CHECK-NODSP-V8-NEXT: it hi
1031 ; CHECK-NODSP-V8-NEXT: movhi r0, r3
1032 ; CHECK-NODSP-V8-NEXT: cmp r3, r2
1033 ; CHECK-NODSP-V8-NEXT: it hs
1034 ; CHECK-NODSP-V8-NEXT: movhs r0, #0
1035 ; CHECK-NODSP-V8-NEXT: bx lr
1037 ; CHECK-NODSP-V7-LABEL: search_through_zext_load:
1038 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1039 ; CHECK-NODSP-V7-NEXT: ldrb r0, [r0]
1040 ; CHECK-NODSP-V7-NEXT: subs r3, r1, r0
1041 ; CHECK-NODSP-V7-NEXT: cmp r3, r2
1042 ; CHECK-NODSP-V7-NEXT: it hi
1043 ; CHECK-NODSP-V7-NEXT: movhi r1, r0
1044 ; CHECK-NODSP-V7-NEXT: cmp r0, r2
1045 ; CHECK-NODSP-V7-NEXT: it hs
1046 ; CHECK-NODSP-V7-NEXT: movhs r1, #0
1047 ; CHECK-NODSP-V7-NEXT: mov r0, r1
1048 ; CHECK-NODSP-V7-NEXT: bx lr
1050 ; CHECK-DSP-LABEL: search_through_zext_load:
1051 ; CHECK-DSP: @ %bb.0: @ %entry
1052 ; CHECK-DSP-NEXT: ldrb r0, [r0]
1053 ; CHECK-DSP-NEXT: subs r3, r1, r0
1054 ; CHECK-DSP-NEXT: cmp r3, r2
1055 ; CHECK-DSP-NEXT: it hi
1056 ; CHECK-DSP-NEXT: movhi r1, r0
1057 ; CHECK-DSP-NEXT: cmp r0, r2
1058 ; CHECK-DSP-NEXT: it hs
1059 ; CHECK-DSP-NEXT: movhs r1, #0
1060 ; CHECK-DSP-NEXT: mov r0, r1
1061 ; CHECK-DSP-NEXT: bx lr
1063 ; CHECK-DSP-IMM-LABEL: search_through_zext_load:
1064 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1065 ; CHECK-DSP-IMM-NEXT: ldrb r3, [r0]
1066 ; CHECK-DSP-IMM-NEXT: subs r0, r1, r3
1067 ; CHECK-DSP-IMM-NEXT: cmp r0, r2
1068 ; CHECK-DSP-IMM-NEXT: it hi
1069 ; CHECK-DSP-IMM-NEXT: movhi r1, r3
1070 ; CHECK-DSP-IMM-NEXT: movs r0, #0
1071 ; CHECK-DSP-IMM-NEXT: cmp r3, r2
1072 ; CHECK-DSP-IMM-NEXT: it lo
1073 ; CHECK-DSP-IMM-NEXT: movlo r0, r1
1074 ; CHECK-DSP-IMM-NEXT: bx lr
1076 %load = load i8, i8* %a
1077 %conv = zext i8 %load to i16
1078 %cmp1 = icmp ult i16 %conv, %c
1079 br i1 %cmp1, label %if.then, label %if.end
1082 %sub = sub nuw i8 %b, %load
1083 %conv2 = zext i8 %sub to i16
1084 %cmp3 = icmp ugt i16 %conv2, %c
1085 %res = select i1 %cmp3, i8 %load, i8 %b
1089 %retval = phi i8 [ 0, %entry ], [ %res, %if.then ]
1093 define i16 @trunc_sink_less_than_cmp(i16 zeroext %a, i16 zeroext %b, i16 zeroext %c, i8 zeroext %d) {
1094 ; CHECK-NODSP-V8-LABEL: trunc_sink_less_than_cmp:
1095 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1096 ; CHECK-NODSP-V8-NEXT: push {r7, lr}
1097 ; CHECK-NODSP-V8-NEXT: sub.w r12, r1, r0
1098 ; CHECK-NODSP-V8-NEXT: adds r3, #1
1099 ; CHECK-NODSP-V8-NEXT: uxth.w lr, r12
1100 ; CHECK-NODSP-V8-NEXT: uxtb.w r12, r12
1101 ; CHECK-NODSP-V8-NEXT: uxtb r3, r3
1102 ; CHECK-NODSP-V8-NEXT: cmp r12, r3
1103 ; CHECK-NODSP-V8-NEXT: it ls
1104 ; CHECK-NODSP-V8-NEXT: movls r0, r1
1105 ; CHECK-NODSP-V8-NEXT: cmp lr, r2
1106 ; CHECK-NODSP-V8-NEXT: it hs
1107 ; CHECK-NODSP-V8-NEXT: movhs r0, #0
1108 ; CHECK-NODSP-V8-NEXT: pop {r7, pc}
1110 ; CHECK-NODSP-V7-LABEL: trunc_sink_less_than_cmp:
1111 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1112 ; CHECK-NODSP-V7-NEXT: .save {r7, lr}
1113 ; CHECK-NODSP-V7-NEXT: push {r7, lr}
1114 ; CHECK-NODSP-V7-NEXT: adds r3, #1
1115 ; CHECK-NODSP-V7-NEXT: sub.w r12, r1, r0
1116 ; CHECK-NODSP-V7-NEXT: uxtb.w lr, r12
1117 ; CHECK-NODSP-V7-NEXT: uxtb r3, r3
1118 ; CHECK-NODSP-V7-NEXT: cmp lr, r3
1119 ; CHECK-NODSP-V7-NEXT: it ls
1120 ; CHECK-NODSP-V7-NEXT: movls r0, r1
1121 ; CHECK-NODSP-V7-NEXT: uxth.w r1, r12
1122 ; CHECK-NODSP-V7-NEXT: cmp r1, r2
1123 ; CHECK-NODSP-V7-NEXT: it hs
1124 ; CHECK-NODSP-V7-NEXT: movhs r0, #0
1125 ; CHECK-NODSP-V7-NEXT: pop {r7, pc}
1127 ; CHECK-DSP-LABEL: trunc_sink_less_than_cmp:
1128 ; CHECK-DSP: @ %bb.0: @ %entry
1129 ; CHECK-DSP-NEXT: push {r7, lr}
1130 ; CHECK-DSP-NEXT: adds r3, #1
1131 ; CHECK-DSP-NEXT: sub.w r12, r1, r0
1132 ; CHECK-DSP-NEXT: uxtb.w lr, r12
1133 ; CHECK-DSP-NEXT: uxtb r3, r3
1134 ; CHECK-DSP-NEXT: cmp lr, r3
1135 ; CHECK-DSP-NEXT: it ls
1136 ; CHECK-DSP-NEXT: movls r0, r1
1137 ; CHECK-DSP-NEXT: uxth.w r1, r12
1138 ; CHECK-DSP-NEXT: cmp r1, r2
1139 ; CHECK-DSP-NEXT: it hs
1140 ; CHECK-DSP-NEXT: movhs r0, #0
1141 ; CHECK-DSP-NEXT: pop {r7, pc}
1143 ; CHECK-DSP-IMM-LABEL: trunc_sink_less_than_cmp:
1144 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1145 ; CHECK-DSP-IMM-NEXT: push {r7, lr}
1146 ; CHECK-DSP-IMM-NEXT: adds r3, #1
1147 ; CHECK-DSP-IMM-NEXT: sub.w r12, r1, r0
1148 ; CHECK-DSP-IMM-NEXT: uxtb r3, r3
1149 ; CHECK-DSP-IMM-NEXT: uxtb.w lr, r12
1150 ; CHECK-DSP-IMM-NEXT: cmp lr, r3
1151 ; CHECK-DSP-IMM-NEXT: it hi
1152 ; CHECK-DSP-IMM-NEXT: movhi r1, r0
1153 ; CHECK-DSP-IMM-NEXT: movs r0, #0
1154 ; CHECK-DSP-IMM-NEXT: uxth.w r3, r12
1155 ; CHECK-DSP-IMM-NEXT: cmp r3, r2
1156 ; CHECK-DSP-IMM-NEXT: it lo
1157 ; CHECK-DSP-IMM-NEXT: movlo r0, r1
1158 ; CHECK-DSP-IMM-NEXT: pop {r7, pc}
1160 %sub = sub nuw i16 %b, %a
1161 %cmp = icmp ult i16 %sub, %c
1162 br i1 %cmp, label %if.then, label %if.end
1165 %trunc = trunc i16 %sub to i8
1166 %add = add nuw i8 %d, 1
1167 %cmp2 = icmp ugt i8 %trunc, %add
1168 %res = select i1 %cmp2, i16 %a, i16 %b
1172 %retval = phi i16 [ 0, %entry ], [ %res, %if.then ]
1176 ; TODO: We should be able to remove the uxth introduced to handle %sub
1177 define i16 @trunc_sink_less_than_arith(i16 zeroext %a, i16 zeroext %b, i16 zeroext %c, i8 zeroext %d, i8 zeroext %e) {
1178 ; CHECK-NODSP-V8-LABEL: trunc_sink_less_than_arith:
1179 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1180 ; CHECK-NODSP-V8-NEXT: push {r4, lr}
1181 ; CHECK-NODSP-V8-NEXT: sub.w lr, r1, r0
1182 ; CHECK-NODSP-V8-NEXT: ldr.w r12, [sp, #8]
1183 ; CHECK-NODSP-V8-NEXT: add r3, lr
1184 ; CHECK-NODSP-V8-NEXT: uxtb r3, r3
1185 ; CHECK-NODSP-V8-NEXT: uxth.w r4, lr
1186 ; CHECK-NODSP-V8-NEXT: cmp r12, r3
1187 ; CHECK-NODSP-V8-NEXT: it ls
1188 ; CHECK-NODSP-V8-NEXT: movls r0, r1
1189 ; CHECK-NODSP-V8-NEXT: cmp r4, r2
1190 ; CHECK-NODSP-V8-NEXT: it hs
1191 ; CHECK-NODSP-V8-NEXT: movhs r0, #0
1192 ; CHECK-NODSP-V8-NEXT: pop {r4, pc}
1194 ; CHECK-NODSP-V7-LABEL: trunc_sink_less_than_arith:
1195 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1196 ; CHECK-NODSP-V7-NEXT: .save {r7, lr}
1197 ; CHECK-NODSP-V7-NEXT: push {r7, lr}
1198 ; CHECK-NODSP-V7-NEXT: sub.w lr, r1, r0
1199 ; CHECK-NODSP-V7-NEXT: ldr.w r12, [sp, #8]
1200 ; CHECK-NODSP-V7-NEXT: add r3, lr
1201 ; CHECK-NODSP-V7-NEXT: uxtb r3, r3
1202 ; CHECK-NODSP-V7-NEXT: cmp r12, r3
1203 ; CHECK-NODSP-V7-NEXT: it ls
1204 ; CHECK-NODSP-V7-NEXT: movls r0, r1
1205 ; CHECK-NODSP-V7-NEXT: uxth.w r1, lr
1206 ; CHECK-NODSP-V7-NEXT: cmp r1, r2
1207 ; CHECK-NODSP-V7-NEXT: it hs
1208 ; CHECK-NODSP-V7-NEXT: movhs r0, #0
1209 ; CHECK-NODSP-V7-NEXT: pop {r7, pc}
1211 ; CHECK-DSP-LABEL: trunc_sink_less_than_arith:
1212 ; CHECK-DSP: @ %bb.0: @ %entry
1213 ; CHECK-DSP-NEXT: push {r7, lr}
1214 ; CHECK-DSP-NEXT: sub.w r12, r1, r0
1215 ; CHECK-DSP-NEXT: add r3, r12
1216 ; CHECK-DSP-NEXT: uxtb.w lr, r3
1217 ; CHECK-DSP-NEXT: ldr r3, [sp, #8]
1218 ; CHECK-DSP-NEXT: cmp r3, lr
1219 ; CHECK-DSP-NEXT: it ls
1220 ; CHECK-DSP-NEXT: movls r0, r1
1221 ; CHECK-DSP-NEXT: uxth.w r1, r12
1222 ; CHECK-DSP-NEXT: cmp r1, r2
1223 ; CHECK-DSP-NEXT: it hs
1224 ; CHECK-DSP-NEXT: movhs r0, #0
1225 ; CHECK-DSP-NEXT: pop {r7, pc}
1227 ; CHECK-DSP-IMM-LABEL: trunc_sink_less_than_arith:
1228 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1229 ; CHECK-DSP-IMM-NEXT: push {r7, lr}
1230 ; CHECK-DSP-IMM-NEXT: sub.w lr, r1, r0
1231 ; CHECK-DSP-IMM-NEXT: ldr.w r12, [sp, #8]
1232 ; CHECK-DSP-IMM-NEXT: add r3, lr
1233 ; CHECK-DSP-IMM-NEXT: uxtb r3, r3
1234 ; CHECK-DSP-IMM-NEXT: cmp r12, r3
1235 ; CHECK-DSP-IMM-NEXT: it hi
1236 ; CHECK-DSP-IMM-NEXT: movhi r1, r0
1237 ; CHECK-DSP-IMM-NEXT: movs r0, #0
1238 ; CHECK-DSP-IMM-NEXT: uxth.w r3, lr
1239 ; CHECK-DSP-IMM-NEXT: cmp r3, r2
1240 ; CHECK-DSP-IMM-NEXT: it lo
1241 ; CHECK-DSP-IMM-NEXT: movlo r0, r1
1242 ; CHECK-DSP-IMM-NEXT: pop {r7, pc}
1244 %sub = sub nuw i16 %b, %a
1245 %cmp = icmp ult i16 %sub, %c
1246 br i1 %cmp, label %if.then, label %if.end
1249 %trunc = trunc i16 %sub to i8
1250 %add = add nuw i8 %d, %trunc
1251 %cmp2 = icmp ugt i8 %e, %add
1252 %res = select i1 %cmp2, i16 %a, i16 %b
1256 %retval = phi i16 [ 0, %entry ], [ %res, %if.then ]
1260 define i16 @trunc_sink_less_than_store(i16 zeroext %a, i16 zeroext %b, i16 zeroext %c, i8 zeroext %d, i8* %e) {
1261 ; CHECK-NODSP-LABEL: trunc_sink_less_than_store:
1262 ; CHECK-NODSP: @ %bb.0: @ %entry
1263 ; CHECK-NODSP-NEXT: subs r0, r1, r0
1264 ; CHECK-NODSP-NEXT: cmp r0, r2
1265 ; CHECK-NODSP-NEXT: iteee hs
1266 ; CHECK-NODSP-NEXT: movhs r0, #0
1267 ; CHECK-NODSP-NEXT: ldrlo r1, [sp]
1268 ; CHECK-NODSP-NEXT: addlo r2, r3, r0
1269 ; CHECK-NODSP-NEXT: strblo r2, [r1]
1270 ; CHECK-NODSP-NEXT: bx lr
1272 ; CHECK-DSP-LABEL: trunc_sink_less_than_store:
1273 ; CHECK-DSP: @ %bb.0: @ %entry
1274 ; CHECK-DSP-NEXT: subs r0, r1, r0
1275 ; CHECK-DSP-NEXT: cmp r0, r2
1276 ; CHECK-DSP-NEXT: iteee hs
1277 ; CHECK-DSP-NEXT: movhs r0, #0
1278 ; CHECK-DSP-NEXT: ldrlo r1, [sp]
1279 ; CHECK-DSP-NEXT: addlo r2, r3, r0
1280 ; CHECK-DSP-NEXT: strblo r2, [r1]
1281 ; CHECK-DSP-NEXT: bx lr
1283 ; CHECK-DSP-IMM-LABEL: trunc_sink_less_than_store:
1284 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1285 ; CHECK-DSP-IMM-NEXT: subs r0, r1, r0
1286 ; CHECK-DSP-IMM-NEXT: cmp r0, r2
1287 ; CHECK-DSP-IMM-NEXT: bhs .LBB19_2
1288 ; CHECK-DSP-IMM-NEXT: @ %bb.1: @ %if.then
1289 ; CHECK-DSP-IMM-NEXT: ldr r1, [sp]
1290 ; CHECK-DSP-IMM-NEXT: adds r2, r3, r0
1291 ; CHECK-DSP-IMM-NEXT: strb r2, [r1]
1292 ; CHECK-DSP-IMM-NEXT: bx lr
1293 ; CHECK-DSP-IMM-NEXT: .LBB19_2:
1294 ; CHECK-DSP-IMM-NEXT: movs r0, #0
1295 ; CHECK-DSP-IMM-NEXT: bx lr
1297 %sub = sub nuw i16 %b, %a
1298 %cmp = icmp ult i16 %sub, %c
1299 br i1 %cmp, label %if.then, label %if.end
1302 %trunc = trunc i16 %sub to i8
1303 %add = add nuw i8 %d, %trunc
1304 store i8 %add, i8* %e
1308 %retval = phi i16 [ 0, %entry ], [ %sub, %if.then ]
1312 define i8 @trunc_sink_less_than_ret(i16 zeroext %a, i16 zeroext %b, i16 zeroext %c, i8 zeroext %d, i8 zeroext %e) {
1313 ; CHECK-NODSP-LABEL: trunc_sink_less_than_ret:
1314 ; CHECK-NODSP: @ %bb.0: @ %entry
1315 ; CHECK-NODSP-NEXT: subs r1, r1, r0
1316 ; CHECK-NODSP-NEXT: movs r0, #0
1317 ; CHECK-NODSP-NEXT: cmp r1, r2
1318 ; CHECK-NODSP-NEXT: it lo
1319 ; CHECK-NODSP-NEXT: uxtablo r0, r3, r1
1320 ; CHECK-NODSP-NEXT: bx lr
1322 ; CHECK-DSP-LABEL: trunc_sink_less_than_ret:
1323 ; CHECK-DSP: @ %bb.0: @ %entry
1324 ; CHECK-DSP-NEXT: subs r1, r1, r0
1325 ; CHECK-DSP-NEXT: movs r0, #0
1326 ; CHECK-DSP-NEXT: cmp r1, r2
1327 ; CHECK-DSP-NEXT: it lo
1328 ; CHECK-DSP-NEXT: uxtablo r0, r3, r1
1329 ; CHECK-DSP-NEXT: bx lr
1331 ; CHECK-DSP-IMM-LABEL: trunc_sink_less_than_ret:
1332 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1333 ; CHECK-DSP-IMM-NEXT: subs r1, r1, r0
1334 ; CHECK-DSP-IMM-NEXT: movs r0, #0
1335 ; CHECK-DSP-IMM-NEXT: cmp r1, r2
1336 ; CHECK-DSP-IMM-NEXT: uxtab r3, r3, r1
1337 ; CHECK-DSP-IMM-NEXT: it lo
1338 ; CHECK-DSP-IMM-NEXT: movlo r0, r3
1339 ; CHECK-DSP-IMM-NEXT: bx lr
1341 %sub = sub nuw i16 %b, %a
1342 %cmp = icmp ult i16 %sub, %c
1343 br i1 %cmp, label %if.then, label %if.end
1346 %trunc = trunc i16 %sub to i8
1347 %add = add nuw i8 %d, %trunc
1351 %retval = phi i8 [ 0, %entry ], [ %add, %if.then ]
1355 define zeroext i8 @trunc_sink_less_than_zext_ret(i16 zeroext %a, i16 zeroext %b, i16 zeroext %c, i8 zeroext %d, i8 zeroext %e) {
1356 ; CHECK-NODSP-LABEL: trunc_sink_less_than_zext_ret:
1357 ; CHECK-NODSP: @ %bb.0: @ %entry
1358 ; CHECK-NODSP-NEXT: subs r0, r1, r0
1359 ; CHECK-NODSP-NEXT: movs r1, #0
1360 ; CHECK-NODSP-NEXT: cmp r0, r2
1361 ; CHECK-NODSP-NEXT: it lo
1362 ; CHECK-NODSP-NEXT: addlo r1, r3, r0
1363 ; CHECK-NODSP-NEXT: uxtb r0, r1
1364 ; CHECK-NODSP-NEXT: bx lr
1366 ; CHECK-DSP-LABEL: trunc_sink_less_than_zext_ret:
1367 ; CHECK-DSP: @ %bb.0: @ %entry
1368 ; CHECK-DSP-NEXT: subs r0, r1, r0
1369 ; CHECK-DSP-NEXT: movs r1, #0
1370 ; CHECK-DSP-NEXT: cmp r0, r2
1371 ; CHECK-DSP-NEXT: it lo
1372 ; CHECK-DSP-NEXT: addlo r1, r3, r0
1373 ; CHECK-DSP-NEXT: uxtb r0, r1
1374 ; CHECK-DSP-NEXT: bx lr
1376 ; CHECK-DSP-IMM-LABEL: trunc_sink_less_than_zext_ret:
1377 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1378 ; CHECK-DSP-IMM-NEXT: subs r0, r1, r0
1379 ; CHECK-DSP-IMM-NEXT: adds r1, r3, r0
1380 ; CHECK-DSP-IMM-NEXT: movs r3, #0
1381 ; CHECK-DSP-IMM-NEXT: cmp r0, r2
1382 ; CHECK-DSP-IMM-NEXT: it lo
1383 ; CHECK-DSP-IMM-NEXT: movlo r3, r1
1384 ; CHECK-DSP-IMM-NEXT: uxtb r0, r3
1385 ; CHECK-DSP-IMM-NEXT: bx lr
1387 %sub = sub nuw i16 %b, %a
1388 %cmp = icmp ult i16 %sub, %c
1389 br i1 %cmp, label %if.then, label %if.end
1392 %trunc = trunc i16 %sub to i8
1393 %add = add nuw i8 %d, %trunc
1397 %retval = phi i8 [ 0, %entry ], [ %add, %if.then ]
1401 define i32 @bitcast_i1(i16 zeroext %a, i32 %b, i32 %c) {
1402 ; CHECK-LABEL: bitcast_i1:
1403 ; CHECK: @ %bb.0: @ %entry
1404 ; CHECK-NEXT: ands r0, r0, #1
1406 ; CHECK-NEXT: movne r0, r1
1409 %0 = bitcast i1 1 to i1
1410 %1 = trunc i16 %a to i1
1411 %cmp = icmp eq i1 %1, %0
1412 br i1 %cmp, label %if.then, label %exit
1415 %conv = zext i1 %0 to i16
1416 %conv1 = zext i1 %1 to i16
1417 %cmp1 = icmp uge i16 %conv, %conv1
1418 %select = select i1 %cmp1, i32 %b, i32 %c
1422 %retval = phi i32 [ %select, %if.then ], [ 0, %entry ]
1426 define void @search_back_through_trunc(i8* %a, i8* %b, i8* %c, i8* %d, i16* %e) {
1427 ; CHECK-NODSP-V8-LABEL: search_back_through_trunc:
1428 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1429 ; CHECK-NODSP-V8-NEXT: push {r7, lr}
1430 ; CHECK-NODSP-V8-NEXT: ldrb.w r12, [r0]
1431 ; CHECK-NODSP-V8-NEXT: ldrb.w lr, [r1]
1432 ; CHECK-NODSP-V8-NEXT: ldrb r1, [r2]
1433 ; CHECK-NODSP-V8-NEXT: ldrb r0, [r3]
1434 ; CHECK-NODSP-V8-NEXT: orr.w r12, lr, r12, lsl #8
1435 ; CHECK-NODSP-V8-NEXT: orr.w r0, r0, r1, lsl #8
1436 ; CHECK-NODSP-V8-NEXT: cmp r12, r0
1437 ; CHECK-NODSP-V8-NEXT: beq .LBB23_2
1438 ; CHECK-NODSP-V8-NEXT: @ %bb.1: @ %if.else136
1439 ; CHECK-NODSP-V8-NEXT: ldr r0, [sp, #8]
1440 ; CHECK-NODSP-V8-NEXT: ldrh r0, [r0]
1441 ; CHECK-NODSP-V8-NEXT: uxtb.w lr, r0
1442 ; CHECK-NODSP-V8-NEXT: lsrs r1, r0, #8
1443 ; CHECK-NODSP-V8-NEXT: .LBB23_2: @ %if.end183
1444 ; CHECK-NODSP-V8-NEXT: strb r1, [r2]
1445 ; CHECK-NODSP-V8-NEXT: strb.w lr, [r3]
1446 ; CHECK-NODSP-V8-NEXT: pop {r7, pc}
1448 ; CHECK-NODSP-V7-LABEL: search_back_through_trunc:
1449 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1450 ; CHECK-NODSP-V7-NEXT: .save {r4, lr}
1451 ; CHECK-NODSP-V7-NEXT: push {r4, lr}
1452 ; CHECK-NODSP-V7-NEXT: ldrb r4, [r0]
1453 ; CHECK-NODSP-V7-NEXT: ldrb.w r12, [r2]
1454 ; CHECK-NODSP-V7-NEXT: ldrb r0, [r1]
1455 ; CHECK-NODSP-V7-NEXT: ldrb.w lr, [r3]
1456 ; CHECK-NODSP-V7-NEXT: orr.w r4, r0, r4, lsl #8
1457 ; CHECK-NODSP-V7-NEXT: orr.w r1, lr, r12, lsl #8
1458 ; CHECK-NODSP-V7-NEXT: cmp r4, r1
1459 ; CHECK-NODSP-V7-NEXT: itttt ne
1460 ; CHECK-NODSP-V7-NEXT: ldrne r0, [sp, #8]
1461 ; CHECK-NODSP-V7-NEXT: ldrhne r0, [r0]
1462 ; CHECK-NODSP-V7-NEXT: lsrne.w r12, r0, #8
1463 ; CHECK-NODSP-V7-NEXT: uxtbne r0, r0
1464 ; CHECK-NODSP-V7-NEXT: strb.w r12, [r2]
1465 ; CHECK-NODSP-V7-NEXT: strb r0, [r3]
1466 ; CHECK-NODSP-V7-NEXT: pop {r4, pc}
1468 ; CHECK-DSP-LABEL: search_back_through_trunc:
1469 ; CHECK-DSP: @ %bb.0: @ %entry
1470 ; CHECK-DSP-NEXT: push {r4, lr}
1471 ; CHECK-DSP-NEXT: ldrb r4, [r0]
1472 ; CHECK-DSP-NEXT: ldrb r0, [r1]
1473 ; CHECK-DSP-NEXT: ldrb.w r12, [r2]
1474 ; CHECK-DSP-NEXT: ldrb.w lr, [r3]
1475 ; CHECK-DSP-NEXT: orr.w lr, lr, r12, lsl #8
1476 ; CHECK-DSP-NEXT: orr.w r1, r0, r4, lsl #8
1477 ; CHECK-DSP-NEXT: cmp r1, lr
1478 ; CHECK-DSP-NEXT: itttt ne
1479 ; CHECK-DSP-NEXT: ldrne r0, [sp, #8]
1480 ; CHECK-DSP-NEXT: ldrhne r0, [r0]
1481 ; CHECK-DSP-NEXT: lsrne.w r12, r0, #8
1482 ; CHECK-DSP-NEXT: uxtbne r0, r0
1483 ; CHECK-DSP-NEXT: strb.w r12, [r2]
1484 ; CHECK-DSP-NEXT: strb r0, [r3]
1485 ; CHECK-DSP-NEXT: pop {r4, pc}
1487 ; CHECK-DSP-IMM-LABEL: search_back_through_trunc:
1488 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1489 ; CHECK-DSP-IMM-NEXT: push {r4, lr}
1490 ; CHECK-DSP-IMM-NEXT: ldrb r4, [r0]
1491 ; CHECK-DSP-IMM-NEXT: ldrb.w r12, [r2]
1492 ; CHECK-DSP-IMM-NEXT: ldrb r0, [r1]
1493 ; CHECK-DSP-IMM-NEXT: ldrb.w lr, [r3]
1494 ; CHECK-DSP-IMM-NEXT: orr.w r4, r0, r4, lsl #8
1495 ; CHECK-DSP-IMM-NEXT: orr.w r1, lr, r12, lsl #8
1496 ; CHECK-DSP-IMM-NEXT: cmp r4, r1
1497 ; CHECK-DSP-IMM-NEXT: beq .LBB23_2
1498 ; CHECK-DSP-IMM-NEXT: @ %bb.1: @ %if.else136
1499 ; CHECK-DSP-IMM-NEXT: ldr r0, [sp, #8]
1500 ; CHECK-DSP-IMM-NEXT: ldrh r0, [r0]
1501 ; CHECK-DSP-IMM-NEXT: lsr.w r12, r0, #8
1502 ; CHECK-DSP-IMM-NEXT: uxtb r0, r0
1503 ; CHECK-DSP-IMM-NEXT: .LBB23_2: @ %if.end183
1504 ; CHECK-DSP-IMM-NEXT: strb.w r12, [r2]
1505 ; CHECK-DSP-IMM-NEXT: strb r0, [r3]
1506 ; CHECK-DSP-IMM-NEXT: pop {r4, pc}
1508 %0 = load i8, i8* %a, align 1
1509 %conv106 = zext i8 %0 to i16
1510 %shl = shl nuw i16 %conv106, 8
1511 %1 = load i8, i8* %b, align 1
1512 %conv108 = zext i8 %1 to i16
1513 %or109 = or i16 %shl, %conv108
1514 %2 = load i8, i8* %c, align 1
1515 %conv119 = zext i8 %2 to i16
1516 %shl120 = shl nuw i16 %conv119, 8
1517 %3 = load i8, i8* %d, align 1
1518 %conv122 = zext i8 %3 to i16
1519 %or123 = or i16 %shl120, %conv122
1520 %cmp133 = icmp eq i16 %or109, %or123
1521 br i1 %cmp133, label %if.end183, label %if.else136
1524 %4 = load i16, i16* %e, align 2
1525 %extract.t854 = trunc i16 %4 to i8
1526 %extract856 = lshr i16 %4, 8
1527 %extract.t857 = trunc i16 %extract856 to i8
1531 %w.0.off0 = phi i8 [ %extract.t854, %if.else136 ], [ %1, %entry ]
1532 %w.0.off8 = phi i8 [ %extract.t857, %if.else136 ], [ %2, %entry ]
1533 store i8 %w.0.off8, i8* %c, align 1
1534 store i8 %w.0.off0, i8* %d, align 1
1538 @c = common dso_local local_unnamed_addr global i16 0, align 2
1539 @b = common dso_local local_unnamed_addr global i16 0, align 2
1540 @f = common dso_local local_unnamed_addr global i32 0, align 4
1541 @e = common dso_local local_unnamed_addr global i8 0, align 1
1542 @a = common dso_local local_unnamed_addr global i8 0, align 1
1543 @d = common dso_local local_unnamed_addr global i32 0, align 4
1545 define void @and_trunc_two_zext() {
1546 ; CHECK-NODSP-V8-LABEL: and_trunc_two_zext:
1547 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1548 ; CHECK-NODSP-V8-NEXT: movw r1, :lower16:b
1549 ; CHECK-NODSP-V8-NEXT: movt r1, :upper16:b
1550 ; CHECK-NODSP-V8-NEXT: ldrh r1, [r1]
1551 ; CHECK-NODSP-V8-NEXT: movw r3, :lower16:f
1552 ; CHECK-NODSP-V8-NEXT: sxth r2, r1
1553 ; CHECK-NODSP-V8-NEXT: movt r3, :upper16:f
1554 ; CHECK-NODSP-V8-NEXT: str r2, [r3]
1555 ; CHECK-NODSP-V8-NEXT: movw r3, :lower16:a
1556 ; CHECK-NODSP-V8-NEXT: movt r3, :upper16:a
1557 ; CHECK-NODSP-V8-NEXT: movw r0, :lower16:c
1558 ; CHECK-NODSP-V8-NEXT: movw r2, :lower16:e
1559 ; CHECK-NODSP-V8-NEXT: ldrb r3, [r3]
1560 ; CHECK-NODSP-V8-NEXT: movt r0, :upper16:c
1561 ; CHECK-NODSP-V8-NEXT: and r1, r1, #1
1562 ; CHECK-NODSP-V8-NEXT: movt r2, :upper16:e
1563 ; CHECK-NODSP-V8-NEXT: ldrh r0, [r0]
1564 ; CHECK-NODSP-V8-NEXT: strb r1, [r2]
1565 ; CHECK-NODSP-V8-NEXT: muls r1, r3, r1
1566 ; CHECK-NODSP-V8-NEXT: uxtb r1, r1
1567 ; CHECK-NODSP-V8-NEXT: movw r2, :lower16:d
1568 ; CHECK-NODSP-V8-NEXT: orrs r0, r1
1569 ; CHECK-NODSP-V8-NEXT: movt r2, :upper16:d
1570 ; CHECK-NODSP-V8-NEXT: lsls r0, r0, #16
1571 ; CHECK-NODSP-V8-NEXT: str r1, [r2]
1572 ; CHECK-NODSP-V8-NEXT: it eq
1573 ; CHECK-NODSP-V8-NEXT: bxeq lr
1574 ; CHECK-NODSP-V8-NEXT: .p2align 2
1575 ; CHECK-NODSP-V8-NEXT: .LBB24_1: @ %for.cond
1576 ; CHECK-NODSP-V8-NEXT: @ =>This Inner Loop Header: Depth=1
1577 ; CHECK-NODSP-V8-NEXT: b .LBB24_1
1579 ; CHECK-NODSP-V7-LABEL: and_trunc_two_zext:
1580 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1581 ; CHECK-NODSP-V7-NEXT: movw r1, :lower16:b
1582 ; CHECK-NODSP-V7-NEXT: movw r2, :lower16:a
1583 ; CHECK-NODSP-V7-NEXT: movt r1, :upper16:b
1584 ; CHECK-NODSP-V7-NEXT: movt r2, :upper16:a
1585 ; CHECK-NODSP-V7-NEXT: ldrh r1, [r1]
1586 ; CHECK-NODSP-V7-NEXT: movw r0, :lower16:c
1587 ; CHECK-NODSP-V7-NEXT: ldrb r2, [r2]
1588 ; CHECK-NODSP-V7-NEXT: movt r0, :upper16:c
1589 ; CHECK-NODSP-V7-NEXT: and r3, r1, #1
1590 ; CHECK-NODSP-V7-NEXT: ldrh.w r12, [r0]
1591 ; CHECK-NODSP-V7-NEXT: movw r0, :lower16:e
1592 ; CHECK-NODSP-V7-NEXT: muls r2, r3, r2
1593 ; CHECK-NODSP-V7-NEXT: movt r0, :upper16:e
1594 ; CHECK-NODSP-V7-NEXT: strb r3, [r0]
1595 ; CHECK-NODSP-V7-NEXT: sxth r0, r1
1596 ; CHECK-NODSP-V7-NEXT: movw r1, :lower16:f
1597 ; CHECK-NODSP-V7-NEXT: movt r1, :upper16:f
1598 ; CHECK-NODSP-V7-NEXT: str r0, [r1]
1599 ; CHECK-NODSP-V7-NEXT: movw r1, :lower16:d
1600 ; CHECK-NODSP-V7-NEXT: movt r1, :upper16:d
1601 ; CHECK-NODSP-V7-NEXT: uxtb r0, r2
1602 ; CHECK-NODSP-V7-NEXT: str r0, [r1]
1603 ; CHECK-NODSP-V7-NEXT: orr.w r0, r0, r12
1604 ; CHECK-NODSP-V7-NEXT: lsls r0, r0, #16
1605 ; CHECK-NODSP-V7-NEXT: it eq
1606 ; CHECK-NODSP-V7-NEXT: bxeq lr
1607 ; CHECK-NODSP-V7-NEXT: .LBB24_1: @ %for.cond
1608 ; CHECK-NODSP-V7-NEXT: @ =>This Inner Loop Header: Depth=1
1609 ; CHECK-NODSP-V7-NEXT: b .LBB24_1
1611 ; CHECK-DSP-LABEL: and_trunc_two_zext:
1612 ; CHECK-DSP: @ %bb.0: @ %entry
1613 ; CHECK-DSP-NEXT: movw r0, :lower16:b
1614 ; CHECK-DSP-NEXT: movw r2, :lower16:f
1615 ; CHECK-DSP-NEXT: movt r0, :upper16:b
1616 ; CHECK-DSP-NEXT: movt r2, :upper16:f
1617 ; CHECK-DSP-NEXT: ldrh r0, [r0]
1618 ; CHECK-DSP-NEXT: sxth r1, r0
1619 ; CHECK-DSP-NEXT: and r0, r0, #1
1620 ; CHECK-DSP-NEXT: str r1, [r2]
1621 ; CHECK-DSP-NEXT: movw r1, :lower16:e
1622 ; CHECK-DSP-NEXT: movt r1, :upper16:e
1623 ; CHECK-DSP-NEXT: strb r0, [r1]
1624 ; CHECK-DSP-NEXT: movw r1, :lower16:a
1625 ; CHECK-DSP-NEXT: movt r1, :upper16:a
1626 ; CHECK-DSP-NEXT: ldrb r1, [r1]
1627 ; CHECK-DSP-NEXT: muls r0, r1, r0
1628 ; CHECK-DSP-NEXT: movw r1, :lower16:d
1629 ; CHECK-DSP-NEXT: uxtb r0, r0
1630 ; CHECK-DSP-NEXT: movt r1, :upper16:d
1631 ; CHECK-DSP-NEXT: str r0, [r1]
1632 ; CHECK-DSP-NEXT: movw r1, :lower16:c
1633 ; CHECK-DSP-NEXT: movt r1, :upper16:c
1634 ; CHECK-DSP-NEXT: ldrh r1, [r1]
1635 ; CHECK-DSP-NEXT: orrs r0, r1
1636 ; CHECK-DSP-NEXT: lsls r0, r0, #16
1637 ; CHECK-DSP-NEXT: it eq
1638 ; CHECK-DSP-NEXT: bxeq lr
1639 ; CHECK-DSP-NEXT: .LBB24_1: @ %for.cond
1640 ; CHECK-DSP-NEXT: @ =>This Inner Loop Header: Depth=1
1641 ; CHECK-DSP-NEXT: b .LBB24_1
1643 ; CHECK-DSP-IMM-LABEL: and_trunc_two_zext:
1644 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1645 ; CHECK-DSP-IMM-NEXT: movw r1, :lower16:b
1646 ; CHECK-DSP-IMM-NEXT: movw r2, :lower16:a
1647 ; CHECK-DSP-IMM-NEXT: movt r1, :upper16:b
1648 ; CHECK-DSP-IMM-NEXT: movt r2, :upper16:a
1649 ; CHECK-DSP-IMM-NEXT: ldrh r1, [r1]
1650 ; CHECK-DSP-IMM-NEXT: movw r0, :lower16:c
1651 ; CHECK-DSP-IMM-NEXT: ldrb r2, [r2]
1652 ; CHECK-DSP-IMM-NEXT: movt r0, :upper16:c
1653 ; CHECK-DSP-IMM-NEXT: and r3, r1, #1
1654 ; CHECK-DSP-IMM-NEXT: ldrh.w r12, [r0]
1655 ; CHECK-DSP-IMM-NEXT: movw r0, :lower16:e
1656 ; CHECK-DSP-IMM-NEXT: muls r2, r3, r2
1657 ; CHECK-DSP-IMM-NEXT: movt r0, :upper16:e
1658 ; CHECK-DSP-IMM-NEXT: strb r3, [r0]
1659 ; CHECK-DSP-IMM-NEXT: sxth r0, r1
1660 ; CHECK-DSP-IMM-NEXT: movw r1, :lower16:f
1661 ; CHECK-DSP-IMM-NEXT: movt r1, :upper16:f
1662 ; CHECK-DSP-IMM-NEXT: str r0, [r1]
1663 ; CHECK-DSP-IMM-NEXT: movw r1, :lower16:d
1664 ; CHECK-DSP-IMM-NEXT: uxtb r0, r2
1665 ; CHECK-DSP-IMM-NEXT: movt r1, :upper16:d
1666 ; CHECK-DSP-IMM-NEXT: str r0, [r1]
1667 ; CHECK-DSP-IMM-NEXT: orr.w r0, r0, r12
1668 ; CHECK-DSP-IMM-NEXT: lsls r0, r0, #16
1669 ; CHECK-DSP-IMM-NEXT: beq .LBB24_2
1670 ; CHECK-DSP-IMM-NEXT: .LBB24_1: @ %for.cond
1671 ; CHECK-DSP-IMM-NEXT: @ =>This Inner Loop Header: Depth=1
1672 ; CHECK-DSP-IMM-NEXT: b .LBB24_1
1673 ; CHECK-DSP-IMM-NEXT: .LBB24_2: @ %if.end
1674 ; CHECK-DSP-IMM-NEXT: bx lr
1676 %0 = load i16, i16* @c, align 2
1677 %1 = load i16, i16* @b, align 2
1678 %conv = sext i16 %1 to i32
1679 store i32 %conv, i32* @f, align 4
1680 %2 = trunc i16 %1 to i8
1681 %conv1 = and i8 %2, 1
1682 store i8 %conv1, i8* @e, align 1
1683 %3 = load i8, i8* @a, align 1
1684 %narrow = mul nuw i8 %3, %conv1
1685 %mul = zext i8 %narrow to i32
1686 store i32 %mul, i32* @d, align 4
1687 %4 = zext i8 %narrow to i16
1688 %conv5 = or i16 %0, %4
1689 %tobool = icmp eq i16 %conv5, 0
1690 br i1 %tobool, label %if.end, label %for.cond
1699 define void @zext_urem_trunc() {
1700 ; CHECK-NODSP-V8-LABEL: zext_urem_trunc:
1701 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1702 ; CHECK-NODSP-V8-NEXT: movw r0, :lower16:c
1703 ; CHECK-NODSP-V8-NEXT: movt r0, :upper16:c
1704 ; CHECK-NODSP-V8-NEXT: ldrh r1, [r0]
1705 ; CHECK-NODSP-V8-NEXT: movw r0, :lower16:e
1706 ; CHECK-NODSP-V8-NEXT: movt r0, :upper16:e
1707 ; CHECK-NODSP-V8-NEXT: ldrb r0, [r0]
1708 ; CHECK-NODSP-V8-NEXT: cbz r1, .LBB25_2
1709 ; CHECK-NODSP-V8-NEXT: @ %bb.1: @ %cond.false
1710 ; CHECK-NODSP-V8-NEXT: udiv r2, r0, r1
1711 ; CHECK-NODSP-V8-NEXT: mls r0, r2, r1, r0
1712 ; CHECK-NODSP-V8-NEXT: .LBB25_2: @ %cond.end
1713 ; CHECK-NODSP-V8-NEXT: movw r1, :lower16:a
1714 ; CHECK-NODSP-V8-NEXT: movt r1, :upper16:a
1715 ; CHECK-NODSP-V8-NEXT: strb r0, [r1]
1716 ; CHECK-NODSP-V8-NEXT: bx lr
1718 ; CHECK-NODSP-V7-LABEL: zext_urem_trunc:
1719 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1720 ; CHECK-NODSP-V7-NEXT: .save {r7, lr}
1721 ; CHECK-NODSP-V7-NEXT: push {r7, lr}
1722 ; CHECK-NODSP-V7-NEXT: movw r0, :lower16:e
1723 ; CHECK-NODSP-V7-NEXT: movw r1, :lower16:c
1724 ; CHECK-NODSP-V7-NEXT: movt r0, :upper16:e
1725 ; CHECK-NODSP-V7-NEXT: movt r1, :upper16:c
1726 ; CHECK-NODSP-V7-NEXT: ldrh r1, [r1]
1727 ; CHECK-NODSP-V7-NEXT: ldrb r0, [r0]
1728 ; CHECK-NODSP-V7-NEXT: cbz r1, .LBB25_2
1729 ; CHECK-NODSP-V7-NEXT: @ %bb.1: @ %cond.false
1730 ; CHECK-NODSP-V7-NEXT: bl __aeabi_uidivmod
1731 ; CHECK-NODSP-V7-NEXT: mov r0, r1
1732 ; CHECK-NODSP-V7-NEXT: .LBB25_2: @ %cond.end
1733 ; CHECK-NODSP-V7-NEXT: movw r1, :lower16:a
1734 ; CHECK-NODSP-V7-NEXT: movt r1, :upper16:a
1735 ; CHECK-NODSP-V7-NEXT: strb r0, [r1]
1736 ; CHECK-NODSP-V7-NEXT: pop {r7, pc}
1738 ; CHECK-DSP-LABEL: zext_urem_trunc:
1739 ; CHECK-DSP: @ %bb.0: @ %entry
1740 ; CHECK-DSP-NEXT: movw r1, :lower16:c
1741 ; CHECK-DSP-NEXT: movw r0, :lower16:e
1742 ; CHECK-DSP-NEXT: movt r1, :upper16:c
1743 ; CHECK-DSP-NEXT: movt r0, :upper16:e
1744 ; CHECK-DSP-NEXT: ldrh r1, [r1]
1745 ; CHECK-DSP-NEXT: ldrb r0, [r0]
1746 ; CHECK-DSP-NEXT: cmp r1, #0
1747 ; CHECK-DSP-NEXT: itt ne
1748 ; CHECK-DSP-NEXT: udivne r2, r0, r1
1749 ; CHECK-DSP-NEXT: mlsne r0, r2, r1, r0
1750 ; CHECK-DSP-NEXT: movw r1, :lower16:a
1751 ; CHECK-DSP-NEXT: movt r1, :upper16:a
1752 ; CHECK-DSP-NEXT: strb r0, [r1]
1753 ; CHECK-DSP-NEXT: bx lr
1755 ; CHECK-DSP-IMM-LABEL: zext_urem_trunc:
1756 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1757 ; CHECK-DSP-IMM-NEXT: movw r0, :lower16:e
1758 ; CHECK-DSP-IMM-NEXT: movw r1, :lower16:c
1759 ; CHECK-DSP-IMM-NEXT: movt r0, :upper16:e
1760 ; CHECK-DSP-IMM-NEXT: movt r1, :upper16:c
1761 ; CHECK-DSP-IMM-NEXT: ldrh r1, [r1]
1762 ; CHECK-DSP-IMM-NEXT: ldrb r0, [r0]
1763 ; CHECK-DSP-IMM-NEXT: cbz r1, .LBB25_2
1764 ; CHECK-DSP-IMM-NEXT: @ %bb.1: @ %cond.false
1765 ; CHECK-DSP-IMM-NEXT: udiv r2, r0, r1
1766 ; CHECK-DSP-IMM-NEXT: mls r0, r2, r1, r0
1767 ; CHECK-DSP-IMM-NEXT: .LBB25_2: @ %cond.end
1768 ; CHECK-DSP-IMM-NEXT: movw r1, :lower16:a
1769 ; CHECK-DSP-IMM-NEXT: movt r1, :upper16:a
1770 ; CHECK-DSP-IMM-NEXT: strb r0, [r1]
1771 ; CHECK-DSP-IMM-NEXT: bx lr
1773 %0 = load i16, i16* @c, align 2
1774 %cmp = icmp eq i16 %0, 0
1775 %1 = load i8, i8* @e, align 1
1776 br i1 %cmp, label %cond.end, label %cond.false
1779 %rem.lhs.trunc = zext i8 %1 to i16
1780 %rem7 = urem i16 %rem.lhs.trunc, %0
1781 %rem.zext = trunc i16 %rem7 to i8
1785 %cond = phi i8 [ %rem.zext, %cond.false ], [ %1, %entry ]
1786 store i8 %cond, i8* @a, align 1
1790 define i1 @dont_replace_trunc_1(i8* %a, i16* %b, i16* %c, i32* %d, i8* %e, i32* %f) {
1791 ; CHECK-NODSP-V8-LABEL: dont_replace_trunc_1:
1792 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1793 ; CHECK-NODSP-V8-NEXT: push {r4, lr}
1794 ; CHECK-NODSP-V8-NEXT: ldrh r1, [r1]
1795 ; CHECK-NODSP-V8-NEXT: ldrd r12, lr, [sp, #8]
1796 ; CHECK-NODSP-V8-NEXT: sxth r4, r1
1797 ; CHECK-NODSP-V8-NEXT: and r1, r1, #1
1798 ; CHECK-NODSP-V8-NEXT: ldrh r2, [r2]
1799 ; CHECK-NODSP-V8-NEXT: str.w r4, [lr]
1800 ; CHECK-NODSP-V8-NEXT: strb.w r1, [r12]
1801 ; CHECK-NODSP-V8-NEXT: ldrb r0, [r0]
1802 ; CHECK-NODSP-V8-NEXT: muls r0, r1, r0
1803 ; CHECK-NODSP-V8-NEXT: uxtb r1, r0
1804 ; CHECK-NODSP-V8-NEXT: orr.w r0, r2, r1
1805 ; CHECK-NODSP-V8-NEXT: uxth r0, r0
1806 ; CHECK-NODSP-V8-NEXT: clz r0, r0
1807 ; CHECK-NODSP-V8-NEXT: lsrs r0, r0, #5
1808 ; CHECK-NODSP-V8-NEXT: str r1, [r3]
1809 ; CHECK-NODSP-V8-NEXT: pop {r4, pc}
1811 ; CHECK-NODSP-V7-LABEL: dont_replace_trunc_1:
1812 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1813 ; CHECK-NODSP-V7-NEXT: .save {r4, lr}
1814 ; CHECK-NODSP-V7-NEXT: push {r4, lr}
1815 ; CHECK-NODSP-V7-NEXT: ldrh r1, [r1]
1816 ; CHECK-NODSP-V7-NEXT: ldrd lr, r12, [sp, #8]
1817 ; CHECK-NODSP-V7-NEXT: ldrh r2, [r2]
1818 ; CHECK-NODSP-V7-NEXT: sxth r4, r1
1819 ; CHECK-NODSP-V7-NEXT: and r1, r1, #1
1820 ; CHECK-NODSP-V7-NEXT: str.w r4, [r12]
1821 ; CHECK-NODSP-V7-NEXT: strb.w r1, [lr]
1822 ; CHECK-NODSP-V7-NEXT: ldrb r0, [r0]
1823 ; CHECK-NODSP-V7-NEXT: muls r0, r1, r0
1824 ; CHECK-NODSP-V7-NEXT: uxtb r0, r0
1825 ; CHECK-NODSP-V7-NEXT: str r0, [r3]
1826 ; CHECK-NODSP-V7-NEXT: orrs r0, r2
1827 ; CHECK-NODSP-V7-NEXT: uxth r0, r0
1828 ; CHECK-NODSP-V7-NEXT: clz r0, r0
1829 ; CHECK-NODSP-V7-NEXT: lsrs r0, r0, #5
1830 ; CHECK-NODSP-V7-NEXT: pop {r4, pc}
1832 ; CHECK-DSP-LABEL: dont_replace_trunc_1:
1833 ; CHECK-DSP: @ %bb.0: @ %entry
1834 ; CHECK-DSP-NEXT: push {r7, lr}
1835 ; CHECK-DSP-NEXT: ldrh r1, [r1]
1836 ; CHECK-DSP-NEXT: ldrh.w r12, [r2]
1837 ; CHECK-DSP-NEXT: ldr r2, [sp, #12]
1838 ; CHECK-DSP-NEXT: sxth.w lr, r1
1839 ; CHECK-DSP-NEXT: and r1, r1, #1
1840 ; CHECK-DSP-NEXT: str.w lr, [r2]
1841 ; CHECK-DSP-NEXT: ldr r2, [sp, #8]
1842 ; CHECK-DSP-NEXT: strb r1, [r2]
1843 ; CHECK-DSP-NEXT: ldrb r0, [r0]
1844 ; CHECK-DSP-NEXT: muls r0, r1, r0
1845 ; CHECK-DSP-NEXT: uxtb r0, r0
1846 ; CHECK-DSP-NEXT: str r0, [r3]
1847 ; CHECK-DSP-NEXT: orr.w r0, r0, r12
1848 ; CHECK-DSP-NEXT: uxth r0, r0
1849 ; CHECK-DSP-NEXT: clz r0, r0
1850 ; CHECK-DSP-NEXT: lsrs r0, r0, #5
1851 ; CHECK-DSP-NEXT: pop {r7, pc}
1853 ; CHECK-DSP-IMM-LABEL: dont_replace_trunc_1:
1854 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1855 ; CHECK-DSP-IMM-NEXT: push {r4, lr}
1856 ; CHECK-DSP-IMM-NEXT: ldrd lr, r12, [sp, #8]
1857 ; CHECK-DSP-IMM-NEXT: ldrh r1, [r1]
1858 ; CHECK-DSP-IMM-NEXT: ldrh r2, [r2]
1859 ; CHECK-DSP-IMM-NEXT: sxth r4, r1
1860 ; CHECK-DSP-IMM-NEXT: str.w r4, [r12]
1861 ; CHECK-DSP-IMM-NEXT: and r1, r1, #1
1862 ; CHECK-DSP-IMM-NEXT: strb.w r1, [lr]
1863 ; CHECK-DSP-IMM-NEXT: ldrb r0, [r0]
1864 ; CHECK-DSP-IMM-NEXT: muls r0, r1, r0
1865 ; CHECK-DSP-IMM-NEXT: uxtb r0, r0
1866 ; CHECK-DSP-IMM-NEXT: str r0, [r3]
1867 ; CHECK-DSP-IMM-NEXT: orrs r0, r2
1868 ; CHECK-DSP-IMM-NEXT: uxth r0, r0
1869 ; CHECK-DSP-IMM-NEXT: clz r0, r0
1870 ; CHECK-DSP-IMM-NEXT: lsrs r0, r0, #5
1871 ; CHECK-DSP-IMM-NEXT: pop {r4, pc}
1873 %0 = load i16, i16* %c, align 2
1874 %1 = load i16, i16* %b, align 2
1875 %conv = sext i16 %1 to i32
1876 store i32 %conv, i32* %f, align 4
1877 %2 = trunc i16 %1 to i8
1878 %conv1 = and i8 %2, 1
1879 store i8 %conv1, i8* %e, align 1
1880 %3 = load i8, i8* %a, align 1
1881 %narrow = mul nuw i8 %3, %conv1
1882 %mul = zext i8 %narrow to i32
1883 store i32 %mul, i32* %d, align 4
1884 %4 = zext i8 %narrow to i16
1885 %conv5 = or i16 %0, %4
1886 %tobool = icmp eq i16 %conv5, 0
1890 define i32 @dont_replace_trunc_2(i16* %a, i8* %b) {
1891 ; CHECK-NODSP-V8-LABEL: dont_replace_trunc_2:
1892 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1893 ; CHECK-NODSP-V8-NEXT: ldrh r0, [r0]
1894 ; CHECK-NODSP-V8-NEXT: cmp r0, #8
1895 ; CHECK-NODSP-V8-NEXT: it ls
1896 ; CHECK-NODSP-V8-NEXT: movls r0, #0
1897 ; CHECK-NODSP-V8-NEXT: ldrb r2, [r1]
1898 ; CHECK-NODSP-V8-NEXT: uxtb r0, r0
1899 ; CHECK-NODSP-V8-NEXT: orrs r0, r2
1900 ; CHECK-NODSP-V8-NEXT: strb r0, [r1]
1901 ; CHECK-NODSP-V8-NEXT: bx lr
1903 ; CHECK-NODSP-V7-LABEL: dont_replace_trunc_2:
1904 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1905 ; CHECK-NODSP-V7-NEXT: ldrh r0, [r0]
1906 ; CHECK-NODSP-V7-NEXT: ldrb r2, [r1]
1907 ; CHECK-NODSP-V7-NEXT: cmp r0, #8
1908 ; CHECK-NODSP-V7-NEXT: it ls
1909 ; CHECK-NODSP-V7-NEXT: movls r0, #0
1910 ; CHECK-NODSP-V7-NEXT: uxtb r0, r0
1911 ; CHECK-NODSP-V7-NEXT: orrs r0, r2
1912 ; CHECK-NODSP-V7-NEXT: strb r0, [r1]
1913 ; CHECK-NODSP-V7-NEXT: bx lr
1915 ; CHECK-DSP-LABEL: dont_replace_trunc_2:
1916 ; CHECK-DSP: @ %bb.0: @ %entry
1917 ; CHECK-DSP-NEXT: ldrh r0, [r0]
1918 ; CHECK-DSP-NEXT: cmp r0, #8
1919 ; CHECK-DSP-NEXT: it ls
1920 ; CHECK-DSP-NEXT: movls r0, #0
1921 ; CHECK-DSP-NEXT: ldrb r2, [r1]
1922 ; CHECK-DSP-NEXT: uxtb r0, r0
1923 ; CHECK-DSP-NEXT: orrs r0, r2
1924 ; CHECK-DSP-NEXT: strb r0, [r1]
1925 ; CHECK-DSP-NEXT: bx lr
1927 ; CHECK-DSP-IMM-LABEL: dont_replace_trunc_2:
1928 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
1929 ; CHECK-DSP-IMM-NEXT: ldrh r0, [r0]
1930 ; CHECK-DSP-IMM-NEXT: movs r2, #0
1931 ; CHECK-DSP-IMM-NEXT: ldrb r3, [r1]
1932 ; CHECK-DSP-IMM-NEXT: cmp r0, #8
1933 ; CHECK-DSP-IMM-NEXT: it hi
1934 ; CHECK-DSP-IMM-NEXT: movhi r2, r0
1935 ; CHECK-DSP-IMM-NEXT: uxtb r0, r2
1936 ; CHECK-DSP-IMM-NEXT: orrs r0, r3
1937 ; CHECK-DSP-IMM-NEXT: strb r0, [r1]
1938 ; CHECK-DSP-IMM-NEXT: bx lr
1940 %0 = load i16, i16* %a, align 2
1941 %cmp = icmp ugt i16 %0, 8
1942 %narrow = select i1 %cmp, i16 %0, i16 0
1943 %cond = trunc i16 %narrow to i8
1944 %1 = load i8, i8* %b, align 1
1945 %or = or i8 %1, %cond
1946 store i8 %or, i8* %b, align 1
1947 %conv5 = zext i8 %or to i32
1951 define i32 @replace_trunk_with_mask(i16* %a) {
1952 ; CHECK-NODSP-V8-LABEL: replace_trunk_with_mask:
1953 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
1954 ; CHECK-NODSP-V8-NEXT: ldrh r0, [r0]
1955 ; CHECK-NODSP-V8-NEXT: cmp r0, #0
1956 ; CHECK-NODSP-V8-NEXT: itt eq
1957 ; CHECK-NODSP-V8-NEXT: moveq r0, #0
1958 ; CHECK-NODSP-V8-NEXT: bxeq lr
1959 ; CHECK-NODSP-V8-NEXT: movw r1, #535
1960 ; CHECK-NODSP-V8-NEXT: udiv r2, r1, r0
1961 ; CHECK-NODSP-V8-NEXT: mls r0, r2, r0, r1
1962 ; CHECK-NODSP-V8-NEXT: movw r1, #43691
1963 ; CHECK-NODSP-V8-NEXT: uxtb r0, r0
1964 ; CHECK-NODSP-V8-NEXT: movt r1, #43690
1965 ; CHECK-NODSP-V8-NEXT: umull r0, r1, r0, r1
1966 ; CHECK-NODSP-V8-NEXT: lsrs r0, r1, #1
1967 ; CHECK-NODSP-V8-NEXT: bx lr
1969 ; CHECK-NODSP-V7-LABEL: replace_trunk_with_mask:
1970 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
1971 ; CHECK-NODSP-V7-NEXT: .save {r7, lr}
1972 ; CHECK-NODSP-V7-NEXT: push {r7, lr}
1973 ; CHECK-NODSP-V7-NEXT: ldrh r1, [r0]
1974 ; CHECK-NODSP-V7-NEXT: cbz r1, .LBB28_2
1975 ; CHECK-NODSP-V7-NEXT: @ %bb.1: @ %cond.false
1976 ; CHECK-NODSP-V7-NEXT: movw r0, #535
1977 ; CHECK-NODSP-V7-NEXT: bl __aeabi_uidivmod
1978 ; CHECK-NODSP-V7-NEXT: uxtb r0, r1
1979 ; CHECK-NODSP-V7-NEXT: movw r1, #43691
1980 ; CHECK-NODSP-V7-NEXT: movt r1, #43690
1981 ; CHECK-NODSP-V7-NEXT: umull r0, r1, r0, r1
1982 ; CHECK-NODSP-V7-NEXT: lsrs r0, r1, #1
1983 ; CHECK-NODSP-V7-NEXT: pop {r7, pc}
1984 ; CHECK-NODSP-V7-NEXT: .LBB28_2:
1985 ; CHECK-NODSP-V7-NEXT: movs r0, #0
1986 ; CHECK-NODSP-V7-NEXT: pop {r7, pc}
1988 ; CHECK-DSP-LABEL: replace_trunk_with_mask:
1989 ; CHECK-DSP: @ %bb.0: @ %entry
1990 ; CHECK-DSP-NEXT: ldrh r0, [r0]
1991 ; CHECK-DSP-NEXT: cmp r0, #0
1992 ; CHECK-DSP-NEXT: itt eq
1993 ; CHECK-DSP-NEXT: moveq r0, #0
1994 ; CHECK-DSP-NEXT: bxeq lr
1995 ; CHECK-DSP-NEXT: movw r1, #535
1996 ; CHECK-DSP-NEXT: udiv r2, r1, r0
1997 ; CHECK-DSP-NEXT: mls r0, r2, r0, r1
1998 ; CHECK-DSP-NEXT: movw r1, #43691
1999 ; CHECK-DSP-NEXT: uxtb r0, r0
2000 ; CHECK-DSP-NEXT: movt r1, #43690
2001 ; CHECK-DSP-NEXT: umull r0, r1, r0, r1
2002 ; CHECK-DSP-NEXT: lsrs r0, r1, #1
2003 ; CHECK-DSP-NEXT: bx lr
2005 ; CHECK-DSP-IMM-LABEL: replace_trunk_with_mask:
2006 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
2007 ; CHECK-DSP-IMM-NEXT: ldrh r0, [r0]
2008 ; CHECK-DSP-IMM-NEXT: cbz r0, .LBB28_2
2009 ; CHECK-DSP-IMM-NEXT: @ %bb.1: @ %cond.false
2010 ; CHECK-DSP-IMM-NEXT: movw r1, #535
2011 ; CHECK-DSP-IMM-NEXT: udiv r2, r1, r0
2012 ; CHECK-DSP-IMM-NEXT: mls r0, r2, r0, r1
2013 ; CHECK-DSP-IMM-NEXT: movw r1, #43691
2014 ; CHECK-DSP-IMM-NEXT: movt r1, #43690
2015 ; CHECK-DSP-IMM-NEXT: uxtb r0, r0
2016 ; CHECK-DSP-IMM-NEXT: umull r0, r1, r0, r1
2017 ; CHECK-DSP-IMM-NEXT: lsrs r0, r1, #1
2018 ; CHECK-DSP-IMM-NEXT: bx lr
2019 ; CHECK-DSP-IMM-NEXT: .LBB28_2:
2020 ; CHECK-DSP-IMM-NEXT: movs r0, #0
2021 ; CHECK-DSP-IMM-NEXT: bx lr
2023 %0 = load i16, i16* %a
2024 %cmp = icmp eq i16 %0, 0
2025 br i1 %cmp, label %cond.end, label %cond.false
2028 %1 = urem i16 535, %0
2029 %.lhs.trunc = trunc i16 %1 to i8
2030 %2 = udiv i8 %.lhs.trunc, 3
2031 %phitmp = zext i8 %2 to i32
2035 %cond = phi i32 [ %phitmp, %cond.false ], [ 0, %entry ]
2039 define float @test_i8_sitofp(i8* %ptr, i8 %arg) {
2040 ; CHECK-NODSP-V8-LABEL: test_i8_sitofp:
2041 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
2042 ; CHECK-NODSP-V8-NEXT: ldrb r0, [r0]
2043 ; CHECK-NODSP-V8-NEXT: uxtb r2, r1
2044 ; CHECK-NODSP-V8-NEXT: cmp r0, r2
2045 ; CHECK-NODSP-V8-NEXT: bne .LBB29_2
2046 ; CHECK-NODSP-V8-NEXT: @ %bb.1:
2047 ; CHECK-NODSP-V8-NEXT: vldr s0, .LCPI29_0
2048 ; CHECK-NODSP-V8-NEXT: vmov r0, s0
2049 ; CHECK-NODSP-V8-NEXT: bx lr
2050 ; CHECK-NODSP-V8-NEXT: .LBB29_2: @ %if.end
2051 ; CHECK-NODSP-V8-NEXT: sxtb r0, r1
2052 ; CHECK-NODSP-V8-NEXT: vmov s0, r0
2053 ; CHECK-NODSP-V8-NEXT: vcvt.f32.s32 s0, s0
2054 ; CHECK-NODSP-V8-NEXT: vmov.f32 s2, #2.000000e+01
2055 ; CHECK-NODSP-V8-NEXT: vdiv.f32 s0, s0, s2
2056 ; CHECK-NODSP-V8-NEXT: vmov r0, s0
2057 ; CHECK-NODSP-V8-NEXT: bx lr
2058 ; CHECK-NODSP-V8-NEXT: .p2align 2
2059 ; CHECK-NODSP-V8-NEXT: @ %bb.3:
2060 ; CHECK-NODSP-V8-NEXT: .LCPI29_0:
2061 ; CHECK-NODSP-V8-NEXT: .long 0 @ float 0
2063 ; CHECK-NODSP-V7-LABEL: test_i8_sitofp:
2064 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
2065 ; CHECK-NODSP-V7-NEXT: ldrb r0, [r0]
2066 ; CHECK-NODSP-V7-NEXT: uxtb r2, r1
2067 ; CHECK-NODSP-V7-NEXT: cmp r0, r2
2068 ; CHECK-NODSP-V7-NEXT: ittt eq
2069 ; CHECK-NODSP-V7-NEXT: vldreq s0, .LCPI29_0
2070 ; CHECK-NODSP-V7-NEXT: vmoveq r0, s0
2071 ; CHECK-NODSP-V7-NEXT: bxeq lr
2072 ; CHECK-NODSP-V7-NEXT: sxtb r0, r1
2073 ; CHECK-NODSP-V7-NEXT: vmov.f32 s0, #2.000000e+01
2074 ; CHECK-NODSP-V7-NEXT: vmov s2, r0
2075 ; CHECK-NODSP-V7-NEXT: vcvt.f32.s32 s2, s2
2076 ; CHECK-NODSP-V7-NEXT: vdiv.f32 s0, s2, s0
2077 ; CHECK-NODSP-V7-NEXT: vmov r0, s0
2078 ; CHECK-NODSP-V7-NEXT: bx lr
2079 ; CHECK-NODSP-V7-NEXT: .p2align 2
2080 ; CHECK-NODSP-V7-NEXT: @ %bb.1:
2081 ; CHECK-NODSP-V7-NEXT: .LCPI29_0:
2082 ; CHECK-NODSP-V7-NEXT: .long 0 @ float 0
2084 ; CHECK-DSP-LABEL: test_i8_sitofp:
2085 ; CHECK-DSP: @ %bb.0: @ %entry
2086 ; CHECK-DSP-NEXT: ldrb r0, [r0]
2087 ; CHECK-DSP-NEXT: uxtb r2, r1
2088 ; CHECK-DSP-NEXT: cmp r0, r2
2089 ; CHECK-DSP-NEXT: ittt eq
2090 ; CHECK-DSP-NEXT: vldreq s0, .LCPI29_0
2091 ; CHECK-DSP-NEXT: vmoveq r0, s0
2092 ; CHECK-DSP-NEXT: bxeq lr
2093 ; CHECK-DSP-NEXT: sxtb r0, r1
2094 ; CHECK-DSP-NEXT: vmov.f32 s0, #2.000000e+01
2095 ; CHECK-DSP-NEXT: vmov s2, r0
2096 ; CHECK-DSP-NEXT: vcvt.f32.s32 s2, s2
2097 ; CHECK-DSP-NEXT: vdiv.f32 s0, s2, s0
2098 ; CHECK-DSP-NEXT: vmov r0, s0
2099 ; CHECK-DSP-NEXT: bx lr
2100 ; CHECK-DSP-NEXT: .p2align 2
2101 ; CHECK-DSP-NEXT: @ %bb.1:
2102 ; CHECK-DSP-NEXT: .LCPI29_0:
2103 ; CHECK-DSP-NEXT: .long 0 @ float 0
2105 ; CHECK-DSP-IMM-LABEL: test_i8_sitofp:
2106 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
2107 ; CHECK-DSP-IMM-NEXT: ldrb r0, [r0]
2108 ; CHECK-DSP-IMM-NEXT: uxtb r2, r1
2109 ; CHECK-DSP-IMM-NEXT: cmp r0, r2
2110 ; CHECK-DSP-IMM-NEXT: bne .LBB29_2
2111 ; CHECK-DSP-IMM-NEXT: @ %bb.1:
2112 ; CHECK-DSP-IMM-NEXT: vldr s0, .LCPI29_0
2113 ; CHECK-DSP-IMM-NEXT: vmov r0, s0
2114 ; CHECK-DSP-IMM-NEXT: bx lr
2115 ; CHECK-DSP-IMM-NEXT: .LBB29_2: @ %if.end
2116 ; CHECK-DSP-IMM-NEXT: sxtb r0, r1
2117 ; CHECK-DSP-IMM-NEXT: vmov.f32 s0, #2.000000e+01
2118 ; CHECK-DSP-IMM-NEXT: vmov s2, r0
2119 ; CHECK-DSP-IMM-NEXT: vcvt.f32.s32 s2, s2
2120 ; CHECK-DSP-IMM-NEXT: vdiv.f32 s0, s2, s0
2121 ; CHECK-DSP-IMM-NEXT: vmov r0, s0
2122 ; CHECK-DSP-IMM-NEXT: bx lr
2123 ; CHECK-DSP-IMM-NEXT: .p2align 2
2124 ; CHECK-DSP-IMM-NEXT: @ %bb.3:
2125 ; CHECK-DSP-IMM-NEXT: .LCPI29_0:
2126 ; CHECK-DSP-IMM-NEXT: .long 0 @ float 0
2128 %0 = load i8, i8* %ptr, align 1
2129 %cmp = icmp eq i8 %0, %arg
2130 br i1 %cmp, label %exit, label %if.end
2133 %conv = sitofp i8 %arg to float
2134 %div = fdiv float %conv, 2.000000e+01
2138 %res = phi float [ 0.0, %entry ], [ %div, %if.end ]
2142 define float @test_i16_sitofp(i16* %ptr, i16 %arg) {
2143 ; CHECK-NODSP-V8-LABEL: test_i16_sitofp:
2144 ; CHECK-NODSP-V8: @ %bb.0: @ %entry
2145 ; CHECK-NODSP-V8-NEXT: ldrh r0, [r0]
2146 ; CHECK-NODSP-V8-NEXT: uxth r2, r1
2147 ; CHECK-NODSP-V8-NEXT: cmp r0, r2
2148 ; CHECK-NODSP-V8-NEXT: bne .LBB30_2
2149 ; CHECK-NODSP-V8-NEXT: @ %bb.1:
2150 ; CHECK-NODSP-V8-NEXT: vldr s0, .LCPI30_0
2151 ; CHECK-NODSP-V8-NEXT: vmov r0, s0
2152 ; CHECK-NODSP-V8-NEXT: bx lr
2153 ; CHECK-NODSP-V8-NEXT: .LBB30_2: @ %if.end
2154 ; CHECK-NODSP-V8-NEXT: sxth r0, r1
2155 ; CHECK-NODSP-V8-NEXT: vmov s0, r0
2156 ; CHECK-NODSP-V8-NEXT: vcvt.f32.s32 s0, s0
2157 ; CHECK-NODSP-V8-NEXT: vmov.f32 s2, #2.000000e+01
2158 ; CHECK-NODSP-V8-NEXT: vdiv.f32 s0, s0, s2
2159 ; CHECK-NODSP-V8-NEXT: vmov r0, s0
2160 ; CHECK-NODSP-V8-NEXT: bx lr
2161 ; CHECK-NODSP-V8-NEXT: .p2align 2
2162 ; CHECK-NODSP-V8-NEXT: @ %bb.3:
2163 ; CHECK-NODSP-V8-NEXT: .LCPI30_0:
2164 ; CHECK-NODSP-V8-NEXT: .long 0 @ float 0
2166 ; CHECK-NODSP-V7-LABEL: test_i16_sitofp:
2167 ; CHECK-NODSP-V7: @ %bb.0: @ %entry
2168 ; CHECK-NODSP-V7-NEXT: ldrh r0, [r0]
2169 ; CHECK-NODSP-V7-NEXT: uxth r2, r1
2170 ; CHECK-NODSP-V7-NEXT: cmp r0, r2
2171 ; CHECK-NODSP-V7-NEXT: ittt eq
2172 ; CHECK-NODSP-V7-NEXT: vldreq s0, .LCPI30_0
2173 ; CHECK-NODSP-V7-NEXT: vmoveq r0, s0
2174 ; CHECK-NODSP-V7-NEXT: bxeq lr
2175 ; CHECK-NODSP-V7-NEXT: sxth r0, r1
2176 ; CHECK-NODSP-V7-NEXT: vmov.f32 s0, #2.000000e+01
2177 ; CHECK-NODSP-V7-NEXT: vmov s2, r0
2178 ; CHECK-NODSP-V7-NEXT: vcvt.f32.s32 s2, s2
2179 ; CHECK-NODSP-V7-NEXT: vdiv.f32 s0, s2, s0
2180 ; CHECK-NODSP-V7-NEXT: vmov r0, s0
2181 ; CHECK-NODSP-V7-NEXT: bx lr
2182 ; CHECK-NODSP-V7-NEXT: .p2align 2
2183 ; CHECK-NODSP-V7-NEXT: @ %bb.1:
2184 ; CHECK-NODSP-V7-NEXT: .LCPI30_0:
2185 ; CHECK-NODSP-V7-NEXT: .long 0 @ float 0
2187 ; CHECK-DSP-LABEL: test_i16_sitofp:
2188 ; CHECK-DSP: @ %bb.0: @ %entry
2189 ; CHECK-DSP-NEXT: ldrh r0, [r0]
2190 ; CHECK-DSP-NEXT: uxth r2, r1
2191 ; CHECK-DSP-NEXT: cmp r0, r2
2192 ; CHECK-DSP-NEXT: ittt eq
2193 ; CHECK-DSP-NEXT: vldreq s0, .LCPI30_0
2194 ; CHECK-DSP-NEXT: vmoveq r0, s0
2195 ; CHECK-DSP-NEXT: bxeq lr
2196 ; CHECK-DSP-NEXT: sxth r0, r1
2197 ; CHECK-DSP-NEXT: vmov.f32 s0, #2.000000e+01
2198 ; CHECK-DSP-NEXT: vmov s2, r0
2199 ; CHECK-DSP-NEXT: vcvt.f32.s32 s2, s2
2200 ; CHECK-DSP-NEXT: vdiv.f32 s0, s2, s0
2201 ; CHECK-DSP-NEXT: vmov r0, s0
2202 ; CHECK-DSP-NEXT: bx lr
2203 ; CHECK-DSP-NEXT: .p2align 2
2204 ; CHECK-DSP-NEXT: @ %bb.1:
2205 ; CHECK-DSP-NEXT: .LCPI30_0:
2206 ; CHECK-DSP-NEXT: .long 0 @ float 0
2208 ; CHECK-DSP-IMM-LABEL: test_i16_sitofp:
2209 ; CHECK-DSP-IMM: @ %bb.0: @ %entry
2210 ; CHECK-DSP-IMM-NEXT: ldrh r0, [r0]
2211 ; CHECK-DSP-IMM-NEXT: uxth r2, r1
2212 ; CHECK-DSP-IMM-NEXT: cmp r0, r2
2213 ; CHECK-DSP-IMM-NEXT: bne .LBB30_2
2214 ; CHECK-DSP-IMM-NEXT: @ %bb.1:
2215 ; CHECK-DSP-IMM-NEXT: vldr s0, .LCPI30_0
2216 ; CHECK-DSP-IMM-NEXT: vmov r0, s0
2217 ; CHECK-DSP-IMM-NEXT: bx lr
2218 ; CHECK-DSP-IMM-NEXT: .LBB30_2: @ %if.end
2219 ; CHECK-DSP-IMM-NEXT: sxth r0, r1
2220 ; CHECK-DSP-IMM-NEXT: vmov.f32 s0, #2.000000e+01
2221 ; CHECK-DSP-IMM-NEXT: vmov s2, r0
2222 ; CHECK-DSP-IMM-NEXT: vcvt.f32.s32 s2, s2
2223 ; CHECK-DSP-IMM-NEXT: vdiv.f32 s0, s2, s0
2224 ; CHECK-DSP-IMM-NEXT: vmov r0, s0
2225 ; CHECK-DSP-IMM-NEXT: bx lr
2226 ; CHECK-DSP-IMM-NEXT: .p2align 2
2227 ; CHECK-DSP-IMM-NEXT: @ %bb.3:
2228 ; CHECK-DSP-IMM-NEXT: .LCPI30_0:
2229 ; CHECK-DSP-IMM-NEXT: .long 0 @ float 0
2231 %0 = load i16, i16* %ptr, align 1
2232 %cmp = icmp eq i16 %0, %arg
2233 br i1 %cmp, label %exit, label %if.end
2236 %conv = sitofp i16 %arg to float
2237 %div = fdiv float %conv, 2.000000e+01
2241 %res = phi float [ 0.0, %entry ], [ %div, %if.end ]