@@ -1615,28 +1615,37 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
1615
1615
SDValue Src1 = Node->getOperand (1 );
1616
1616
SDValue Src2 = Node->getOperand (2 );
1617
1617
bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu;
1618
- bool IsCmpUnsignedZero = false ;
1618
+ bool IsCmpConstant = false ;
1619
+ bool IsCmpMinimum = false ;
1619
1620
// Only custom select scalar second operand.
1620
1621
if (Src2.getValueType () != XLenVT)
1621
1622
break ;
1622
1623
// Small constants are handled with patterns.
1624
+ int64_t CVal = 0 ;
1625
+ MVT Src1VT = Src1.getSimpleValueType ();
1623
1626
if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
1624
- int64_t CVal = C->getSExtValue ();
1627
+ IsCmpConstant = true ;
1628
+ CVal = C->getSExtValue ();
1625
1629
if (CVal >= -15 && CVal <= 16 ) {
1626
1630
if (!IsUnsigned || CVal != 0 )
1627
1631
break ;
1628
- IsCmpUnsignedZero = true ;
1632
+ IsCmpMinimum = true ;
1633
+ } else if (!IsUnsigned && CVal == APInt::getSignedMinValue (
1634
+ Src1VT.getScalarSizeInBits ())
1635
+ .getSExtValue ()) {
1636
+ IsCmpMinimum = true ;
1629
1637
}
1630
1638
}
1631
- MVT Src1VT = Src1.getSimpleValueType ();
1632
- unsigned VMSLTOpcode, VMNANDOpcode, VMSetOpcode;
1639
+ unsigned VMSLTOpcode, VMNANDOpcode, VMSetOpcode, VMSGTOpcode;
1633
1640
switch (RISCVTargetLowering::getLMUL (Src1VT)) {
1634
1641
default :
1635
1642
llvm_unreachable (" Unexpected LMUL!" );
1636
1643
#define CASE_VMSLT_VMNAND_VMSET_OPCODES (lmulenum, suffix, suffix_b ) \
1637
1644
case RISCVII::VLMUL::lmulenum: \
1638
1645
VMSLTOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix \
1639
1646
: RISCV::PseudoVMSLT_VX_##suffix; \
1647
+ VMSGTOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix \
1648
+ : RISCV::PseudoVMSGT_VX_##suffix; \
1640
1649
VMNANDOpcode = RISCV::PseudoVMNAND_MM_##suffix; \
1641
1650
VMSetOpcode = RISCV::PseudoVMSET_M_##suffix_b; \
1642
1651
break ;
@@ -1654,12 +1663,21 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
1654
1663
SDValue VL;
1655
1664
selectVLOp (Node->getOperand (3 ), VL);
1656
1665
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 ) {
1659
1668
ReplaceNode (Node, CurDAG->getMachineNode (VMSetOpcode, DL, VT, VL, SEW));
1660
1669
return ;
1661
1670
}
1662
1671
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
+
1663
1681
// Expand to
1664
1682
// vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd
1665
1683
SDValue Cmp = SDValue (
@@ -1674,22 +1692,29 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
1674
1692
SDValue Src1 = Node->getOperand (2 );
1675
1693
SDValue Src2 = Node->getOperand (3 );
1676
1694
bool IsUnsigned = IntNo == Intrinsic::riscv_vmsgeu_mask;
1677
- bool IsCmpUnsignedZero = false ;
1695
+ bool IsCmpConstant = false ;
1696
+ bool IsCmpMinimum = false ;
1678
1697
// Only custom select scalar second operand.
1679
1698
if (Src2.getValueType () != XLenVT)
1680
1699
break ;
1681
1700
// Small constants are handled with patterns.
1701
+ MVT Src1VT = Src1.getSimpleValueType ();
1702
+ int64_t CVal = 0 ;
1682
1703
if (auto *C = dyn_cast<ConstantSDNode>(Src2)) {
1683
- int64_t CVal = C->getSExtValue ();
1704
+ IsCmpConstant = true ;
1705
+ CVal = C->getSExtValue ();
1684
1706
if (CVal >= -15 && CVal <= 16 ) {
1685
1707
if (!IsUnsigned || CVal != 0 )
1686
1708
break ;
1687
- IsCmpUnsignedZero = true ;
1709
+ IsCmpMinimum = true ;
1710
+ } else if (!IsUnsigned && CVal == APInt::getSignedMinValue (
1711
+ Src1VT.getScalarSizeInBits ())
1712
+ .getSExtValue ()) {
1713
+ IsCmpMinimum = true ;
1688
1714
}
1689
1715
}
1690
- MVT Src1VT = Src1.getSimpleValueType ();
1691
1716
unsigned VMSLTOpcode, VMSLTMaskOpcode, VMXOROpcode, VMANDNOpcode,
1692
- VMOROpcode;
1717
+ VMOROpcode, VMSGTMaskOpcode ;
1693
1718
switch (RISCVTargetLowering::getLMUL (Src1VT)) {
1694
1719
default :
1695
1720
llvm_unreachable (" Unexpected LMUL!" );
@@ -1699,6 +1724,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
1699
1724
: RISCV::PseudoVMSLT_VX_##suffix; \
1700
1725
VMSLTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSLTU_VX_##suffix##_MASK \
1701
1726
: RISCV::PseudoVMSLT_VX_##suffix##_MASK; \
1727
+ VMSGTMaskOpcode = IsUnsigned ? RISCV::PseudoVMSGTU_VX_##suffix##_MASK \
1728
+ : RISCV::PseudoVMSGT_VX_##suffix##_MASK; \
1702
1729
break ;
1703
1730
CASE_VMSLT_OPCODES (LMUL_F8, MF8, B1)
1704
1731
CASE_VMSLT_OPCODES (LMUL_F4, MF4, B2)
@@ -1736,8 +1763,8 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
1736
1763
SDValue MaskedOff = Node->getOperand (1 );
1737
1764
SDValue Mask = Node->getOperand (4 );
1738
1765
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 ) {
1741
1768
// We don't need vmor if the MaskedOff and the Mask are the same
1742
1769
// value.
1743
1770
if (Mask == MaskedOff) {
@@ -1768,6 +1795,16 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
1768
1795
SDValue Glue = Chain.getValue (1 );
1769
1796
SDValue V0 = CurDAG->getRegister (RISCV::V0, VT);
1770
1797
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
+
1771
1808
// Otherwise use
1772
1809
// vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0
1773
1810
// The result is mask undisturbed.
0 commit comments