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