Skip to content

Commit a6f8af6

Browse files
authored
[RISCV] Improve vmsge and vmsgeu selection (#115435)
Select vmsge(u) vs, C to vmsgt(u) vs, C-1 if C is not in the imm range and not the minimum value. Fix #114505.
1 parent 9a365bc commit a6f8af6

File tree

3 files changed

+158
-14
lines changed

3 files changed

+158
-14
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 51 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -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.

llvm/test/CodeGen/RISCV/rvv/vmsge.ll

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,6 +1084,45 @@ entry:
10841084
ret <vscale x 4 x i1> %a
10851085
}
10861086

1087+
define <vscale x 4 x i1> @intrinsic_vmsge_mask_vx_nxv4i8_i8_1(<vscale x 4 x i1> %0, <vscale x 4 x i8> %1, <vscale x 4 x i1> %2, iXLen %3) nounwind {
1088+
; CHECK-LABEL: intrinsic_vmsge_mask_vx_nxv4i8_i8_1:
1089+
; CHECK: # %bb.0: # %entry
1090+
; CHECK-NEXT: vmv1r.v v10, v0
1091+
; CHECK-NEXT: li a1, 99
1092+
; CHECK-NEXT: vmv1r.v v0, v9
1093+
; CHECK-NEXT: vsetvli zero, a0, e8, mf2, ta, mu
1094+
; CHECK-NEXT: vmsgt.vx v10, v8, a1, v0.t
1095+
; CHECK-NEXT: vmv1r.v v0, v10
1096+
; CHECK-NEXT: ret
1097+
entry:
1098+
%a = call <vscale x 4 x i1> @llvm.riscv.vmsge.mask.nxv4i8.i8(
1099+
<vscale x 4 x i1> %0,
1100+
<vscale x 4 x i8> %1,
1101+
i8 100,
1102+
<vscale x 4 x i1> %2,
1103+
iXLen %3)
1104+
1105+
ret <vscale x 4 x i1> %a
1106+
}
1107+
1108+
define <vscale x 4 x i1> @intrinsic_vmsge_mask_vx_nxv4i8_i8_2(<vscale x 4 x i1> %0, <vscale x 4 x i8> %1, <vscale x 4 x i1> %2, iXLen %3) nounwind {
1109+
; CHECK-LABEL: intrinsic_vmsge_mask_vx_nxv4i8_i8_2:
1110+
; CHECK: # %bb.0: # %entry
1111+
; CHECK-NEXT: vsetvli zero, a0, e8, mf2, ta, ma
1112+
; CHECK-NEXT: vmor.mm v0, v9, v0
1113+
; CHECK-NEXT: ret
1114+
entry:
1115+
%a = call <vscale x 4 x i1> @llvm.riscv.vmsge.mask.nxv4i8.i8(
1116+
<vscale x 4 x i1> %0,
1117+
<vscale x 4 x i8> %1,
1118+
i8 -128,
1119+
<vscale x 4 x i1> %2,
1120+
iXLen %3)
1121+
1122+
ret <vscale x 4 x i1> %a
1123+
}
1124+
1125+
10871126
declare <vscale x 8 x i1> @llvm.riscv.vmsge.nxv8i8.i8(
10881127
<vscale x 8 x i8>,
10891128
i8,
@@ -1970,6 +2009,37 @@ entry:
19702009
ret <vscale x 4 x i1> %a
19712010
}
19722011

