319 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=+zbkb -verify-machineinstrs < %s \5; RUN: | FileCheck %s -check-prefixes=CHECK,RV32ZBKB6 7define i32 @pack_i32(i32 %a, i32 %b) nounwind {8; RV32I-LABEL: pack_i32:9; RV32I: # %bb.0:10; RV32I-NEXT: slli a0, a0, 1611; RV32I-NEXT: srli a0, a0, 1612; RV32I-NEXT: slli a1, a1, 1613; RV32I-NEXT: or a0, a1, a014; RV32I-NEXT: ret15;16; RV32ZBKB-LABEL: pack_i32:17; RV32ZBKB: # %bb.0:18; RV32ZBKB-NEXT: pack a0, a0, a119; RV32ZBKB-NEXT: ret20 %shl = and i32 %a, 6553521 %shl1 = shl i32 %b, 1622 %or = or i32 %shl1, %shl23 ret i32 %or24}25 26define i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind {27; RV32I-LABEL: pack_i32_2:28; RV32I: # %bb.0:29; RV32I-NEXT: slli a1, a1, 1630; RV32I-NEXT: or a0, a1, a031; RV32I-NEXT: ret32;33; RV32ZBKB-LABEL: pack_i32_2:34; RV32ZBKB: # %bb.0:35; RV32ZBKB-NEXT: pack a0, a0, a136; RV32ZBKB-NEXT: ret37 %zexta = zext i16 %a to i3238 %zextb = zext i16 %b to i3239 %shl1 = shl i32 %zextb, 1640 %or = or i32 %shl1, %zexta41 ret i32 %or42}43 44define i32 @pack_i32_3(i16 zeroext %0, i16 zeroext %1, i32 %2) {45; RV32I-LABEL: pack_i32_3:46; RV32I: # %bb.0:47; RV32I-NEXT: slli a0, a0, 1648; RV32I-NEXT: or a0, a0, a149; RV32I-NEXT: add a0, a0, a250; RV32I-NEXT: ret51;52; RV32ZBKB-LABEL: pack_i32_3:53; RV32ZBKB: # %bb.0:54; RV32ZBKB-NEXT: pack a0, a1, a055; RV32ZBKB-NEXT: add a0, a0, a256; RV32ZBKB-NEXT: ret57 %4 = zext i16 %0 to i3258 %5 = shl nuw i32 %4, 1659 %6 = zext i16 %1 to i3260 %7 = or i32 %5, %661 %8 = add i32 %7, %262 ret i32 %863}64 65; As we are not matching directly i64 code patterns on RV32 some i64 patterns66; don't have yet any matching bit manipulation instructions on RV32.67; This test is presented here in case future expansions of the Bitmanip68; extensions introduce instructions suitable for this pattern.69 70define i64 @pack_i64(i64 %a, i64 %b) nounwind {71; CHECK-LABEL: pack_i64:72; CHECK: # %bb.0:73; CHECK-NEXT: mv a1, a274; CHECK-NEXT: ret75 %shl = and i64 %a, 429496729576 %shl1 = shl i64 %b, 3277 %or = or i64 %shl1, %shl78 ret i64 %or79}80 81define i64 @pack_i64_2(i32 %a, i32 %b) nounwind {82; CHECK-LABEL: pack_i64_2:83; CHECK: # %bb.0:84; CHECK-NEXT: ret85 %zexta = zext i32 %a to i6486 %zextb = zext i32 %b to i6487 %shl1 = shl i64 %zextb, 3288 %or = or i64 %shl1, %zexta89 ret i64 %or90}91 92define i64 @pack_i64_3(ptr %0, ptr %1) {93; CHECK-LABEL: pack_i64_3:94; CHECK: # %bb.0:95; CHECK-NEXT: lw a2, 0(a0)96; CHECK-NEXT: lw a0, 0(a1)97; CHECK-NEXT: mv a1, a298; CHECK-NEXT: ret99 %3 = load i32, ptr %0, align 4100 %4 = zext i32 %3 to i64101 %5 = shl i64 %4, 32102 %6 = load i32, ptr %1, align 4103 %7 = zext i32 %6 to i64104 %8 = or i64 %5, %7105 ret i64 %8106}107 108; FIXME: Use packh.109define i32 @packh_i32(i32 %a, i32 %b) nounwind {110; CHECK-LABEL: packh_i32:111; CHECK: # %bb.0:112; CHECK-NEXT: lui a2, 16113; CHECK-NEXT: zext.b a0, a0114; CHECK-NEXT: addi a2, a2, -256115; CHECK-NEXT: slli a1, a1, 8116; CHECK-NEXT: and a1, a1, a2117; CHECK-NEXT: or a0, a1, a0118; CHECK-NEXT: ret119 %and = and i32 %a, 255120 %and1 = shl i32 %b, 8121 %shl = and i32 %and1, 65280122 %or = or i32 %shl, %and123 ret i32 %or124}125 126define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {127; RV32I-LABEL: packh_i32_2:128; RV32I: # %bb.0:129; RV32I-NEXT: zext.b a0, a0130; RV32I-NEXT: zext.b a1, a1131; RV32I-NEXT: slli a1, a1, 8132; RV32I-NEXT: or a0, a1, a0133; RV32I-NEXT: ret134;135; RV32ZBKB-LABEL: packh_i32_2:136; RV32ZBKB: # %bb.0:137; RV32ZBKB-NEXT: packh a0, a0, a1138; RV32ZBKB-NEXT: ret139 %and = and i32 %a, 255140 %and1 = and i32 %b, 255141 %shl = shl i32 %and1, 8142 %or = or i32 %shl, %and143 ret i32 %or144}145 146; FIMXE: Use packh147define i64 @packh_i64(i64 %a, i64 %b) nounwind {148; CHECK-LABEL: packh_i64:149; CHECK: # %bb.0:150; CHECK-NEXT: lui a1, 16151; CHECK-NEXT: zext.b a0, a0152; CHECK-NEXT: addi a1, a1, -256153; CHECK-NEXT: slli a2, a2, 8154; CHECK-NEXT: and a1, a2, a1155; CHECK-NEXT: or a0, a1, a0156; CHECK-NEXT: li a1, 0157; CHECK-NEXT: ret158 %and = and i64 %a, 255159 %and1 = shl i64 %b, 8160 %shl = and i64 %and1, 65280161 %or = or i64 %shl, %and162 ret i64 %or163}164 165; FIXME The andi+srli for RV32ZBKB should fold to 0.166define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {167; RV32I-LABEL: packh_i64_2:168; RV32I: # %bb.0:169; RV32I-NEXT: zext.b a0, a0170; RV32I-NEXT: zext.b a1, a2171; RV32I-NEXT: slli a2, a1, 8172; RV32I-NEXT: srli a1, a1, 24173; RV32I-NEXT: or a0, a2, a0174; RV32I-NEXT: ret175;176; RV32ZBKB-LABEL: packh_i64_2:177; RV32ZBKB: # %bb.0:178; RV32ZBKB-NEXT: zext.b a1, a2179; RV32ZBKB-NEXT: srli a1, a1, 24180; RV32ZBKB-NEXT: packh a0, a0, a2181; RV32ZBKB-NEXT: ret182 %and = and i64 %a, 255183 %and1 = and i64 %b, 255184 %shl = shl i64 %and1, 8185 %or = or i64 %shl, %and186 ret i64 %or187}188 189 190define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind {191; RV32I-LABEL: packh_i16:192; RV32I: # %bb.0:193; RV32I-NEXT: slli a1, a1, 8194; RV32I-NEXT: or a0, a1, a0195; RV32I-NEXT: ret196;197; RV32ZBKB-LABEL: packh_i16:198; RV32ZBKB: # %bb.0:199; RV32ZBKB-NEXT: packh a0, a0, a1200; RV32ZBKB-NEXT: ret201 %zext = zext i8 %a to i16202 %zext1 = zext i8 %b to i16203 %shl = shl i16 %zext1, 8204 %or = or i16 %shl, %zext205 ret i16 %or206}207 208 209define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) {210; RV32I-LABEL: packh_i16_2:211; RV32I: # %bb.0:212; RV32I-NEXT: add a0, a1, a0213; RV32I-NEXT: zext.b a0, a0214; RV32I-NEXT: slli a0, a0, 8215; RV32I-NEXT: or a0, a0, a2216; RV32I-NEXT: ret217;218; RV32ZBKB-LABEL: packh_i16_2:219; RV32ZBKB: # %bb.0:220; RV32ZBKB-NEXT: add a0, a1, a0221; RV32ZBKB-NEXT: packh a0, a2, a0222; RV32ZBKB-NEXT: ret223 %4 = add i8 %1, %0224 %5 = zext i8 %4 to i16225 %6 = shl i16 %5, 8226 %7 = zext i8 %2 to i16227 %8 = or i16 %6, %7228 ret i16 %8229}230 231define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {232; RV32I-LABEL: packh_i16_3:233; RV32I: # %bb.0:234; RV32I-NEXT: add a0, a1, a0235; RV32I-NEXT: zext.b a0, a0236; RV32I-NEXT: slli a0, a0, 8237; RV32I-NEXT: or a0, a0, a2238; RV32I-NEXT: sh a0, 0(a3)239; RV32I-NEXT: ret240;241; RV32ZBKB-LABEL: packh_i16_3:242; RV32ZBKB: # %bb.0:243; RV32ZBKB-NEXT: add a0, a1, a0244; RV32ZBKB-NEXT: packh a0, a2, a0245; RV32ZBKB-NEXT: sh a0, 0(a3)246; RV32ZBKB-NEXT: ret247 %4 = add i8 %1, %0248 %5 = zext i8 %4 to i16249 %6 = shl i16 %5, 8250 %7 = zext i8 %2 to i16251 %8 = or i16 %6, %7252 store i16 %8, ptr %p253 ret void254}255 256define i32 @zexth_i32(i32 %a) nounwind {257; RV32I-LABEL: zexth_i32:258; RV32I: # %bb.0:259; RV32I-NEXT: slli a0, a0, 16260; RV32I-NEXT: srli a0, a0, 16261; RV32I-NEXT: ret262;263; RV32ZBKB-LABEL: zexth_i32:264; RV32ZBKB: # %bb.0:265; RV32ZBKB-NEXT: zext.h a0, a0266; RV32ZBKB-NEXT: ret267 %and = and i32 %a, 65535268 ret i32 %and269}270 271define i64 @zexth_i64(i64 %a) nounwind {272; RV32I-LABEL: zexth_i64:273; RV32I: # %bb.0:274; RV32I-NEXT: slli a0, a0, 16275; RV32I-NEXT: srli a0, a0, 16276; RV32I-NEXT: li a1, 0277; RV32I-NEXT: ret278;279; RV32ZBKB-LABEL: zexth_i64:280; RV32ZBKB: # %bb.0:281; RV32ZBKB-NEXT: zext.h a0, a0282; RV32ZBKB-NEXT: li a1, 0283; RV32ZBKB-NEXT: ret284 %and = and i64 %a, 65535285 ret i64 %and286}287 288define i32 @zext_i16_to_i32(i16 %a) nounwind {289; RV32I-LABEL: zext_i16_to_i32:290; RV32I: # %bb.0:291; RV32I-NEXT: slli a0, a0, 16292; RV32I-NEXT: srli a0, a0, 16293; RV32I-NEXT: ret294;295; RV32ZBKB-LABEL: zext_i16_to_i32:296; RV32ZBKB: # %bb.0:297; RV32ZBKB-NEXT: zext.h a0, a0298; RV32ZBKB-NEXT: ret299 %1 = zext i16 %a to i32300 ret i32 %1301}302 303define i64 @zext_i16_to_i64(i16 %a) nounwind {304; RV32I-LABEL: zext_i16_to_i64:305; RV32I: # %bb.0:306; RV32I-NEXT: slli a0, a0, 16307; RV32I-NEXT: srli a0, a0, 16308; RV32I-NEXT: li a1, 0309; RV32I-NEXT: ret310;311; RV32ZBKB-LABEL: zext_i16_to_i64:312; RV32ZBKB: # %bb.0:313; RV32ZBKB-NEXT: zext.h a0, a0314; RV32ZBKB-NEXT: li a1, 0315; RV32ZBKB-NEXT: ret316 %1 = zext i16 %a to i64317 ret i64 %1318}319