392 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=riscv32 -global-isel -verify-machineinstrs < %s \3; RUN: | FileCheck %s -check-prefixes=CHECK,RV32I4; RUN: llc -mtriple=riscv32 -global-isel -mattr=+zbb -verify-machineinstrs < %s \5; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBKB,RV32ZBB6; RUN: llc -mtriple=riscv32 -global-isel -mattr=+zbkb -verify-machineinstrs < %s \7; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBB-ZBKB,RV32ZBKB8 9define i32 @andn_i32(i32 %a, i32 %b) nounwind {10; RV32I-LABEL: andn_i32:11; RV32I: # %bb.0:12; RV32I-NEXT: not a1, a113; RV32I-NEXT: and a0, a1, a014; RV32I-NEXT: ret15;16; RV32ZBB-ZBKB-LABEL: andn_i32:17; RV32ZBB-ZBKB: # %bb.0:18; RV32ZBB-ZBKB-NEXT: andn a0, a0, a119; RV32ZBB-ZBKB-NEXT: ret20 %neg = xor i32 %b, -121 %and = and i32 %neg, %a22 ret i32 %and23}24 25define i64 @andn_i64(i64 %a, i64 %b) nounwind {26; RV32I-LABEL: andn_i64:27; RV32I: # %bb.0:28; RV32I-NEXT: not a2, a229; RV32I-NEXT: not a3, a330; RV32I-NEXT: and a0, a2, a031; RV32I-NEXT: and a1, a3, a132; RV32I-NEXT: ret33;34; RV32ZBB-ZBKB-LABEL: andn_i64:35; RV32ZBB-ZBKB: # %bb.0:36; RV32ZBB-ZBKB-NEXT: andn a0, a0, a237; RV32ZBB-ZBKB-NEXT: andn a1, a1, a338; RV32ZBB-ZBKB-NEXT: ret39 %neg = xor i64 %b, -140 %and = and i64 %neg, %a41 ret i64 %and42}43 44define i32 @orn_i32(i32 %a, i32 %b) nounwind {45; RV32I-LABEL: orn_i32:46; RV32I: # %bb.0:47; RV32I-NEXT: not a1, a148; RV32I-NEXT: or a0, a1, a049; RV32I-NEXT: ret50;51; RV32ZBB-ZBKB-LABEL: orn_i32:52; RV32ZBB-ZBKB: # %bb.0:53; RV32ZBB-ZBKB-NEXT: orn a0, a0, a154; RV32ZBB-ZBKB-NEXT: ret55 %neg = xor i32 %b, -156 %or = or i32 %neg, %a57 ret i32 %or58}59 60define i64 @orn_i64(i64 %a, i64 %b) nounwind {61; RV32I-LABEL: orn_i64:62; RV32I: # %bb.0:63; RV32I-NEXT: not a2, a264; RV32I-NEXT: not a3, a365; RV32I-NEXT: or a0, a2, a066; RV32I-NEXT: or a1, a3, a167; RV32I-NEXT: ret68;69; RV32ZBB-ZBKB-LABEL: orn_i64:70; RV32ZBB-ZBKB: # %bb.0:71; RV32ZBB-ZBKB-NEXT: orn a0, a0, a272; RV32ZBB-ZBKB-NEXT: orn a1, a1, a373; RV32ZBB-ZBKB-NEXT: ret74 %neg = xor i64 %b, -175 %or = or i64 %neg, %a76 ret i64 %or77}78 79define i32 @xnor_i32(i32 %a, i32 %b) nounwind {80; RV32I-LABEL: xnor_i32:81; RV32I: # %bb.0:82; RV32I-NEXT: not a0, a083; RV32I-NEXT: xor a0, a0, a184; RV32I-NEXT: ret85;86; RV32ZBB-ZBKB-LABEL: xnor_i32:87; RV32ZBB-ZBKB: # %bb.0:88; RV32ZBB-ZBKB-NEXT: xnor a0, a0, a189; RV32ZBB-ZBKB-NEXT: ret90 %neg = xor i32 %a, -191 %xor = xor i32 %neg, %b92 ret i32 %xor93}94 95define i64 @xnor_i64(i64 %a, i64 %b) nounwind {96; RV32I-LABEL: xnor_i64:97; RV32I: # %bb.0:98; RV32I-NEXT: not a0, a099; RV32I-NEXT: not a1, a1100; RV32I-NEXT: xor a0, a0, a2101; RV32I-NEXT: xor a1, a1, a3102; RV32I-NEXT: ret103;104; RV32ZBB-ZBKB-LABEL: xnor_i64:105; RV32ZBB-ZBKB: # %bb.0:106; RV32ZBB-ZBKB-NEXT: xnor a0, a0, a2107; RV32ZBB-ZBKB-NEXT: xnor a1, a1, a3108; RV32ZBB-ZBKB-NEXT: ret109 %neg = xor i64 %a, -1110 %xor = xor i64 %neg, %b111 ret i64 %xor112}113 114define i32 @rol_i32(i32 %a, i32 %b) nounwind {115; RV32I-LABEL: rol_i32:116; RV32I: # %bb.0:117; RV32I-NEXT: neg a2, a1118; RV32I-NEXT: sll a1, a0, a1119; RV32I-NEXT: srl a0, a0, a2120; RV32I-NEXT: or a0, a1, a0121; RV32I-NEXT: ret122;123; RV32ZBB-ZBKB-LABEL: rol_i32:124; RV32ZBB-ZBKB: # %bb.0:125; RV32ZBB-ZBKB-NEXT: rol a0, a0, a1126; RV32ZBB-ZBKB-NEXT: ret127 %or = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 %b)128 ret i32 %or129}130 131; This test is presented here in case future expansions of the Bitmanip132; extensions introduce instructions suitable for this pattern.133 134define i64 @rol_i64(i64 %a, i64 %b) nounwind {135; CHECK-LABEL: rol_i64:136; CHECK: # %bb.0:137; CHECK-NEXT: andi a6, a2, 63138; CHECK-NEXT: li a4, 32139; CHECK-NEXT: bltu a6, a4, .LBB7_2140; CHECK-NEXT: # %bb.1:141; CHECK-NEXT: li a3, 0142; CHECK-NEXT: sll a7, a0, a6143; CHECK-NEXT: j .LBB7_3144; CHECK-NEXT: .LBB7_2:145; CHECK-NEXT: sll a3, a0, a2146; CHECK-NEXT: neg a5, a6147; CHECK-NEXT: srl a5, a0, a5148; CHECK-NEXT: sll a7, a1, a2149; CHECK-NEXT: or a7, a5, a7150; CHECK-NEXT: .LBB7_3:151; CHECK-NEXT: neg a5, a2152; CHECK-NEXT: mv a2, a1153; CHECK-NEXT: beqz a6, .LBB7_5154; CHECK-NEXT: # %bb.4:155; CHECK-NEXT: mv a2, a7156; CHECK-NEXT: .LBB7_5:157; CHECK-NEXT: andi a6, a5, 63158; CHECK-NEXT: bltu a6, a4, .LBB7_7159; CHECK-NEXT: # %bb.6:160; CHECK-NEXT: srl a7, a1, a6161; CHECK-NEXT: bnez a6, .LBB7_8162; CHECK-NEXT: j .LBB7_9163; CHECK-NEXT: .LBB7_7:164; CHECK-NEXT: srl a7, a0, a5165; CHECK-NEXT: neg t0, a6166; CHECK-NEXT: sll t0, a1, t0167; CHECK-NEXT: or a7, a7, t0168; CHECK-NEXT: beqz a6, .LBB7_9169; CHECK-NEXT: .LBB7_8:170; CHECK-NEXT: mv a0, a7171; CHECK-NEXT: .LBB7_9:172; CHECK-NEXT: bltu a6, a4, .LBB7_11173; CHECK-NEXT: # %bb.10:174; CHECK-NEXT: li a1, 0175; CHECK-NEXT: j .LBB7_12176; CHECK-NEXT: .LBB7_11:177; CHECK-NEXT: srl a1, a1, a5178; CHECK-NEXT: .LBB7_12:179; CHECK-NEXT: or a0, a3, a0180; CHECK-NEXT: or a1, a2, a1181; CHECK-NEXT: ret182 %or = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 %b)183 ret i64 %or184}185 186define i32 @ror_i32(i32 %a, i32 %b) nounwind {187; RV32I-LABEL: ror_i32:188; RV32I: # %bb.0:189; RV32I-NEXT: neg a2, a1190; RV32I-NEXT: srl a1, a0, a1191; RV32I-NEXT: sll a0, a0, a2192; RV32I-NEXT: or a0, a1, a0193; RV32I-NEXT: ret194;195; RV32ZBB-ZBKB-LABEL: ror_i32:196; RV32ZBB-ZBKB: # %bb.0:197; RV32ZBB-ZBKB-NEXT: ror a0, a0, a1198; RV32ZBB-ZBKB-NEXT: ret199 %or = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 %b)200 ret i32 %or201}202 203; This test is presented here in case future expansions of the Bitmanip204; extensions introduce instructions suitable for this pattern.205 206define i64 @ror_i64(i64 %a, i64 %b) nounwind {207; CHECK-LABEL: ror_i64:208; CHECK: # %bb.0:209; CHECK-NEXT: andi a5, a2, 63210; CHECK-NEXT: li a4, 32211; CHECK-NEXT: bltu a5, a4, .LBB9_2212; CHECK-NEXT: # %bb.1:213; CHECK-NEXT: srl a6, a1, a5214; CHECK-NEXT: mv a3, a0215; CHECK-NEXT: bnez a5, .LBB9_3216; CHECK-NEXT: j .LBB9_4217; CHECK-NEXT: .LBB9_2:218; CHECK-NEXT: srl a3, a0, a2219; CHECK-NEXT: neg a6, a5220; CHECK-NEXT: sll a6, a1, a6221; CHECK-NEXT: or a6, a3, a6222; CHECK-NEXT: mv a3, a0223; CHECK-NEXT: beqz a5, .LBB9_4224; CHECK-NEXT: .LBB9_3:225; CHECK-NEXT: mv a3, a6226; CHECK-NEXT: .LBB9_4:227; CHECK-NEXT: neg a6, a2228; CHECK-NEXT: bltu a5, a4, .LBB9_7229; CHECK-NEXT: # %bb.5:230; CHECK-NEXT: li a2, 0231; CHECK-NEXT: andi a5, a6, 63232; CHECK-NEXT: bgeu a5, a4, .LBB9_8233; CHECK-NEXT: .LBB9_6:234; CHECK-NEXT: sll a4, a0, a6235; CHECK-NEXT: neg a7, a5236; CHECK-NEXT: srl a0, a0, a7237; CHECK-NEXT: sll a6, a1, a6238; CHECK-NEXT: or a0, a0, a6239; CHECK-NEXT: bnez a5, .LBB9_9240; CHECK-NEXT: j .LBB9_10241; CHECK-NEXT: .LBB9_7:242; CHECK-NEXT: srl a2, a1, a2243; CHECK-NEXT: andi a5, a6, 63244; CHECK-NEXT: bltu a5, a4, .LBB9_6245; CHECK-NEXT: .LBB9_8:246; CHECK-NEXT: li a4, 0247; CHECK-NEXT: sll a0, a0, a5248; CHECK-NEXT: beqz a5, .LBB9_10249; CHECK-NEXT: .LBB9_9:250; CHECK-NEXT: mv a1, a0251; CHECK-NEXT: .LBB9_10:252; CHECK-NEXT: or a0, a3, a4253; CHECK-NEXT: or a1, a2, a1254; CHECK-NEXT: ret255 %or = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 %b)256 ret i64 %or257}258 259define i32 @rori_i32_fshl(i32 %a) nounwind {260; RV32I-LABEL: rori_i32_fshl:261; RV32I: # %bb.0:262; RV32I-NEXT: slli a1, a0, 31263; RV32I-NEXT: srli a0, a0, 1264; RV32I-NEXT: or a0, a1, a0265; RV32I-NEXT: ret266;267; RV32ZBB-ZBKB-LABEL: rori_i32_fshl:268; RV32ZBB-ZBKB: # %bb.0:269; RV32ZBB-ZBKB-NEXT: rori a0, a0, 1270; RV32ZBB-ZBKB-NEXT: ret271 %1 = tail call i32 @llvm.fshl.i32(i32 %a, i32 %a, i32 31)272 ret i32 %1273}274 275define i32 @rori_i32_fshr(i32 %a) nounwind {276; RV32I-LABEL: rori_i32_fshr:277; RV32I: # %bb.0:278; RV32I-NEXT: srli a1, a0, 31279; RV32I-NEXT: slli a0, a0, 1280; RV32I-NEXT: or a0, a1, a0281; RV32I-NEXT: ret282;283; RV32ZBB-ZBKB-LABEL: rori_i32_fshr:284; RV32ZBB-ZBKB: # %bb.0:285; RV32ZBB-ZBKB-NEXT: rori a0, a0, 31286; RV32ZBB-ZBKB-NEXT: ret287 %1 = tail call i32 @llvm.fshr.i32(i32 %a, i32 %a, i32 31)288 ret i32 %1289}290 291define i64 @rori_i64(i64 %a) nounwind {292; CHECK-LABEL: rori_i64:293; CHECK: # %bb.0:294; CHECK-NEXT: slli a2, a0, 31295; CHECK-NEXT: srli a0, a0, 1296; CHECK-NEXT: slli a3, a1, 31297; CHECK-NEXT: srli a1, a1, 1298; CHECK-NEXT: or a0, a0, a3299; CHECK-NEXT: or a1, a2, a1300; CHECK-NEXT: ret301 %1 = tail call i64 @llvm.fshl.i64(i64 %a, i64 %a, i64 63)302 ret i64 %1303}304 305define i64 @rori_i64_fshr(i64 %a) nounwind {306; CHECK-LABEL: rori_i64_fshr:307; CHECK: # %bb.0:308; CHECK-NEXT: srli a2, a1, 31309; CHECK-NEXT: slli a3, a0, 1310; CHECK-NEXT: slli a1, a1, 1311; CHECK-NEXT: srli a0, a0, 31312; CHECK-NEXT: or a1, a1, a0313; CHECK-NEXT: or a0, a2, a3314; CHECK-NEXT: ret315 %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63)316 ret i64 %1317}318 319define i8 @srli_i8(i8 %a) nounwind {320; CHECK-LABEL: srli_i8:321; CHECK: # %bb.0:322; CHECK-NEXT: zext.b a0, a0323; CHECK-NEXT: srli a0, a0, 6324; CHECK-NEXT: ret325 %1 = lshr i8 %a, 6326 ret i8 %1327}328 329; FIXME: We should use slli+srai with Zbb for better compression.330define i8 @srai_i8(i8 %a) nounwind {331; RV32I-LABEL: srai_i8:332; RV32I: # %bb.0:333; RV32I-NEXT: slli a0, a0, 24334; RV32I-NEXT: srai a0, a0, 29335; RV32I-NEXT: ret336;337; RV32ZBB-LABEL: srai_i8:338; RV32ZBB: # %bb.0:339; RV32ZBB-NEXT: sext.b a0, a0340; RV32ZBB-NEXT: srai a0, a0, 5341; RV32ZBB-NEXT: ret342;343; RV32ZBKB-LABEL: srai_i8:344; RV32ZBKB: # %bb.0:345; RV32ZBKB-NEXT: slli a0, a0, 24346; RV32ZBKB-NEXT: srai a0, a0, 29347; RV32ZBKB-NEXT: ret348 %1 = ashr i8 %a, 5349 ret i8 %1350}351 352; FIXME: We should use slli+srli.353define i16 @srli_i16(i16 %a) nounwind {354; RV32I-LABEL: srli_i16:355; RV32I: # %bb.0:356; RV32I-NEXT: slli a0, a0, 16357; RV32I-NEXT: srli a0, a0, 16358; RV32I-NEXT: srli a0, a0, 6359; RV32I-NEXT: ret360;361; RV32ZBB-ZBKB-LABEL: srli_i16:362; RV32ZBB-ZBKB: # %bb.0:363; RV32ZBB-ZBKB-NEXT: zext.h a0, a0364; RV32ZBB-ZBKB-NEXT: srli a0, a0, 6365; RV32ZBB-ZBKB-NEXT: ret366 %1 = lshr i16 %a, 6367 ret i16 %1368}369 370; FIXME: We should use slli+srai with Zbb/Zbkb for better compression.371define i16 @srai_i16(i16 %a) nounwind {372; RV32I-LABEL: srai_i16:373; RV32I: # %bb.0:374; RV32I-NEXT: slli a0, a0, 16375; RV32I-NEXT: srai a0, a0, 25376; RV32I-NEXT: ret377;378; RV32ZBB-LABEL: srai_i16:379; RV32ZBB: # %bb.0:380; RV32ZBB-NEXT: sext.h a0, a0381; RV32ZBB-NEXT: srai a0, a0, 9382; RV32ZBB-NEXT: ret383;384; RV32ZBKB-LABEL: srai_i16:385; RV32ZBKB: # %bb.0:386; RV32ZBKB-NEXT: slli a0, a0, 16387; RV32ZBKB-NEXT: srai a0, a0, 25388; RV32ZBKB-NEXT: ret389 %1 = ashr i16 %a, 9390 ret i16 %1391}392