xref: /llvm-project/llvm/test/CodeGen/RISCV/sextw-removal.ll (revision 6657d4bd70523e6852f07f64711fb15bdf7b347a)
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
8
9define 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
30;
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
51bb:
52  %i = ashr i32 %arg, %arg1
53  br label %bb2
54
55bb2:                                              ; 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
61
62bb7:                                              ; preds = %bb2
63  ret void
64}
65
66declare signext i32 @bar(i32 signext)
67
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.
72define 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
81;
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
89;
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
102}
103
104define 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
113;
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
121;
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
134}
135
136define 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
145;
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
153;
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
166}
167
168; Make sure we don't put a sext.w before bar when using cpopw.
169define 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:    lui a2, 209715
181; RV64I-NEXT:    lui a3, 61681
182; RV64I-NEXT:    lui a4, 4112
183; RV64I-NEXT:    addiw s0, a1, 1365
184; RV64I-NEXT:    addiw s1, a2, 819
185; RV64I-NEXT:    addi s2, a3, -241
186; RV64I-NEXT:    addi s3, a4, 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
212;
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
228;
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
244bb:
245  %i = ashr i32 %arg, %arg1
246  br label %bb2
247
248bb2:                                              ; 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
254
255bb7:                                              ; preds = %bb2
256  ret void
257}
258
259declare i32 @llvm.ctpop.i32(i32)
260
261define 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
280;
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
300bb:
301  %i = ashr i32 %arg, %arg1
302  br label %bb2
303
304bb2:                                              ; 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
310
311bb7:                                              ; preds = %bb2
312  ret void
313}
314declare float @baz(i32 signext %i3)
315
316define 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:    lui a2, 209715
328; RV64I-NEXT:    lui a3, 61681
329; RV64I-NEXT:    lui a4, 4112
330; RV64I-NEXT:    addiw s0, a1, 1365
331; RV64I-NEXT:    addiw s1, a2, 819
332; RV64I-NEXT:    addiw s2, a3, -241
333; RV64I-NEXT:    addiw s3, a4, 257
334; RV64I-NEXT:    slli a1, s0, 32
335; RV64I-NEXT:    add s0, s0, a1
336; RV64I-NEXT:    slli a1, s1, 32
337; RV64I-NEXT:    add s1, s1, a1
338; RV64I-NEXT:    slli a1, s2, 32
339; RV64I-NEXT:    add s2, s2, a1
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
366;
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
381;
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
397bb:
398  %i = ashr i32 %arg, %arg1
399  br label %bb2
400
401bb2:                                              ; 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
408
409bb7:                                              ; preds = %bb2
410  ret void
411}
412
413declare i64 @llvm.ctpop.i64(i64)
414
415define 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
430;
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
446bb:
447  %i = ashr i32 %arg, %arg1
448  br label %bb2
449
450bb2:                                              ; 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
457
458bb7:                                              ; preds = %bb2
459  ret void
460}
461
462declare i64 @foo(i32 signext)
463
464define 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
483;
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
502bb:
503  %i = ashr i32 %arg, %arg1
504  br label %bb2
505
506bb2:                                              ; 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
513
514bb7:                                              ; preds = %bb2
515  ret void
516}
517
518define 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
537;
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
557bb:
558  %i = ashr i32 %arg, %arg1
559  br label %bb2
560
561bb2:                                              ; 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
567
568bb7:                                              ; preds = %bb2
569  ret void
570}
571
572; simple test for forward-searching. (and 1234) only uses lower word of input
573define 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
586;
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
600entry:
601  br label %bb2
602
603bb2:                                              ; 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
611
612bb7:                                              ; preds = %bb2
613  %i7 = trunc i64 %i5 to i32
614  ret i32 %i7
615}
616
617; circular use-dependency and multiple transformations.
618define 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
635;
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
652entry:
653  br label %bb2
654
655bb2:                                              ; 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
666
667bb7:                                              ; preds = %bb2
668  %r = trunc i64 %i8 to i32
669  ret i32 %r
670}
671
672; Not optimized. sdiv doesn't only use lower word
673define 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
687;
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
701entry:
702  br label %bb2
703
704bb2:                                              ; 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
712
713bb7:                                              ; preds = %bb2
714  %i8 = trunc i64 %i5 to i32
715  ret i32 %i8
716}
717
718
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;   }
725;
726;   return a;
727; }
728;
729; There should be no sext.w in the loop.
730define 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
749;
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
771
7724:                                                ; 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
777
7788:                                                ; 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
783
78412:                                               ; preds = %8, %4, %2
785  %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
786  ret i32 %13
787}
788
789; Same as test14 but the signext attribute is missing from the argument so we
790; can't optimize out the sext.w.
791define 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
813;
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
837
8384:                                                ; 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
843
8448:                                                ; 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
849
85012:                                               ; preds = %8, %4, %2
851  %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
852  ret i32 %13
853}
854
855; Same as test14, but the argument is zero extended instead of sign extended so
856; we can't optimize it.
857define 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
879;
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
903
9044:                                                ; 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
909
9108:                                                ; 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
915
91612:                                               ; preds = %8, %4, %2
917  %13 = phi i32 [ %0, %2 ], [ -1, %4 ], [ %9, %8 ]
918  ret i32 %13
919}
920
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.
923define 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
942;
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
965
9664:                                                ; 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
971
9728:                                                ; 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
977
97812:                                               ; preds = %8, %4, %2
979  %13 = phi i32 [ %zext, %2 ], [ -1, %4 ], [ %9, %8 ]
980  ret i32 %13
981}
982
983define 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
997;
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
1012entry:
1013  br label %bb2
1014
1015bb2:                                              ; 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
1025
1026bb7:                                              ; preds = %bb2
1027  %i7 = trunc i64 %i5 to i32
1028  ret i32 %i7
1029}
1030
1031; This test previously removed a sext.w without converting a slli to slliw.
1032define signext i32 @bug(i32 signext %x) {
1033; CHECK-LABEL: bug:
1034; CHECK:       # %bb.0: # %entry
1035; CHECK-NEXT:    beqz a0, .LBB18_5
1036; CHECK-NEXT:  # %bb.1: # %if.end
1037; CHECK-NEXT:    srliw a1, a0, 16
1038; CHECK-NEXT:    seqz a2, a1
1039; CHECK-NEXT:    slli a2, a2, 4
1040; CHECK-NEXT:    sllw a0, a0, a2
1041; CHECK-NEXT:    beqz a1, .LBB18_3
1042; CHECK-NEXT:  # %bb.2: # %if.end
1043; CHECK-NEXT:    li a1, 32
1044; CHECK-NEXT:    j .LBB18_4
1045; CHECK-NEXT:  .LBB18_3:
1046; CHECK-NEXT:    li a1, 16
1047; CHECK-NEXT:  .LBB18_4: # %if.end
1048; CHECK-NEXT:    srliw a2, a0, 24
1049; CHECK-NEXT:    seqz a2, a2
1050; CHECK-NEXT:    slli a3, a2, 3
1051; CHECK-NEXT:    negw a2, a2
1052; CHECK-NEXT:    sllw a0, a0, a3
1053; CHECK-NEXT:    andi a2, a2, -8
1054; CHECK-NEXT:    add a1, a1, a2
1055; CHECK-NEXT:    srliw a2, a0, 28
1056; CHECK-NEXT:    seqz a2, a2
1057; CHECK-NEXT:    slli a3, a2, 2
1058; CHECK-NEXT:    negw a2, a2
1059; CHECK-NEXT:    sllw a0, a0, a3
1060; CHECK-NEXT:    andi a2, a2, -4
1061; CHECK-NEXT:    add a1, a1, a2
1062; CHECK-NEXT:    srliw a2, a0, 30
1063; CHECK-NEXT:    seqz a2, a2
1064; CHECK-NEXT:    slli a3, a2, 1
1065; CHECK-NEXT:    negw a2, a2
1066; CHECK-NEXT:    sllw a0, a0, a3
1067; CHECK-NEXT:    andi a2, a2, -2
1068; CHECK-NEXT:    add a1, a1, a2
1069; CHECK-NEXT:    not a0, a0
1070; CHECK-NEXT:    srli a0, a0, 31
1071; CHECK-NEXT:    addw a0, a1, a0
1072; CHECK-NEXT:  .LBB18_5: # %cleanup
1073; CHECK-NEXT:    ret
1074;
1075; NOREMOVAL-LABEL: bug:
1076; NOREMOVAL:       # %bb.0: # %entry
1077; NOREMOVAL-NEXT:    beqz a0, .LBB18_5
1078; NOREMOVAL-NEXT:  # %bb.1: # %if.end
1079; NOREMOVAL-NEXT:    srliw a1, a0, 16
1080; NOREMOVAL-NEXT:    seqz a2, a1
1081; NOREMOVAL-NEXT:    slli a2, a2, 4
1082; NOREMOVAL-NEXT:    sllw a0, a0, a2
1083; NOREMOVAL-NEXT:    beqz a1, .LBB18_3
1084; NOREMOVAL-NEXT:  # %bb.2: # %if.end
1085; NOREMOVAL-NEXT:    li a1, 32
1086; NOREMOVAL-NEXT:    j .LBB18_4
1087; NOREMOVAL-NEXT:  .LBB18_3:
1088; NOREMOVAL-NEXT:    li a1, 16
1089; NOREMOVAL-NEXT:  .LBB18_4: # %if.end
1090; NOREMOVAL-NEXT:    srliw a2, a0, 24
1091; NOREMOVAL-NEXT:    seqz a2, a2
1092; NOREMOVAL-NEXT:    slli a3, a2, 3
1093; NOREMOVAL-NEXT:    negw a2, a2
1094; NOREMOVAL-NEXT:    sllw a0, a0, a3
1095; NOREMOVAL-NEXT:    andi a2, a2, -8
1096; NOREMOVAL-NEXT:    add a1, a1, a2
1097; NOREMOVAL-NEXT:    srliw a2, a0, 28
1098; NOREMOVAL-NEXT:    seqz a2, a2
1099; NOREMOVAL-NEXT:    slli a3, a2, 2
1100; NOREMOVAL-NEXT:    negw a2, a2
1101; NOREMOVAL-NEXT:    sllw a0, a0, a3
1102; NOREMOVAL-NEXT:    andi a2, a2, -4
1103; NOREMOVAL-NEXT:    add a1, a1, a2
1104; NOREMOVAL-NEXT:    srliw a2, a0, 30
1105; NOREMOVAL-NEXT:    seqz a2, a2
1106; NOREMOVAL-NEXT:    slli a3, a2, 1
1107; NOREMOVAL-NEXT:    negw a2, a2
1108; NOREMOVAL-NEXT:    sllw a0, a0, a3
1109; NOREMOVAL-NEXT:    andi a2, a2, -2
1110; NOREMOVAL-NEXT:    add a1, a1, a2
1111; NOREMOVAL-NEXT:    not a0, a0
1112; NOREMOVAL-NEXT:    srli a0, a0, 31
1113; NOREMOVAL-NEXT:    addw a0, a1, a0
1114; NOREMOVAL-NEXT:  .LBB18_5: # %cleanup
1115; NOREMOVAL-NEXT:    ret
1116entry:
1117  %tobool.not = icmp eq i32 %x, 0
1118  br i1 %tobool.not, label %cleanup, label %if.end
1119
1120if.end:                                           ; preds = %entry
1121  %tobool1.not = icmp ult i32 %x, 65536
1122  %shl = shl i32 %x, 16
1123  %spec.select = select i1 %tobool1.not, i32 %shl, i32 %x
1124  %spec.select43 = select i1 %tobool1.not, i32 16, i32 32
1125  %tobool5.not = icmp ult i32 %spec.select, 16777216
1126  %shl7 = shl i32 %spec.select, 8
1127  %sub8 = add nsw i32 %spec.select43, -8
1128  %x.addr.1 = select i1 %tobool5.not, i32 %shl7, i32 %spec.select
1129  %r.1 = select i1 %tobool5.not, i32 %sub8, i32 %spec.select43
1130  %tobool11.not = icmp ult i32 %x.addr.1, 268435456
1131  %shl13 = shl i32 %x.addr.1, 4
1132  %sub14 = add nsw i32 %r.1, -4
1133  %x.addr.2 = select i1 %tobool11.not, i32 %shl13, i32 %x.addr.1
1134  %r.2 = select i1 %tobool11.not, i32 %sub14, i32 %r.1
1135  %tobool17.not = icmp ult i32 %x.addr.2, 1073741824
1136  %shl19 = shl i32 %x.addr.2, 2
1137  %sub20 = add nsw i32 %r.2, -2
1138  %x.addr.3 = select i1 %tobool17.not, i32 %shl19, i32 %x.addr.2
1139  %r.3 = select i1 %tobool17.not, i32 %sub20, i32 %r.2
1140  %x.addr.3.lobit = ashr i32 %x.addr.3, 31
1141  %x.addr.3.lobit.not = xor i32 %x.addr.3.lobit, -1
1142  %r.4 = add nsw i32 %r.3, %x.addr.3.lobit.not
1143  br label %cleanup
1144
1145cleanup:                                          ; preds = %entry, %if.end
1146  %retval.0 = phi i32 [ %r.4, %if.end ], [ 0, %entry ]
1147  ret i32 %retval.0
1148}
1149
1150define void @test16(i32 signext %arg, i32 signext %arg1) nounwind {
1151; CHECK-LABEL: test16:
1152; CHECK:       # %bb.0: # %bb
1153; CHECK-NEXT:    addi sp, sp, -32
1154; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1155; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1156; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1157; CHECK-NEXT:    mv s0, a1
1158; CHECK-NEXT:    call bar
1159; CHECK-NEXT:    mv s1, a0
1160; CHECK-NEXT:  .LBB19_1: # %bb2
1161; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1162; CHECK-NEXT:    mv a0, s1
1163; CHECK-NEXT:    call bar
1164; CHECK-NEXT:    sllw s1, s1, s0
1165; CHECK-NEXT:    bnez a0, .LBB19_1
1166; CHECK-NEXT:  # %bb.2: # %bb7
1167; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1168; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1169; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1170; CHECK-NEXT:    addi sp, sp, 32
1171; CHECK-NEXT:    ret
1172;
1173; NOREMOVAL-LABEL: test16:
1174; NOREMOVAL:       # %bb.0: # %bb
1175; NOREMOVAL-NEXT:    addi sp, sp, -32
1176; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1177; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1178; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1179; NOREMOVAL-NEXT:    mv s0, a1
1180; NOREMOVAL-NEXT:    call bar
1181; NOREMOVAL-NEXT:    mv s1, a0
1182; NOREMOVAL-NEXT:  .LBB19_1: # %bb2
1183; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1184; NOREMOVAL-NEXT:    sext.w a0, s1
1185; NOREMOVAL-NEXT:    call bar
1186; NOREMOVAL-NEXT:    sllw s1, s1, s0
1187; NOREMOVAL-NEXT:    bnez a0, .LBB19_1
1188; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1189; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1190; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1191; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1192; NOREMOVAL-NEXT:    addi sp, sp, 32
1193; NOREMOVAL-NEXT:    ret
1194bb:
1195  %i = call signext i32 @bar(i32 signext %arg)
1196  br label %bb2
1197
1198bb2:                                              ; preds = %bb2, %bb
1199  %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
1200  %i4 = tail call signext i32 @bar(i32 signext %i3)
1201  %i5 = shl i32 %i3, %arg1
1202  %i6 = icmp eq i32 %i4, 0
1203  br i1 %i6, label %bb7, label %bb2
1204
1205bb7:                                              ; preds = %bb2
1206  ret void
1207}
1208
1209define void @test17(i32 signext %arg, i32 signext %arg1) nounwind {
1210; CHECK-LABEL: test17:
1211; CHECK:       # %bb.0: # %bb
1212; CHECK-NEXT:    addi sp, sp, -32
1213; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1214; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1215; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1216; CHECK-NEXT:    mv s0, a1
1217; CHECK-NEXT:    call bat
1218; CHECK-NEXT:    mv s1, a0
1219; CHECK-NEXT:  .LBB20_1: # %bb2
1220; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1221; CHECK-NEXT:    mv a0, s1
1222; CHECK-NEXT:    call bar
1223; CHECK-NEXT:    sllw s1, s1, s0
1224; CHECK-NEXT:    bnez a0, .LBB20_1
1225; CHECK-NEXT:  # %bb.2: # %bb7
1226; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1227; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1228; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1229; CHECK-NEXT:    addi sp, sp, 32
1230; CHECK-NEXT:    ret
1231;
1232; NOREMOVAL-LABEL: test17:
1233; NOREMOVAL:       # %bb.0: # %bb
1234; NOREMOVAL-NEXT:    addi sp, sp, -32
1235; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1236; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1237; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1238; NOREMOVAL-NEXT:    mv s0, a1
1239; NOREMOVAL-NEXT:    call bat
1240; NOREMOVAL-NEXT:    mv s1, a0
1241; NOREMOVAL-NEXT:  .LBB20_1: # %bb2
1242; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1243; NOREMOVAL-NEXT:    sext.w a0, s1
1244; NOREMOVAL-NEXT:    call bar
1245; NOREMOVAL-NEXT:    sllw s1, s1, s0
1246; NOREMOVAL-NEXT:    bnez a0, .LBB20_1
1247; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1248; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1249; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1250; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1251; NOREMOVAL-NEXT:    addi sp, sp, 32
1252; NOREMOVAL-NEXT:    ret
1253bb:
1254  %i = call zeroext i16 @bat(i32 signext %arg)
1255  %zext = zext i16 %i to i32
1256  br label %bb2
1257
1258bb2:                                              ; preds = %bb2, %bb
1259  %i3 = phi i32 [ %zext, %bb ], [ %i5, %bb2 ]
1260  %i4 = tail call signext i32 @bar(i32 signext %i3)
1261  %i5 = shl i32 %i3, %arg1
1262  %i6 = icmp eq i32 %i4, 0
1263  br i1 %i6, label %bb7, label %bb2
1264
1265bb7:                                              ; preds = %bb2
1266  ret void
1267}
1268declare zeroext i16 @bat(i32 signext)
1269
1270define void @test18(i32 signext %arg, i32 signext %arg1) nounwind {
1271; CHECK-LABEL: test18:
1272; CHECK:       # %bb.0: # %bb
1273; CHECK-NEXT:    addi sp, sp, -32
1274; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1275; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1276; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1277; CHECK-NEXT:    mv s0, a1
1278; CHECK-NEXT:    sha256sig0 s1, a1
1279; CHECK-NEXT:  .LBB21_1: # %bb2
1280; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1281; CHECK-NEXT:    mv a0, s1
1282; CHECK-NEXT:    call bar
1283; CHECK-NEXT:    sllw s1, s1, s0
1284; CHECK-NEXT:    bnez a0, .LBB21_1
1285; CHECK-NEXT:  # %bb.2: # %bb7
1286; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1287; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1288; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1289; CHECK-NEXT:    addi sp, sp, 32
1290; CHECK-NEXT:    ret
1291;
1292; NOREMOVAL-LABEL: test18:
1293; NOREMOVAL:       # %bb.0: # %bb
1294; NOREMOVAL-NEXT:    addi sp, sp, -32
1295; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1296; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1297; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1298; NOREMOVAL-NEXT:    mv s0, a1
1299; NOREMOVAL-NEXT:    sha256sig0 s1, a1
1300; NOREMOVAL-NEXT:  .LBB21_1: # %bb2
1301; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1302; NOREMOVAL-NEXT:    sext.w a0, s1
1303; NOREMOVAL-NEXT:    call bar
1304; NOREMOVAL-NEXT:    sllw s1, s1, s0
1305; NOREMOVAL-NEXT:    bnez a0, .LBB21_1
1306; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1307; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1308; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1309; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1310; NOREMOVAL-NEXT:    addi sp, sp, 32
1311; NOREMOVAL-NEXT:    ret
1312bb:
1313  %i = call i32 @llvm.riscv.sha256sig0(i32 %arg1)
1314  br label %bb2
1315
1316bb2:                                              ; preds = %bb2, %bb
1317  %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
1318  %i4 = tail call signext i32 @bar(i32 signext %i3)
1319  %i5 = shl i32 %i3, %arg1
1320  %i6 = icmp eq i32 %i4, 0
1321  br i1 %i6, label %bb7, label %bb2
1322
1323bb7:                                              ; preds = %bb2
1324  ret void
1325}
1326declare i32 @llvm.riscv.sha256sig0(i32)
1327
1328; The type promotion of %7 forms a sext_inreg, but %7 and %6 are combined to
1329; form a sh2add. This leaves behind a sext.w that isn't needed.
1330define signext i32 @sextw_sh2add(i1 zeroext %0, ptr %1, i32 signext %2, i32 signext %3, i32 signext %4) {
1331; RV64I-LABEL: sextw_sh2add:
1332; RV64I:       # %bb.0:
1333; RV64I-NEXT:    slli a2, a2, 2
1334; RV64I-NEXT:    add a3, a2, a3
1335; RV64I-NEXT:    beqz a0, .LBB22_2
1336; RV64I-NEXT:  # %bb.1:
1337; RV64I-NEXT:    sw a3, 0(a1)
1338; RV64I-NEXT:  .LBB22_2:
1339; RV64I-NEXT:    addw a0, a3, a4
1340; RV64I-NEXT:    ret
1341;
1342; RV64ZBB-LABEL: sextw_sh2add:
1343; RV64ZBB:       # %bb.0:
1344; RV64ZBB-NEXT:    sh2add a2, a2, a3
1345; RV64ZBB-NEXT:    beqz a0, .LBB22_2
1346; RV64ZBB-NEXT:  # %bb.1:
1347; RV64ZBB-NEXT:    sw a2, 0(a1)
1348; RV64ZBB-NEXT:  .LBB22_2:
1349; RV64ZBB-NEXT:    addw a0, a2, a4
1350; RV64ZBB-NEXT:    ret
1351;
1352; NOREMOVAL-LABEL: sextw_sh2add:
1353; NOREMOVAL:       # %bb.0:
1354; NOREMOVAL-NEXT:    sh2add a2, a2, a3
1355; NOREMOVAL-NEXT:    mv a2, a2
1356; NOREMOVAL-NEXT:    beqz a0, .LBB22_2
1357; NOREMOVAL-NEXT:  # %bb.1:
1358; NOREMOVAL-NEXT:    sw a2, 0(a1)
1359; NOREMOVAL-NEXT:  .LBB22_2:
1360; NOREMOVAL-NEXT:    addw a0, a2, a4
1361; NOREMOVAL-NEXT:    ret
1362  %6 = shl i32 %2, 2
1363  %7 = add i32 %6, %3
1364  br i1 %0, label %8, label %9
1365
13668:                                                ; preds = %5
1367  store i32 %7, ptr %1, align 4
1368  br label %9
1369
13709:                                                ; preds = %5, %8
1371  %10 = add i32 %7, %4
1372  ret i32 %10
1373}
1374
1375; Negative test - an explicit sext.w *is* required
1376define signext i32 @test19(i64 %arg, i1 zeroext %c1, i1 zeroext %c2, ptr %p) nounwind {
1377; CHECK-LABEL: test19:
1378; CHECK:       # %bb.0: # %bb
1379; CHECK-NEXT:    addi sp, sp, -16
1380; CHECK-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
1381; CHECK-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
1382; CHECK-NEXT:    neg a0, a1
1383; CHECK-NEXT:    li a1, 1
1384; CHECK-NEXT:    slli a1, a1, 32
1385; CHECK-NEXT:    addi s0, a1, 35
1386; CHECK-NEXT:    and s0, a0, s0
1387; CHECK-NEXT:    sd s0, 0(a3)
1388; CHECK-NEXT:    beqz a2, .LBB23_2
1389; CHECK-NEXT:  # %bb.1: # %bb2
1390; CHECK-NEXT:    li a0, 0
1391; CHECK-NEXT:    call bar
1392; CHECK-NEXT:    mv s0, a0
1393; CHECK-NEXT:  .LBB23_2: # %bb7
1394; CHECK-NEXT:    call side_effect
1395; CHECK-NEXT:    sext.w a0, s0
1396; CHECK-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
1397; CHECK-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
1398; CHECK-NEXT:    addi sp, sp, 16
1399; CHECK-NEXT:    ret
1400;
1401; NOREMOVAL-LABEL: test19:
1402; NOREMOVAL:       # %bb.0: # %bb
1403; NOREMOVAL-NEXT:    addi sp, sp, -16
1404; NOREMOVAL-NEXT:    sd ra, 8(sp) # 8-byte Folded Spill
1405; NOREMOVAL-NEXT:    sd s0, 0(sp) # 8-byte Folded Spill
1406; NOREMOVAL-NEXT:    neg a0, a1
1407; NOREMOVAL-NEXT:    li a1, 1
1408; NOREMOVAL-NEXT:    slli a1, a1, 32
1409; NOREMOVAL-NEXT:    addi s0, a1, 35
1410; NOREMOVAL-NEXT:    and s0, a0, s0
1411; NOREMOVAL-NEXT:    sd s0, 0(a3)
1412; NOREMOVAL-NEXT:    beqz a2, .LBB23_2
1413; NOREMOVAL-NEXT:  # %bb.1: # %bb2
1414; NOREMOVAL-NEXT:    li a0, 0
1415; NOREMOVAL-NEXT:    call bar
1416; NOREMOVAL-NEXT:    mv s0, a0
1417; NOREMOVAL-NEXT:  .LBB23_2: # %bb7
1418; NOREMOVAL-NEXT:    call side_effect
1419; NOREMOVAL-NEXT:    sext.w a0, s0
1420; NOREMOVAL-NEXT:    ld ra, 8(sp) # 8-byte Folded Reload
1421; NOREMOVAL-NEXT:    ld s0, 0(sp) # 8-byte Folded Reload
1422; NOREMOVAL-NEXT:    addi sp, sp, 16
1423; NOREMOVAL-NEXT:    ret
1424bb:
1425  %sel = select i1 %c1, i64 4294967331, i64 0
1426  store i64 %sel, ptr %p, align 8
1427  br i1 %c2, label %bb2, label %bb7
1428
1429bb2:                                              ; preds = %bb2, %bb
1430  %i4 = call signext i32 @bar(i32 0)
1431  %i4.sext = sext i32 %i4 to i64
1432  br label %bb7
1433
1434bb7:                                              ; preds = %bb2
1435  %phi = phi i64 [ %sel, %bb ], [ %i4.sext, %bb2 ]
1436  %trunc = trunc i64 %phi to i32
1437  call void @side_effect()
1438  ret i32 %trunc
1439}
1440
1441 declare void @side_effect(i64)
1442
1443define void @test20(<vscale x 1 x i32> %arg, i32 signext %arg1) nounwind {
1444; CHECK-LABEL: test20:
1445; CHECK:       # %bb.0: # %bb
1446; CHECK-NEXT:    addi sp, sp, -32
1447; CHECK-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1448; CHECK-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1449; CHECK-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1450; CHECK-NEXT:    mv s0, a0
1451; CHECK-NEXT:    vsetivli zero, 1, e32, m1, ta, ma
1452; CHECK-NEXT:    vmv.x.s s1, v8
1453; CHECK-NEXT:  .LBB24_1: # %bb2
1454; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
1455; CHECK-NEXT:    mv a0, s1
1456; CHECK-NEXT:    call bar
1457; CHECK-NEXT:    sllw s1, s1, s0
1458; CHECK-NEXT:    bnez a0, .LBB24_1
1459; CHECK-NEXT:  # %bb.2: # %bb7
1460; CHECK-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1461; CHECK-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1462; CHECK-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1463; CHECK-NEXT:    addi sp, sp, 32
1464; CHECK-NEXT:    ret
1465;
1466; NOREMOVAL-LABEL: test20:
1467; NOREMOVAL:       # %bb.0: # %bb
1468; NOREMOVAL-NEXT:    addi sp, sp, -32
1469; NOREMOVAL-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
1470; NOREMOVAL-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
1471; NOREMOVAL-NEXT:    sd s1, 8(sp) # 8-byte Folded Spill
1472; NOREMOVAL-NEXT:    mv s0, a0
1473; NOREMOVAL-NEXT:    vsetivli zero, 1, e32, m1, ta, ma
1474; NOREMOVAL-NEXT:    vmv.x.s s1, v8
1475; NOREMOVAL-NEXT:  .LBB24_1: # %bb2
1476; NOREMOVAL-NEXT:    # =>This Inner Loop Header: Depth=1
1477; NOREMOVAL-NEXT:    sext.w a0, s1
1478; NOREMOVAL-NEXT:    call bar
1479; NOREMOVAL-NEXT:    sllw s1, s1, s0
1480; NOREMOVAL-NEXT:    bnez a0, .LBB24_1
1481; NOREMOVAL-NEXT:  # %bb.2: # %bb7
1482; NOREMOVAL-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
1483; NOREMOVAL-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
1484; NOREMOVAL-NEXT:    ld s1, 8(sp) # 8-byte Folded Reload
1485; NOREMOVAL-NEXT:    addi sp, sp, 32
1486; NOREMOVAL-NEXT:    ret
1487bb:
1488  %i = call i32 @llvm.riscv.vmv.x.s.nxv1i32(<vscale x 1 x i32> %arg)
1489  br label %bb2
1490
1491bb2:                                              ; preds = %bb2, %bb
1492  %i3 = phi i32 [ %i, %bb ], [ %i5, %bb2 ]
1493  %i4 = tail call signext i32 @bar(i32 signext %i3)
1494  %i5 = shl i32 %i3, %arg1
1495  %i6 = icmp eq i32 %i4, 0
1496  br i1 %i6, label %bb7, label %bb2
1497
1498bb7:                                              ; preds = %bb2
1499  ret void
1500}
1501
1502declare i32 @llvm.riscv.vmv.x.s.nxv1i32( <vscale x 1 x i32>)
1503