@@ -1616,28 +1616,37 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
16161616 SDValue Src1 = Node->getOperand (1 );
16171617 SDValue Src2 = Node->getOperand (2 );
16181618 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu;
1619- bool IsCmpUnsignedZero = false ;
1619+ bool IsCmpConstant = false ;
1620+ bool IsCmpMinimum = false ;
16201621 // Only custom select scalar second operand.
16211622 if (Src2.getValueType () != XLenVT)
16221623 break ;
16231624 // Small constants are handled with patterns.
1625+ int64_t CVal = 0 ;
1626+ MVT Src1VT = Src1.getSimpleValueType ();
16241627 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
1625- int64_t CVal = C->getSExtValue ();
1628+ IsCmpConstant = true ;
1629+ CVal = C->getSExtValue ();
16261630 if (CVal >= -15 && CVal <= 16 ) {
16271631 if (!IsUnsigned || CVal != 0 )
16281632 break ;
1629- IsCmpUnsignedZero = true ;
1633+ IsCmpMinimum = true ;
1634+ } else if (!IsUnsigned &&
1635+ CVal == APSInt::getMinValue (Src1VT.getScalarSizeInBits (),
1636+ /* Unsigned=*/ false )) {
1637+ IsCmpMinimum = true ;
16301638 }
16311639 }
1632- MVT Src1VT = Src1.getSimpleValueType ();
1633- unsigned VMSLTOpcode, VMNANDOpcode, VMSetOpcode;
1640+ unsigned VMSLTOpcode, VMNANDOpcode, VMSetOpcode, VMSGTOpcode;
16341641 switch (RISCVTargetLowering::getLMUL (Src1VT)) {
16351642 default :
16361643 llvm_unreachable (" Unexpected LMUL!" );
16371644#define CASE_VMSLT_VMNAND_VMSET_OPCODES (lmulenum, suffix, suffix_b ) \
16381645 case RISCVII::VLMUL::lmulenum: \
16391646 VMSLTOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix \
16401647 : RISCV::PseudoVMSLT_VX_##suffix; \
1648+ VMSGTOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix \
1649+ : RISCV::PseudoVMSGT_VX_##suffix; \
16411650 VMNANDOpcode = RISCV::PseudoVMNAND_MM_##suffix; \
16421651 VMSetOpcode = RISCV::PseudoVMSET_M_##suffix_b; \
16431652 break ;
@@ -1656,11 +1665,20 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
16561665 selectVLOp (Node->getOperand (3 ), VL);
16571666
16581667 // If vmsgeu with 0 immediate, expand it to vmset.
1659- if (IsCmpUnsignedZero ) {
1668+ if (IsCmpMinimum ) {
16601669 ReplaceNode (Node, CurDAG->getMachineNode (VMSetOpcode, DL, VT, VL, SEW));
16611670 return ;
16621671 }
16631672
1673+ if (IsCmpConstant) {
1674+ SDValue Imm =
1675+ selectImm (CurDAG, SDLoc (Src2), XLenVT, CVal - 1 , *Subtarget);
1676+
1677+ ReplaceNode (Node, CurDAG->getMachineNode (VMSGTOpcode, DL, VT,
1678+ {Src1, Imm, VL, SEW}));
1679+ return ;
1680+ }
1681+
16641682 // Expand to
16651683 // vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
16661684 SDValue Cmp = SDValue (
@@ -1675,22 +1693,29 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
16751693 SDValue Src1 = Node->getOperand (2 );
16761694 SDValue Src2 = Node->getOperand (3 );
16771695 bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu_mask;
1678- bool IsCmpUnsignedZero = false ;
1696+ bool IsCmpConstant = false ;
1697+ bool IsCmpMinimum = false ;
16791698 // Only custom select scalar second operand.
16801699 if (Src2.getValueType () != XLenVT)
16811700 break ;
16821701 // Small constants are handled with patterns.
1702+ MVT Src1VT = Src1.getSimpleValueType ();
1703+ int64_t CVal = 0 ;
16831704 if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
1684- int64_t CVal = C->getSExtValue ();
1705+ IsCmpConstant = true ;
1706+ CVal = C->getSExtValue ();
16851707 if (CVal >= -15 && CVal <= 16 ) {
16861708 if (!IsUnsigned || CVal != 0 )
16871709 break ;
1688- IsCmpUnsignedZero = true ;
1710+ IsCmpMinimum = true ;
1711+ } else if (!IsUnsigned &&
1712+ CVal == APSInt::getMinValue (Src1VT.getScalarSizeInBits (),
1713+ /* Unsigned=*/ false )) {
1714+ IsCmpMinimum = true ;
16891715 }
16901716 }
1691- MVT Src1VT = Src1.getSimpleValueType ();
16921717 unsigned VMSLTOpcode, VMSLTMaskOpcode, VMXOROpcode, VMANDNOpcode,
1693- VMOROpcode;
1718+ VMOROpcode, VMSGTMaskOpcode ;
16941719 switch (RISCVTargetLowering::getLMUL (Src1VT)) {
16951720 default :
16961721 llvm_unreachable (" Unexpected LMUL!" );
@@ -1700,6 +1725,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
17001725 : RISCV::PseudoVMSLT_VX_##suffix; \
17011726 VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix##_MASK \
17021727 : RISCV::PseudoVMSLT_VX_##suffix##_MASK; \
1728+ VMSGTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix##_MASK \
1729+ : RISCV::PseudoVMSGT_VX_##suffix##_MASK; \
17031730 break ;
17041731 CASE_VMSLT_OPCODES (LMUL_F8, MF8, B1)
17051732 CASE_VMSLT_OPCODES (LMUL_F4, MF4, B2)
@@ -1738,7 +1765,7 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
17381765 SDValue Mask = Node->getOperand (4 );
17391766
17401767 // If vmsgeu_mask with 0 immediate, expand it to vmor mask, maskedoff.
1741- if (IsCmpUnsignedZero ) {
1768+ if (IsCmpMinimum ) {
17421769 // We don't need vmor if the MaskedOff and the Mask are the same
17431770 // value.
17441771 if (Mask == MaskedOff) {
@@ -1769,6 +1796,16 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
17691796 SDValue Glue = Chain.getValue (1 );
17701797 SDValue V0 = CurDAG->getRegister (RISCV::V0, VT);
17711798
1799+ if (IsCmpConstant) {
1800+ SDValue Imm =
1801+ selectImm (CurDAG, SDLoc (Src2), XLenVT, CVal - 1 , *Subtarget);
1802+
1803+ ReplaceNode (Node, CurDAG->getMachineNode (
1804+ VMSGTMaskOpcode, DL, VT,
1805+ {MaskedOff, Src1, Imm, V0, VL, SEW, Glue}));
1806+ return ;
1807+ }
1808+
17721809 // Otherwise use
17731810 // vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
17741811 // The result is mask undisturbed.
0 commit comments