diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index bc718b454ffb6..389bdbe6d5e91 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -261,7 +261,9 @@ RISCVInstructionSelector::selectZExtBits(MachineOperand &Root, return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}}; } - // TODO: Use computeKnownBits. + unsigned Size = MRI->getType(RootReg).getScalarSizeInBits(); + if (KB->maskedValueIsZero(RootReg, APInt::getBitsSetFrom(Size, Bits))) + return {{[=](MachineInstrBuilder &MIB) { MIB.add(Root); }}}; return std::nullopt; } diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll index bb21bb5721c66..d9b093448cb46 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll @@ -25,11 +25,16 @@ define i32 @pack_i32(i32 %a, i32 %b) nounwind { } define i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind { -; CHECK-LABEL: pack_i32_2: -; CHECK: # %bb.0: -; CHECK-NEXT: slli a1, a1, 16 -; CHECK-NEXT: or a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: pack_i32_2: +; RV32I: # %bb.0: +; RV32I-NEXT: slli a1, a1, 16 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: ret +; +; RV32ZBKB-LABEL: pack_i32_2: +; RV32ZBKB: # %bb.0: +; RV32ZBKB-NEXT: pack a0, a0, a1 +; RV32ZBKB-NEXT: ret %zexta = zext i16 %a to i32 %zextb = zext i16 %b to i32 %shl1 = shl i32 %zextb, 16 @@ -38,12 +43,18 @@ define i32 @pack_i32_2(i16 zeroext %a, i16 zeroext %b) nounwind { } define i32 @pack_i32_3(i16 zeroext %0, i16 zeroext %1, i32 %2) { -; CHECK-LABEL: pack_i32_3: -; CHECK: # %bb.0: -; CHECK-NEXT: slli a0, a0, 16 -; CHECK-NEXT: or a0, a0, a1 -; CHECK-NEXT: add a0, a0, a2 -; CHECK-NEXT: ret +; RV32I-LABEL: pack_i32_3: +; RV32I: # %bb.0: +; RV32I-NEXT: slli a0, a0, 16 +; RV32I-NEXT: or a0, a0, a1 +; RV32I-NEXT: add a0, a0, a2 +; RV32I-NEXT: ret +; +; RV32ZBKB-LABEL: pack_i32_3: +; RV32ZBKB: # %bb.0: +; RV32ZBKB-NEXT: pack a0, a1, a0 +; RV32ZBKB-NEXT: add a0, a0, a2 +; RV32ZBKB-NEXT: ret %4 = zext i16 %0 to i32 %5 = shl nuw i32 %4, 16 %6 = zext i16 %1 to i32 @@ -175,11 +186,16 @@ define i64 @packh_i64_2(i64 %a, i64 %b) nounwind { define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind { -; CHECK-LABEL: packh_i16: -; CHECK: # %bb.0: -; CHECK-NEXT: slli a1, a1, 8 -; CHECK-NEXT: or a0, a1, a0 -; CHECK-NEXT: ret +; RV32I-LABEL: packh_i16: +; RV32I: # %bb.0: +; RV32I-NEXT: slli a1, a1, 8 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: ret +; +; RV32ZBKB-LABEL: packh_i16: +; RV32ZBKB: # %bb.0: +; RV32ZBKB-NEXT: packh a0, a0, a1 +; RV32ZBKB-NEXT: ret %zext = zext i8 %a to i16 %zext1 = zext i8 %b to i16 %shl = shl i16 %zext1, 8 @@ -189,13 +205,19 @@ define zeroext i16 @packh_i16(i8 zeroext %a, i8 zeroext %b) nounwind { define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) { -; CHECK-LABEL: packh_i16_2: -; CHECK: # %bb.0: -; CHECK-NEXT: add a0, a1, a0 -; CHECK-NEXT: andi a0, a0, 255 -; CHECK-NEXT: slli a0, a0, 8 -; CHECK-NEXT: or a0, a0, a2 -; CHECK-NEXT: ret +; RV32I-LABEL: packh_i16_2: +; RV32I: # %bb.0: +; RV32I-NEXT: add a0, a1, a0 +; RV32I-NEXT: andi a0, a0, 255 +; RV32I-NEXT: slli a0, a0, 8 +; RV32I-NEXT: or a0, a0, a2 +; RV32I-NEXT: ret +; +; RV32ZBKB-LABEL: packh_i16_2: +; RV32ZBKB: # %bb.0: +; RV32ZBKB-NEXT: add a0, a1, a0 +; RV32ZBKB-NEXT: packh a0, a2, a0 +; RV32ZBKB-NEXT: ret %4 = add i8 %1, %0 %5 = zext i8 %4 to i16 %6 = shl i16 %5, 8 @@ -205,14 +227,21 @@ define zeroext i16 @packh_i16_2(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2) { } define void @packh_i16_3(i8 zeroext %0, i8 zeroext %1, i8 zeroext %2, ptr %p) { -; CHECK-LABEL: packh_i16_3: -; CHECK: # %bb.0: -; CHECK-NEXT: add a0, a1, a0 -; CHECK-NEXT: andi a0, a0, 255 -; CHECK-NEXT: slli a0, a0, 8 -; CHECK-NEXT: or a0, a0, a2 -; CHECK-NEXT: sh a0, 0(a3) -; CHECK-NEXT: ret +; RV32I-LABEL: packh_i16_3: +; RV32I: # %bb.0: +; RV32I-NEXT: add a0, a1, a0 +; RV32I-NEXT: andi a0, a0, 255 +; RV32I-NEXT: slli a0, a0, 8 +; RV32I-NEXT: or a0, a0, a2 +; RV32I-NEXT: sh a0, 0(a3) +; RV32I-NEXT: ret +; +; RV32ZBKB-LABEL: packh_i16_3: +; RV32ZBKB: # %bb.0: +; RV32ZBKB-NEXT: add a0, a1, a0 +; RV32ZBKB-NEXT: packh a0, a2, a0 +; RV32ZBKB-NEXT: sh a0, 0(a3) +; RV32ZBKB-NEXT: ret %4 = add i8 %1, %0 %5 = zext i8 %4 to i16 %6 = shl i16 %5, 8 diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll index abeefb3b1c97f..6b57b179240d7 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll @@ -130,8 +130,7 @@ define i64 @pack_i64_3(ptr %0, ptr %1) { ; RV64ZBKB: # %bb.0: ; RV64ZBKB-NEXT: lwu a0, 0(a0) ; RV64ZBKB-NEXT: lwu a1, 0(a1) -; RV64ZBKB-NEXT: slli a0, a0, 32 -; RV64ZBKB-NEXT: or a0, a0, a1 +; RV64ZBKB-NEXT: pack a0, a1, a0 ; RV64ZBKB-NEXT: ret %3 = load i32, ptr %0, align 4 %4 = zext i32 %3 to i64