643 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \3; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I4; RUN: llc -mtriple=riscv32 -mattr=+xtheadbb -verify-machineinstrs < %s \5; RUN: | FileCheck %s -check-prefixes=CHECK,RV32XTHEADBB,RV32XTHEADBB-NOB6; RUN: llc -mtriple=riscv32 -mattr=+xtheadbb,+b -verify-machineinstrs < %s \7; RUN: | FileCheck %s -check-prefixes=CHECK,RV32XTHEADBB,RV32XTHEADBB-B8 9define i32 @ctlz_i32(i32 %a) nounwind {10; RV32I-LABEL: ctlz_i32:11; RV32I: # %bb.0:12; RV32I-NEXT: beqz a0, .LBB0_213; RV32I-NEXT: # %bb.1: # %cond.false14; RV32I-NEXT: srli a1, a0, 115; RV32I-NEXT: lui a2, 34952516; RV32I-NEXT: or a0, a0, a117; RV32I-NEXT: addi a1, a2, 136518; RV32I-NEXT: srli a2, a0, 219; RV32I-NEXT: or a0, a0, a220; RV32I-NEXT: srli a2, a0, 421; RV32I-NEXT: or a0, a0, a222; RV32I-NEXT: srli a2, a0, 823; RV32I-NEXT: or a0, a0, a224; RV32I-NEXT: srli a2, a0, 1625; RV32I-NEXT: or a0, a0, a226; RV32I-NEXT: not a0, a027; RV32I-NEXT: srli a2, a0, 128; RV32I-NEXT: and a1, a2, a129; RV32I-NEXT: lui a2, 20971530; RV32I-NEXT: addi a2, a2, 81931; RV32I-NEXT: sub a0, a0, a132; RV32I-NEXT: and a1, a0, a233; RV32I-NEXT: srli a0, a0, 234; RV32I-NEXT: and a0, a0, a235; RV32I-NEXT: lui a2, 6168136; RV32I-NEXT: add a0, a1, a037; RV32I-NEXT: srli a1, a0, 438; RV32I-NEXT: add a0, a0, a139; RV32I-NEXT: addi a1, a2, -24140; RV32I-NEXT: and a0, a0, a141; RV32I-NEXT: slli a1, a0, 842; RV32I-NEXT: add a0, a0, a143; RV32I-NEXT: slli a1, a0, 1644; RV32I-NEXT: add a0, a0, a145; RV32I-NEXT: srli a0, a0, 2446; RV32I-NEXT: ret47; RV32I-NEXT: .LBB0_2:48; RV32I-NEXT: li a0, 3249; RV32I-NEXT: ret50;51; RV32XTHEADBB-NOB-LABEL: ctlz_i32:52; RV32XTHEADBB-NOB: # %bb.0:53; RV32XTHEADBB-NOB-NEXT: th.ff1 a0, a054; RV32XTHEADBB-NOB-NEXT: ret55;56; RV32XTHEADBB-B-LABEL: ctlz_i32:57; RV32XTHEADBB-B: # %bb.0:58; RV32XTHEADBB-B-NEXT: clz a0, a059; RV32XTHEADBB-B-NEXT: ret60 %1 = call i32 @llvm.ctlz.i32(i32 %a, i1 false)61 ret i32 %162}63 64define i64 @ctlz_i64(i64 %a) nounwind {65; RV32I-LABEL: ctlz_i64:66; RV32I: # %bb.0:67; RV32I-NEXT: or a2, a0, a168; RV32I-NEXT: beqz a2, .LBB1_369; RV32I-NEXT: # %bb.1: # %cond.false70; RV32I-NEXT: lui a2, 34952571; RV32I-NEXT: lui a3, 20971572; RV32I-NEXT: lui a5, 6168173; RV32I-NEXT: addi a4, a2, 136574; RV32I-NEXT: addi a3, a3, 81975; RV32I-NEXT: addi a2, a5, -24176; RV32I-NEXT: bnez a1, .LBB1_477; RV32I-NEXT: # %bb.2: # %cond.false78; RV32I-NEXT: srli a1, a0, 179; RV32I-NEXT: or a0, a0, a180; RV32I-NEXT: srli a1, a0, 281; RV32I-NEXT: or a0, a0, a182; RV32I-NEXT: srli a1, a0, 483; RV32I-NEXT: or a0, a0, a184; RV32I-NEXT: srli a1, a0, 885; RV32I-NEXT: or a0, a0, a186; RV32I-NEXT: srli a1, a0, 1687; RV32I-NEXT: or a0, a0, a188; RV32I-NEXT: not a0, a089; RV32I-NEXT: srli a1, a0, 190; RV32I-NEXT: and a1, a1, a491; RV32I-NEXT: sub a0, a0, a192; RV32I-NEXT: and a1, a0, a393; RV32I-NEXT: srli a0, a0, 294; RV32I-NEXT: and a0, a0, a395; RV32I-NEXT: add a0, a1, a096; RV32I-NEXT: srli a1, a0, 497; RV32I-NEXT: add a0, a0, a198; RV32I-NEXT: and a0, a0, a299; RV32I-NEXT: slli a1, a0, 8100; RV32I-NEXT: add a0, a0, a1101; RV32I-NEXT: slli a1, a0, 16102; RV32I-NEXT: add a0, a0, a1103; RV32I-NEXT: srli a0, a0, 24104; RV32I-NEXT: addi a0, a0, 32105; RV32I-NEXT: li a1, 0106; RV32I-NEXT: ret107; RV32I-NEXT: .LBB1_3:108; RV32I-NEXT: li a1, 0109; RV32I-NEXT: li a0, 64110; RV32I-NEXT: ret111; RV32I-NEXT: .LBB1_4:112; RV32I-NEXT: srli a0, a1, 1113; RV32I-NEXT: or a0, a1, a0114; RV32I-NEXT: srli a1, a0, 2115; RV32I-NEXT: or a0, a0, a1116; RV32I-NEXT: srli a1, a0, 4117; RV32I-NEXT: or a0, a0, a1118; RV32I-NEXT: srli a1, a0, 8119; RV32I-NEXT: or a0, a0, a1120; RV32I-NEXT: srli a1, a0, 16121; RV32I-NEXT: or a0, a0, a1122; RV32I-NEXT: not a0, a0123; RV32I-NEXT: srli a1, a0, 1124; RV32I-NEXT: and a1, a1, a4125; RV32I-NEXT: sub a0, a0, a1126; RV32I-NEXT: and a1, a0, a3127; RV32I-NEXT: srli a0, a0, 2128; RV32I-NEXT: and a0, a0, a3129; RV32I-NEXT: add a0, a1, a0130; RV32I-NEXT: srli a1, a0, 4131; RV32I-NEXT: add a0, a0, a1132; RV32I-NEXT: and a0, a0, a2133; RV32I-NEXT: slli a1, a0, 8134; RV32I-NEXT: add a0, a0, a1135; RV32I-NEXT: slli a1, a0, 16136; RV32I-NEXT: add a0, a0, a1137; RV32I-NEXT: srli a0, a0, 24138; RV32I-NEXT: li a1, 0139; RV32I-NEXT: ret140;141; RV32XTHEADBB-NOB-LABEL: ctlz_i64:142; RV32XTHEADBB-NOB: # %bb.0:143; RV32XTHEADBB-NOB-NEXT: bnez a1, .LBB1_2144; RV32XTHEADBB-NOB-NEXT: # %bb.1:145; RV32XTHEADBB-NOB-NEXT: th.ff1 a0, a0146; RV32XTHEADBB-NOB-NEXT: addi a0, a0, 32147; RV32XTHEADBB-NOB-NEXT: li a1, 0148; RV32XTHEADBB-NOB-NEXT: ret149; RV32XTHEADBB-NOB-NEXT: .LBB1_2:150; RV32XTHEADBB-NOB-NEXT: th.ff1 a0, a1151; RV32XTHEADBB-NOB-NEXT: li a1, 0152; RV32XTHEADBB-NOB-NEXT: ret153;154; RV32XTHEADBB-B-LABEL: ctlz_i64:155; RV32XTHEADBB-B: # %bb.0:156; RV32XTHEADBB-B-NEXT: bnez a1, .LBB1_2157; RV32XTHEADBB-B-NEXT: # %bb.1:158; RV32XTHEADBB-B-NEXT: clz a0, a0159; RV32XTHEADBB-B-NEXT: addi a0, a0, 32160; RV32XTHEADBB-B-NEXT: li a1, 0161; RV32XTHEADBB-B-NEXT: ret162; RV32XTHEADBB-B-NEXT: .LBB1_2:163; RV32XTHEADBB-B-NEXT: clz a0, a1164; RV32XTHEADBB-B-NEXT: li a1, 0165; RV32XTHEADBB-B-NEXT: ret166 %1 = call i64 @llvm.ctlz.i64(i64 %a, i1 false)167 ret i64 %1168}169 170define i32 @cttz_i32(i32 %a) nounwind {171; RV32I-LABEL: cttz_i32:172; RV32I: # %bb.0:173; RV32I-NEXT: beqz a0, .LBB2_2174; RV32I-NEXT: # %bb.1: # %cond.false175; RV32I-NEXT: addi sp, sp, -16176; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill177; RV32I-NEXT: neg a1, a0178; RV32I-NEXT: and a0, a0, a1179; RV32I-NEXT: lui a1, 30667180; RV32I-NEXT: addi a1, a1, 1329181; RV32I-NEXT: call __mulsi3182; RV32I-NEXT: srli a0, a0, 27183; RV32I-NEXT: lui a1, %hi(.LCPI2_0)184; RV32I-NEXT: addi a1, a1, %lo(.LCPI2_0)185; RV32I-NEXT: add a0, a1, a0186; RV32I-NEXT: lbu a0, 0(a0)187; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload188; RV32I-NEXT: addi sp, sp, 16189; RV32I-NEXT: ret190; RV32I-NEXT: .LBB2_2:191; RV32I-NEXT: li a0, 32192; RV32I-NEXT: ret193;194; RV32XTHEADBB-NOB-LABEL: cttz_i32:195; RV32XTHEADBB-NOB: # %bb.0:196; RV32XTHEADBB-NOB-NEXT: beqz a0, .LBB2_2197; RV32XTHEADBB-NOB-NEXT: # %bb.1: # %cond.false198; RV32XTHEADBB-NOB-NEXT: addi a1, a0, -1199; RV32XTHEADBB-NOB-NEXT: not a0, a0200; RV32XTHEADBB-NOB-NEXT: and a0, a0, a1201; RV32XTHEADBB-NOB-NEXT: th.ff1 a0, a0202; RV32XTHEADBB-NOB-NEXT: li a1, 32203; RV32XTHEADBB-NOB-NEXT: sub a0, a1, a0204; RV32XTHEADBB-NOB-NEXT: ret205; RV32XTHEADBB-NOB-NEXT: .LBB2_2:206; RV32XTHEADBB-NOB-NEXT: li a0, 32207; RV32XTHEADBB-NOB-NEXT: ret208;209; RV32XTHEADBB-B-LABEL: cttz_i32:210; RV32XTHEADBB-B: # %bb.0:211; RV32XTHEADBB-B-NEXT: ctz a0, a0212; RV32XTHEADBB-B-NEXT: ret213 %1 = call i32 @llvm.cttz.i32(i32 %a, i1 false)214 ret i32 %1215}216 217define i64 @cttz_i64(i64 %a) nounwind {218; RV32I-LABEL: cttz_i64:219; RV32I: # %bb.0:220; RV32I-NEXT: addi sp, sp, -32221; RV32I-NEXT: sw ra, 28(sp) # 4-byte Folded Spill222; RV32I-NEXT: sw s0, 24(sp) # 4-byte Folded Spill223; RV32I-NEXT: sw s1, 20(sp) # 4-byte Folded Spill224; RV32I-NEXT: sw s2, 16(sp) # 4-byte Folded Spill225; RV32I-NEXT: sw s3, 12(sp) # 4-byte Folded Spill226; RV32I-NEXT: sw s4, 8(sp) # 4-byte Folded Spill227; RV32I-NEXT: mv s0, a1228; RV32I-NEXT: or a1, a0, a1229; RV32I-NEXT: beqz a1, .LBB3_3230; RV32I-NEXT: # %bb.1: # %cond.false231; RV32I-NEXT: neg a1, a0232; RV32I-NEXT: and a1, a0, a1233; RV32I-NEXT: lui s2, 30667234; RV32I-NEXT: addi s2, s2, 1329235; RV32I-NEXT: mv s4, a0236; RV32I-NEXT: mv a0, a1237; RV32I-NEXT: mv a1, s2238; RV32I-NEXT: call __mulsi3239; RV32I-NEXT: mv s1, a0240; RV32I-NEXT: lui s3, %hi(.LCPI3_0)241; RV32I-NEXT: addi s3, s3, %lo(.LCPI3_0)242; RV32I-NEXT: neg a0, s0243; RV32I-NEXT: and a0, s0, a0244; RV32I-NEXT: mv a1, s2245; RV32I-NEXT: call __mulsi3246; RV32I-NEXT: bnez s4, .LBB3_4247; RV32I-NEXT: # %bb.2: # %cond.false248; RV32I-NEXT: srli a0, a0, 27249; RV32I-NEXT: add a0, s3, a0250; RV32I-NEXT: lbu a0, 0(a0)251; RV32I-NEXT: addi a0, a0, 32252; RV32I-NEXT: j .LBB3_5253; RV32I-NEXT: .LBB3_3:254; RV32I-NEXT: li a0, 64255; RV32I-NEXT: j .LBB3_6256; RV32I-NEXT: .LBB3_4:257; RV32I-NEXT: srli s1, s1, 27258; RV32I-NEXT: add s1, s3, s1259; RV32I-NEXT: lbu a0, 0(s1)260; RV32I-NEXT: .LBB3_5: # %cond.false261; RV32I-NEXT: li a1, 0262; RV32I-NEXT: .LBB3_6: # %cond.end263; RV32I-NEXT: lw ra, 28(sp) # 4-byte Folded Reload264; RV32I-NEXT: lw s0, 24(sp) # 4-byte Folded Reload265; RV32I-NEXT: lw s1, 20(sp) # 4-byte Folded Reload266; RV32I-NEXT: lw s2, 16(sp) # 4-byte Folded Reload267; RV32I-NEXT: lw s3, 12(sp) # 4-byte Folded Reload268; RV32I-NEXT: lw s4, 8(sp) # 4-byte Folded Reload269; RV32I-NEXT: addi sp, sp, 32270; RV32I-NEXT: ret271;272; RV32XTHEADBB-NOB-LABEL: cttz_i64:273; RV32XTHEADBB-NOB: # %bb.0:274; RV32XTHEADBB-NOB-NEXT: or a2, a0, a1275; RV32XTHEADBB-NOB-NEXT: beqz a2, .LBB3_3276; RV32XTHEADBB-NOB-NEXT: # %bb.1: # %cond.false277; RV32XTHEADBB-NOB-NEXT: bnez a0, .LBB3_4278; RV32XTHEADBB-NOB-NEXT: # %bb.2: # %cond.false279; RV32XTHEADBB-NOB-NEXT: addi a0, a1, -1280; RV32XTHEADBB-NOB-NEXT: not a1, a1281; RV32XTHEADBB-NOB-NEXT: and a0, a1, a0282; RV32XTHEADBB-NOB-NEXT: th.ff1 a0, a0283; RV32XTHEADBB-NOB-NEXT: li a1, 64284; RV32XTHEADBB-NOB-NEXT: j .LBB3_5285; RV32XTHEADBB-NOB-NEXT: .LBB3_3:286; RV32XTHEADBB-NOB-NEXT: li a1, 0287; RV32XTHEADBB-NOB-NEXT: li a0, 64288; RV32XTHEADBB-NOB-NEXT: ret289; RV32XTHEADBB-NOB-NEXT: .LBB3_4:290; RV32XTHEADBB-NOB-NEXT: addi a1, a0, -1291; RV32XTHEADBB-NOB-NEXT: not a0, a0292; RV32XTHEADBB-NOB-NEXT: and a0, a0, a1293; RV32XTHEADBB-NOB-NEXT: th.ff1 a0, a0294; RV32XTHEADBB-NOB-NEXT: li a1, 32295; RV32XTHEADBB-NOB-NEXT: .LBB3_5: # %cond.false296; RV32XTHEADBB-NOB-NEXT: sub a0, a1, a0297; RV32XTHEADBB-NOB-NEXT: li a1, 0298; RV32XTHEADBB-NOB-NEXT: ret299;300; RV32XTHEADBB-B-LABEL: cttz_i64:301; RV32XTHEADBB-B: # %bb.0:302; RV32XTHEADBB-B-NEXT: bnez a0, .LBB3_2303; RV32XTHEADBB-B-NEXT: # %bb.1:304; RV32XTHEADBB-B-NEXT: ctz a0, a1305; RV32XTHEADBB-B-NEXT: addi a0, a0, 32306; RV32XTHEADBB-B-NEXT: li a1, 0307; RV32XTHEADBB-B-NEXT: ret308; RV32XTHEADBB-B-NEXT: .LBB3_2:309; RV32XTHEADBB-B-NEXT: ctz a0, a0310; RV32XTHEADBB-B-NEXT: li a1, 0311; RV32XTHEADBB-B-NEXT: ret312 %1 = call i64 @llvm.cttz.i64(i64 %a, i1 false)313 ret i64 %1314}315 316define i32 @sexti1_i32(i32 %a) nounwind {317; RV32I-LABEL: sexti1_i32:318; RV32I: # %bb.0:319; RV32I-NEXT: slli a0, a0, 31320; RV32I-NEXT: srai a0, a0, 31321; RV32I-NEXT: ret322;323; RV32XTHEADBB-LABEL: sexti1_i32:324; RV32XTHEADBB: # %bb.0:325; RV32XTHEADBB-NEXT: th.ext a0, a0, 0, 0326; RV32XTHEADBB-NEXT: ret327 %shl = shl i32 %a, 31328 %shr = ashr exact i32 %shl, 31329 ret i32 %shr330}331 332define i32 @sexti1_i32_2(i1 %a) nounwind {333; RV32I-LABEL: sexti1_i32_2:334; RV32I: # %bb.0:335; RV32I-NEXT: slli a0, a0, 31336; RV32I-NEXT: srai a0, a0, 31337; RV32I-NEXT: ret338;339; RV32XTHEADBB-LABEL: sexti1_i32_2:340; RV32XTHEADBB: # %bb.0:341; RV32XTHEADBB-NEXT: th.ext a0, a0, 0, 0342; RV32XTHEADBB-NEXT: ret343 %sext = sext i1 %a to i32344 ret i32 %sext345}346 347; Make sure we don't use not+th.ext348define zeroext i8 @sexti1_i32_setcc(i32 signext %a) {349; CHECK-LABEL: sexti1_i32_setcc:350; CHECK: # %bb.0:351; CHECK-NEXT: srli a0, a0, 31352; CHECK-NEXT: addi a0, a0, -1353; CHECK-NEXT: zext.b a0, a0354; CHECK-NEXT: ret355 %icmp = icmp sgt i32 %a, -1356 %sext = sext i1 %icmp to i8357 ret i8 %sext358}359 360; Make sure we don't use seqz+th.ext instead of snez+addi361define i32 @sexti1_i32_setcc_2(i32 %a, i32 %b) {362; CHECK-LABEL: sexti1_i32_setcc_2:363; CHECK: # %bb.0:364; CHECK-NEXT: xor a0, a0, a1365; CHECK-NEXT: snez a0, a0366; CHECK-NEXT: addi a0, a0, -1367; CHECK-NEXT: ret368 %icmp = icmp eq i32 %a, %b369 %sext = sext i1 %icmp to i32370 ret i32 %sext371}372 373; Make sure we don't use th.ext instead of neg.374define i32 @sexti1_i32_setcc_3(i32 %a, i32 %b) {375; CHECK-LABEL: sexti1_i32_setcc_3:376; CHECK: # %bb.0:377; CHECK-NEXT: slt a0, a0, a1378; CHECK-NEXT: neg a0, a0379; CHECK-NEXT: ret380 %icmp = icmp slt i32 %a, %b381 %sext = sext i1 %icmp to i32382 ret i32 %sext383}384 385define i32 @sextb_i32(i32 %a) nounwind {386; RV32I-LABEL: sextb_i32:387; RV32I: # %bb.0:388; RV32I-NEXT: slli a0, a0, 24389; RV32I-NEXT: srai a0, a0, 24390; RV32I-NEXT: ret391;392; RV32XTHEADBB-NOB-LABEL: sextb_i32:393; RV32XTHEADBB-NOB: # %bb.0:394; RV32XTHEADBB-NOB-NEXT: th.ext a0, a0, 7, 0395; RV32XTHEADBB-NOB-NEXT: ret396;397; RV32XTHEADBB-B-LABEL: sextb_i32:398; RV32XTHEADBB-B: # %bb.0:399; RV32XTHEADBB-B-NEXT: sext.b a0, a0400; RV32XTHEADBB-B-NEXT: ret401 %shl = shl i32 %a, 24402 %shr = ashr exact i32 %shl, 24403 ret i32 %shr404}405 406define i64 @sextb_i64(i64 %a) nounwind {407; RV32I-LABEL: sextb_i64:408; RV32I: # %bb.0:409; RV32I-NEXT: slli a1, a0, 24410; RV32I-NEXT: srai a0, a1, 24411; RV32I-NEXT: srai a1, a1, 31412; RV32I-NEXT: ret413;414; RV32XTHEADBB-NOB-LABEL: sextb_i64:415; RV32XTHEADBB-NOB: # %bb.0:416; RV32XTHEADBB-NOB-NEXT: th.ext a0, a0, 7, 0417; RV32XTHEADBB-NOB-NEXT: srai a1, a0, 31418; RV32XTHEADBB-NOB-NEXT: ret419;420; RV32XTHEADBB-B-LABEL: sextb_i64:421; RV32XTHEADBB-B: # %bb.0:422; RV32XTHEADBB-B-NEXT: sext.b a0, a0423; RV32XTHEADBB-B-NEXT: srai a1, a0, 31424; RV32XTHEADBB-B-NEXT: ret425 %shl = shl i64 %a, 56426 %shr = ashr exact i64 %shl, 56427 ret i64 %shr428}429 430define i32 @sexth_i32(i32 %a) nounwind {431; RV32I-LABEL: sexth_i32:432; RV32I: # %bb.0:433; RV32I-NEXT: slli a0, a0, 16434; RV32I-NEXT: srai a0, a0, 16435; RV32I-NEXT: ret436;437; RV32XTHEADBB-NOB-LABEL: sexth_i32:438; RV32XTHEADBB-NOB: # %bb.0:439; RV32XTHEADBB-NOB-NEXT: th.ext a0, a0, 15, 0440; RV32XTHEADBB-NOB-NEXT: ret441;442; RV32XTHEADBB-B-LABEL: sexth_i32:443; RV32XTHEADBB-B: # %bb.0:444; RV32XTHEADBB-B-NEXT: sext.h a0, a0445; RV32XTHEADBB-B-NEXT: ret446 %shl = shl i32 %a, 16447 %shr = ashr exact i32 %shl, 16448 ret i32 %shr449}450 451define i32 @no_sexth_i32(i32 %a) nounwind {452; CHECK-LABEL: no_sexth_i32:453; CHECK: # %bb.0:454; CHECK-NEXT: slli a0, a0, 17455; CHECK-NEXT: srai a0, a0, 16456; CHECK-NEXT: ret457 %shl = shl i32 %a, 17458 %shr = ashr exact i32 %shl, 16459 ret i32 %shr460}461 462define i64 @sexth_i64(i64 %a) nounwind {463; RV32I-LABEL: sexth_i64:464; RV32I: # %bb.0:465; RV32I-NEXT: slli a1, a0, 16466; RV32I-NEXT: srai a0, a1, 16467; RV32I-NEXT: srai a1, a1, 31468; RV32I-NEXT: ret469;470; RV32XTHEADBB-NOB-LABEL: sexth_i64:471; RV32XTHEADBB-NOB: # %bb.0:472; RV32XTHEADBB-NOB-NEXT: th.ext a0, a0, 15, 0473; RV32XTHEADBB-NOB-NEXT: srai a1, a0, 31474; RV32XTHEADBB-NOB-NEXT: ret475;476; RV32XTHEADBB-B-LABEL: sexth_i64:477; RV32XTHEADBB-B: # %bb.0:478; RV32XTHEADBB-B-NEXT: sext.h a0, a0479; RV32XTHEADBB-B-NEXT: srai a1, a0, 31480; RV32XTHEADBB-B-NEXT: ret481 %shl = shl i64 %a, 48482 %shr = ashr exact i64 %shl, 48483 ret i64 %shr484}485 486define i64 @no_sexth_i64(i64 %a) nounwind {487; CHECK-LABEL: no_sexth_i64:488; CHECK: # %bb.0:489; CHECK-NEXT: slli a1, a0, 17490; CHECK-NEXT: srai a0, a1, 16491; CHECK-NEXT: srai a1, a1, 31492; CHECK-NEXT: ret493 %shl = shl i64 %a, 49494 %shr = ashr exact i64 %shl, 48495 ret i64 %shr496}497 498define i32 @sext_sextinreg_sra(i16 %a) nounwind {499; RV32I-LABEL: sext_sextinreg_sra:500; RV32I: # %bb.0:501; RV32I-NEXT: slli a0, a0, 16502; RV32I-NEXT: srai a0, a0, 26503; RV32I-NEXT: ret504;505; RV32XTHEADBB-LABEL: sext_sextinreg_sra:506; RV32XTHEADBB: # %bb.0:507; RV32XTHEADBB-NEXT: th.ext a0, a0, 15, 10508; RV32XTHEADBB-NEXT: ret509 %sext = sext i16 %a to i32510 %shr = ashr exact i32 %sext, 10511 ret i32 %shr512}513 514define i32 @sext_sextinreg_sra_2(i16 %a) nounwind {515; RV32I-LABEL: sext_sextinreg_sra_2:516; RV32I: # %bb.0:517; RV32I-NEXT: slli a0, a0, 16518; RV32I-NEXT: srai a0, a0, 31519; RV32I-NEXT: ret520;521; RV32XTHEADBB-LABEL: sext_sextinreg_sra_2:522; RV32XTHEADBB: # %bb.0:523; RV32XTHEADBB-NEXT: th.ext a0, a0, 15, 15524; RV32XTHEADBB-NEXT: ret525 %sext = sext i16 %a to i32526 %shr = ashr exact i32 %sext, 24527 ret i32 %shr528}529 530define i32 @zexth_i32(i32 %a) nounwind {531; RV32I-LABEL: zexth_i32:532; RV32I: # %bb.0:533; RV32I-NEXT: slli a0, a0, 16534; RV32I-NEXT: srli a0, a0, 16535; RV32I-NEXT: ret536;537; RV32XTHEADBB-NOB-LABEL: zexth_i32:538; RV32XTHEADBB-NOB: # %bb.0:539; RV32XTHEADBB-NOB-NEXT: th.extu a0, a0, 15, 0540; RV32XTHEADBB-NOB-NEXT: ret541;542; RV32XTHEADBB-B-LABEL: zexth_i32:543; RV32XTHEADBB-B: # %bb.0:544; RV32XTHEADBB-B-NEXT: zext.h a0, a0545; RV32XTHEADBB-B-NEXT: ret546 %and = and i32 %a, 65535547 ret i32 %and548}549 550define i64 @zexth_i64(i64 %a) nounwind {551; RV32I-LABEL: zexth_i64:552; RV32I: # %bb.0:553; RV32I-NEXT: slli a0, a0, 16554; RV32I-NEXT: srli a0, a0, 16555; RV32I-NEXT: li a1, 0556; RV32I-NEXT: ret557;558; RV32XTHEADBB-NOB-LABEL: zexth_i64:559; RV32XTHEADBB-NOB: # %bb.0:560; RV32XTHEADBB-NOB-NEXT: th.extu a0, a0, 15, 0561; RV32XTHEADBB-NOB-NEXT: li a1, 0562; RV32XTHEADBB-NOB-NEXT: ret563;564; RV32XTHEADBB-B-LABEL: zexth_i64:565; RV32XTHEADBB-B: # %bb.0:566; RV32XTHEADBB-B-NEXT: zext.h a0, a0567; RV32XTHEADBB-B-NEXT: li a1, 0568; RV32XTHEADBB-B-NEXT: ret569 %and = and i64 %a, 65535570 ret i64 %and571}572 573define i32 @bswap_i32(i32 %a) nounwind {574; RV32I-LABEL: bswap_i32:575; RV32I: # %bb.0:576; RV32I-NEXT: srli a1, a0, 8577; RV32I-NEXT: lui a2, 16578; RV32I-NEXT: srli a3, a0, 24579; RV32I-NEXT: addi a2, a2, -256580; RV32I-NEXT: and a1, a1, a2581; RV32I-NEXT: and a2, a0, a2582; RV32I-NEXT: or a1, a1, a3583; RV32I-NEXT: slli a2, a2, 8584; RV32I-NEXT: slli a0, a0, 24585; RV32I-NEXT: or a0, a0, a2586; RV32I-NEXT: or a0, a0, a1587; RV32I-NEXT: ret588;589; RV32XTHEADBB-NOB-LABEL: bswap_i32:590; RV32XTHEADBB-NOB: # %bb.0:591; RV32XTHEADBB-NOB-NEXT: th.rev a0, a0592; RV32XTHEADBB-NOB-NEXT: ret593;594; RV32XTHEADBB-B-LABEL: bswap_i32:595; RV32XTHEADBB-B: # %bb.0:596; RV32XTHEADBB-B-NEXT: rev8 a0, a0597; RV32XTHEADBB-B-NEXT: ret598 %1 = tail call i32 @llvm.bswap.i32(i32 %a)599 ret i32 %1600}601 602define i64 @bswap_i64(i64 %a) {603; RV32I-LABEL: bswap_i64:604; RV32I: # %bb.0:605; RV32I-NEXT: srli a2, a1, 8606; RV32I-NEXT: lui a3, 16607; RV32I-NEXT: srli a4, a1, 24608; RV32I-NEXT: srli a5, a0, 8609; RV32I-NEXT: addi a3, a3, -256610; RV32I-NEXT: and a2, a2, a3611; RV32I-NEXT: or a2, a2, a4612; RV32I-NEXT: srli a4, a0, 24613; RV32I-NEXT: and a5, a5, a3614; RV32I-NEXT: or a4, a5, a4615; RV32I-NEXT: slli a5, a1, 24616; RV32I-NEXT: and a1, a1, a3617; RV32I-NEXT: slli a1, a1, 8618; RV32I-NEXT: or a1, a5, a1619; RV32I-NEXT: and a3, a0, a3620; RV32I-NEXT: slli a0, a0, 24621; RV32I-NEXT: slli a3, a3, 8622; RV32I-NEXT: or a3, a0, a3623; RV32I-NEXT: or a0, a1, a2624; RV32I-NEXT: or a1, a3, a4625; RV32I-NEXT: ret626;627; RV32XTHEADBB-NOB-LABEL: bswap_i64:628; RV32XTHEADBB-NOB: # %bb.0:629; RV32XTHEADBB-NOB-NEXT: th.rev a2, a1630; RV32XTHEADBB-NOB-NEXT: th.rev a1, a0631; RV32XTHEADBB-NOB-NEXT: mv a0, a2632; RV32XTHEADBB-NOB-NEXT: ret633;634; RV32XTHEADBB-B-LABEL: bswap_i64:635; RV32XTHEADBB-B: # %bb.0:636; RV32XTHEADBB-B-NEXT: rev8 a2, a1637; RV32XTHEADBB-B-NEXT: rev8 a1, a0638; RV32XTHEADBB-B-NEXT: mv a0, a2639; RV32XTHEADBB-B-NEXT: ret640 %1 = call i64 @llvm.bswap.i64(i64 %a)641 ret i64 %1642}643