461 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=+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 108define i32 @packh_i32(i32 %a, i32 %b) nounwind {109; RV32I-LABEL: packh_i32:110; RV32I: # %bb.0:111; RV32I-NEXT: zext.b a0, a0112; RV32I-NEXT: slli a1, a1, 24113; RV32I-NEXT: srli a1, a1, 16114; RV32I-NEXT: or a0, a1, a0115; RV32I-NEXT: ret116;117; RV32ZBKB-LABEL: packh_i32:118; RV32ZBKB: # %bb.0:119; RV32ZBKB-NEXT: packh a0, a0, a1120; RV32ZBKB-NEXT: ret121 %and = and i32 %a, 255122 %and1 = shl i32 %b, 8123 %shl = and i32 %and1, 65280124 %or = or i32 %shl, %and125 ret i32 %or126}127 128define i32 @packh_i32_2(i32 %a, i32 %b) nounwind {129; RV32I-LABEL: packh_i32_2:130; RV32I: # %bb.0:131; RV32I-NEXT: zext.b a0, a0132; RV32I-NEXT: zext.b a1, a1133; RV32I-NEXT: slli a1, a1, 8134; RV32I-NEXT: or a0, a1, a0135; RV32I-NEXT: ret136;137; RV32ZBKB-LABEL: packh_i32_2:138; RV32ZBKB: # %bb.0:139; RV32ZBKB-NEXT: packh a0, a0, a1140; RV32ZBKB-NEXT: ret141 %and = and i32 %a, 255142 %and1 = and i32 %b, 255143 %shl = shl i32 %and1, 8144 %or = or i32 %shl, %and145 ret i32 %or146}147 148define i64 @packh_i64(i64 %a, i64 %b) nounwind {149; RV32I-LABEL: packh_i64:150; RV32I: # %bb.0:151; RV32I-NEXT: zext.b a0, a0152; RV32I-NEXT: slli a2, a2, 24153; RV32I-NEXT: srli a2, a2, 16154; RV32I-NEXT: or a0, a2, a0155; RV32I-NEXT: li a1, 0156; RV32I-NEXT: ret157;158; RV32ZBKB-LABEL: packh_i64:159; RV32ZBKB: # %bb.0:160; RV32ZBKB-NEXT: packh a0, a0, a2161; RV32ZBKB-NEXT: li a1, 0162; RV32ZBKB-NEXT: ret163 %and = and i64 %a, 255164 %and1 = shl i64 %b, 8165 %shl = and i64 %and1, 65280166 %or = or i64 %shl, %and167 ret i64 %or168}169 170define i64 @packh_i64_2(i64 %a, i64 %b) nounwind {171; RV32I-LABEL: packh_i64_2:172; RV32I: # %bb.0:173; RV32I-NEXT: zext.b a0, a0174; RV32I-NEXT: zext.b a1, a2175; RV32I-NEXT: slli a1, a1, 8176; RV32I-NEXT: or a0, a1, a0177; RV32I-NEXT: li a1, 0178; RV32I-NEXT: ret179;180; RV32ZBKB-LABEL: packh_i64_2:181; RV32ZBKB: # %bb.0:182; RV32ZBKB-NEXT: packh a0, a0, a2183; RV32ZBKB-NEXT: li a1, 0184; RV32ZBKB-NEXT: ret185 %and = and i64 %a, 255186 %and1 = and i64 %b, 255187 %shl = shl i64 %and1, 8188 %or = or i64 %shl, %and189 ret i64 %or190}191 192 193define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind {194; RV32I-LABEL: packh_i16:195; RV32I: # %bb.0:196; RV32I-NEXT: slli a1, a1, 8197; RV32I-NEXT: or a0, a1, a0198; RV32I-NEXT: ret199;200; RV32ZBKB-LABEL: packh_i16:201; RV32ZBKB: # %bb.0:202; RV32ZBKB-NEXT: packh a0, a0, a1203; RV32ZBKB-NEXT: ret204 %zext = zext i8 %a to i16205 %zext1 = zext i8 %b to i16206 %shl = shl i16 %zext1, 8207 %or = or i16 %shl, %zext208 ret i16 %or209}210 211 212define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) {213; RV32I-LABEL: packh_i16_2:214; RV32I: # %bb.0:215; RV32I-NEXT: add a0, a1, a0216; RV32I-NEXT: slli a0, a0, 8217; RV32I-NEXT: or a0, a0, a2218; RV32I-NEXT: slli a0, a0, 16219; RV32I-NEXT: srli a0, a0, 16220; RV32I-NEXT: ret221;222; RV32ZBKB-LABEL: packh_i16_2:223; RV32ZBKB: # %bb.0:224; RV32ZBKB-NEXT: add a0, a1, a0225; RV32ZBKB-NEXT: packh a0, a2, a0226; RV32ZBKB-NEXT: ret227 %4 = add i8 %1, %0228 %5 = zext i8 %4 to i16229 %6 = shl i16 %5, 8230 %7 = zext i8 %2 to i16231 %8 = or i16 %6, %7232 ret i16 %8233}234 235define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) {236; RV32I-LABEL: packh_i16_3:237; RV32I: # %bb.0:238; RV32I-NEXT: add a0, a1, a0239; RV32I-NEXT: slli a0, a0, 8240; RV32I-NEXT: or a0, a0, a2241; RV32I-NEXT: sh a0, 0(a3)242; RV32I-NEXT: ret243;244; RV32ZBKB-LABEL: packh_i16_3:245; RV32ZBKB: # %bb.0:246; RV32ZBKB-NEXT: add a0, a1, a0247; RV32ZBKB-NEXT: packh a0, a2, a0248; RV32ZBKB-NEXT: sh a0, 0(a3)249; RV32ZBKB-NEXT: ret250 %4 = add i8 %1, %0251 %5 = zext i8 %4 to i16252 %6 = shl i16 %5, 8253 %7 = zext i8 %2 to i16254 %8 = or i16 %6, %7255 store i16 %8, ptr %p256 ret void257}258 259define i32 @zexth_i32(i32 %a) nounwind {260; RV32I-LABEL: zexth_i32:261; RV32I: # %bb.0:262; RV32I-NEXT: slli a0, a0, 16263; RV32I-NEXT: srli a0, a0, 16264; RV32I-NEXT: ret265;266; RV32ZBKB-LABEL: zexth_i32:267; RV32ZBKB: # %bb.0:268; RV32ZBKB-NEXT: zext.h a0, a0269; RV32ZBKB-NEXT: ret270 %and = and i32 %a, 65535271 ret i32 %and272}273 274define i64 @zexth_i64(i64 %a) nounwind {275; RV32I-LABEL: zexth_i64:276; RV32I: # %bb.0:277; RV32I-NEXT: slli a0, a0, 16278; RV32I-NEXT: srli a0, a0, 16279; RV32I-NEXT: li a1, 0280; RV32I-NEXT: ret281;282; RV32ZBKB-LABEL: zexth_i64:283; RV32ZBKB: # %bb.0:284; RV32ZBKB-NEXT: zext.h a0, a0285; RV32ZBKB-NEXT: li a1, 0286; RV32ZBKB-NEXT: ret287 %and = and i64 %a, 65535288 ret i64 %and289}290 291define i32 @zext_i16_to_i32(i16 %a) nounwind {292; RV32I-LABEL: zext_i16_to_i32:293; RV32I: # %bb.0:294; RV32I-NEXT: slli a0, a0, 16295; RV32I-NEXT: srli a0, a0, 16296; RV32I-NEXT: ret297;298; RV32ZBKB-LABEL: zext_i16_to_i32:299; RV32ZBKB: # %bb.0:300; RV32ZBKB-NEXT: zext.h a0, a0301; RV32ZBKB-NEXT: ret302 %1 = zext i16 %a to i32303 ret i32 %1304}305 306define i64 @zext_i16_to_i64(i16 %a) nounwind {307; RV32I-LABEL: zext_i16_to_i64:308; RV32I: # %bb.0:309; RV32I-NEXT: slli a0, a0, 16310; RV32I-NEXT: srli a0, a0, 16311; RV32I-NEXT: li a1, 0312; RV32I-NEXT: ret313;314; RV32ZBKB-LABEL: zext_i16_to_i64:315; RV32ZBKB: # %bb.0:316; RV32ZBKB-NEXT: zext.h a0, a0317; RV32ZBKB-NEXT: li a1, 0318; RV32ZBKB-NEXT: ret319 %1 = zext i16 %a to i64320 ret i64 %1321}322 323define i32 @pack_lo_packh_hi_packh(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, i8 zeroext %3) nounwind {324; RV32I-LABEL: pack_lo_packh_hi_packh:325; RV32I: # %bb.0:326; RV32I-NEXT: slli a1, a1, 8327; RV32I-NEXT: slli a2, a2, 16328; RV32I-NEXT: slli a3, a3, 24329; RV32I-NEXT: or a0, a0, a1330; RV32I-NEXT: or a2, a2, a3331; RV32I-NEXT: or a0, a0, a2332; RV32I-NEXT: ret333;334; RV32ZBKB-LABEL: pack_lo_packh_hi_packh:335; RV32ZBKB: # %bb.0:336; RV32ZBKB-NEXT: packh a0, a0, a1337; RV32ZBKB-NEXT: packh a1, a2, a3338; RV32ZBKB-NEXT: pack a0, a0, a1339; RV32ZBKB-NEXT: ret340 %a = zext i8 %0 to i32341 %b = zext i8 %1 to i32342 %c = zext i8 %2 to i32343 %d = zext i8 %3 to i32344 %e = shl i32 %b, 8345 %f = shl i32 %c, 16346 %g = shl i32 %d, 24347 %h = or i32 %a, %e348 %i = or i32 %h, %f349 %j = or i32 %i, %g350 ret i32 %j351}352 353define i32 @pack_lo_packh_hi_packh_2(i8 %0, i8 %1, i8 %2, i8 %3) nounwind {354; RV32I-LABEL: pack_lo_packh_hi_packh_2:355; RV32I: # %bb.0:356; RV32I-NEXT: zext.b a0, a0357; RV32I-NEXT: zext.b a1, a1358; RV32I-NEXT: zext.b a2, a2359; RV32I-NEXT: slli a3, a3, 24360; RV32I-NEXT: slli a1, a1, 8361; RV32I-NEXT: slli a2, a2, 16362; RV32I-NEXT: or a0, a0, a1363; RV32I-NEXT: or a2, a2, a3364; RV32I-NEXT: or a0, a0, a2365; RV32I-NEXT: ret366;367; RV32ZBKB-LABEL: pack_lo_packh_hi_packh_2:368; RV32ZBKB: # %bb.0:369; RV32ZBKB-NEXT: packh a0, a0, a1370; RV32ZBKB-NEXT: packh a1, a2, a3371; RV32ZBKB-NEXT: pack a0, a0, a1372; RV32ZBKB-NEXT: ret373 %a = zext i8 %0 to i32374 %b = zext i8 %1 to i32375 %c = zext i8 %2 to i32376 %d = zext i8 %3 to i32377 %e = shl i32 %b, 8378 %f = shl i32 %c, 16379 %g = shl i32 %d, 24380 %h = or i32 %a, %e381 %i = or i32 %h, %f382 %j = or i32 %i, %g383 ret i32 %j384}385 386define i32 @pack_lo_zext_hi_packh(i16 zeroext %0, i8 zeroext %1, i8 zeroext %2) nounwind {387; RV32I-LABEL: pack_lo_zext_hi_packh:388; RV32I: # %bb.0:389; RV32I-NEXT: slli a1, a1, 16390; RV32I-NEXT: slli a2, a2, 24391; RV32I-NEXT: or a1, a2, a1392; RV32I-NEXT: or a0, a1, a0393; RV32I-NEXT: ret394;395; RV32ZBKB-LABEL: pack_lo_zext_hi_packh:396; RV32ZBKB: # %bb.0:397; RV32ZBKB-NEXT: packh a1, a1, a2398; RV32ZBKB-NEXT: pack a0, a0, a1399; RV32ZBKB-NEXT: ret400 %a = zext i16 %0 to i32401 %b = zext i8 %1 to i32402 %c = zext i8 %2 to i32403 %d = shl i32 %c, 8404 %e = or i32 %b, %d405 %f = shl i32 %e, 16406 %g = or i32 %f, %a407 ret i32 %g408}409 410; Negative test, %a isn't extended so we can't use pack for the outer or, but411; we can use packh for the high half.412define i32 @pack_lo_noext_hi_packh(i32 %a, i8 zeroext %1, i8 zeroext %2) nounwind {413; RV32I-LABEL: pack_lo_noext_hi_packh:414; RV32I: # %bb.0:415; RV32I-NEXT: slli a1, a1, 16416; RV32I-NEXT: slli a2, a2, 24417; RV32I-NEXT: or a1, a2, a1418; RV32I-NEXT: or a0, a1, a0419; RV32I-NEXT: ret420;421; RV32ZBKB-LABEL: pack_lo_noext_hi_packh:422; RV32ZBKB: # %bb.0:423; RV32ZBKB-NEXT: packh a1, a1, a2424; RV32ZBKB-NEXT: slli a1, a1, 16425; RV32ZBKB-NEXT: or a0, a1, a0426; RV32ZBKB-NEXT: ret427 %b = zext i8 %1 to i32428 %c = zext i8 %2 to i32429 %d = shl i32 %c, 8430 %e = or i32 %b, %d431 %f = shl i32 %e, 16432 %g = or i32 %f, %a433 ret i32 %g434}435 436; Make sure we can match packh+slli without having the input bytes zero extended.437define i32 @pack_lo_noext_hi_packh_nozeroext(i32 %a, i8 %1, i8 %2) nounwind {438; RV32I-LABEL: pack_lo_noext_hi_packh_nozeroext:439; RV32I: # %bb.0:440; RV32I-NEXT: zext.b a1, a1441; RV32I-NEXT: slli a2, a2, 24442; RV32I-NEXT: slli a1, a1, 16443; RV32I-NEXT: or a0, a2, a0444; RV32I-NEXT: or a0, a0, a1445; RV32I-NEXT: ret446;447; RV32ZBKB-LABEL: pack_lo_noext_hi_packh_nozeroext:448; RV32ZBKB: # %bb.0:449; RV32ZBKB-NEXT: packh a1, a1, a2450; RV32ZBKB-NEXT: slli a1, a1, 16451; RV32ZBKB-NEXT: or a0, a1, a0452; RV32ZBKB-NEXT: ret453 %b = zext i8 %1 to i32454 %c = zext i8 %2 to i32455 %d = shl i32 %c, 8456 %e = or i32 %b, %d457 %f = shl i32 %e, 16458 %g = or i32 %f, %a459 ret i32 %g460}461