706 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 42; RUN: llc -mtriple=riscv32 -mattr=+m < %s \3; RUN: | FileCheck %s -check-prefix=RV32I4; RUN: llc -mtriple=riscv32 -mattr=+m,+zbb < %s \5; RUN: | FileCheck %s -check-prefix=RV32ZBB6; RUN: llc -mtriple=riscv64 -mattr=+m < %s \7; RUN: | FileCheck %s -check-prefixes=RV64I8; RUN: llc -mtriple=riscv64 -mattr=+m,+zbb < %s \9; RUN: | FileCheck %s -check-prefixes=RV64ZBB10 11define i8 @shl_cttz_i8(i8 %x, i8 %y) {12; RV32I-LABEL: shl_cttz_i8:13; RV32I: # %bb.0: # %entry14; RV32I-NEXT: addi a2, a1, -115; RV32I-NEXT: not a1, a116; RV32I-NEXT: and a1, a1, a217; RV32I-NEXT: srli a2, a1, 118; RV32I-NEXT: andi a2, a2, 8519; RV32I-NEXT: sub a1, a1, a220; RV32I-NEXT: andi a2, a1, 5121; RV32I-NEXT: srli a1, a1, 222; RV32I-NEXT: andi a1, a1, 5123; RV32I-NEXT: add a1, a2, a124; RV32I-NEXT: srli a2, a1, 425; RV32I-NEXT: add a1, a1, a226; RV32I-NEXT: andi a1, a1, 1527; RV32I-NEXT: sll a0, a0, a128; RV32I-NEXT: ret29;30; RV32ZBB-LABEL: shl_cttz_i8:31; RV32ZBB: # %bb.0: # %entry32; RV32ZBB-NEXT: ctz a1, a133; RV32ZBB-NEXT: sll a0, a0, a134; RV32ZBB-NEXT: ret35;36; RV64I-LABEL: shl_cttz_i8:37; RV64I: # %bb.0: # %entry38; RV64I-NEXT: addi a2, a1, -139; RV64I-NEXT: not a1, a140; RV64I-NEXT: and a1, a1, a241; RV64I-NEXT: srli a2, a1, 142; RV64I-NEXT: andi a2, a2, 8543; RV64I-NEXT: sub a1, a1, a244; RV64I-NEXT: andi a2, a1, 5145; RV64I-NEXT: srli a1, a1, 246; RV64I-NEXT: andi a1, a1, 5147; RV64I-NEXT: add a1, a2, a148; RV64I-NEXT: srli a2, a1, 449; RV64I-NEXT: add a1, a1, a250; RV64I-NEXT: andi a1, a1, 1551; RV64I-NEXT: sll a0, a0, a152; RV64I-NEXT: ret53;54; RV64ZBB-LABEL: shl_cttz_i8:55; RV64ZBB: # %bb.0: # %entry56; RV64ZBB-NEXT: ctz a1, a157; RV64ZBB-NEXT: sll a0, a0, a158; RV64ZBB-NEXT: ret59entry:60 %cttz = call i8 @llvm.cttz.i8(i8 %y, i1 true)61 %res = shl i8 %x, %cttz62 ret i8 %res63}64 65define i8 @shl_cttz_constant_i8(i8 %y) {66; RV32I-LABEL: shl_cttz_constant_i8:67; RV32I: # %bb.0: # %entry68; RV32I-NEXT: addi a1, a0, -169; RV32I-NEXT: not a0, a070; RV32I-NEXT: and a0, a0, a171; RV32I-NEXT: srli a1, a0, 172; RV32I-NEXT: andi a1, a1, 8573; RV32I-NEXT: sub a0, a0, a174; RV32I-NEXT: andi a1, a0, 5175; RV32I-NEXT: srli a0, a0, 276; RV32I-NEXT: andi a0, a0, 5177; RV32I-NEXT: add a0, a1, a078; RV32I-NEXT: srli a1, a0, 479; RV32I-NEXT: add a0, a0, a180; RV32I-NEXT: andi a0, a0, 1581; RV32I-NEXT: li a1, 482; RV32I-NEXT: sll a0, a1, a083; RV32I-NEXT: ret84;85; RV32ZBB-LABEL: shl_cttz_constant_i8:86; RV32ZBB: # %bb.0: # %entry87; RV32ZBB-NEXT: ctz a0, a088; RV32ZBB-NEXT: li a1, 489; RV32ZBB-NEXT: sll a0, a1, a090; RV32ZBB-NEXT: ret91;92; RV64I-LABEL: shl_cttz_constant_i8:93; RV64I: # %bb.0: # %entry94; RV64I-NEXT: addi a1, a0, -195; RV64I-NEXT: not a0, a096; RV64I-NEXT: and a0, a0, a197; RV64I-NEXT: srli a1, a0, 198; RV64I-NEXT: andi a1, a1, 8599; RV64I-NEXT: sub a0, a0, a1100; RV64I-NEXT: andi a1, a0, 51101; RV64I-NEXT: srli a0, a0, 2102; RV64I-NEXT: andi a0, a0, 51103; RV64I-NEXT: add a0, a1, a0104; RV64I-NEXT: srli a1, a0, 4105; RV64I-NEXT: add a0, a0, a1106; RV64I-NEXT: andi a0, a0, 15107; RV64I-NEXT: li a1, 4108; RV64I-NEXT: sll a0, a1, a0109; RV64I-NEXT: ret110;111; RV64ZBB-LABEL: shl_cttz_constant_i8:112; RV64ZBB: # %bb.0: # %entry113; RV64ZBB-NEXT: ctz a0, a0114; RV64ZBB-NEXT: li a1, 4115; RV64ZBB-NEXT: sll a0, a1, a0116; RV64ZBB-NEXT: ret117entry:118 %cttz = call i8 @llvm.cttz.i8(i8 %y, i1 true)119 %res = shl i8 4, %cttz120 ret i8 %res121}122 123define i16 @shl_cttz_i16(i16 %x, i16 %y) {124; RV32I-LABEL: shl_cttz_i16:125; RV32I: # %bb.0: # %entry126; RV32I-NEXT: addi a2, a1, -1127; RV32I-NEXT: not a1, a1128; RV32I-NEXT: lui a3, 5129; RV32I-NEXT: and a1, a1, a2130; RV32I-NEXT: addi a2, a3, 1365131; RV32I-NEXT: srli a3, a1, 1132; RV32I-NEXT: and a2, a3, a2133; RV32I-NEXT: lui a3, 3134; RV32I-NEXT: addi a3, a3, 819135; RV32I-NEXT: sub a1, a1, a2136; RV32I-NEXT: and a2, a1, a3137; RV32I-NEXT: srli a1, a1, 2138; RV32I-NEXT: and a1, a1, a3139; RV32I-NEXT: add a1, a2, a1140; RV32I-NEXT: srli a2, a1, 4141; RV32I-NEXT: add a1, a1, a2142; RV32I-NEXT: andi a2, a1, 15143; RV32I-NEXT: slli a1, a1, 20144; RV32I-NEXT: srli a1, a1, 28145; RV32I-NEXT: add a1, a2, a1146; RV32I-NEXT: sll a0, a0, a1147; RV32I-NEXT: ret148;149; RV32ZBB-LABEL: shl_cttz_i16:150; RV32ZBB: # %bb.0: # %entry151; RV32ZBB-NEXT: ctz a1, a1152; RV32ZBB-NEXT: sll a0, a0, a1153; RV32ZBB-NEXT: ret154;155; RV64I-LABEL: shl_cttz_i16:156; RV64I: # %bb.0: # %entry157; RV64I-NEXT: addi a2, a1, -1158; RV64I-NEXT: not a1, a1159; RV64I-NEXT: lui a3, 5160; RV64I-NEXT: and a1, a1, a2161; RV64I-NEXT: addi a2, a3, 1365162; RV64I-NEXT: srli a3, a1, 1163; RV64I-NEXT: and a2, a3, a2164; RV64I-NEXT: lui a3, 3165; RV64I-NEXT: addi a3, a3, 819166; RV64I-NEXT: sub a1, a1, a2167; RV64I-NEXT: and a2, a1, a3168; RV64I-NEXT: srli a1, a1, 2169; RV64I-NEXT: and a1, a1, a3170; RV64I-NEXT: add a1, a2, a1171; RV64I-NEXT: srli a2, a1, 4172; RV64I-NEXT: add a1, a1, a2173; RV64I-NEXT: andi a2, a1, 15174; RV64I-NEXT: slli a1, a1, 52175; RV64I-NEXT: srli a1, a1, 60176; RV64I-NEXT: add a1, a2, a1177; RV64I-NEXT: sll a0, a0, a1178; RV64I-NEXT: ret179;180; RV64ZBB-LABEL: shl_cttz_i16:181; RV64ZBB: # %bb.0: # %entry182; RV64ZBB-NEXT: ctz a1, a1183; RV64ZBB-NEXT: sll a0, a0, a1184; RV64ZBB-NEXT: ret185entry:186 %cttz = call i16 @llvm.cttz.i16(i16 %y, i1 true)187 %res = shl i16 %x, %cttz188 ret i16 %res189}190 191define i16 @shl_cttz_constant_i16(i16 %y) {192; RV32I-LABEL: shl_cttz_constant_i16:193; RV32I: # %bb.0: # %entry194; RV32I-NEXT: addi a1, a0, -1195; RV32I-NEXT: not a0, a0196; RV32I-NEXT: lui a2, 5197; RV32I-NEXT: and a0, a0, a1198; RV32I-NEXT: addi a1, a2, 1365199; RV32I-NEXT: srli a2, a0, 1200; RV32I-NEXT: and a1, a2, a1201; RV32I-NEXT: lui a2, 3202; RV32I-NEXT: addi a2, a2, 819203; RV32I-NEXT: sub a0, a0, a1204; RV32I-NEXT: and a1, a0, a2205; RV32I-NEXT: srli a0, a0, 2206; RV32I-NEXT: and a0, a0, a2207; RV32I-NEXT: add a0, a1, a0208; RV32I-NEXT: srli a1, a0, 4209; RV32I-NEXT: add a0, a0, a1210; RV32I-NEXT: andi a1, a0, 15211; RV32I-NEXT: slli a0, a0, 20212; RV32I-NEXT: srli a0, a0, 28213; RV32I-NEXT: add a0, a1, a0214; RV32I-NEXT: li a1, 4215; RV32I-NEXT: sll a0, a1, a0216; RV32I-NEXT: ret217;218; RV32ZBB-LABEL: shl_cttz_constant_i16:219; RV32ZBB: # %bb.0: # %entry220; RV32ZBB-NEXT: ctz a0, a0221; RV32ZBB-NEXT: li a1, 4222; RV32ZBB-NEXT: sll a0, a1, a0223; RV32ZBB-NEXT: ret224;225; RV64I-LABEL: shl_cttz_constant_i16:226; RV64I: # %bb.0: # %entry227; RV64I-NEXT: addi a1, a0, -1228; RV64I-NEXT: not a0, a0229; RV64I-NEXT: lui a2, 5230; RV64I-NEXT: and a0, a0, a1231; RV64I-NEXT: addi a1, a2, 1365232; RV64I-NEXT: srli a2, a0, 1233; RV64I-NEXT: and a1, a2, a1234; RV64I-NEXT: lui a2, 3235; RV64I-NEXT: addi a2, a2, 819236; RV64I-NEXT: sub a0, a0, a1237; RV64I-NEXT: and a1, a0, a2238; RV64I-NEXT: srli a0, a0, 2239; RV64I-NEXT: and a0, a0, a2240; RV64I-NEXT: add a0, a1, a0241; RV64I-NEXT: srli a1, a0, 4242; RV64I-NEXT: add a0, a0, a1243; RV64I-NEXT: andi a1, a0, 15244; RV64I-NEXT: slli a0, a0, 52245; RV64I-NEXT: srli a0, a0, 60246; RV64I-NEXT: add a0, a1, a0247; RV64I-NEXT: li a1, 4248; RV64I-NEXT: sll a0, a1, a0249; RV64I-NEXT: ret250;251; RV64ZBB-LABEL: shl_cttz_constant_i16:252; RV64ZBB: # %bb.0: # %entry253; RV64ZBB-NEXT: ctz a0, a0254; RV64ZBB-NEXT: li a1, 4255; RV64ZBB-NEXT: sll a0, a1, a0256; RV64ZBB-NEXT: ret257entry:258 %cttz = call i16 @llvm.cttz.i16(i16 %y, i1 true)259 %res = shl i16 4, %cttz260 ret i16 %res261}262 263define i32 @shl_cttz_i32(i32 %x, i32 %y) {264; RV32I-LABEL: shl_cttz_i32:265; RV32I: # %bb.0: # %entry266; RV32I-NEXT: neg a2, a1267; RV32I-NEXT: and a1, a1, a2268; RV32I-NEXT: mul a0, a1, a0269; RV32I-NEXT: ret270;271; RV32ZBB-LABEL: shl_cttz_i32:272; RV32ZBB: # %bb.0: # %entry273; RV32ZBB-NEXT: ctz a1, a1274; RV32ZBB-NEXT: sll a0, a0, a1275; RV32ZBB-NEXT: ret276;277; RV64I-LABEL: shl_cttz_i32:278; RV64I: # %bb.0: # %entry279; RV64I-NEXT: neg a2, a1280; RV64I-NEXT: and a1, a1, a2281; RV64I-NEXT: lui a2, 30667282; RV64I-NEXT: addi a2, a2, 1329283; RV64I-NEXT: mul a1, a1, a2284; RV64I-NEXT: srliw a1, a1, 27285; RV64I-NEXT: lui a2, %hi(.LCPI4_0)286; RV64I-NEXT: addi a2, a2, %lo(.LCPI4_0)287; RV64I-NEXT: add a1, a2, a1288; RV64I-NEXT: lbu a1, 0(a1)289; RV64I-NEXT: sllw a0, a0, a1290; RV64I-NEXT: ret291;292; RV64ZBB-LABEL: shl_cttz_i32:293; RV64ZBB: # %bb.0: # %entry294; RV64ZBB-NEXT: ctzw a1, a1295; RV64ZBB-NEXT: sllw a0, a0, a1296; RV64ZBB-NEXT: ret297entry:298 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)299 %res = shl i32 %x, %cttz300 ret i32 %res301}302 303define i32 @shl_cttz_i32_zero_is_defined(i32 %x, i32 %y) {304; RV32I-LABEL: shl_cttz_i32_zero_is_defined:305; RV32I: # %bb.0: # %entry306; RV32I-NEXT: beqz a1, .LBB5_2307; RV32I-NEXT: # %bb.1: # %cond.false308; RV32I-NEXT: neg a2, a1309; RV32I-NEXT: and a1, a1, a2310; RV32I-NEXT: lui a2, 30667311; RV32I-NEXT: addi a2, a2, 1329312; RV32I-NEXT: mul a1, a1, a2313; RV32I-NEXT: srli a1, a1, 27314; RV32I-NEXT: lui a2, %hi(.LCPI5_0)315; RV32I-NEXT: addi a2, a2, %lo(.LCPI5_0)316; RV32I-NEXT: add a1, a2, a1317; RV32I-NEXT: lbu a1, 0(a1)318; RV32I-NEXT: sll a0, a0, a1319; RV32I-NEXT: ret320; RV32I-NEXT: .LBB5_2:321; RV32I-NEXT: li a1, 32322; RV32I-NEXT: sll a0, a0, a1323; RV32I-NEXT: ret324;325; RV32ZBB-LABEL: shl_cttz_i32_zero_is_defined:326; RV32ZBB: # %bb.0: # %entry327; RV32ZBB-NEXT: ctz a1, a1328; RV32ZBB-NEXT: sll a0, a0, a1329; RV32ZBB-NEXT: ret330;331; RV64I-LABEL: shl_cttz_i32_zero_is_defined:332; RV64I: # %bb.0: # %entry333; RV64I-NEXT: sext.w a2, a1334; RV64I-NEXT: beqz a2, .LBB5_2335; RV64I-NEXT: # %bb.1: # %cond.false336; RV64I-NEXT: neg a2, a1337; RV64I-NEXT: and a1, a1, a2338; RV64I-NEXT: lui a2, 30667339; RV64I-NEXT: addi a2, a2, 1329340; RV64I-NEXT: mul a1, a1, a2341; RV64I-NEXT: srliw a1, a1, 27342; RV64I-NEXT: lui a2, %hi(.LCPI5_0)343; RV64I-NEXT: addi a2, a2, %lo(.LCPI5_0)344; RV64I-NEXT: add a1, a2, a1345; RV64I-NEXT: lbu a1, 0(a1)346; RV64I-NEXT: sllw a0, a0, a1347; RV64I-NEXT: ret348; RV64I-NEXT: .LBB5_2:349; RV64I-NEXT: li a1, 32350; RV64I-NEXT: sllw a0, a0, a1351; RV64I-NEXT: ret352;353; RV64ZBB-LABEL: shl_cttz_i32_zero_is_defined:354; RV64ZBB: # %bb.0: # %entry355; RV64ZBB-NEXT: ctzw a1, a1356; RV64ZBB-NEXT: sllw a0, a0, a1357; RV64ZBB-NEXT: ret358entry:359 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 false)360 %res = shl i32 %x, %cttz361 ret i32 %res362}363 364define i32 @shl_cttz_constant_i32(i32 %y) {365; RV32I-LABEL: shl_cttz_constant_i32:366; RV32I: # %bb.0: # %entry367; RV32I-NEXT: neg a1, a0368; RV32I-NEXT: and a0, a0, a1369; RV32I-NEXT: slli a0, a0, 2370; RV32I-NEXT: ret371;372; RV32ZBB-LABEL: shl_cttz_constant_i32:373; RV32ZBB: # %bb.0: # %entry374; RV32ZBB-NEXT: ctz a0, a0375; RV32ZBB-NEXT: li a1, 4376; RV32ZBB-NEXT: sll a0, a1, a0377; RV32ZBB-NEXT: ret378;379; RV64I-LABEL: shl_cttz_constant_i32:380; RV64I: # %bb.0: # %entry381; RV64I-NEXT: neg a1, a0382; RV64I-NEXT: and a0, a0, a1383; RV64I-NEXT: lui a1, 30667384; RV64I-NEXT: addi a1, a1, 1329385; RV64I-NEXT: mul a0, a0, a1386; RV64I-NEXT: srliw a0, a0, 27387; RV64I-NEXT: lui a1, %hi(.LCPI6_0)388; RV64I-NEXT: addi a1, a1, %lo(.LCPI6_0)389; RV64I-NEXT: add a0, a1, a0390; RV64I-NEXT: lbu a0, 0(a0)391; RV64I-NEXT: li a1, 4392; RV64I-NEXT: sllw a0, a1, a0393; RV64I-NEXT: ret394;395; RV64ZBB-LABEL: shl_cttz_constant_i32:396; RV64ZBB: # %bb.0: # %entry397; RV64ZBB-NEXT: ctzw a0, a0398; RV64ZBB-NEXT: li a1, 4399; RV64ZBB-NEXT: sllw a0, a1, a0400; RV64ZBB-NEXT: ret401entry:402 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)403 %res = shl i32 4, %cttz404 ret i32 %res405}406 407define i32 @shl_cttz_multiuse_i32(i32 %x, i32 %y) {408; RV32I-LABEL: shl_cttz_multiuse_i32:409; RV32I: # %bb.0: # %entry410; RV32I-NEXT: addi sp, sp, -16411; RV32I-NEXT: .cfi_def_cfa_offset 16412; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill413; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill414; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill415; RV32I-NEXT: .cfi_offset ra, -4416; RV32I-NEXT: .cfi_offset s0, -8417; RV32I-NEXT: .cfi_offset s1, -12418; RV32I-NEXT: neg a2, a1419; RV32I-NEXT: and a1, a1, a2420; RV32I-NEXT: lui a2, 30667421; RV32I-NEXT: addi a2, a2, 1329422; RV32I-NEXT: mul a1, a1, a2423; RV32I-NEXT: srli a1, a1, 27424; RV32I-NEXT: lui a2, %hi(.LCPI7_0)425; RV32I-NEXT: addi a2, a2, %lo(.LCPI7_0)426; RV32I-NEXT: add a1, a2, a1427; RV32I-NEXT: lbu s0, 0(a1)428; RV32I-NEXT: mv s1, a0429; RV32I-NEXT: mv a0, s0430; RV32I-NEXT: call use32431; RV32I-NEXT: sll a0, s1, s0432; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload433; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload434; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload435; RV32I-NEXT: .cfi_restore ra436; RV32I-NEXT: .cfi_restore s0437; RV32I-NEXT: .cfi_restore s1438; RV32I-NEXT: addi sp, sp, 16439; RV32I-NEXT: .cfi_def_cfa_offset 0440; RV32I-NEXT: ret441;442; RV32ZBB-LABEL: shl_cttz_multiuse_i32:443; RV32ZBB: # %bb.0: # %entry444; RV32ZBB-NEXT: addi sp, sp, -16445; RV32ZBB-NEXT: .cfi_def_cfa_offset 16446; RV32ZBB-NEXT: sw ra, 12(sp) # 4-byte Folded Spill447; RV32ZBB-NEXT: sw s0, 8(sp) # 4-byte Folded Spill448; RV32ZBB-NEXT: sw s1, 4(sp) # 4-byte Folded Spill449; RV32ZBB-NEXT: .cfi_offset ra, -4450; RV32ZBB-NEXT: .cfi_offset s0, -8451; RV32ZBB-NEXT: .cfi_offset s1, -12452; RV32ZBB-NEXT: mv s0, a0453; RV32ZBB-NEXT: ctz s1, a1454; RV32ZBB-NEXT: mv a0, s1455; RV32ZBB-NEXT: call use32456; RV32ZBB-NEXT: sll a0, s0, s1457; RV32ZBB-NEXT: lw ra, 12(sp) # 4-byte Folded Reload458; RV32ZBB-NEXT: lw s0, 8(sp) # 4-byte Folded Reload459; RV32ZBB-NEXT: lw s1, 4(sp) # 4-byte Folded Reload460; RV32ZBB-NEXT: .cfi_restore ra461; RV32ZBB-NEXT: .cfi_restore s0462; RV32ZBB-NEXT: .cfi_restore s1463; RV32ZBB-NEXT: addi sp, sp, 16464; RV32ZBB-NEXT: .cfi_def_cfa_offset 0465; RV32ZBB-NEXT: ret466;467; RV64I-LABEL: shl_cttz_multiuse_i32:468; RV64I: # %bb.0: # %entry469; RV64I-NEXT: addi sp, sp, -32470; RV64I-NEXT: .cfi_def_cfa_offset 32471; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill472; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill473; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill474; RV64I-NEXT: .cfi_offset ra, -8475; RV64I-NEXT: .cfi_offset s0, -16476; RV64I-NEXT: .cfi_offset s1, -24477; RV64I-NEXT: neg a2, a1478; RV64I-NEXT: and a1, a1, a2479; RV64I-NEXT: lui a2, 30667480; RV64I-NEXT: addi a2, a2, 1329481; RV64I-NEXT: mul a1, a1, a2482; RV64I-NEXT: srliw a1, a1, 27483; RV64I-NEXT: lui a2, %hi(.LCPI7_0)484; RV64I-NEXT: addi a2, a2, %lo(.LCPI7_0)485; RV64I-NEXT: add a1, a2, a1486; RV64I-NEXT: lbu s0, 0(a1)487; RV64I-NEXT: mv s1, a0488; RV64I-NEXT: mv a0, s0489; RV64I-NEXT: call use32490; RV64I-NEXT: sllw a0, s1, s0491; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload492; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload493; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload494; RV64I-NEXT: .cfi_restore ra495; RV64I-NEXT: .cfi_restore s0496; RV64I-NEXT: .cfi_restore s1497; RV64I-NEXT: addi sp, sp, 32498; RV64I-NEXT: .cfi_def_cfa_offset 0499; RV64I-NEXT: ret500;501; RV64ZBB-LABEL: shl_cttz_multiuse_i32:502; RV64ZBB: # %bb.0: # %entry503; RV64ZBB-NEXT: addi sp, sp, -32504; RV64ZBB-NEXT: .cfi_def_cfa_offset 32505; RV64ZBB-NEXT: sd ra, 24(sp) # 8-byte Folded Spill506; RV64ZBB-NEXT: sd s0, 16(sp) # 8-byte Folded Spill507; RV64ZBB-NEXT: sd s1, 8(sp) # 8-byte Folded Spill508; RV64ZBB-NEXT: .cfi_offset ra, -8509; RV64ZBB-NEXT: .cfi_offset s0, -16510; RV64ZBB-NEXT: .cfi_offset s1, -24511; RV64ZBB-NEXT: mv s0, a0512; RV64ZBB-NEXT: ctzw s1, a1513; RV64ZBB-NEXT: mv a0, s1514; RV64ZBB-NEXT: call use32515; RV64ZBB-NEXT: sllw a0, s0, s1516; RV64ZBB-NEXT: ld ra, 24(sp) # 8-byte Folded Reload517; RV64ZBB-NEXT: ld s0, 16(sp) # 8-byte Folded Reload518; RV64ZBB-NEXT: ld s1, 8(sp) # 8-byte Folded Reload519; RV64ZBB-NEXT: .cfi_restore ra520; RV64ZBB-NEXT: .cfi_restore s0521; RV64ZBB-NEXT: .cfi_restore s1522; RV64ZBB-NEXT: addi sp, sp, 32523; RV64ZBB-NEXT: .cfi_def_cfa_offset 0524; RV64ZBB-NEXT: ret525entry:526 %cttz = call i32 @llvm.cttz.i32(i32 %y, i1 true)527 call void @use32(i32 %cttz)528 %res = shl i32 %x, %cttz529 ret i32 %res530}531 532define i64 @shl_cttz_i64(i64 %x, i64 %y) {533; RV32I-LABEL: shl_cttz_i64:534; RV32I: # %bb.0: # %entry535; RV32I-NEXT: lui a5, 30667536; RV32I-NEXT: addi a5, a5, 1329537; RV32I-NEXT: lui a4, %hi(.LCPI8_0)538; RV32I-NEXT: addi a4, a4, %lo(.LCPI8_0)539; RV32I-NEXT: bnez a2, .LBB8_2540; RV32I-NEXT: # %bb.1: # %entry541; RV32I-NEXT: neg a2, a3542; RV32I-NEXT: and a2, a3, a2543; RV32I-NEXT: mul a2, a2, a5544; RV32I-NEXT: srli a2, a2, 27545; RV32I-NEXT: add a2, a4, a2546; RV32I-NEXT: lbu a2, 0(a2)547; RV32I-NEXT: addi a4, a2, 32548; RV32I-NEXT: j .LBB8_3549; RV32I-NEXT: .LBB8_2:550; RV32I-NEXT: neg a3, a2551; RV32I-NEXT: and a2, a2, a3552; RV32I-NEXT: mul a2, a2, a5553; RV32I-NEXT: srli a2, a2, 27554; RV32I-NEXT: add a2, a4, a2555; RV32I-NEXT: lbu a4, 0(a2)556; RV32I-NEXT: .LBB8_3: # %entry557; RV32I-NEXT: addi a3, a4, -32558; RV32I-NEXT: sll a2, a0, a4559; RV32I-NEXT: bltz a3, .LBB8_5560; RV32I-NEXT: # %bb.4: # %entry561; RV32I-NEXT: mv a1, a2562; RV32I-NEXT: j .LBB8_6563; RV32I-NEXT: .LBB8_5:564; RV32I-NEXT: sll a1, a1, a4565; RV32I-NEXT: not a4, a4566; RV32I-NEXT: srli a0, a0, 1567; RV32I-NEXT: srl a0, a0, a4568; RV32I-NEXT: or a1, a1, a0569; RV32I-NEXT: .LBB8_6: # %entry570; RV32I-NEXT: srai a0, a3, 31571; RV32I-NEXT: and a0, a0, a2572; RV32I-NEXT: ret573;574; RV32ZBB-LABEL: shl_cttz_i64:575; RV32ZBB: # %bb.0: # %entry576; RV32ZBB-NEXT: bnez a2, .LBB8_2577; RV32ZBB-NEXT: # %bb.1: # %entry578; RV32ZBB-NEXT: ctz a2, a3579; RV32ZBB-NEXT: addi a4, a2, 32580; RV32ZBB-NEXT: j .LBB8_3581; RV32ZBB-NEXT: .LBB8_2:582; RV32ZBB-NEXT: ctz a4, a2583; RV32ZBB-NEXT: .LBB8_3: # %entry584; RV32ZBB-NEXT: addi a3, a4, -32585; RV32ZBB-NEXT: sll a2, a0, a4586; RV32ZBB-NEXT: bltz a3, .LBB8_5587; RV32ZBB-NEXT: # %bb.4: # %entry588; RV32ZBB-NEXT: mv a1, a2589; RV32ZBB-NEXT: j .LBB8_6590; RV32ZBB-NEXT: .LBB8_5:591; RV32ZBB-NEXT: sll a1, a1, a4592; RV32ZBB-NEXT: not a4, a4593; RV32ZBB-NEXT: srli a0, a0, 1594; RV32ZBB-NEXT: srl a0, a0, a4595; RV32ZBB-NEXT: or a1, a1, a0596; RV32ZBB-NEXT: .LBB8_6: # %entry597; RV32ZBB-NEXT: srai a0, a3, 31598; RV32ZBB-NEXT: and a0, a0, a2599; RV32ZBB-NEXT: ret600;601; RV64I-LABEL: shl_cttz_i64:602; RV64I: # %bb.0: # %entry603; RV64I-NEXT: neg a2, a1604; RV64I-NEXT: and a1, a1, a2605; RV64I-NEXT: mul a0, a1, a0606; RV64I-NEXT: ret607;608; RV64ZBB-LABEL: shl_cttz_i64:609; RV64ZBB: # %bb.0: # %entry610; RV64ZBB-NEXT: ctz a1, a1611; RV64ZBB-NEXT: sll a0, a0, a1612; RV64ZBB-NEXT: ret613entry:614 %cttz = call i64 @llvm.cttz.i64(i64 %y, i1 true)615 %res = shl i64 %x, %cttz616 ret i64 %res617}618 619define i64 @shl_cttz_constant_i64(i64 %y) {620; RV32I-LABEL: shl_cttz_constant_i64:621; RV32I: # %bb.0: # %entry622; RV32I-NEXT: lui a3, 30667623; RV32I-NEXT: addi a3, a3, 1329624; RV32I-NEXT: lui a2, %hi(.LCPI9_0)625; RV32I-NEXT: addi a2, a2, %lo(.LCPI9_0)626; RV32I-NEXT: bnez a0, .LBB9_2627; RV32I-NEXT: # %bb.1: # %entry628; RV32I-NEXT: neg a0, a1629; RV32I-NEXT: and a0, a1, a0630; RV32I-NEXT: mul a0, a0, a3631; RV32I-NEXT: srli a0, a0, 27632; RV32I-NEXT: add a0, a2, a0633; RV32I-NEXT: lbu a0, 0(a0)634; RV32I-NEXT: addi a1, a0, 32635; RV32I-NEXT: j .LBB9_3636; RV32I-NEXT: .LBB9_2:637; RV32I-NEXT: neg a1, a0638; RV32I-NEXT: and a0, a0, a1639; RV32I-NEXT: mul a0, a0, a3640; RV32I-NEXT: srli a0, a0, 27641; RV32I-NEXT: add a0, a2, a0642; RV32I-NEXT: lbu a1, 0(a0)643; RV32I-NEXT: .LBB9_3: # %entry644; RV32I-NEXT: li a0, 4645; RV32I-NEXT: addi a2, a1, -32646; RV32I-NEXT: sll a0, a0, a1647; RV32I-NEXT: bltz a2, .LBB9_5648; RV32I-NEXT: # %bb.4: # %entry649; RV32I-NEXT: mv a1, a0650; RV32I-NEXT: j .LBB9_6651; RV32I-NEXT: .LBB9_5:652; RV32I-NEXT: not a1, a1653; RV32I-NEXT: li a3, 2654; RV32I-NEXT: srl a1, a3, a1655; RV32I-NEXT: .LBB9_6: # %entry656; RV32I-NEXT: srai a2, a2, 31657; RV32I-NEXT: and a0, a2, a0658; RV32I-NEXT: ret659;660; RV32ZBB-LABEL: shl_cttz_constant_i64:661; RV32ZBB: # %bb.0: # %entry662; RV32ZBB-NEXT: bnez a0, .LBB9_2663; RV32ZBB-NEXT: # %bb.1: # %entry664; RV32ZBB-NEXT: ctz a0, a1665; RV32ZBB-NEXT: addi a1, a0, 32666; RV32ZBB-NEXT: j .LBB9_3667; RV32ZBB-NEXT: .LBB9_2:668; RV32ZBB-NEXT: ctz a1, a0669; RV32ZBB-NEXT: .LBB9_3: # %entry670; RV32ZBB-NEXT: li a0, 4671; RV32ZBB-NEXT: addi a2, a1, -32672; RV32ZBB-NEXT: sll a0, a0, a1673; RV32ZBB-NEXT: bltz a2, .LBB9_5674; RV32ZBB-NEXT: # %bb.4: # %entry675; RV32ZBB-NEXT: mv a1, a0676; RV32ZBB-NEXT: j .LBB9_6677; RV32ZBB-NEXT: .LBB9_5:678; RV32ZBB-NEXT: not a1, a1679; RV32ZBB-NEXT: li a3, 2680; RV32ZBB-NEXT: srl a1, a3, a1681; RV32ZBB-NEXT: .LBB9_6: # %entry682; RV32ZBB-NEXT: srai a2, a2, 31683; RV32ZBB-NEXT: and a0, a2, a0684; RV32ZBB-NEXT: ret685;686; RV64I-LABEL: shl_cttz_constant_i64:687; RV64I: # %bb.0: # %entry688; RV64I-NEXT: neg a1, a0689; RV64I-NEXT: and a0, a0, a1690; RV64I-NEXT: slli a0, a0, 2691; RV64I-NEXT: ret692;693; RV64ZBB-LABEL: shl_cttz_constant_i64:694; RV64ZBB: # %bb.0: # %entry695; RV64ZBB-NEXT: ctz a0, a0696; RV64ZBB-NEXT: li a1, 4697; RV64ZBB-NEXT: sll a0, a1, a0698; RV64ZBB-NEXT: ret699entry:700 %cttz = call i64 @llvm.cttz.i64(i64 %y, i1 true)701 %res = shl i64 4, %cttz702 ret i64 %res703}704 705declare void @use32(i32 signext)706