@@ -1615,28 +1615,37 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
16151615 SDValue Src1 = Node->getOperand (1 );
16161616 SDValue Src2 = Node->getOperand (2 );
16171617 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu;
1618- bool IsCmpUnsignedZero = false ;
1618+ bool IsCmpConstant = false ;
1619+ bool IsCmpMinimum = false ;
16191620 // Only custom select scalar second operand.
16201621 if (Src2.getValueType () != XLenVT)
16211622 break ;
16221623 // Small constants are handled with patterns.
1624+ int64_t CVal = 0 ;
1625+ MVT Src1VT = Src1.getSimpleValueType ();
16231626 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
1624- int64_t CVal = C->getSExtValue ();
1627+ IsCmpConstant = true ;
1628+ CVal = C->getSExtValue ();
16251629 if (CVal >= -15 && CVal <= 16 ) {
16261630 if (!IsUnsigned || CVal != 0 )
16271631 break ;
1628- IsCmpUnsignedZero = true ;
1632+ IsCmpMinimum = true ;
1633+ } else if (!IsUnsigned && CVal == APInt::getSignedMinValue (
1634+ Src1VT.getScalarSizeInBits ())
1635+ .getSExtValue ()) {
1636+ IsCmpMinimum = true ;
16291637 }
16301638 }
1631- MVT Src1VT = Src1.getSimpleValueType ();
1632- unsigned VMSLTOpcode, VMNANDOpcode, VMSetOpcode;
1639+ unsigned VMSLTOpcode, VMNANDOpcode, VMSetOpcode, VMSGTOpcode;
16331640 switch (RISCVTargetLowering::getLMUL (Src1VT)) {
16341641 default :
16351642 llvm_unreachable (" Unexpected LMUL!" );
16361643#define CASE_VMSLT_VMNAND_VMSET_OPCODES (lmulenum, suffix, suffix_b ) \
16371644 case RISCVII::VLMUL::lmulenum: \
16381645 VMSLTOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix \
16391646 : RISCV::PseudoVMSLT_VX_##suffix; \
1647+ VMSGTOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix \
1648+ : RISCV::PseudoVMSGT_VX_##suffix; \
16401649 VMNANDOpcode = RISCV::PseudoVMNAND_MM_##suffix; \
16411650 VMSetOpcode = RISCV::PseudoVMSET_M_##suffix_b; \
16421651 break ;
@@ -1654,12 +1663,21 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
16541663 SDValue VL;
16551664 selectVLOp (Node->getOperand (3 ), VL);
16561665
1657- // If vmsgeu with 0 immediate , expand it to vmset.
1658- if (IsCmpUnsignedZero ) {
1666+ // If vmsge(u) with minimum value , expand it to vmset.
1667+ if (IsCmpMinimum ) {
16591668 ReplaceNode (Node, CurDAG->getMachineNode (VMSetOpcode, DL, VT, VL, SEW));
16601669 return ;
16611670 }
16621671
1672+ if (IsCmpConstant) {
1673+ SDValue Imm =
1674+ selectImm (CurDAG, SDLoc (Src2), XLenVT, CVal - 1 , *Subtarget);
1675+
1676+ ReplaceNode (Node, CurDAG->getMachineNode (VMSGTOpcode, DL, VT,
1677+ {Src1, Imm, VL, SEW}));
1678+ return ;
1679+ }
1680+
16631681 // Expand to
16641682 // vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
16651683 SDValue Cmp = SDValue (
@@ -1674,22 +1692,29 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
16741692 SDValue Src1 = Node->getOperand (2 );
16751693 SDValue Src2 = Node->getOperand (3 );
16761694 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu_mask;
1677- bool IsCmpUnsignedZero = false ;
1695+ bool IsCmpConstant = false ;
1696+ bool IsCmpMinimum = false ;
16781697 // Only custom select scalar second operand.
16791698 if (Src2.getValueType () != XLenVT)
16801699 break ;
16811700 // Small constants are handled with patterns.
1701+ MVT Src1VT = Src1.getSimpleValueType ();
1702+ int64_t CVal = 0 ;
16821703 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
1683- int64_t CVal = C->getSExtValue ();
1704+ IsCmpConstant = true ;
1705+ CVal = C->getSExtValue ();
16841706 if (CVal >= -15 && CVal <= 16 ) {
16851707 if (!IsUnsigned || CVal != 0 )
16861708 break ;
1687- IsCmpUnsignedZero = true ;
1709+ IsCmpMinimum = true ;
1710+ } else if (!IsUnsigned && CVal == APInt::getSignedMinValue (
1711+ Src1VT.getScalarSizeInBits ())
1712+ .getSExtValue ()) {
1713+ IsCmpMinimum = true ;
16881714 }
16891715 }
1690- MVT Src1VT = Src1.getSimpleValueType ();
16911716 unsigned VMSLTOpcode, VMSLTMaskOpcode, VMXOROpcode, VMANDNOpcode,
1692- VMOROpcode;
1717+ VMOROpcode, VMSGTMaskOpcode ;
16931718 switch (RISCVTargetLowering::getLMUL (Src1VT)) {
16941719 default :
16951720 llvm_unreachable (" Unexpected LMUL!" );
@@ -1699,6 +1724,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
16991724 : RISCV::PseudoVMSLT_VX_##suffix; \
17001725 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix##_MASK \
17011726 : RISCV::PseudoVMSLT_VX_##suffix##_MASK; \
1727+ VMSGTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix##_MASK \
1728+ : RISCV::PseudoVMSGT_VX_##suffix##_MASK; \
17021729 break ;
17031730 CASE_VMSLT_OPCODES (LMUL_F8, MF8, B1)
17041731 CASE_VMSLT_OPCODES (LMUL_F4, MF4, B2)
@@ -1736,8 +1763,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
17361763 SDValue MaskedOff = Node->getOperand (1 );
17371764 SDValue Mask = Node->getOperand (4 );
17381765
1739- // If vmsgeu_mask with 0 immediate , expand it to vmor mask, maskedoff.
1740- if (IsCmpUnsignedZero ) {
1766+ // If vmsge(u) with minimum value , expand it to vmor mask, maskedoff.
1767+ if (IsCmpMinimum ) {
17411768 // We don't need vmor if the MaskedOff and the Mask are the same
17421769 // value.
17431770 if (Mask == MaskedOff) {
@@ -1768,6 +1795,16 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
17681795 SDValue Glue = Chain.getValue (1 );
17691796 SDValue V0 = CurDAG->getRegister (RISCV::V0, VT);
17701797
1798+ if (IsCmpConstant) {
1799+ SDValue Imm =
1800+ selectImm (CurDAG, SDLoc (Src2), XLenVT, CVal - 1 , *Subtarget);
1801+
1802+ ReplaceNode (Node, CurDAG->getMachineNode (
1803+ VMSGTMaskOpcode, DL, VT,
1804+ {MaskedOff, Src1, Imm, V0, VL, SEW, Glue}));
1805+ return ;
1806+ }
1807+
17711808 // Otherwise use
17721809 // vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
17731810 // The result is mask undisturbed.
0 commit comments