Skip to content

Commit 88f3ddd

Browse files
committed
[RISCV] Improve vmsge and vmsgeu selection
Select vmsge(u) vs, C to vmsgt(u) vs, C-1 if C is not in the imm range and not the minimum value.
1 parent c17a914 commit 88f3ddd

File tree

3 files changed

+156
-12
lines changed

3 files changed

+156
-12
lines changed

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

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

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)