1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+f -target-abi=lp64f \
3 ; RUN: | FileCheck %s --check-prefixes=CHECK,RV64I
4 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zbb,+f -target-abi=lp64f \
5 ; RUN: | FileCheck %s --check-prefixes=CHECK,RV64ZBB
6 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zbb,+f -target-abi=lp64f \
7 ; RUN: -riscv-disable-sextw-removal | FileCheck %s --check-prefix=NOREMOVAL
9 define void @test1(i32 signext %arg, i32 signext %arg1) nounwind {
11 ; CHECK: # %bb.0: # %bb
12 ; CHECK-NEXT: addi sp, sp, -32
13 ; CHECK-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
14 ; CHECK-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
15 ; CHECK-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
16 ; CHECK-NEXT: mv s0, a1
17 ; CHECK-NEXT: sraw s1, a0, a1
18 ; CHECK-NEXT: .LBB0_1: # %bb2
19 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
20 ; CHECK-NEXT: mv a0, s1
21 ; CHECK-NEXT: call bar@plt
22 ; CHECK-NEXT: sllw s1, s1, s0
23 ; CHECK-NEXT: bnez a0, .LBB0_1
24 ; CHECK-NEXT: # %bb.2: # %bb7
25 ; CHECK-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
26 ; CHECK-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
27 ; CHECK-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
28 ; CHECK-NEXT: addi sp, sp, 32
31 ; NOREMOVAL-LABEL: test1:
32 ; NOREMOVAL: # %bb.0: # %bb
33 ; NOREMOVAL-NEXT: addi sp, sp, -32
34 ; NOREMOVAL-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
35 ; NOREMOVAL-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
36 ; NOREMOVAL-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
37 ; NOREMOVAL-NEXT: mv s0, a1
38 ; NOREMOVAL-NEXT: sraw s1, a0, a1
39 ; NOREMOVAL-NEXT: .LBB0_1: # %bb2
40 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
41 ; NOREMOVAL-NEXT: sext.w a0, s1
42 ; NOREMOVAL-NEXT: call bar@plt
43 ; NOREMOVAL-NEXT: sllw s1, s1, s0
44 ; NOREMOVAL-NEXT: bnez a0, .LBB0_1
45 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
46 ; NOREMOVAL-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
47 ; NOREMOVAL-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
48 ; NOREMOVAL-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
49 ; NOREMOVAL-NEXT: addi sp, sp, 32
52 %i = ashr i32 %arg, %arg1
55 bb2: ; preds = %bb2, %bb
56 %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
57 %i4 = tail call signext i32 @bar(i32 signext %i3)
58 %i5 = shl i32 %i3, %arg1
59 %i6 = icmp eq i32 %i4, 0
60 br i1 %i6, label %bb7, label %bb2
66 declare signext i32 @bar(i32 signext)
68 ; The load here will be an anyext load in isel and sext.w will be emitted for
69 ; the ret. Make sure we can look through logic ops to prove the sext.w is
71 define signext i32 @test2(i32* %p, i32 signext %b) nounwind {
74 ; RV64I-NEXT: lw a0, 0(a0)
75 ; RV64I-NEXT: li a2, 1
76 ; RV64I-NEXT: sllw a1, a2, a1
77 ; RV64I-NEXT: not a1, a1
78 ; RV64I-NEXT: and a0, a1, a0
81 ; RV64ZBB-LABEL: test2:
83 ; RV64ZBB-NEXT: lw a0, 0(a0)
84 ; RV64ZBB-NEXT: li a2, -2
85 ; RV64ZBB-NEXT: rolw a1, a2, a1
86 ; RV64ZBB-NEXT: and a0, a1, a0
89 ; NOREMOVAL-LABEL: test2:
91 ; NOREMOVAL-NEXT: lw a0, 0(a0)
92 ; NOREMOVAL-NEXT: li a2, -2
93 ; NOREMOVAL-NEXT: rolw a1, a2, a1
94 ; NOREMOVAL-NEXT: and a0, a1, a0
95 ; NOREMOVAL-NEXT: sext.w a0, a0
97 %a = load i32, i32* %p
99 %neg = xor i32 %shl, -1
100 %and1 = and i32 %neg, %a
104 define signext i32 @test3(i32* %p, i32 signext %b) nounwind {
105 ; RV64I-LABEL: test3:
107 ; RV64I-NEXT: lw a0, 0(a0)
108 ; RV64I-NEXT: li a2, 1
109 ; RV64I-NEXT: sllw a1, a2, a1
110 ; RV64I-NEXT: not a1, a1
111 ; RV64I-NEXT: or a0, a1, a0
114 ; RV64ZBB-LABEL: test3:
116 ; RV64ZBB-NEXT: lw a0, 0(a0)
117 ; RV64ZBB-NEXT: li a2, -2
118 ; RV64ZBB-NEXT: rolw a1, a2, a1
119 ; RV64ZBB-NEXT: or a0, a1, a0
122 ; NOREMOVAL-LABEL: test3:
123 ; NOREMOVAL: # %bb.0:
124 ; NOREMOVAL-NEXT: lw a0, 0(a0)
125 ; NOREMOVAL-NEXT: li a2, -2
126 ; NOREMOVAL-NEXT: rolw a1, a2, a1
127 ; NOREMOVAL-NEXT: or a0, a1, a0
128 ; NOREMOVAL-NEXT: sext.w a0, a0
129 ; NOREMOVAL-NEXT: ret
130 %a = load i32, i32* %p
132 %neg = xor i32 %shl, -1
133 %and1 = or i32 %neg, %a
137 define signext i32 @test4(i32* %p, i32 signext %b) nounwind {
138 ; RV64I-LABEL: test4:
140 ; RV64I-NEXT: lw a0, 0(a0)
141 ; RV64I-NEXT: li a2, 1
142 ; RV64I-NEXT: sllw a1, a2, a1
143 ; RV64I-NEXT: xor a0, a1, a0
144 ; RV64I-NEXT: not a0, a0
147 ; RV64ZBB-LABEL: test4:
149 ; RV64ZBB-NEXT: lw a0, 0(a0)
150 ; RV64ZBB-NEXT: li a2, 1
151 ; RV64ZBB-NEXT: sllw a1, a2, a1
152 ; RV64ZBB-NEXT: xnor a0, a1, a0
155 ; NOREMOVAL-LABEL: test4:
156 ; NOREMOVAL: # %bb.0:
157 ; NOREMOVAL-NEXT: lw a0, 0(a0)
158 ; NOREMOVAL-NEXT: li a2, 1
159 ; NOREMOVAL-NEXT: sllw a1, a2, a1
160 ; NOREMOVAL-NEXT: xnor a0, a1, a0
161 ; NOREMOVAL-NEXT: sext.w a0, a0
162 ; NOREMOVAL-NEXT: ret
163 %a = load i32, i32* %p
165 %neg = xor i32 %shl, -1
166 %and1 = xor i32 %neg, %a
170 ; Make sure we don't put a sext.w before bar when using cpopw.
171 define void @test5(i32 signext %arg, i32 signext %arg1) nounwind {
172 ; RV64I-LABEL: test5:
173 ; RV64I: # %bb.0: # %bb
174 ; RV64I-NEXT: addi sp, sp, -48
175 ; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
176 ; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
177 ; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
178 ; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
179 ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
180 ; RV64I-NEXT: sraw a0, a0, a1
181 ; RV64I-NEXT: lui a1, 349525
182 ; RV64I-NEXT: addiw s0, a1, 1365
183 ; RV64I-NEXT: lui a1, 209715
184 ; RV64I-NEXT: addiw s1, a1, 819
185 ; RV64I-NEXT: lui a1, 61681
186 ; RV64I-NEXT: addiw s2, a1, -241
187 ; RV64I-NEXT: lui a1, 4112
188 ; RV64I-NEXT: addiw s3, a1, 257
189 ; RV64I-NEXT: .LBB4_1: # %bb2
190 ; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
191 ; RV64I-NEXT: call bar@plt
192 ; RV64I-NEXT: mv a1, a0
193 ; RV64I-NEXT: srli a0, a0, 1
194 ; RV64I-NEXT: and a0, a0, s0
195 ; RV64I-NEXT: subw a0, a1, a0
196 ; RV64I-NEXT: and a2, a0, s1
197 ; RV64I-NEXT: srli a0, a0, 2
198 ; RV64I-NEXT: and a0, a0, s1
199 ; RV64I-NEXT: add a0, a2, a0
200 ; RV64I-NEXT: srli a2, a0, 4
201 ; RV64I-NEXT: add a0, a0, a2
202 ; RV64I-NEXT: and a0, a0, s2
203 ; RV64I-NEXT: mulw a0, a0, s3
204 ; RV64I-NEXT: srliw a0, a0, 24
205 ; RV64I-NEXT: bnez a1, .LBB4_1
206 ; RV64I-NEXT: # %bb.2: # %bb7
207 ; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
208 ; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
209 ; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
210 ; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
211 ; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
212 ; RV64I-NEXT: addi sp, sp, 48
215 ; RV64ZBB-LABEL: test5:
216 ; RV64ZBB: # %bb.0: # %bb
217 ; RV64ZBB-NEXT: addi sp, sp, -16
218 ; RV64ZBB-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
219 ; RV64ZBB-NEXT: sraw a0, a0, a1
220 ; RV64ZBB-NEXT: .LBB4_1: # %bb2
221 ; RV64ZBB-NEXT: # =>This Inner Loop Header: Depth=1
222 ; RV64ZBB-NEXT: call bar@plt
223 ; RV64ZBB-NEXT: mv a1, a0
224 ; RV64ZBB-NEXT: cpopw a0, a0
225 ; RV64ZBB-NEXT: bnez a1, .LBB4_1
226 ; RV64ZBB-NEXT: # %bb.2: # %bb7
227 ; RV64ZBB-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
228 ; RV64ZBB-NEXT: addi sp, sp, 16
231 ; NOREMOVAL-LABEL: test5:
232 ; NOREMOVAL: # %bb.0: # %bb
233 ; NOREMOVAL-NEXT: addi sp, sp, -16
234 ; NOREMOVAL-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
235 ; NOREMOVAL-NEXT: sraw a1, a0, a1
236 ; NOREMOVAL-NEXT: .LBB4_1: # %bb2
237 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
238 ; NOREMOVAL-NEXT: sext.w a0, a1
239 ; NOREMOVAL-NEXT: call bar@plt
240 ; NOREMOVAL-NEXT: cpopw a1, a0
241 ; NOREMOVAL-NEXT: bnez a0, .LBB4_1
242 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
243 ; NOREMOVAL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
244 ; NOREMOVAL-NEXT: addi sp, sp, 16
245 ; NOREMOVAL-NEXT: ret
247 %i = ashr i32 %arg, %arg1
250 bb2: ; preds = %bb2, %bb
251 %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
252 %i4 = tail call signext i32 @bar(i32 signext %i3)
253 %i5 = tail call i32 @llvm.ctpop.i32(i32 %i4)
254 %i6 = icmp eq i32 %i4, 0
255 br i1 %i6, label %bb7, label %bb2
261 declare i32 @llvm.ctpop.i32(i32)
263 define void @test6(i32 signext %arg, i32 signext %arg1) nounwind {
264 ; CHECK-LABEL: test6:
265 ; CHECK: # %bb.0: # %bb
266 ; CHECK-NEXT: addi sp, sp, -16
267 ; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
268 ; CHECK-NEXT: fsw fs0, 4(sp) # 4-byte Folded Spill
269 ; CHECK-NEXT: sraw a0, a0, a1
270 ; CHECK-NEXT: fmv.w.x fs0, zero
271 ; CHECK-NEXT: .LBB5_1: # %bb2
272 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
273 ; CHECK-NEXT: call baz@plt
274 ; CHECK-NEXT: feq.s a1, fa0, fs0
275 ; CHECK-NEXT: fcvt.w.s a0, fa0, rtz
276 ; CHECK-NEXT: beqz a1, .LBB5_1
277 ; CHECK-NEXT: # %bb.2: # %bb7
278 ; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
279 ; CHECK-NEXT: flw fs0, 4(sp) # 4-byte Folded Reload
280 ; CHECK-NEXT: addi sp, sp, 16
283 ; NOREMOVAL-LABEL: test6:
284 ; NOREMOVAL: # %bb.0: # %bb
285 ; NOREMOVAL-NEXT: addi sp, sp, -16
286 ; NOREMOVAL-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
287 ; NOREMOVAL-NEXT: fsw fs0, 4(sp) # 4-byte Folded Spill
288 ; NOREMOVAL-NEXT: sraw a0, a0, a1
289 ; NOREMOVAL-NEXT: fmv.w.x fs0, zero
290 ; NOREMOVAL-NEXT: .LBB5_1: # %bb2
291 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
292 ; NOREMOVAL-NEXT: sext.w a0, a0
293 ; NOREMOVAL-NEXT: call baz@plt
294 ; NOREMOVAL-NEXT: feq.s a1, fa0, fs0
295 ; NOREMOVAL-NEXT: fcvt.w.s a0, fa0, rtz
296 ; NOREMOVAL-NEXT: beqz a1, .LBB5_1
297 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
298 ; NOREMOVAL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
299 ; NOREMOVAL-NEXT: flw fs0, 4(sp) # 4-byte Folded Reload
300 ; NOREMOVAL-NEXT: addi sp, sp, 16
301 ; NOREMOVAL-NEXT: ret
303 %i = ashr i32 %arg, %arg1
306 bb2: ; preds = %bb2, %bb
307 %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
308 %i4 = tail call float @baz(i32 signext %i3)
309 %i5 = fptosi float %i4 to i32
310 %i6 = fcmp oeq float %i4, zeroinitializer
311 br i1 %i6, label %bb7, label %bb2
316 declare float @baz(i32 signext %i3)
318 define void @test7(i32 signext %arg, i32 signext %arg1) nounwind {
319 ; RV64I-LABEL: test7:
320 ; RV64I: # %bb.0: # %bb
321 ; RV64I-NEXT: addi sp, sp, -48
322 ; RV64I-NEXT: sd ra, 40(sp) # 8-byte Folded Spill
323 ; RV64I-NEXT: sd s0, 32(sp) # 8-byte Folded Spill
324 ; RV64I-NEXT: sd s1, 24(sp) # 8-byte Folded Spill
325 ; RV64I-NEXT: sd s2, 16(sp) # 8-byte Folded Spill
326 ; RV64I-NEXT: sd s3, 8(sp) # 8-byte Folded Spill
327 ; RV64I-NEXT: lui a2, %hi(.LCPI6_0)
328 ; RV64I-NEXT: ld s0, %lo(.LCPI6_0)(a2)
329 ; RV64I-NEXT: lui a2, %hi(.LCPI6_1)
330 ; RV64I-NEXT: ld s1, %lo(.LCPI6_1)(a2)
331 ; RV64I-NEXT: lui a2, %hi(.LCPI6_2)
332 ; RV64I-NEXT: ld s2, %lo(.LCPI6_2)(a2)
333 ; RV64I-NEXT: lui a2, %hi(.LCPI6_3)
334 ; RV64I-NEXT: ld s3, %lo(.LCPI6_3)(a2)
335 ; RV64I-NEXT: sraw a0, a0, a1
336 ; RV64I-NEXT: .LBB6_1: # %bb2
337 ; RV64I-NEXT: # =>This Inner Loop Header: Depth=1
338 ; RV64I-NEXT: call foo@plt
339 ; RV64I-NEXT: srli a1, a0, 1
340 ; RV64I-NEXT: and a1, a1, s0
341 ; RV64I-NEXT: sub a0, a0, a1
342 ; RV64I-NEXT: and a1, a0, s1
343 ; RV64I-NEXT: srli a0, a0, 2
344 ; RV64I-NEXT: and a0, a0, s1
345 ; RV64I-NEXT: add a0, a1, a0
346 ; RV64I-NEXT: srli a1, a0, 4
347 ; RV64I-NEXT: add a0, a0, a1
348 ; RV64I-NEXT: and a0, a0, s2
349 ; RV64I-NEXT: mul a0, a0, s3
350 ; RV64I-NEXT: srli a0, a0, 56
351 ; RV64I-NEXT: bnez a0, .LBB6_1
352 ; RV64I-NEXT: # %bb.2: # %bb7
353 ; RV64I-NEXT: ld ra, 40(sp) # 8-byte Folded Reload
354 ; RV64I-NEXT: ld s0, 32(sp) # 8-byte Folded Reload
355 ; RV64I-NEXT: ld s1, 24(sp) # 8-byte Folded Reload
356 ; RV64I-NEXT: ld s2, 16(sp) # 8-byte Folded Reload
357 ; RV64I-NEXT: ld s3, 8(sp) # 8-byte Folded Reload
358 ; RV64I-NEXT: addi sp, sp, 48
361 ; RV64ZBB-LABEL: test7:
362 ; RV64ZBB: # %bb.0: # %bb
363 ; RV64ZBB-NEXT: addi sp, sp, -16
364 ; RV64ZBB-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
365 ; RV64ZBB-NEXT: sraw a0, a0, a1
366 ; RV64ZBB-NEXT: .LBB6_1: # %bb2
367 ; RV64ZBB-NEXT: # =>This Inner Loop Header: Depth=1
368 ; RV64ZBB-NEXT: call foo@plt
369 ; RV64ZBB-NEXT: cpop a0, a0
370 ; RV64ZBB-NEXT: bnez a0, .LBB6_1
371 ; RV64ZBB-NEXT: # %bb.2: # %bb7
372 ; RV64ZBB-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
373 ; RV64ZBB-NEXT: addi sp, sp, 16
376 ; NOREMOVAL-LABEL: test7:
377 ; NOREMOVAL: # %bb.0: # %bb
378 ; NOREMOVAL-NEXT: addi sp, sp, -16
379 ; NOREMOVAL-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
380 ; NOREMOVAL-NEXT: sraw a0, a0, a1
381 ; NOREMOVAL-NEXT: .LBB6_1: # %bb2
382 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
383 ; NOREMOVAL-NEXT: sext.w a0, a0
384 ; NOREMOVAL-NEXT: call foo@plt
385 ; NOREMOVAL-NEXT: cpop a0, a0
386 ; NOREMOVAL-NEXT: bnez a0, .LBB6_1
387 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
388 ; NOREMOVAL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
389 ; NOREMOVAL-NEXT: addi sp, sp, 16
390 ; NOREMOVAL-NEXT: ret
392 %i = ashr i32 %arg, %arg1
395 bb2: ; preds = %bb2, %bb
396 %i3 = phi i32 [ %i, %bb ], [ %i6, %bb2 ]
397 %i4 = tail call signext i64 @foo(i32 signext %i3)
398 %i5 = tail call i64 @llvm.ctpop.i64(i64 %i4)
399 %i6 = trunc i64 %i5 to i32
400 %i7 = icmp eq i32 %i6, 0
401 br i1 %i7, label %bb7, label %bb2
407 declare i64 @llvm.ctpop.i64(i64)
409 define void @test8(i32 signext %arg, i32 signext %arg1) nounwind {
410 ; CHECK-LABEL: test8:
411 ; CHECK: # %bb.0: # %bb
412 ; CHECK-NEXT: addi sp, sp, -16
413 ; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
414 ; CHECK-NEXT: sraw a0, a0, a1
415 ; CHECK-NEXT: .LBB7_1: # %bb2
416 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
417 ; CHECK-NEXT: call foo@plt
418 ; CHECK-NEXT: ori a0, a0, -256
419 ; CHECK-NEXT: bnez a0, .LBB7_1
420 ; CHECK-NEXT: # %bb.2: # %bb7
421 ; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
422 ; CHECK-NEXT: addi sp, sp, 16
425 ; NOREMOVAL-LABEL: test8:
426 ; NOREMOVAL: # %bb.0: # %bb
427 ; NOREMOVAL-NEXT: addi sp, sp, -16
428 ; NOREMOVAL-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
429 ; NOREMOVAL-NEXT: sraw a0, a0, a1
430 ; NOREMOVAL-NEXT: .LBB7_1: # %bb2
431 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
432 ; NOREMOVAL-NEXT: sext.w a0, a0
433 ; NOREMOVAL-NEXT: call foo@plt
434 ; NOREMOVAL-NEXT: ori a0, a0, -256
435 ; NOREMOVAL-NEXT: bnez a0, .LBB7_1
436 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
437 ; NOREMOVAL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
438 ; NOREMOVAL-NEXT: addi sp, sp, 16
439 ; NOREMOVAL-NEXT: ret
441 %i = ashr i32 %arg, %arg1
444 bb2: ; preds = %bb2, %bb
445 %i3 = phi i32 [ %i, %bb ], [ %i6, %bb2 ]
446 %i4 = tail call signext i64 @foo(i32 signext %i3)
447 %i5 = or i64 %i4, -256
448 %i6 = trunc i64 %i5 to i32
449 %i7 = icmp eq i32 %i6, 0
450 br i1 %i7, label %bb7, label %bb2
456 declare i64 @foo(i32 signext)
458 define void @test9(i32 signext %arg, i32 signext %arg1) nounwind {
459 ; CHECK-LABEL: test9:
460 ; CHECK: # %bb.0: # %bb
461 ; CHECK-NEXT: addi sp, sp, -16
462 ; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
463 ; CHECK-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
464 ; CHECK-NEXT: sraw a0, a0, a1
465 ; CHECK-NEXT: li s0, 254
466 ; CHECK-NEXT: .LBB8_1: # %bb2
467 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
468 ; CHECK-NEXT: call bar@plt
469 ; CHECK-NEXT: mv a1, a0
470 ; CHECK-NEXT: slti a0, a0, 255
471 ; CHECK-NEXT: blt s0, a1, .LBB8_1
472 ; CHECK-NEXT: # %bb.2: # %bb7
473 ; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
474 ; CHECK-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
475 ; CHECK-NEXT: addi sp, sp, 16
478 ; NOREMOVAL-LABEL: test9:
479 ; NOREMOVAL: # %bb.0: # %bb
480 ; NOREMOVAL-NEXT: addi sp, sp, -16
481 ; NOREMOVAL-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
482 ; NOREMOVAL-NEXT: sd s0, 0(sp) # 8-byte Folded Spill
483 ; NOREMOVAL-NEXT: sraw a1, a0, a1
484 ; NOREMOVAL-NEXT: li s0, 254
485 ; NOREMOVAL-NEXT: .LBB8_1: # %bb2
486 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
487 ; NOREMOVAL-NEXT: sext.w a0, a1
488 ; NOREMOVAL-NEXT: call bar@plt
489 ; NOREMOVAL-NEXT: slti a1, a0, 255
490 ; NOREMOVAL-NEXT: blt s0, a0, .LBB8_1
491 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
492 ; NOREMOVAL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
493 ; NOREMOVAL-NEXT: ld s0, 0(sp) # 8-byte Folded Reload
494 ; NOREMOVAL-NEXT: addi sp, sp, 16
495 ; NOREMOVAL-NEXT: ret
497 %i = ashr i32 %arg, %arg1
500 bb2: ; preds = %bb2, %bb
501 %i3 = phi i32 [ %i, %bb ], [ %i7, %bb2 ]
502 %i4 = tail call signext i32 @bar(i32 signext %i3)
503 %i5 = icmp slt i32 %i4, 255
504 %i6 = sext i1 %i5 to i32
506 br i1 %i5, label %bb7, label %bb2
512 define void @test10(i32 signext %arg, i32 signext %arg1) nounwind {
513 ; CHECK-LABEL: test10:
514 ; CHECK: # %bb.0: # %bb
515 ; CHECK-NEXT: addi sp, sp, -16
516 ; CHECK-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
517 ; CHECK-NEXT: fsw fs0, 4(sp) # 4-byte Folded Spill
518 ; CHECK-NEXT: sraw a0, a0, a1
519 ; CHECK-NEXT: fmv.w.x fs0, zero
520 ; CHECK-NEXT: .LBB9_1: # %bb2
521 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
522 ; CHECK-NEXT: call baz@plt
523 ; CHECK-NEXT: feq.s a1, fa0, fs0
524 ; CHECK-NEXT: fmv.x.w a0, fa0
525 ; CHECK-NEXT: beqz a1, .LBB9_1
526 ; CHECK-NEXT: # %bb.2: # %bb7
527 ; CHECK-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
528 ; CHECK-NEXT: flw fs0, 4(sp) # 4-byte Folded Reload
529 ; CHECK-NEXT: addi sp, sp, 16
532 ; NOREMOVAL-LABEL: test10:
533 ; NOREMOVAL: # %bb.0: # %bb
534 ; NOREMOVAL-NEXT: addi sp, sp, -16
535 ; NOREMOVAL-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
536 ; NOREMOVAL-NEXT: fsw fs0, 4(sp) # 4-byte Folded Spill
537 ; NOREMOVAL-NEXT: sraw a0, a0, a1
538 ; NOREMOVAL-NEXT: fmv.w.x fs0, zero
539 ; NOREMOVAL-NEXT: .LBB9_1: # %bb2
540 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
541 ; NOREMOVAL-NEXT: sext.w a0, a0
542 ; NOREMOVAL-NEXT: call baz@plt
543 ; NOREMOVAL-NEXT: feq.s a1, fa0, fs0
544 ; NOREMOVAL-NEXT: fmv.x.w a0, fa0
545 ; NOREMOVAL-NEXT: beqz a1, .LBB9_1
546 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
547 ; NOREMOVAL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
548 ; NOREMOVAL-NEXT: flw fs0, 4(sp) # 4-byte Folded Reload
549 ; NOREMOVAL-NEXT: addi sp, sp, 16
550 ; NOREMOVAL-NEXT: ret
552 %i = ashr i32 %arg, %arg1
555 bb2: ; preds = %bb2, %bb
556 %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
557 %i4 = tail call float @baz(i32 signext %i3)
558 %i5 = bitcast float %i4 to i32
559 %i6 = fcmp oeq float %i4, zeroinitializer
560 br i1 %i6, label %bb7, label %bb2
566 ; simple test for forward-searching. (and 1234) only uses lower word of input
567 define signext i32 @test11(i64 %arg1, i64 %arg2, i64 %arg3) {
568 ; CHECK-LABEL: test11:
569 ; CHECK: # %bb.0: # %entry
570 ; CHECK-NEXT: addi a2, a2, -1
571 ; CHECK-NEXT: li a3, 256
572 ; CHECK-NEXT: .LBB10_1: # %bb2
573 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
574 ; CHECK-NEXT: andi a0, a0, 1234
575 ; CHECK-NEXT: addi a2, a2, 1
576 ; CHECK-NEXT: addw a0, a0, a1
577 ; CHECK-NEXT: bltu a2, a3, .LBB10_1
578 ; CHECK-NEXT: # %bb.2: # %bb7
581 ; NOREMOVAL-LABEL: test11:
582 ; NOREMOVAL: # %bb.0: # %entry
583 ; NOREMOVAL-NEXT: addi a2, a2, -1
584 ; NOREMOVAL-NEXT: li a3, 256
585 ; NOREMOVAL-NEXT: .LBB10_1: # %bb2
586 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
587 ; NOREMOVAL-NEXT: andi a0, a0, 1234
588 ; NOREMOVAL-NEXT: addi a2, a2, 1
589 ; NOREMOVAL-NEXT: add a0, a0, a1
590 ; NOREMOVAL-NEXT: bltu a2, a3, .LBB10_1
591 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
592 ; NOREMOVAL-NEXT: sext.w a0, a0
593 ; NOREMOVAL-NEXT: ret
597 bb2: ; preds = %bb2, %entry
598 %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ]
599 %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
601 %i4 = and i64 %i1, 1234
602 %i5 = add i64 %i4, %arg2
603 %i6 = icmp ugt i64 %i2, 255
604 br i1 %i6, label %bb7, label %bb2
607 %i7 = trunc i64 %i5 to i32
611 ; circular use-dependency and multiple transformations.
612 define signext i32 @test12(i64 %arg1, i64 %arg2, i64 %arg3) {
613 ; CHECK-LABEL: test12:
614 ; CHECK: # %bb.0: # %entry
615 ; CHECK-NEXT: addi a3, a2, -1
616 ; CHECK-NEXT: li a4, 256
617 ; CHECK-NEXT: .LBB11_1: # %bb2
618 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
619 ; CHECK-NEXT: xor a0, a0, a1
620 ; CHECK-NEXT: mulw a2, a0, a1
621 ; CHECK-NEXT: addw a0, a0, a2
622 ; CHECK-NEXT: and a2, a2, a0
623 ; CHECK-NEXT: addi a3, a3, 1
624 ; CHECK-NEXT: add a0, a2, a1
625 ; CHECK-NEXT: bltu a3, a4, .LBB11_1
626 ; CHECK-NEXT: # %bb.2: # %bb7
627 ; CHECK-NEXT: mv a0, a2
630 ; NOREMOVAL-LABEL: test12:
631 ; NOREMOVAL: # %bb.0: # %entry
632 ; NOREMOVAL-NEXT: addi a2, a2, -1
633 ; NOREMOVAL-NEXT: li a3, 256
634 ; NOREMOVAL-NEXT: .LBB11_1: # %bb2
635 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
636 ; NOREMOVAL-NEXT: xor a0, a0, a1
637 ; NOREMOVAL-NEXT: mul a4, a0, a1
638 ; NOREMOVAL-NEXT: add a0, a0, a4
639 ; NOREMOVAL-NEXT: and a4, a4, a0
640 ; NOREMOVAL-NEXT: addi a2, a2, 1
641 ; NOREMOVAL-NEXT: add a0, a4, a1
642 ; NOREMOVAL-NEXT: bltu a2, a3, .LBB11_1
643 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
644 ; NOREMOVAL-NEXT: sext.w a0, a4
645 ; NOREMOVAL-NEXT: ret
649 bb2: ; preds = %bb2, %entry
650 %i1 = phi i64 [ %arg1, %entry ], [ %i6, %bb2 ]
651 %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
653 %i4 = xor i64 %i1, %arg2
654 %i5 = mul i64 %i4, %arg2
655 %i9 = add i64 %i4, %i5
656 %i8 = and i64 %i5, %i9
657 %i6 = add i64 %i8, %arg2
658 %i7 = icmp ugt i64 %i2, 255
659 br i1 %i7, label %bb7, label %bb2
662 %r = trunc i64 %i8 to i32
666 ; Not optimized. sdiv doesn't only use lower word
667 define signext i32 @test13(i64 %arg1, i64 %arg2, i64 %arg3) {
668 ; CHECK-LABEL: test13:
669 ; CHECK: # %bb.0: # %entry
670 ; CHECK-NEXT: addi a2, a2, -1
671 ; CHECK-NEXT: li a3, 256
672 ; CHECK-NEXT: .LBB12_1: # %bb2
673 ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
674 ; CHECK-NEXT: div a0, a0, a1
675 ; CHECK-NEXT: addi a2, a2, 1
676 ; CHECK-NEXT: add a0, a0, a1
677 ; CHECK-NEXT: bltu a2, a3, .LBB12_1
678 ; CHECK-NEXT: # %bb.2: # %bb7
679 ; CHECK-NEXT: sext.w a0, a0
682 ; NOREMOVAL-LABEL: test13:
683 ; NOREMOVAL: # %bb.0: # %entry
684 ; NOREMOVAL-NEXT: addi a2, a2, -1
685 ; NOREMOVAL-NEXT: li a3, 256
686 ; NOREMOVAL-NEXT: .LBB12_1: # %bb2
687 ; NOREMOVAL-NEXT: # =>This Inner Loop Header: Depth=1
688 ; NOREMOVAL-NEXT: div a0, a0, a1
689 ; NOREMOVAL-NEXT: addi a2, a2, 1
690 ; NOREMOVAL-NEXT: add a0, a0, a1
691 ; NOREMOVAL-NEXT: bltu a2, a3, .LBB12_1
692 ; NOREMOVAL-NEXT: # %bb.2: # %bb7
693 ; NOREMOVAL-NEXT: sext.w a0, a0
694 ; NOREMOVAL-NEXT: ret
698 bb2: ; preds = %bb2, %entry
699 %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ]
700 %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
702 %i4 = sdiv i64 %i1, %arg2
703 %i5 = add i64 %i4, %arg2
704 %i6 = icmp ugt i64 %i2, 255
705 br i1 %i6, label %bb7, label %bb2
708 %i8 = trunc i64 %i5 to i32