diff --git a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp index 7f14e98b5bc6a..bc718b454ffb6 100644 --- a/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp +++ b/llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp @@ -87,6 +87,12 @@ class RISCVInstructionSelector : public InstructionSelector { ComplexRendererFns selectShiftMask(MachineOperand &Root) const; ComplexRendererFns selectAddrRegImm(MachineOperand &Root) const; + ComplexRendererFns selectZExtBits(MachineOperand &Root, unsigned Bits) const; + template + ComplexRendererFns selectZExtBits(MachineOperand &Root) const { + return selectZExtBits(Root, Bits); + } + ComplexRendererFns selectSHXADDOp(MachineOperand &Root, unsigned ShAmt) const; template ComplexRendererFns selectSHXADDOp(MachineOperand &Root) const { @@ -242,6 +248,24 @@ RISCVInstructionSelector::selectShiftMask(MachineOperand &Root) const { return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(ShAmtReg); }}}; } +InstructionSelector::ComplexRendererFns +RISCVInstructionSelector::selectZExtBits(MachineOperand &Root, + unsigned Bits) const { + if (!Root.isReg()) + return std::nullopt; + Register RootReg = Root.getReg(); + + Register RegX; + uint64_t Mask = maskTrailingOnes(Bits); + if (mi_match(RootReg, *MRI, m_GAnd(m_Reg(RegX), m_SpecificICst(Mask)))) { + return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(RegX); }}}; + } + + // TODO: Use computeKnownBits. + + return std::nullopt; +} + InstructionSelector::ComplexRendererFns RISCVInstructionSelector::selectSHXADDOp(MachineOperand &Root, unsigned ShAmt) const { diff --git a/llvm/lib/Target/RISCV/RISCVGISel.td b/llvm/lib/Target/RISCV/RISCVGISel.td index 40aae220fbd47..9f30875a11e79 100644 --- a/llvm/lib/Target/RISCV/RISCVGISel.td +++ b/llvm/lib/Target/RISCV/RISCVGISel.td @@ -96,6 +96,11 @@ def gi_sh2add_uw_op : GIComplexOperandMatcher">, def gi_sh3add_uw_op : GIComplexOperandMatcher">, GIComplexPatternEquiv; +def gi_zexti32 : GIComplexOperandMatcher">, + GIComplexPatternEquiv; +def gi_zexti16 : GIComplexOperandMatcher">, + GIComplexPatternEquiv; + // Ptr type used in patterns with GlobalISelEmitter def PtrVT : PtrValueTypeByHwMode; diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll index b6f13aa7227a7..529e821504405 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv32zbkb.ll @@ -16,9 +16,7 @@ define i32 @pack_i32(i32 %a, i32 %b) nounwind { ; ; RV32ZBKB-LABEL: pack_i32: ; RV32ZBKB: # %bb.0: -; RV32ZBKB-NEXT: zext.h a0, a0 -; RV32ZBKB-NEXT: slli a1, a1, 16 -; RV32ZBKB-NEXT: or a0, a1, a0 +; RV32ZBKB-NEXT: pack a0, a0, a1 ; RV32ZBKB-NEXT: ret %shl = and i32 %a, 65535 %shl1 = shl i32 %b, 16 diff --git a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll index 0a56b15dfbf09..8c5a2ec3dab4f 100644 --- a/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll +++ b/llvm/test/CodeGen/RISCV/GlobalISel/rv64zbkb.ll @@ -85,10 +85,7 @@ define i64 @pack_i64(i64 %a, i64 %b) nounwind { ; ; RV64ZBKB-LABEL: pack_i64: ; RV64ZBKB: # %bb.0: -; RV64ZBKB-NEXT: slli a0, a0, 32 -; RV64ZBKB-NEXT: srli a0, a0, 32 -; RV64ZBKB-NEXT: slli a1, a1, 32 -; RV64ZBKB-NEXT: or a0, a1, a0 +; RV64ZBKB-NEXT: pack a0, a0, a1 ; RV64ZBKB-NEXT: ret %shl = and i64 %a, 4294967295 %shl1 = shl i64 %b, 32 @@ -109,12 +106,9 @@ define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind { ; ; RV64ZBKB-LABEL: pack_i64_2: ; RV64ZBKB: # %bb.0: -; RV64ZBKB-NEXT: slli a0, a0, 32 -; RV64ZBKB-NEXT: srli a0, a0, 32 ; RV64ZBKB-NEXT: slli a1, a1, 32 ; RV64ZBKB-NEXT: srli a1, a1, 32 -; RV64ZBKB-NEXT: slli a1, a1, 32 -; RV64ZBKB-NEXT: or a0, a1, a0 +; RV64ZBKB-NEXT: pack a0, a0, a1 ; RV64ZBKB-NEXT: ret %zexta = zext i32 %a to i64 %zextb = zext i32 %b to i64 @@ -343,10 +337,7 @@ define i64 @pack_i64_allWUsers(i32 signext %0, i32 signext %1, i32 signext %2) { ; RV64ZBKB-NEXT: add a0, a1, a0 ; RV64ZBKB-NEXT: slli a0, a0, 32 ; RV64ZBKB-NEXT: srli a0, a0, 32 -; RV64ZBKB-NEXT: slli a0, a0, 32 -; RV64ZBKB-NEXT: slli a2, a2, 32 -; RV64ZBKB-NEXT: srli a2, a2, 32 -; RV64ZBKB-NEXT: or a0, a0, a2 +; RV64ZBKB-NEXT: pack a0, a2, a0 ; RV64ZBKB-NEXT: ret %4 = add i32 %1, %0 %5 = zext i32 %4 to i64