Bump version to 19.1.0-rc3
[llvm-project.git] / llvm / test / CodeGen / RISCV / sextw-removal.ll
blob8cf78551d28f985ebf9ce3579146b74859a3b058
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+f,+zknh,+v -target-abi=lp64f \
3 ; RUN:   | FileCheck %s --check-prefixes=CHECK,RV64I
4 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba,+zbb,+f,+zknh,+v -target-abi=lp64f \
5 ; RUN:   | FileCheck %s --check-prefixes=CHECK,RV64ZBB
6 ; RUN: llc < %s -mtriple=riscv64 -mattr=+m,+zba,+zbb,+f,+zknh,+v -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 {
10 ; CHECK-LABEL: test1:
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
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
29 ; CHECK-NEXT:    ret
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
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
50 ; NOREMOVAL-NEXT:    ret
51 bb:
52   %i = ashr i32 %arg, %arg1
53   br label %bb2
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
62 bb7:                                              ; preds = %bb2
63   ret void
66 declare signext i32 @bar(i32 signext)
68 ; The load here was previously an aext load, but this has since been changed
69 ; to a signext load allowing us to remove a sext.w before isel. Thus we get
70 ; the same result with or without the sext.w removal pass.
71 ; Test has been left for coverage purposes.
72 define signext i32 @test2(ptr %p, i32 signext %b) nounwind {
73 ; RV64I-LABEL: test2:
74 ; RV64I:       # %bb.0:
75 ; RV64I-NEXT:    lw a0, 0(a0)
76 ; RV64I-NEXT:    li a2, 1
77 ; RV64I-NEXT:    sllw a1, a2, a1
78 ; RV64I-NEXT:    not a1, a1
79 ; RV64I-NEXT:    and a0, a1, a0
80 ; RV64I-NEXT:    ret
82 ; RV64ZBB-LABEL: test2:
83 ; RV64ZBB:       # %bb.0:
84 ; RV64ZBB-NEXT:    lw a0, 0(a0)
85 ; RV64ZBB-NEXT:    li a2, -2
86 ; RV64ZBB-NEXT:    rolw a1, a2, a1
87 ; RV64ZBB-NEXT:    and a0, a1, a0
88 ; RV64ZBB-NEXT:    ret
90 ; NOREMOVAL-LABEL: test2:
91 ; NOREMOVAL:       # %bb.0:
92 ; NOREMOVAL-NEXT:    lw a0, 0(a0)
93 ; NOREMOVAL-NEXT:    li a2, -2
94 ; NOREMOVAL-NEXT:    rolw a1, a2, a1
95 ; NOREMOVAL-NEXT:    and a0, a1, a0
96 ; NOREMOVAL-NEXT:    ret
97   %a = load i32, ptr %p
98   %shl = shl i32 1, %b
99   %neg = xor i32 %shl, -1
100   %and1 = and i32 %neg, %a
101   ret i32 %and1
104 define signext i32 @test3(ptr %p, i32 signext %b) nounwind {
105 ; RV64I-LABEL: test3:
106 ; RV64I:       # %bb.0:
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
112 ; RV64I-NEXT:    ret
114 ; RV64ZBB-LABEL: test3:
115 ; RV64ZBB:       # %bb.0:
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
120 ; RV64ZBB-NEXT:    ret
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:    ret
129   %a = load i32, ptr %p
130   %shl = shl i32 1, %b
131   %neg = xor i32 %shl, -1
132   %and1 = or i32 %neg, %a
133   ret i32 %and1
136 define signext i32 @test4(ptr %p, i32 signext %b) nounwind {
137 ; RV64I-LABEL: test4:
138 ; RV64I:       # %bb.0:
139 ; RV64I-NEXT:    lw a0, 0(a0)
140 ; RV64I-NEXT:    li a2, 1
141 ; RV64I-NEXT:    sllw a1, a2, a1
142 ; RV64I-NEXT:    xor a0, a1, a0
143 ; RV64I-NEXT:    not a0, a0
144 ; RV64I-NEXT:    ret
146 ; RV64ZBB-LABEL: test4:
147 ; RV64ZBB:       # %bb.0:
148 ; RV64ZBB-NEXT:    lw a0, 0(a0)
149 ; RV64ZBB-NEXT:    li a2, 1
150 ; RV64ZBB-NEXT:    sllw a1, a2, a1
151 ; RV64ZBB-NEXT:    xnor a0, a1, a0
152 ; RV64ZBB-NEXT:    ret
154 ; NOREMOVAL-LABEL: test4:
155 ; NOREMOVAL:       # %bb.0:
156 ; NOREMOVAL-NEXT:    lw a0, 0(a0)
157 ; NOREMOVAL-NEXT:    li a2, 1
158 ; NOREMOVAL-NEXT:    sllw a1, a2, a1
159 ; NOREMOVAL-NEXT:    xnor a0, a1, a0
160 ; NOREMOVAL-NEXT:    ret
161   %a = load i32, ptr %p
162   %shl = shl i32 1, %b
163   %neg = xor i32 %shl, -1
164   %and1 = xor i32 %neg, %a
165   ret i32 %and1
168 ; Make sure we don't put a sext.w before bar when using cpopw.
169 define void @test5(i32 signext %arg, i32 signext %arg1) nounwind {
170 ; RV64I-LABEL: test5:
171 ; RV64I:       # %bb.0: # %bb
172 ; RV64I-NEXT:    addi sp, sp, -48
173 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
174 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
175 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
176 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
177 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
178 ; RV64I-NEXT:    sraw a0, a0, a1
179 ; RV64I-NEXT:    lui a1, 349525
180 ; RV64I-NEXT:    addiw s0, a1, 1365
181 ; RV64I-NEXT:    lui a1, 209715
182 ; RV64I-NEXT:    addiw s1, a1, 819
183 ; RV64I-NEXT:    lui a1, 61681
184 ; RV64I-NEXT:    addi s2, a1, -241
185 ; RV64I-NEXT:    lui a1, 4112
186 ; RV64I-NEXT:    addi s3, a1, 257
187 ; RV64I-NEXT:  .LBB4_1: # %bb2
188 ; RV64I-NEXT:    # =>This Inner Loop Header: Depth=1
189 ; RV64I-NEXT:    call bar
190 ; RV64I-NEXT:    mv a1, a0
191 ; RV64I-NEXT:    srli a0, a0, 1
192 ; RV64I-NEXT:    and a0, a0, s0
193 ; RV64I-NEXT:    sub a0, a1, a0
194 ; RV64I-NEXT:    and a2, a0, s1
195 ; RV64I-NEXT:    srli a0, a0, 2
196 ; RV64I-NEXT:    and a0, a0, s1
197 ; RV64I-NEXT:    add a0, a2, a0
198 ; RV64I-NEXT:    srli a2, a0, 4
199 ; RV64I-NEXT:    add a0, a0, a2
200 ; RV64I-NEXT:    and a0, a0, s2
201 ; RV64I-NEXT:    mul a0, a0, s3
202 ; RV64I-NEXT:    srliw a0, a0, 24
203 ; RV64I-NEXT:    bnez a1, .LBB4_1
204 ; RV64I-NEXT:  # %bb.2: # %bb7
205 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
206 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
207 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
208 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
209 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
210 ; RV64I-NEXT:    addi sp, sp, 48
211 ; RV64I-NEXT:    ret
213 ; RV64ZBB-LABEL: test5:
214 ; RV64ZBB:       # %bb.0: # %bb
215 ; RV64ZBB-NEXT:    addi sp, sp, -16
216 ; RV64ZBB-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
217 ; RV64ZBB-NEXT:    sraw a0, a0, a1
218 ; RV64ZBB-NEXT:  .LBB4_1: # %bb2
219 ; RV64ZBB-NEXT:    # =>This Inner Loop Header: Depth=1
220 ; RV64ZBB-NEXT:    call bar
221 ; RV64ZBB-NEXT:    mv a1, a0
222 ; RV64ZBB-NEXT:    cpopw a0, a0
223 ; RV64ZBB-NEXT:    bnez a1, .LBB4_1
224 ; RV64ZBB-NEXT:  # %bb.2: # %bb7
225 ; RV64ZBB-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
226 ; RV64ZBB-NEXT:    addi sp, sp, 16
227 ; RV64ZBB-NEXT:    ret
229 ; NOREMOVAL-LABEL: test5:
230 ; NOREMOVAL:       # %bb.0: # %bb
231 ; NOREMOVAL-NEXT:    addi sp, sp, -16
232 ; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
233 ; NOREMOVAL-NEXT:    sraw a1, a0, a1
234 ; NOREMOVAL-NEXT:  .LBB4_1: # %bb2
235 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
236 ; NOREMOVAL-NEXT:    sext.w a0, a1
237 ; NOREMOVAL-NEXT:    call bar
238 ; NOREMOVAL-NEXT:    cpopw a1, a0
239 ; NOREMOVAL-NEXT:    bnez a0, .LBB4_1
240 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
241 ; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
242 ; NOREMOVAL-NEXT:    addi sp, sp, 16
243 ; NOREMOVAL-NEXT:    ret
245   %i = ashr i32 %arg, %arg1
246   br label %bb2
248 bb2:                                              ; preds = %bb2, %bb
249   %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
250   %i4 = tail call signext i32 @bar(i32 signext %i3)
251   %i5 = tail call i32 @llvm.ctpop.i32(i32 %i4)
252   %i6 = icmp eq i32 %i4, 0
253   br i1 %i6, label %bb7, label %bb2
255 bb7:                                              ; preds = %bb2
256   ret void
259 declare i32 @llvm.ctpop.i32(i32)
261 define void @test6(i32 signext %arg, i32 signext %arg1) nounwind {
262 ; CHECK-LABEL: test6:
263 ; CHECK:       # %bb.0: # %bb
264 ; CHECK-NEXT:    addi sp, sp, -16
265 ; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
266 ; CHECK-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
267 ; CHECK-NEXT:    sraw a0, a0, a1
268 ; CHECK-NEXT:    fmv.w.x fs0, zero
269 ; CHECK-NEXT:  .LBB5_1: # %bb2
270 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
271 ; CHECK-NEXT:    call baz
272 ; CHECK-NEXT:    feq.s a1, fa0, fs0
273 ; CHECK-NEXT:    fcvt.w.s a0, fa0, rtz
274 ; CHECK-NEXT:    beqz a1, .LBB5_1
275 ; CHECK-NEXT:  # %bb.2: # %bb7
276 ; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
277 ; CHECK-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
278 ; CHECK-NEXT:    addi sp, sp, 16
279 ; CHECK-NEXT:    ret
281 ; NOREMOVAL-LABEL: test6:
282 ; NOREMOVAL:       # %bb.0: # %bb
283 ; NOREMOVAL-NEXT:    addi sp, sp, -16
284 ; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
285 ; NOREMOVAL-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
286 ; NOREMOVAL-NEXT:    sraw a0, a0, a1
287 ; NOREMOVAL-NEXT:    fmv.w.x fs0, zero
288 ; NOREMOVAL-NEXT:  .LBB5_1: # %bb2
289 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
290 ; NOREMOVAL-NEXT:    sext.w a0, a0
291 ; NOREMOVAL-NEXT:    call baz
292 ; NOREMOVAL-NEXT:    feq.s a1, fa0, fs0
293 ; NOREMOVAL-NEXT:    fcvt.w.s a0, fa0, rtz
294 ; NOREMOVAL-NEXT:    beqz a1, .LBB5_1
295 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
296 ; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
297 ; NOREMOVAL-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
298 ; NOREMOVAL-NEXT:    addi sp, sp, 16
299 ; NOREMOVAL-NEXT:    ret
301   %i = ashr i32 %arg, %arg1
302   br label %bb2
304 bb2:                                              ; preds = %bb2, %bb
305   %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
306   %i4 = tail call float @baz(i32 signext %i3)
307   %i5 = fptosi float %i4 to i32
308   %i6 = fcmp oeq float %i4, zeroinitializer
309   br i1 %i6, label %bb7, label %bb2
311 bb7:                                              ; preds = %bb2
312   ret void
314 declare float @baz(i32 signext %i3)
316 define void @test7(i32 signext %arg, i32 signext %arg1) nounwind {
317 ; RV64I-LABEL: test7:
318 ; RV64I:       # %bb.0: # %bb
319 ; RV64I-NEXT:    addi sp, sp, -48
320 ; RV64I-NEXT:    sd ra, 40(sp) # 8-byte Folded Spill
321 ; RV64I-NEXT:    sd s0, 32(sp) # 8-byte Folded Spill
322 ; RV64I-NEXT:    sd s1, 24(sp) # 8-byte Folded Spill
323 ; RV64I-NEXT:    sd s2, 16(sp) # 8-byte Folded Spill
324 ; RV64I-NEXT:    sd s3, 8(sp) # 8-byte Folded Spill
325 ; RV64I-NEXT:    sraw a0, a0, a1
326 ; RV64I-NEXT:    lui a1, 349525
327 ; RV64I-NEXT:    addiw s0, a1, 1365
328 ; RV64I-NEXT:    slli a1, s0, 32
329 ; RV64I-NEXT:    add s0, s0, a1
330 ; RV64I-NEXT:    lui a1, 209715
331 ; RV64I-NEXT:    addiw s1, a1, 819
332 ; RV64I-NEXT:    slli a1, s1, 32
333 ; RV64I-NEXT:    add s1, s1, a1
334 ; RV64I-NEXT:    lui a1, 61681
335 ; RV64I-NEXT:    addiw s2, a1, -241
336 ; RV64I-NEXT:    slli a1, s2, 32
337 ; RV64I-NEXT:    add s2, s2, a1
338 ; RV64I-NEXT:    lui a1, 4112
339 ; RV64I-NEXT:    addiw s3, a1, 257
340 ; RV64I-NEXT:    slli a1, s3, 32
341 ; RV64I-NEXT:    add s3, s3, a1
342 ; RV64I-NEXT:  .LBB6_1: # %bb2
343 ; RV64I-NEXT:    # =>This Inner Loop Header: Depth=1
344 ; RV64I-NEXT:    call foo
345 ; RV64I-NEXT:    srli a1, a0, 1
346 ; RV64I-NEXT:    and a1, a1, s0
347 ; RV64I-NEXT:    sub a0, a0, a1
348 ; RV64I-NEXT:    and a1, a0, s1
349 ; RV64I-NEXT:    srli a0, a0, 2
350 ; RV64I-NEXT:    and a0, a0, s1
351 ; RV64I-NEXT:    add a0, a1, a0
352 ; RV64I-NEXT:    srli a1, a0, 4
353 ; RV64I-NEXT:    add a0, a0, a1
354 ; RV64I-NEXT:    and a0, a0, s2
355 ; RV64I-NEXT:    mul a0, a0, s3
356 ; RV64I-NEXT:    srli a0, a0, 56
357 ; RV64I-NEXT:    bnez a0, .LBB6_1
358 ; RV64I-NEXT:  # %bb.2: # %bb7
359 ; RV64I-NEXT:    ld ra, 40(sp) # 8-byte Folded Reload
360 ; RV64I-NEXT:    ld s0, 32(sp) # 8-byte Folded Reload
361 ; RV64I-NEXT:    ld s1, 24(sp) # 8-byte Folded Reload
362 ; RV64I-NEXT:    ld s2, 16(sp) # 8-byte Folded Reload
363 ; RV64I-NEXT:    ld s3, 8(sp) # 8-byte Folded Reload
364 ; RV64I-NEXT:    addi sp, sp, 48
365 ; RV64I-NEXT:    ret
367 ; RV64ZBB-LABEL: test7:
368 ; RV64ZBB:       # %bb.0: # %bb
369 ; RV64ZBB-NEXT:    addi sp, sp, -16
370 ; RV64ZBB-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
371 ; RV64ZBB-NEXT:    sraw a0, a0, a1
372 ; RV64ZBB-NEXT:  .LBB6_1: # %bb2
373 ; RV64ZBB-NEXT:    # =>This Inner Loop Header: Depth=1
374 ; RV64ZBB-NEXT:    call foo
375 ; RV64ZBB-NEXT:    cpop a0, a0
376 ; RV64ZBB-NEXT:    bnez a0, .LBB6_1
377 ; RV64ZBB-NEXT:  # %bb.2: # %bb7
378 ; RV64ZBB-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
379 ; RV64ZBB-NEXT:    addi sp, sp, 16
380 ; RV64ZBB-NEXT:    ret
382 ; NOREMOVAL-LABEL: test7:
383 ; NOREMOVAL:       # %bb.0: # %bb
384 ; NOREMOVAL-NEXT:    addi sp, sp, -16
385 ; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
386 ; NOREMOVAL-NEXT:    sraw a0, a0, a1
387 ; NOREMOVAL-NEXT:  .LBB6_1: # %bb2
388 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
389 ; NOREMOVAL-NEXT:    sext.w a0, a0
390 ; NOREMOVAL-NEXT:    call foo
391 ; NOREMOVAL-NEXT:    cpop a0, a0
392 ; NOREMOVAL-NEXT:    bnez a0, .LBB6_1
393 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
394 ; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
395 ; NOREMOVAL-NEXT:    addi sp, sp, 16
396 ; NOREMOVAL-NEXT:    ret
398   %i = ashr i32 %arg, %arg1
399   br label %bb2
401 bb2:                                              ; preds = %bb2, %bb
402   %i3 = phi i32 [ %i, %bb ], [ %i6, %bb2 ]
403   %i4 = tail call signext i64 @foo(i32 signext %i3)
404   %i5 = tail call i64 @llvm.ctpop.i64(i64 %i4)
405   %i6 = trunc i64 %i5 to i32
406   %i7 = icmp eq i32 %i6, 0
407   br i1 %i7, label %bb7, label %bb2
409 bb7:                                              ; preds = %bb2
410   ret void
413 declare i64 @llvm.ctpop.i64(i64)
415 define void @test8(i32 signext %arg, i32 signext %arg1) nounwind {
416 ; CHECK-LABEL: test8:
417 ; CHECK:       # %bb.0: # %bb
418 ; CHECK-NEXT:    addi sp, sp, -16
419 ; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
420 ; CHECK-NEXT:    sraw a0, a0, a1
421 ; CHECK-NEXT:  .LBB7_1: # %bb2
422 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
423 ; CHECK-NEXT:    call foo
424 ; CHECK-NEXT:    ori a0, a0, -256
425 ; CHECK-NEXT:    bnez a0, .LBB7_1
426 ; CHECK-NEXT:  # %bb.2: # %bb7
427 ; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
428 ; CHECK-NEXT:    addi sp, sp, 16
429 ; CHECK-NEXT:    ret
431 ; NOREMOVAL-LABEL: test8:
432 ; NOREMOVAL:       # %bb.0: # %bb
433 ; NOREMOVAL-NEXT:    addi sp, sp, -16
434 ; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
435 ; NOREMOVAL-NEXT:    sraw a0, a0, a1
436 ; NOREMOVAL-NEXT:  .LBB7_1: # %bb2
437 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
438 ; NOREMOVAL-NEXT:    sext.w a0, a0
439 ; NOREMOVAL-NEXT:    call foo
440 ; NOREMOVAL-NEXT:    ori a0, a0, -256
441 ; NOREMOVAL-NEXT:    bnez a0, .LBB7_1
442 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
443 ; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
444 ; NOREMOVAL-NEXT:    addi sp, sp, 16
445 ; NOREMOVAL-NEXT:    ret
447   %i = ashr i32 %arg, %arg1
448   br label %bb2
450 bb2:                                              ; preds = %bb2, %bb
451   %i3 = phi i32 [ %i, %bb ], [ %i6, %bb2 ]
452   %i4 = tail call signext i64 @foo(i32 signext %i3)
453   %i5 = or i64 %i4, -256
454   %i6 = trunc i64 %i5 to i32
455   %i7 = icmp eq i32 %i6, 0
456   br i1 %i7, label %bb7, label %bb2
458 bb7:                                              ; preds = %bb2
459   ret void
462 declare i64 @foo(i32 signext)
464 define void @test9(i32 signext %arg, i32 signext %arg1) nounwind {
465 ; CHECK-LABEL: test9:
466 ; CHECK:       # %bb.0: # %bb
467 ; CHECK-NEXT:    addi sp, sp, -16
468 ; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
469 ; CHECK-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
470 ; CHECK-NEXT:    sraw a0, a0, a1
471 ; CHECK-NEXT:    li s0, 254
472 ; CHECK-NEXT:  .LBB8_1: # %bb2
473 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
474 ; CHECK-NEXT:    call bar
475 ; CHECK-NEXT:    mv a1, a0
476 ; CHECK-NEXT:    slti a0, a0, 255
477 ; CHECK-NEXT:    blt s0, a1, .LBB8_1
478 ; CHECK-NEXT:  # %bb.2: # %bb7
479 ; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
480 ; CHECK-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
481 ; CHECK-NEXT:    addi sp, sp, 16
482 ; CHECK-NEXT:    ret
484 ; NOREMOVAL-LABEL: test9:
485 ; NOREMOVAL:       # %bb.0: # %bb
486 ; NOREMOVAL-NEXT:    addi sp, sp, -16
487 ; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
488 ; NOREMOVAL-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
489 ; NOREMOVAL-NEXT:    sraw a1, a0, a1
490 ; NOREMOVAL-NEXT:    li s0, 254
491 ; NOREMOVAL-NEXT:  .LBB8_1: # %bb2
492 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
493 ; NOREMOVAL-NEXT:    sext.w a0, a1
494 ; NOREMOVAL-NEXT:    call bar
495 ; NOREMOVAL-NEXT:    slti a1, a0, 255
496 ; NOREMOVAL-NEXT:    blt s0, a0, .LBB8_1
497 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
498 ; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
499 ; NOREMOVAL-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
500 ; NOREMOVAL-NEXT:    addi sp, sp, 16
501 ; NOREMOVAL-NEXT:    ret
503   %i = ashr i32 %arg, %arg1
504   br label %bb2
506 bb2:                                              ; preds = %bb2, %bb
507   %i3 = phi i32 [ %i, %bb ], [ %i7, %bb2 ]
508   %i4 = tail call signext i32 @bar(i32 signext %i3)
509   %i5 = icmp slt i32 %i4, 255
510   %i6 = sext i1 %i5 to i32
511   %i7 = sub i32 0, %i6
512   br i1 %i5, label %bb7, label %bb2
514 bb7:                                              ; preds = %bb2
515   ret void
518 define void @test10(i32 signext %arg, i32 signext %arg1) nounwind {
519 ; CHECK-LABEL: test10:
520 ; CHECK:       # %bb.0: # %bb
521 ; CHECK-NEXT:    addi sp, sp, -16
522 ; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
523 ; CHECK-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
524 ; CHECK-NEXT:    sraw a0, a0, a1
525 ; CHECK-NEXT:    fmv.w.x fs0, zero
526 ; CHECK-NEXT:  .LBB9_1: # %bb2
527 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
528 ; CHECK-NEXT:    call baz
529 ; CHECK-NEXT:    feq.s a1, fa0, fs0
530 ; CHECK-NEXT:    fmv.x.w a0, fa0
531 ; CHECK-NEXT:    beqz a1, .LBB9_1
532 ; CHECK-NEXT:  # %bb.2: # %bb7
533 ; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
534 ; CHECK-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
535 ; CHECK-NEXT:    addi sp, sp, 16
536 ; CHECK-NEXT:    ret
538 ; NOREMOVAL-LABEL: test10:
539 ; NOREMOVAL:       # %bb.0: # %bb
540 ; NOREMOVAL-NEXT:    addi sp, sp, -16
541 ; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
542 ; NOREMOVAL-NEXT:    fsw fs0, 4(sp) # 4-byte Folded Spill
543 ; NOREMOVAL-NEXT:    sraw a0, a0, a1
544 ; NOREMOVAL-NEXT:    fmv.w.x fs0, zero
545 ; NOREMOVAL-NEXT:  .LBB9_1: # %bb2
546 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
547 ; NOREMOVAL-NEXT:    sext.w a0, a0
548 ; NOREMOVAL-NEXT:    call baz
549 ; NOREMOVAL-NEXT:    feq.s a1, fa0, fs0
550 ; NOREMOVAL-NEXT:    fmv.x.w a0, fa0
551 ; NOREMOVAL-NEXT:    beqz a1, .LBB9_1
552 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
553 ; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
554 ; NOREMOVAL-NEXT:    flw fs0, 4(sp) # 4-byte Folded Reload
555 ; NOREMOVAL-NEXT:    addi sp, sp, 16
556 ; NOREMOVAL-NEXT:    ret
558   %i = ashr i32 %arg, %arg1
559   br label %bb2
561 bb2:                                              ; preds = %bb2, %bb
562   %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
563   %i4 = tail call float @baz(i32 signext %i3)
564   %i5 = bitcast float %i4 to i32
565   %i6 = fcmp oeq float %i4, zeroinitializer
566   br i1 %i6, label %bb7, label %bb2
568 bb7:                                              ; preds = %bb2
569   ret void
572 ; simple test for forward-searching. (and 1234) only uses lower word of input
573 define signext i32 @test11(i64 %arg1, i64 %arg2, i64 %arg3)  {
574 ; CHECK-LABEL: test11:
575 ; CHECK:       # %bb.0: # %entry
576 ; CHECK-NEXT:    addi a2, a2, -1
577 ; CHECK-NEXT:    li a3, 256
578 ; CHECK-NEXT:  .LBB10_1: # %bb2
579 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
580 ; CHECK-NEXT:    andi a0, a0, 1234
581 ; CHECK-NEXT:    addi a2, a2, 1
582 ; CHECK-NEXT:    addw a0, a0, a1
583 ; CHECK-NEXT:    bltu a2, a3, .LBB10_1
584 ; CHECK-NEXT:  # %bb.2: # %bb7
585 ; CHECK-NEXT:    ret
587 ; NOREMOVAL-LABEL: test11:
588 ; NOREMOVAL:       # %bb.0: # %entry
589 ; NOREMOVAL-NEXT:    addi a2, a2, -1
590 ; NOREMOVAL-NEXT:    li a3, 256
591 ; NOREMOVAL-NEXT:  .LBB10_1: # %bb2
592 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
593 ; NOREMOVAL-NEXT:    andi a0, a0, 1234
594 ; NOREMOVAL-NEXT:    addi a2, a2, 1
595 ; NOREMOVAL-NEXT:    add a0, a0, a1
596 ; NOREMOVAL-NEXT:    bltu a2, a3, .LBB10_1
597 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
598 ; NOREMOVAL-NEXT:    sext.w a0, a0
599 ; NOREMOVAL-NEXT:    ret
600 entry:
601   br label %bb2
603 bb2:                                              ; preds = %bb2, %entry
604   %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ]
605   %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
606   %i3 = add i64 %i2, 1
607   %i4 = and i64 %i1, 1234
608   %i5 = add i64 %i4, %arg2
609   %i6 = icmp ugt i64 %i2, 255
610   br i1 %i6, label %bb7, label %bb2
612 bb7:                                              ; preds = %bb2
613   %i7 = trunc i64 %i5 to i32
614   ret i32 %i7
617 ; circular use-dependency and multiple transformations.
618 define signext i32 @test12(i64 %arg1, i64 %arg2, i64 %arg3)  {
619 ; CHECK-LABEL: test12:
620 ; CHECK:       # %bb.0: # %entry
621 ; CHECK-NEXT:    addi a3, a2, -1
622 ; CHECK-NEXT:    li a4, 256
623 ; CHECK-NEXT:  .LBB11_1: # %bb2
624 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
625 ; CHECK-NEXT:    xor a0, a0, a1
626 ; CHECK-NEXT:    mulw a2, a0, a1
627 ; CHECK-NEXT:    addw a0, a0, a2
628 ; CHECK-NEXT:    and a2, a2, a0
629 ; CHECK-NEXT:    addi a3, a3, 1
630 ; CHECK-NEXT:    add a0, a2, a1
631 ; CHECK-NEXT:    bltu a3, a4, .LBB11_1
632 ; CHECK-NEXT:  # %bb.2: # %bb7
633 ; CHECK-NEXT:    mv a0, a2
634 ; CHECK-NEXT:    ret
636 ; NOREMOVAL-LABEL: test12:
637 ; NOREMOVAL:       # %bb.0: # %entry
638 ; NOREMOVAL-NEXT:    addi a2, a2, -1
639 ; NOREMOVAL-NEXT:    li a3, 256
640 ; NOREMOVAL-NEXT:  .LBB11_1: # %bb2
641 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
642 ; NOREMOVAL-NEXT:    xor a0, a0, a1
643 ; NOREMOVAL-NEXT:    mul a4, a0, a1
644 ; NOREMOVAL-NEXT:    add a0, a0, a4
645 ; NOREMOVAL-NEXT:    and a4, a4, a0
646 ; NOREMOVAL-NEXT:    addi a2, a2, 1
647 ; NOREMOVAL-NEXT:    add a0, a4, a1
648 ; NOREMOVAL-NEXT:    bltu a2, a3, .LBB11_1
649 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
650 ; NOREMOVAL-NEXT:    sext.w a0, a4
651 ; NOREMOVAL-NEXT:    ret
652 entry:
653   br label %bb2
655 bb2:                                              ; preds = %bb2, %entry
656   %i1 = phi i64 [ %arg1, %entry ], [ %i6, %bb2 ]
657   %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
658   %i3 = add i64 %i2, 1
659   %i4 = xor i64 %i1, %arg2
660   %i5 = mul i64 %i4, %arg2
661   %i9 = add i64 %i4, %i5
662   %i8 = and i64 %i5, %i9
663   %i6 = add i64 %i8, %arg2
664   %i7 = icmp ugt i64 %i2, 255
665   br i1 %i7, label %bb7, label %bb2
667 bb7:                                              ; preds = %bb2
668   %r = trunc i64 %i8 to i32
669   ret i32 %r
672 ; Not optimized. sdiv doesn't only use lower word
673 define signext i32 @test13(i64 %arg1, i64 %arg2, i64 %arg3)  {
674 ; CHECK-LABEL: test13:
675 ; CHECK:       # %bb.0: # %entry
676 ; CHECK-NEXT:    addi a2, a2, -1
677 ; CHECK-NEXT:    li a3, 256
678 ; CHECK-NEXT:  .LBB12_1: # %bb2
679 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
680 ; CHECK-NEXT:    div a0, a0, a1
681 ; CHECK-NEXT:    addi a2, a2, 1
682 ; CHECK-NEXT:    add a0, a0, a1
683 ; CHECK-NEXT:    bltu a2, a3, .LBB12_1
684 ; CHECK-NEXT:  # %bb.2: # %bb7
685 ; CHECK-NEXT:    sext.w a0, a0
686 ; CHECK-NEXT:    ret
688 ; NOREMOVAL-LABEL: test13:
689 ; NOREMOVAL:       # %bb.0: # %entry
690 ; NOREMOVAL-NEXT:    addi a2, a2, -1
691 ; NOREMOVAL-NEXT:    li a3, 256
692 ; NOREMOVAL-NEXT:  .LBB12_1: # %bb2
693 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
694 ; NOREMOVAL-NEXT:    div a0, a0, a1
695 ; NOREMOVAL-NEXT:    addi a2, a2, 1
696 ; NOREMOVAL-NEXT:    add a0, a0, a1
697 ; NOREMOVAL-NEXT:    bltu a2, a3, .LBB12_1
698 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
699 ; NOREMOVAL-NEXT:    sext.w a0, a0
700 ; NOREMOVAL-NEXT:    ret
701 entry:
702   br label %bb2
704 bb2:                                              ; preds = %bb2, %entry
705   %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ]
706   %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
707   %i3 = add i64 %i2, 1
708   %i4 = sdiv i64 %i1, %arg2
709   %i5 = add i64 %i4, %arg2
710   %i6 = icmp ugt i64 %i2, 255
711   br i1 %i6, label %bb7, label %bb2
713 bb7:                                              ; preds = %bb2
714   %i8 = trunc i64 %i5 to i32
715   ret i32 %i8
719 ; int test14(int a, int n) {
720 ;   for (int i = 1; i < n; ++i) {
721 ;     if (a > 1000)
722 ;       return -1;
723 ;     a += i;
724 ;   }
726 ;   return a;
727 ; }
729 ; There should be no sext.w in the loop.
730 define signext i32 @test14(i32 signext %0, i32 signext %1) {
731 ; CHECK-LABEL: test14:
732 ; CHECK:       # %bb.0:
733 ; CHECK-NEXT:    li a2, 2
734 ; CHECK-NEXT:    blt a1, a2, .LBB13_4
735 ; CHECK-NEXT:  # %bb.1: # %.preheader
736 ; CHECK-NEXT:    li a2, 1
737 ; CHECK-NEXT:    li a3, 1000
738 ; CHECK-NEXT:  .LBB13_2: # =>This Inner Loop Header: Depth=1
739 ; CHECK-NEXT:    blt a3, a0, .LBB13_5
740 ; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB13_2 Depth=1
741 ; CHECK-NEXT:    addw a0, a2, a0
742 ; CHECK-NEXT:    addiw a2, a2, 1
743 ; CHECK-NEXT:    blt a2, a1, .LBB13_2
744 ; CHECK-NEXT:  .LBB13_4:
745 ; CHECK-NEXT:    ret
746 ; CHECK-NEXT:  .LBB13_5:
747 ; CHECK-NEXT:    li a0, -1
748 ; CHECK-NEXT:    ret
750 ; NOREMOVAL-LABEL: test14:
751 ; NOREMOVAL:       # %bb.0:
752 ; NOREMOVAL-NEXT:    li a2, 2
753 ; NOREMOVAL-NEXT:    blt a1, a2, .LBB13_4
754 ; NOREMOVAL-NEXT:  # %bb.1: # %.preheader
755 ; NOREMOVAL-NEXT:    li a2, 1
756 ; NOREMOVAL-NEXT:    li a3, 1000
757 ; NOREMOVAL-NEXT:  .LBB13_2: # =>This Inner Loop Header: Depth=1
758 ; NOREMOVAL-NEXT:    sext.w a4, a0
759 ; NOREMOVAL-NEXT:    blt a3, a4, .LBB13_5
760 ; NOREMOVAL-NEXT:  # %bb.3: # in Loop: Header=BB13_2 Depth=1
761 ; NOREMOVAL-NEXT:    addw a0, a2, a0
762 ; NOREMOVAL-NEXT:    addiw a2, a2, 1
763 ; NOREMOVAL-NEXT:    blt a2, a1, .LBB13_2
764 ; NOREMOVAL-NEXT:  .LBB13_4:
765 ; NOREMOVAL-NEXT:    ret
766 ; NOREMOVAL-NEXT:  .LBB13_5:
767 ; NOREMOVAL-NEXT:    li a0, -1
768 ; NOREMOVAL-NEXT:    ret
769   %3 = icmp sgt i32 %1, 1
770   br i1 %3, label %4, label %12
772 4:                                                ; preds = %2, %8
773   %5 = phi i32 [ %10, %8 ], [ 1, %2 ]
774   %6 = phi i32 [ %9, %8 ], [ %0, %2 ]
775   %7 = icmp sgt i32 %6, 1000
776   br i1 %7, label %12, label %8
778 8:                                                ; preds = %4
779   %9 = add nsw i32 %5, %6
780   %10 = add nuw nsw i32 %5, 1
781   %11 = icmp slt i32 %10, %1
782   br i1 %11, label %4, label %12
784 12:                                               ; preds = %8, %4, %2
785   %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
786   ret i32 %13
789 ; Same as test14 but the signext attribute is missing from the argument so we
790 ; can't optimize out the sext.w.
791 define signext i32 @test14b(i32 %0, i32 signext %1) {
792 ; CHECK-LABEL: test14b:
793 ; CHECK:       # %bb.0:
794 ; CHECK-NEXT:    li a2, 2
795 ; CHECK-NEXT:    blt a1, a2, .LBB14_4
796 ; CHECK-NEXT:  # %bb.1: # %.preheader
797 ; CHECK-NEXT:    li a2, 1
798 ; CHECK-NEXT:    li a3, 1000
799 ; CHECK-NEXT:  .LBB14_2: # =>This Inner Loop Header: Depth=1
800 ; CHECK-NEXT:    sext.w a4, a0
801 ; CHECK-NEXT:    blt a3, a4, .LBB14_5
802 ; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB14_2 Depth=1
803 ; CHECK-NEXT:    add a0, a2, a0
804 ; CHECK-NEXT:    addiw a2, a2, 1
805 ; CHECK-NEXT:    blt a2, a1, .LBB14_2
806 ; CHECK-NEXT:  .LBB14_4:
807 ; CHECK-NEXT:    sext.w a0, a0
808 ; CHECK-NEXT:    ret
809 ; CHECK-NEXT:  .LBB14_5:
810 ; CHECK-NEXT:    li a0, -1
811 ; CHECK-NEXT:    sext.w a0, a0
812 ; CHECK-NEXT:    ret
814 ; NOREMOVAL-LABEL: test14b:
815 ; NOREMOVAL:       # %bb.0:
816 ; NOREMOVAL-NEXT:    li a2, 2
817 ; NOREMOVAL-NEXT:    blt a1, a2, .LBB14_4
818 ; NOREMOVAL-NEXT:  # %bb.1: # %.preheader
819 ; NOREMOVAL-NEXT:    li a2, 1
820 ; NOREMOVAL-NEXT:    li a3, 1000
821 ; NOREMOVAL-NEXT:  .LBB14_2: # =>This Inner Loop Header: Depth=1
822 ; NOREMOVAL-NEXT:    sext.w a4, a0
823 ; NOREMOVAL-NEXT:    blt a3, a4, .LBB14_5
824 ; NOREMOVAL-NEXT:  # %bb.3: # in Loop: Header=BB14_2 Depth=1
825 ; NOREMOVAL-NEXT:    add a0, a2, a0
826 ; NOREMOVAL-NEXT:    addiw a2, a2, 1
827 ; NOREMOVAL-NEXT:    blt a2, a1, .LBB14_2
828 ; NOREMOVAL-NEXT:  .LBB14_4:
829 ; NOREMOVAL-NEXT:    sext.w a0, a0
830 ; NOREMOVAL-NEXT:    ret
831 ; NOREMOVAL-NEXT:  .LBB14_5:
832 ; NOREMOVAL-NEXT:    li a0, -1
833 ; NOREMOVAL-NEXT:    sext.w a0, a0
834 ; NOREMOVAL-NEXT:    ret
835   %3 = icmp sgt i32 %1, 1
836   br i1 %3, label %4, label %12
838 4:                                                ; preds = %2, %8
839   %5 = phi i32 [ %10, %8 ], [ 1, %2 ]
840   %6 = phi i32 [ %9, %8 ], [ %0, %2 ]
841   %7 = icmp sgt i32 %6, 1000
842   br i1 %7, label %12, label %8
844 8:                                                ; preds = %4
845   %9 = add nsw i32 %5, %6
846   %10 = add nuw nsw i32 %5, 1
847   %11 = icmp slt i32 %10, %1
848   br i1 %11, label %4, label %12
850 12:                                               ; preds = %8, %4, %2
851   %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
852   ret i32 %13
855 ; Same as test14, but the argument is zero extended instead of sign extended so
856 ; we can't optimize it.
857 define signext i32 @test14c(i32 zeroext %0, i32 signext %1) {
858 ; CHECK-LABEL: test14c:
859 ; CHECK:       # %bb.0:
860 ; CHECK-NEXT:    li a2, 2
861 ; CHECK-NEXT:    blt a1, a2, .LBB15_4
862 ; CHECK-NEXT:  # %bb.1: # %.preheader
863 ; CHECK-NEXT:    li a2, 1
864 ; CHECK-NEXT:    li a3, 1000
865 ; CHECK-NEXT:  .LBB15_2: # =>This Inner Loop Header: Depth=1
866 ; CHECK-NEXT:    sext.w a4, a0
867 ; CHECK-NEXT:    blt a3, a4, .LBB15_5
868 ; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB15_2 Depth=1
869 ; CHECK-NEXT:    add a0, a2, a0
870 ; CHECK-NEXT:    addiw a2, a2, 1
871 ; CHECK-NEXT:    blt a2, a1, .LBB15_2
872 ; CHECK-NEXT:  .LBB15_4:
873 ; CHECK-NEXT:    sext.w a0, a0
874 ; CHECK-NEXT:    ret
875 ; CHECK-NEXT:  .LBB15_5:
876 ; CHECK-NEXT:    li a0, -1
877 ; CHECK-NEXT:    sext.w a0, a0
878 ; CHECK-NEXT:    ret
880 ; NOREMOVAL-LABEL: test14c:
881 ; NOREMOVAL:       # %bb.0:
882 ; NOREMOVAL-NEXT:    li a2, 2
883 ; NOREMOVAL-NEXT:    blt a1, a2, .LBB15_4
884 ; NOREMOVAL-NEXT:  # %bb.1: # %.preheader
885 ; NOREMOVAL-NEXT:    li a2, 1
886 ; NOREMOVAL-NEXT:    li a3, 1000
887 ; NOREMOVAL-NEXT:  .LBB15_2: # =>This Inner Loop Header: Depth=1
888 ; NOREMOVAL-NEXT:    sext.w a4, a0
889 ; NOREMOVAL-NEXT:    blt a3, a4, .LBB15_5
890 ; NOREMOVAL-NEXT:  # %bb.3: # in Loop: Header=BB15_2 Depth=1
891 ; NOREMOVAL-NEXT:    add a0, a2, a0
892 ; NOREMOVAL-NEXT:    addiw a2, a2, 1
893 ; NOREMOVAL-NEXT:    blt a2, a1, .LBB15_2
894 ; NOREMOVAL-NEXT:  .LBB15_4:
895 ; NOREMOVAL-NEXT:    sext.w a0, a0
896 ; NOREMOVAL-NEXT:    ret
897 ; NOREMOVAL-NEXT:  .LBB15_5:
898 ; NOREMOVAL-NEXT:    li a0, -1
899 ; NOREMOVAL-NEXT:    sext.w a0, a0
900 ; NOREMOVAL-NEXT:    ret
901   %3 = icmp sgt i32 %1, 1
902   br i1 %3, label %4, label %12
904 4:                                                ; preds = %2, %8
905   %5 = phi i32 [ %10, %8 ], [ 1, %2 ]
906   %6 = phi i32 [ %9, %8 ], [ %0, %2 ]
907   %7 = icmp sgt i32 %6, 1000
908   br i1 %7, label %12, label %8
910 8:                                                ; preds = %4
911   %9 = add nsw i32 %5, %6
912   %10 = add nuw nsw i32 %5, 1
913   %11 = icmp slt i32 %10, %1
914   br i1 %11, label %4, label %12
916 12:                                               ; preds = %8, %4, %2
917   %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
918   ret i32 %13
921 ; Same as test14 but the argument is zero extended from i31. Since bits 63:31
922 ; are zero, this counts as an i32 sign extend so we can optimize it.
923 define signext i32 @test14d(i31 zeroext %0, i32 signext %1) {
924 ; CHECK-LABEL: test14d:
925 ; CHECK:       # %bb.0:
926 ; CHECK-NEXT:    li a2, 2
927 ; CHECK-NEXT:    blt a1, a2, .LBB16_4
928 ; CHECK-NEXT:  # %bb.1: # %.preheader
929 ; CHECK-NEXT:    li a2, 1
930 ; CHECK-NEXT:    li a3, 1000
931 ; CHECK-NEXT:  .LBB16_2: # =>This Inner Loop Header: Depth=1
932 ; CHECK-NEXT:    blt a3, a0, .LBB16_5
933 ; CHECK-NEXT:  # %bb.3: # in Loop: Header=BB16_2 Depth=1
934 ; CHECK-NEXT:    addw a0, a2, a0
935 ; CHECK-NEXT:    addiw a2, a2, 1
936 ; CHECK-NEXT:    blt a2, a1, .LBB16_2
937 ; CHECK-NEXT:  .LBB16_4:
938 ; CHECK-NEXT:    ret
939 ; CHECK-NEXT:  .LBB16_5:
940 ; CHECK-NEXT:    li a0, -1
941 ; CHECK-NEXT:    ret
943 ; NOREMOVAL-LABEL: test14d:
944 ; NOREMOVAL:       # %bb.0:
945 ; NOREMOVAL-NEXT:    li a2, 2
946 ; NOREMOVAL-NEXT:    blt a1, a2, .LBB16_4
947 ; NOREMOVAL-NEXT:  # %bb.1: # %.preheader
948 ; NOREMOVAL-NEXT:    li a2, 1
949 ; NOREMOVAL-NEXT:    li a3, 1000
950 ; NOREMOVAL-NEXT:  .LBB16_2: # =>This Inner Loop Header: Depth=1
951 ; NOREMOVAL-NEXT:    sext.w a4, a0
952 ; NOREMOVAL-NEXT:    blt a3, a4, .LBB16_5
953 ; NOREMOVAL-NEXT:  # %bb.3: # in Loop: Header=BB16_2 Depth=1
954 ; NOREMOVAL-NEXT:    addw a0, a2, a0
955 ; NOREMOVAL-NEXT:    addiw a2, a2, 1
956 ; NOREMOVAL-NEXT:    blt a2, a1, .LBB16_2
957 ; NOREMOVAL-NEXT:  .LBB16_4:
958 ; NOREMOVAL-NEXT:    ret
959 ; NOREMOVAL-NEXT:  .LBB16_5:
960 ; NOREMOVAL-NEXT:    li a0, -1
961 ; NOREMOVAL-NEXT:    ret
962   %zext = zext i31 %0 to i32
963   %3 = icmp sgt i32 %1, 1
964   br i1 %3, label %4, label %12
966 4:                                                ; preds = %2, %8
967   %5 = phi i32 [ %10, %8 ], [ 1, %2 ]
968   %6 = phi i32 [ %9, %8 ], [ %zext, %2 ]
969   %7 = icmp sgt i32 %6, 1000
970   br i1 %7, label %12, label %8
972 8:                                                ; preds = %4
973   %9 = add nsw i32 %5, %6
974   %10 = add nuw nsw i32 %5, 1
975   %11 = icmp slt i32 %10, %1
976   br i1 %11, label %4, label %12
978 12:                                               ; preds = %8, %4, %2
979   %13 = phi i32 [ %zext, %2 ], [ -1, %4 ], [ %9, %8 ]
980   ret i32 %13
983 define signext i32 @test15(i64 %arg1, i64 %arg2, i64 %arg3, ptr %arg4)  {
984 ; CHECK-LABEL: test15:
985 ; CHECK:       # %bb.0: # %entry
986 ; CHECK-NEXT:    addi a2, a2, -1
987 ; CHECK-NEXT:    li a4, 256
988 ; CHECK-NEXT:  .LBB17_1: # %bb2
989 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
990 ; CHECK-NEXT:    andi a0, a0, 1234
991 ; CHECK-NEXT:    addw a0, a0, a1
992 ; CHECK-NEXT:    addi a2, a2, 1
993 ; CHECK-NEXT:    sw a0, 0(a3)
994 ; CHECK-NEXT:    bltu a2, a4, .LBB17_1
995 ; CHECK-NEXT:  # %bb.2: # %bb7
996 ; CHECK-NEXT:    ret
998 ; NOREMOVAL-LABEL: test15:
999 ; NOREMOVAL:       # %bb.0: # %entry
1000 ; NOREMOVAL-NEXT:    addi a2, a2, -1
1001 ; NOREMOVAL-NEXT:    li a4, 256
1002 ; NOREMOVAL-NEXT:  .LBB17_1: # %bb2
1003 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1004 ; NOREMOVAL-NEXT:    andi a0, a0, 1234
1005 ; NOREMOVAL-NEXT:    add a0, a0, a1
1006 ; NOREMOVAL-NEXT:    addi a2, a2, 1
1007 ; NOREMOVAL-NEXT:    sw a0, 0(a3)
1008 ; NOREMOVAL-NEXT:    bltu a2, a4, .LBB17_1
1009 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1010 ; NOREMOVAL-NEXT:    sext.w a0, a0
1011 ; NOREMOVAL-NEXT:    ret
1012 entry:
1013   br label %bb2
1015 bb2:                                              ; preds = %bb2, %entry
1016   %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ]
1017   %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ]
1018   %i3 = add i64 %i2, 1
1019   %i4 = and i64 %i1, 1234
1020   %i5 = add i64 %i4, %arg2
1021   %i8 = trunc i64 %i5 to i32
1022   store i32 %i8, ptr %arg4
1023   %i6 = icmp ugt i64 %i2, 255
1024   br i1 %i6, label %bb7, label %bb2
1026 bb7:                                              ; preds = %bb2
1027   %i7 = trunc i64 %i5 to i32
1028   ret i32 %i7
1031 ; This test previously removed a sext.w without converting a slli to slliw.
1032 define signext i32 @bug(i32 signext %x) {
1033 ; CHECK-LABEL: bug:
1034 ; CHECK:       # %bb.0: # %entry
1035 ; CHECK-NEXT:    beqz a0, .LBB18_4
1036 ; CHECK-NEXT:  # %bb.1: # %if.end
1037 ; CHECK-NEXT:    srliw a2, a0, 16
1038 ; CHECK-NEXT:    seqz a1, a2
1039 ; CHECK-NEXT:    slli a1, a1, 4
1040 ; CHECK-NEXT:    sllw a1, a0, a1
1041 ; CHECK-NEXT:    li a0, 16
1042 ; CHECK-NEXT:    beqz a2, .LBB18_3
1043 ; CHECK-NEXT:  # %bb.2: # %if.end
1044 ; CHECK-NEXT:    li a0, 32
1045 ; CHECK-NEXT:  .LBB18_3: # %if.end
1046 ; CHECK-NEXT:    srliw a2, a1, 24
1047 ; CHECK-NEXT:    seqz a2, a2
1048 ; CHECK-NEXT:    slli a3, a2, 3
1049 ; CHECK-NEXT:    sllw a1, a1, a3
1050 ; CHECK-NEXT:    negw a2, a2
1051 ; CHECK-NEXT:    andi a2, a2, -8
1052 ; CHECK-NEXT:    add a0, a0, a2
1053 ; CHECK-NEXT:    srliw a2, a1, 28
1054 ; CHECK-NEXT:    seqz a2, a2
1055 ; CHECK-NEXT:    slli a3, a2, 2
1056 ; CHECK-NEXT:    sllw a1, a1, a3
1057 ; CHECK-NEXT:    negw a2, a2
1058 ; CHECK-NEXT:    andi a2, a2, -4
1059 ; CHECK-NEXT:    add a0, a0, a2
1060 ; CHECK-NEXT:    srliw a2, a1, 30
1061 ; CHECK-NEXT:    seqz a2, a2
1062 ; CHECK-NEXT:    slli a3, a2, 1
1063 ; CHECK-NEXT:    sllw a1, a1, a3
1064 ; CHECK-NEXT:    negw a2, a2
1065 ; CHECK-NEXT:    andi a2, a2, -2
1066 ; CHECK-NEXT:    add a0, a0, a2
1067 ; CHECK-NEXT:    not a1, a1
1068 ; CHECK-NEXT:    srli a1, a1, 31
1069 ; CHECK-NEXT:    addw a0, a0, a1
1070 ; CHECK-NEXT:  .LBB18_4: # %cleanup
1071 ; CHECK-NEXT:    ret
1073 ; NOREMOVAL-LABEL: bug:
1074 ; NOREMOVAL:       # %bb.0: # %entry
1075 ; NOREMOVAL-NEXT:    beqz a0, .LBB18_4
1076 ; NOREMOVAL-NEXT:  # %bb.1: # %if.end
1077 ; NOREMOVAL-NEXT:    srliw a2, a0, 16
1078 ; NOREMOVAL-NEXT:    seqz a1, a2
1079 ; NOREMOVAL-NEXT:    slli a1, a1, 4
1080 ; NOREMOVAL-NEXT:    sllw a1, a0, a1
1081 ; NOREMOVAL-NEXT:    li a0, 16
1082 ; NOREMOVAL-NEXT:    beqz a2, .LBB18_3
1083 ; NOREMOVAL-NEXT:  # %bb.2: # %if.end
1084 ; NOREMOVAL-NEXT:    li a0, 32
1085 ; NOREMOVAL-NEXT:  .LBB18_3: # %if.end
1086 ; NOREMOVAL-NEXT:    srliw a2, a1, 24
1087 ; NOREMOVAL-NEXT:    seqz a2, a2
1088 ; NOREMOVAL-NEXT:    slli a3, a2, 3
1089 ; NOREMOVAL-NEXT:    sllw a1, a1, a3
1090 ; NOREMOVAL-NEXT:    negw a2, a2
1091 ; NOREMOVAL-NEXT:    andi a2, a2, -8
1092 ; NOREMOVAL-NEXT:    add a0, a0, a2
1093 ; NOREMOVAL-NEXT:    srliw a2, a1, 28
1094 ; NOREMOVAL-NEXT:    seqz a2, a2
1095 ; NOREMOVAL-NEXT:    slli a3, a2, 2
1096 ; NOREMOVAL-NEXT:    sllw a1, a1, a3
1097 ; NOREMOVAL-NEXT:    negw a2, a2
1098 ; NOREMOVAL-NEXT:    andi a2, a2, -4
1099 ; NOREMOVAL-NEXT:    add a0, a0, a2
1100 ; NOREMOVAL-NEXT:    srliw a2, a1, 30
1101 ; NOREMOVAL-NEXT:    seqz a2, a2
1102 ; NOREMOVAL-NEXT:    slli a3, a2, 1
1103 ; NOREMOVAL-NEXT:    sllw a1, a1, a3
1104 ; NOREMOVAL-NEXT:    negw a2, a2
1105 ; NOREMOVAL-NEXT:    andi a2, a2, -2
1106 ; NOREMOVAL-NEXT:    add a0, a0, a2
1107 ; NOREMOVAL-NEXT:    not a1, a1
1108 ; NOREMOVAL-NEXT:    srli a1, a1, 31
1109 ; NOREMOVAL-NEXT:    addw a0, a0, a1
1110 ; NOREMOVAL-NEXT:  .LBB18_4: # %cleanup
1111 ; NOREMOVAL-NEXT:    ret
1112 entry:
1113   %tobool.not = icmp eq i32 %x, 0
1114   br i1 %tobool.not, label %cleanup, label %if.end
1116 if.end:                                           ; preds = %entry
1117   %tobool1.not = icmp ult i32 %x, 65536
1118   %shl = shl i32 %x, 16
1119   %spec.select = select i1 %tobool1.not, i32 %shl, i32 %x
1120   %spec.select43 = select i1 %tobool1.not, i32 16, i32 32
1121   %tobool5.not = icmp ult i32 %spec.select, 16777216
1122   %shl7 = shl i32 %spec.select, 8
1123   %sub8 = add nsw i32 %spec.select43, -8
1124   %x.addr.1 = select i1 %tobool5.not, i32 %shl7, i32 %spec.select
1125   %r.1 = select i1 %tobool5.not, i32 %sub8, i32 %spec.select43
1126   %tobool11.not = icmp ult i32 %x.addr.1, 268435456
1127   %shl13 = shl i32 %x.addr.1, 4
1128   %sub14 = add nsw i32 %r.1, -4
1129   %x.addr.2 = select i1 %tobool11.not, i32 %shl13, i32 %x.addr.1
1130   %r.2 = select i1 %tobool11.not, i32 %sub14, i32 %r.1
1131   %tobool17.not = icmp ult i32 %x.addr.2, 1073741824
1132   %shl19 = shl i32 %x.addr.2, 2
1133   %sub20 = add nsw i32 %r.2, -2
1134   %x.addr.3 = select i1 %tobool17.not, i32 %shl19, i32 %x.addr.2
1135   %r.3 = select i1 %tobool17.not, i32 %sub20, i32 %r.2
1136   %x.addr.3.lobit = ashr i32 %x.addr.3, 31
1137   %x.addr.3.lobit.not = xor i32 %x.addr.3.lobit, -1
1138   %r.4 = add nsw i32 %r.3, %x.addr.3.lobit.not
1139   br label %cleanup
1141 cleanup:                                          ; preds = %entry, %if.end
1142   %retval.0 = phi i32 [ %r.4, %if.end ], [ 0, %entry ]
1143   ret i32 %retval.0
1146 define void @test16(i32 signext %arg, i32 signext %arg1) nounwind {
1147 ; CHECK-LABEL: test16:
1148 ; CHECK:       # %bb.0: # %bb
1149 ; CHECK-NEXT:    addi sp, sp, -32
1150 ; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1151 ; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1152 ; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1153 ; CHECK-NEXT:    mv s0, a1
1154 ; CHECK-NEXT:    call bar
1155 ; CHECK-NEXT:    mv s1, a0
1156 ; CHECK-NEXT:  .LBB19_1: # %bb2
1157 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1158 ; CHECK-NEXT:    mv a0, s1
1159 ; CHECK-NEXT:    call bar
1160 ; CHECK-NEXT:    sllw s1, s1, s0
1161 ; CHECK-NEXT:    bnez a0, .LBB19_1
1162 ; CHECK-NEXT:  # %bb.2: # %bb7
1163 ; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1164 ; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1165 ; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1166 ; CHECK-NEXT:    addi sp, sp, 32
1167 ; CHECK-NEXT:    ret
1169 ; NOREMOVAL-LABEL: test16:
1170 ; NOREMOVAL:       # %bb.0: # %bb
1171 ; NOREMOVAL-NEXT:    addi sp, sp, -32
1172 ; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1173 ; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1174 ; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1175 ; NOREMOVAL-NEXT:    mv s0, a1
1176 ; NOREMOVAL-NEXT:    call bar
1177 ; NOREMOVAL-NEXT:    mv s1, a0
1178 ; NOREMOVAL-NEXT:  .LBB19_1: # %bb2
1179 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1180 ; NOREMOVAL-NEXT:    sext.w a0, s1
1181 ; NOREMOVAL-NEXT:    call bar
1182 ; NOREMOVAL-NEXT:    sllw s1, s1, s0
1183 ; NOREMOVAL-NEXT:    bnez a0, .LBB19_1
1184 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1185 ; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1186 ; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1187 ; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1188 ; NOREMOVAL-NEXT:    addi sp, sp, 32
1189 ; NOREMOVAL-NEXT:    ret
1191   %i = call signext i32 @bar(i32 signext %arg)
1192   br label %bb2
1194 bb2:                                              ; preds = %bb2, %bb
1195   %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
1196   %i4 = tail call signext i32 @bar(i32 signext %i3)
1197   %i5 = shl i32 %i3, %arg1
1198   %i6 = icmp eq i32 %i4, 0
1199   br i1 %i6, label %bb7, label %bb2
1201 bb7:                                              ; preds = %bb2
1202   ret void
1205 define void @test17(i32 signext %arg, i32 signext %arg1) nounwind {
1206 ; CHECK-LABEL: test17:
1207 ; CHECK:       # %bb.0: # %bb
1208 ; CHECK-NEXT:    addi sp, sp, -32
1209 ; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1210 ; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1211 ; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1212 ; CHECK-NEXT:    mv s0, a1
1213 ; CHECK-NEXT:    call bat
1214 ; CHECK-NEXT:    mv s1, a0
1215 ; CHECK-NEXT:  .LBB20_1: # %bb2
1216 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1217 ; CHECK-NEXT:    mv a0, s1
1218 ; CHECK-NEXT:    call bar
1219 ; CHECK-NEXT:    sllw s1, s1, s0
1220 ; CHECK-NEXT:    bnez a0, .LBB20_1
1221 ; CHECK-NEXT:  # %bb.2: # %bb7
1222 ; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1223 ; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1224 ; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1225 ; CHECK-NEXT:    addi sp, sp, 32
1226 ; CHECK-NEXT:    ret
1228 ; NOREMOVAL-LABEL: test17:
1229 ; NOREMOVAL:       # %bb.0: # %bb
1230 ; NOREMOVAL-NEXT:    addi sp, sp, -32
1231 ; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1232 ; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1233 ; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1234 ; NOREMOVAL-NEXT:    mv s0, a1
1235 ; NOREMOVAL-NEXT:    call bat
1236 ; NOREMOVAL-NEXT:    mv s1, a0
1237 ; NOREMOVAL-NEXT:  .LBB20_1: # %bb2
1238 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1239 ; NOREMOVAL-NEXT:    sext.w a0, s1
1240 ; NOREMOVAL-NEXT:    call bar
1241 ; NOREMOVAL-NEXT:    sllw s1, s1, s0
1242 ; NOREMOVAL-NEXT:    bnez a0, .LBB20_1
1243 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1244 ; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1245 ; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1246 ; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1247 ; NOREMOVAL-NEXT:    addi sp, sp, 32
1248 ; NOREMOVAL-NEXT:    ret
1250   %i = call zeroext i16 @bat(i32 signext %arg)
1251   %zext = zext i16 %i to i32
1252   br label %bb2
1254 bb2:                                              ; preds = %bb2, %bb
1255   %i3 = phi i32 [ %zext, %bb ], [ %i5, %bb2 ]
1256   %i4 = tail call signext i32 @bar(i32 signext %i3)
1257   %i5 = shl i32 %i3, %arg1
1258   %i6 = icmp eq i32 %i4, 0
1259   br i1 %i6, label %bb7, label %bb2
1261 bb7:                                              ; preds = %bb2
1262   ret void
1264 declare zeroext i16 @bat(i32 signext)
1266 define void @test18(i32 signext %arg, i32 signext %arg1) nounwind {
1267 ; CHECK-LABEL: test18:
1268 ; CHECK:       # %bb.0: # %bb
1269 ; CHECK-NEXT:    addi sp, sp, -32
1270 ; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1271 ; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1272 ; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1273 ; CHECK-NEXT:    mv s0, a1
1274 ; CHECK-NEXT:    sha256sig0 s1, a1
1275 ; CHECK-NEXT:  .LBB21_1: # %bb2
1276 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1277 ; CHECK-NEXT:    mv a0, s1
1278 ; CHECK-NEXT:    call bar
1279 ; CHECK-NEXT:    sllw s1, s1, s0
1280 ; CHECK-NEXT:    bnez a0, .LBB21_1
1281 ; CHECK-NEXT:  # %bb.2: # %bb7
1282 ; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1283 ; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1284 ; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1285 ; CHECK-NEXT:    addi sp, sp, 32
1286 ; CHECK-NEXT:    ret
1288 ; NOREMOVAL-LABEL: test18:
1289 ; NOREMOVAL:       # %bb.0: # %bb
1290 ; NOREMOVAL-NEXT:    addi sp, sp, -32
1291 ; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1292 ; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1293 ; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1294 ; NOREMOVAL-NEXT:    mv s0, a1
1295 ; NOREMOVAL-NEXT:    sha256sig0 s1, a1
1296 ; NOREMOVAL-NEXT:  .LBB21_1: # %bb2
1297 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1298 ; NOREMOVAL-NEXT:    sext.w a0, s1
1299 ; NOREMOVAL-NEXT:    call bar
1300 ; NOREMOVAL-NEXT:    sllw s1, s1, s0
1301 ; NOREMOVAL-NEXT:    bnez a0, .LBB21_1
1302 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1303 ; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1304 ; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1305 ; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1306 ; NOREMOVAL-NEXT:    addi sp, sp, 32
1307 ; NOREMOVAL-NEXT:    ret
1309   %i = call i32 @llvm.riscv.sha256sig0(i32 %arg1)
1310   br label %bb2
1312 bb2:                                              ; preds = %bb2, %bb
1313   %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
1314   %i4 = tail call signext i32 @bar(i32 signext %i3)
1315   %i5 = shl i32 %i3, %arg1
1316   %i6 = icmp eq i32 %i4, 0
1317   br i1 %i6, label %bb7, label %bb2
1319 bb7:                                              ; preds = %bb2
1320   ret void
1322 declare i32 @llvm.riscv.sha256sig0(i32)
1324 ; The type promotion of %7 forms a sext_inreg, but %7 and %6 are combined to
1325 ; form a sh2add. This leaves behind a sext.w that isn't needed.
1326 define signext i32 @sextw_sh2add(i1 zeroext %0, ptr %1, i32 signext %2, i32 signext %3, i32 signext %4) {
1327 ; RV64I-LABEL: sextw_sh2add:
1328 ; RV64I:       # %bb.0:
1329 ; RV64I-NEXT:    slli a2, a2, 2
1330 ; RV64I-NEXT:    add a3, a2, a3
1331 ; RV64I-NEXT:    beqz a0, .LBB22_2
1332 ; RV64I-NEXT:  # %bb.1:
1333 ; RV64I-NEXT:    sw a3, 0(a1)
1334 ; RV64I-NEXT:  .LBB22_2:
1335 ; RV64I-NEXT:    addw a0, a3, a4
1336 ; RV64I-NEXT:    ret
1338 ; RV64ZBB-LABEL: sextw_sh2add:
1339 ; RV64ZBB:       # %bb.0:
1340 ; RV64ZBB-NEXT:    sh2add a2, a2, a3
1341 ; RV64ZBB-NEXT:    beqz a0, .LBB22_2
1342 ; RV64ZBB-NEXT:  # %bb.1:
1343 ; RV64ZBB-NEXT:    sw a2, 0(a1)
1344 ; RV64ZBB-NEXT:  .LBB22_2:
1345 ; RV64ZBB-NEXT:    addw a0, a2, a4
1346 ; RV64ZBB-NEXT:    ret
1348 ; NOREMOVAL-LABEL: sextw_sh2add:
1349 ; NOREMOVAL:       # %bb.0:
1350 ; NOREMOVAL-NEXT:    sh2add a2, a2, a3
1351 ; NOREMOVAL-NEXT:    mv a2, a2
1352 ; NOREMOVAL-NEXT:    beqz a0, .LBB22_2
1353 ; NOREMOVAL-NEXT:  # %bb.1:
1354 ; NOREMOVAL-NEXT:    sw a2, 0(a1)
1355 ; NOREMOVAL-NEXT:  .LBB22_2:
1356 ; NOREMOVAL-NEXT:    addw a0, a2, a4
1357 ; NOREMOVAL-NEXT:    ret
1358   %6 = shl i32 %2, 2
1359   %7 = add i32 %6, %3
1360   br i1 %0, label %8, label %9
1362 8:                                                ; preds = %5
1363   store i32 %7, ptr %1, align 4
1364   br label %9
1366 9:                                                ; preds = %5, %8
1367   %10 = add i32 %7, %4
1368   ret i32 %10
1371 ; Negative test - an explicit sext.w *is* required
1372 define signext i32 @test19(i64 %arg, i1 zeroext %c1, i1 zeroext %c2, ptr %p) nounwind {
1373 ; CHECK-LABEL: test19:
1374 ; CHECK:       # %bb.0: # %bb
1375 ; CHECK-NEXT:    addi sp, sp, -16
1376 ; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
1377 ; CHECK-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
1378 ; CHECK-NEXT:    neg a0, a1
1379 ; CHECK-NEXT:    li a1, 1
1380 ; CHECK-NEXT:    slli a1, a1, 32
1381 ; CHECK-NEXT:    addi s0, a1, 35
1382 ; CHECK-NEXT:    and s0, a0, s0
1383 ; CHECK-NEXT:    sd s0, 0(a3)
1384 ; CHECK-NEXT:    beqz a2, .LBB23_2
1385 ; CHECK-NEXT:  # %bb.1: # %bb2
1386 ; CHECK-NEXT:    li a0, 0
1387 ; CHECK-NEXT:    call bar
1388 ; CHECK-NEXT:    mv s0, a0
1389 ; CHECK-NEXT:  .LBB23_2: # %bb7
1390 ; CHECK-NEXT:    call side_effect
1391 ; CHECK-NEXT:    sext.w a0, s0
1392 ; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
1393 ; CHECK-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
1394 ; CHECK-NEXT:    addi sp, sp, 16
1395 ; CHECK-NEXT:    ret
1397 ; NOREMOVAL-LABEL: test19:
1398 ; NOREMOVAL:       # %bb.0: # %bb
1399 ; NOREMOVAL-NEXT:    addi sp, sp, -16
1400 ; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
1401 ; NOREMOVAL-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
1402 ; NOREMOVAL-NEXT:    neg a0, a1
1403 ; NOREMOVAL-NEXT:    li a1, 1
1404 ; NOREMOVAL-NEXT:    slli a1, a1, 32
1405 ; NOREMOVAL-NEXT:    addi s0, a1, 35
1406 ; NOREMOVAL-NEXT:    and s0, a0, s0
1407 ; NOREMOVAL-NEXT:    sd s0, 0(a3)
1408 ; NOREMOVAL-NEXT:    beqz a2, .LBB23_2
1409 ; NOREMOVAL-NEXT:  # %bb.1: # %bb2
1410 ; NOREMOVAL-NEXT:    li a0, 0
1411 ; NOREMOVAL-NEXT:    call bar
1412 ; NOREMOVAL-NEXT:    mv s0, a0
1413 ; NOREMOVAL-NEXT:  .LBB23_2: # %bb7
1414 ; NOREMOVAL-NEXT:    call side_effect
1415 ; NOREMOVAL-NEXT:    sext.w a0, s0
1416 ; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
1417 ; NOREMOVAL-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
1418 ; NOREMOVAL-NEXT:    addi sp, sp, 16
1419 ; NOREMOVAL-NEXT:    ret
1421   %sel = select i1 %c1, i64 4294967331, i64 0
1422   store i64 %sel, ptr %p, align 8
1423   br i1 %c2, label %bb2, label %bb7
1425 bb2:                                              ; preds = %bb2, %bb
1426   %i4 = call signext i32 @bar(i32 0)
1427   %i4.sext = sext i32 %i4 to i64
1428   br label %bb7
1430 bb7:                                              ; preds = %bb2
1431   %phi = phi i64 [ %sel, %bb ], [ %i4.sext, %bb2 ]
1432   %trunc = trunc i64 %phi to i32
1433   call void @side_effect()
1434   ret i32 %trunc
1437  declare void @side_effect(i64)
1439 define void @test20(<vscale x 1 x i32> %arg, i32 signext %arg1) nounwind {
1440 ; CHECK-LABEL: test20:
1441 ; CHECK:       # %bb.0: # %bb
1442 ; CHECK-NEXT:    addi sp, sp, -32
1443 ; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1444 ; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1445 ; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1446 ; CHECK-NEXT:    mv s0, a0
1447 ; CHECK-NEXT:    vsetivli zero, 1, e32, m1, ta, ma
1448 ; CHECK-NEXT:    vmv.x.s s1, v8
1449 ; CHECK-NEXT:  .LBB24_1: # %bb2
1450 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1451 ; CHECK-NEXT:    mv a0, s1
1452 ; CHECK-NEXT:    call bar
1453 ; CHECK-NEXT:    sllw s1, s1, s0
1454 ; CHECK-NEXT:    bnez a0, .LBB24_1
1455 ; CHECK-NEXT:  # %bb.2: # %bb7
1456 ; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1457 ; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1458 ; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1459 ; CHECK-NEXT:    addi sp, sp, 32
1460 ; CHECK-NEXT:    ret
1462 ; NOREMOVAL-LABEL: test20:
1463 ; NOREMOVAL:       # %bb.0: # %bb
1464 ; NOREMOVAL-NEXT:    addi sp, sp, -32
1465 ; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1466 ; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1467 ; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1468 ; NOREMOVAL-NEXT:    mv s0, a0
1469 ; NOREMOVAL-NEXT:    vsetivli zero, 1, e32, m1, ta, ma
1470 ; NOREMOVAL-NEXT:    vmv.x.s s1, v8
1471 ; NOREMOVAL-NEXT:  .LBB24_1: # %bb2
1472 ; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1473 ; NOREMOVAL-NEXT:    sext.w a0, s1
1474 ; NOREMOVAL-NEXT:    call bar
1475 ; NOREMOVAL-NEXT:    sllw s1, s1, s0
1476 ; NOREMOVAL-NEXT:    bnez a0, .LBB24_1
1477 ; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1478 ; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1479 ; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1480 ; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1481 ; NOREMOVAL-NEXT:    addi sp, sp, 32
1482 ; NOREMOVAL-NEXT:    ret
1484   %i = call i32 @llvm.riscv.vmv.x.s.nxv1i32(<vscale x 1 x i32> %arg)
1485   br label %bb2
1487 bb2:                                              ; preds = %bb2, %bb
1488   %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
1489   %i4 = tail call signext i32 @bar(i32 signext %i3)
1490   %i5 = shl i32 %i3, %arg1
1491   %i6 = icmp eq i32 %i4, 0
1492   br i1 %i6, label %bb7, label %bb2
1494 bb7:                                              ; preds = %bb2
1495   ret void
1498 declare i32 @llvm.riscv.vmv.x.s.nxv1i32( <vscale x 1 x i32>)