2012+
define <vscale x 4 x i1> @intrinsic_vmsge_vi_nxv4i8_i8_1(<vscale x 4 x i8> %0, iXLen %1) nounwind {
2013+
; CHECK-LABEL: intrinsic_vmsge_vi_nxv4i8_i8_1:
2014+
; CHECK: # %bb.0: # %entry
2015+
; CHECK-NEXT: li a1, 99
2016+
; CHECK-NEXT: vsetvli zero, a0, e8, mf2, ta, ma
2017+
; CHECK-NEXT: vmsgt.vx v0, v8, a1
2018+
; CHECK-NEXT: ret
2019+
entry:
2020+
%a = call <vscale x 4 x i1> @llvm.riscv.vmsge.nxv4i8.i8(
2021+
<vscale x 4 x i8> %0,
2022+
i8 100,
2023+
iXLen %1)
2024+
2025+
ret <vscale x 4 x i1> %a
2026+
}
2027+
2028+
define <vscale x 4 x i1> @intrinsic_vmsge_vi_nxv4i8_i8_2(<vscale x 4 x i8> %0, iXLen %1) nounwind {
2029+
; CHECK-LABEL: intrinsic_vmsge_vi_nxv4i8_i8_2:
2030+
; CHECK: # %bb.0: # %entry
2031+
; CHECK-NEXT: vsetvli zero, a0, e8, mf2, ta, ma
2032+
; CHECK-NEXT: vmset.m v0
2033+
; CHECK-NEXT: ret
2034+
entry:
2035+
%a = call <vscale x 4 x i1> @llvm.riscv.vmsge.nxv4i8.i8(
2036+
<vscale x 4 x i8> %0,
2037+
i8 -128,
2038+
iXLen %1)
2039+
2040+
ret <vscale x 4 x i1> %a
2041+
}
2042+
19732043
define <vscale x 4 x i1> @intrinsic_vmsge_mask_vi_nxv4i8_i8(<vscale x 4 x i1> %0, <vscale x 4 x i8> %1, <vscale x 4 x i1> %2, iXLen %3) nounwind {
19742044
; CHECK-LABEL: intrinsic_vmsge_mask_vi_nxv4i8_i8:
19752045
; CHECK: # %bb.0: # %entry

llvm/test/CodeGen/RISCV/rvv/vmsgeu.ll

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,6 +1990,27 @@ entry:
19901990
ret <vscale x 4 x i1> %a
19911991
}
19921992

1993+
define <vscale x 4 x i1> @intrinsic_vmsgeu_mask_vi_nxv4i8_i8_1(<vscale x 4 x i1> %0, <vscale x 4 x i8> %1, <vscale x 4 x i1> %2, iXLen %3) nounwind {
1994+
; CHECK-LABEL: intrinsic_vmsgeu_mask_vi_nxv4i8_i8_1:
1995+
; CHECK: # %bb.0: # %entry
1996+
; CHECK-NEXT: vmv1r.v v10, v0
1997+
; CHECK-NEXT: li a1, 99
1998+
; CHECK-NEXT: vmv1r.v v0, v9
1999+
; CHECK-NEXT: vsetvli zero, a0, e8, mf2, ta, mu
2000+
; CHECK-NEXT: vmsgtu.vx v10, v8, a1, v0.t
2001+
; CHECK-NEXT: vmv1r.v v0, v10
2002+
; CHECK-NEXT: ret
2003+
entry:
2004+
%a = call <vscale x 4 x i1> @llvm.riscv.vmsgeu.mask.nxv4i8.i8(
2005+
<vscale x 4 x i1> %0,
2006+
<vscale x 4 x i8> %1,
2007+
i8 100,
2008+
<vscale x 4 x i1> %2,
2009+
iXLen %3)
2010+
2011+
ret <vscale x 4 x i1> %a
2012+
}
2013+
19932014
define <vscale x 8 x i1> @intrinsic_vmsgeu_vi_nxv8i8_i8(<vscale x 8 x i8> %0, iXLen %1) nounwind {
19942015
; CHECK-LABEL: intrinsic_vmsgeu_vi_nxv8i8_i8:
19952016
; CHECK: # %bb.0: # %entry
@@ -2192,6 +2213,22 @@ entry:
21922213
ret <vscale x 4 x i1> %a
21932214
}
21942215

2216+
define <vscale x 4 x i1> @intrinsic_vmsgeu_vi_nxv4i16_i16_1(<vscale x 4 x i16> %0, iXLen %1) nounwind {
2217+
; CHECK-LABEL: intrinsic_vmsgeu_vi_nxv4i16_i16_1:
2218+
; CHECK: # %bb.0: # %entry
2219+
; CHECK-NEXT: li a1, 99
2220+
; CHECK-NEXT: vsetvli zero, a0, e16, m1, ta, ma
2221+
; CHECK-NEXT: vmsgtu.vx v0, v8, a1
2222+
; CHECK-NEXT: ret
2223+
entry:
2224+
%a = call <vscale x 4 x i1> @llvm.riscv.vmsgeu.nxv4i16.i16(
2225+
<vscale x 4 x i16> %0,
2226+
i16 100,
2227+
iXLen %1)
2228+
2229+
ret <vscale x 4 x i1> %a
2230+
}
2231+
21952232
define <vscale x 4 x i1> @intrinsic_vmsgeu_mask_vi_nxv4i16_i16(<vscale x 4 x i1> %0, <vscale x 4 x i16> %1, <vscale x 4 x i1> %2, iXLen %3) nounwind {
21962233
; CHECK-LABEL: intrinsic_vmsgeu_mask_vi_nxv4i16_i16:
21972234
; CHECK: # %bb.0: # %entry

0 commit comments

Comments
 (0)