Skip to content

Commit 0590ce0

Browse files
committed
[SelectionDAG] Add support for the 3-way comparison intrinsics [US]CMP
1 parent d98a785 commit 0590ce0

File tree

11 files changed

+271
-0
lines changed

11 files changed

+271
-0
lines changed

llvm/include/llvm/CodeGen/ISDOpcodes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,11 @@ enum NodeType {
677677
UMIN,
678678
UMAX,
679679

680+
/// [US]CMP - 3-way comparison of signed or unsigned integers. Returns -1, 0,
681+
/// or 1 depending on whether Op0 <, ==, or > Op1
682+
SCMP,
683+
UCMP,
684+
680685
/// Bitwise operators - logical and, logical or, logical xor.
681686
AND,
682687
OR,

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5402,6 +5402,10 @@ class TargetLowering : public TargetLoweringBase {
54025402
/// method accepts integers as its arguments.
54035403
SDValue expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const;
54045404

5405+
/// Method for building the DAG expansion of ISD::[US]CMP. This
5406+
/// method accepts integers as its arguments
5407+
SDValue expandCmp(SDNode *Node, SelectionDAG &DAG) const;
5408+
54055409
/// Method for building the DAG expansion of ISD::[US]SHLSAT. This
54065410
/// method accepts integers as its arguments.
54075411
SDValue expandShlSat(SDNode *Node, SelectionDAG &DAG) const;

llvm/include/llvm/Target/TargetSelectionDAG.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,11 @@ def umin : SDNode<"ISD::UMIN" , SDTIntBinOp,
434434
def umax : SDNode<"ISD::UMAX" , SDTIntBinOp,
435435
[SDNPCommutative, SDNPAssociative]>;
436436

437+
def scmp : SDNode<"ISD::SCMP" , SDTIntBinOp,
438+
[]>;
439+
def ucmp : SDNode<"ISD::UCMP" , SDTIntBinOp,
440+
[]>;
441+
437442
def saddsat : SDNode<"ISD::SADDSAT" , SDTIntBinOp, [SDNPCommutative]>;
438443
def uaddsat : SDNode<"ISD::UADDSAT" , SDTIntBinOp, [SDNPCommutative]>;
439444
def ssubsat : SDNode<"ISD::SSUBSAT" , SDTIntBinOp>;

llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,8 @@ void SelectionDAGLegalize::LegalizeOp(SDNode *Node) {
11481148
case ISD::USUBSAT:
11491149
case ISD::SSHLSAT:
11501150
case ISD::USHLSAT:
1151+
case ISD::SCMP:
1152+
case ISD::UCMP:
11511153
case ISD::FP_TO_SINT_SAT:
11521154
case ISD::FP_TO_UINT_SAT:
11531155
Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
@@ -3864,6 +3866,10 @@ bool SelectionDAGLegalize::ExpandNode(SDNode *Node) {
38643866
case ISD::USUBSAT:
38653867
Results.push_back(TLI.expandAddSubSat(Node, DAG));
38663868
break;
3869+
case ISD::SCMP:
3870+
case ISD::UCMP:
3871+
Results.push_back(TLI.expandCmp(Node, DAG));
3872+
break;
38673873
case ISD::SSHLSAT:
38683874
case ISD::USHLSAT:
38693875
Results.push_back(TLI.expandShlSat(Node, DAG));

llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
232232
Res = PromoteIntRes_ADDSUBSHLSAT<VPMatchContext>(N);
233233
break;
234234

235+
case ISD::SCMP:
236+
case ISD::UCMP:
237+
Res = PromoteIntRes_CMP(N);
238+
break;
239+
235240
case ISD::SMULFIX:
236241
case ISD::SMULFIXSAT:
237242
case ISD::UMULFIX:
@@ -1246,6 +1251,14 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) {
12461251
return Res;
12471252
}
12481253

1254+
SDValue DAGTypeLegalizer::PromoteIntRes_CMP(SDNode *N) {
1255+
EVT PromotedResultTy =
1256+
TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0));
1257+
SDValue Result = DAG.getNode(N->getOpcode(), SDLoc(N), PromotedResultTy,
1258+
N->getOperand(0), N->getOperand(1));
1259+
return Result;
1260+
}
1261+
12491262
SDValue DAGTypeLegalizer::PromoteIntRes_Select(SDNode *N) {
12501263
SDValue Mask = N->getOperand(0);
12511264

@@ -1874,6 +1887,9 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
18741887
case ISD::ROTL:
18751888
case ISD::ROTR: Res = PromoteIntOp_Shift(N); break;
18761889

1890+
case ISD::SCMP:
1891+
case ISD::UCMP: Res = PromoteIntOp_CMP(N); break;
1892+
18771893
case ISD::FSHL:
18781894
case ISD::FSHR: Res = PromoteIntOp_FunnelShift(N); break;
18791895

@@ -2184,6 +2200,17 @@ SDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) {
21842200
ZExtPromotedInteger(N->getOperand(1))), 0);
21852201
}
21862202

2203+
SDValue DAGTypeLegalizer::PromoteIntOp_CMP(SDNode *N) {
2204+
SDValue LHS = N->getOpcode() == ISD::UCMP
2205+
? ZExtPromotedInteger(N->getOperand(0))
2206+
: SExtPromotedInteger(N->getOperand(0));
2207+
SDValue RHS = N->getOpcode() == ISD::UCMP
2208+
? ZExtPromotedInteger(N->getOperand(1))
2209+
: SExtPromotedInteger(N->getOperand(1));
2210+
2211+
return SDValue(DAG.UpdateNodeOperands(N, LHS, RHS), 0);
2212+
}
2213+
21872214
SDValue DAGTypeLegalizer::PromoteIntOp_FunnelShift(SDNode *N) {
21882215
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), N->getOperand(1),
21892216
ZExtPromotedInteger(N->getOperand(2))), 0);
@@ -2741,6 +2768,9 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
27412768
case ISD::UMIN:
27422769
case ISD::SMIN: ExpandIntRes_MINMAX(N, Lo, Hi); break;
27432770

2771+
case ISD::SCMP:
2772+
case ISD::UCMP: ExpandIntRes_CMP(N, Lo, Hi); break;
2773+
27442774
case ISD::ADD:
27452775
case ISD::SUB: ExpandIntRes_ADDSUB(N, Lo, Hi); break;
27462776

@@ -3233,6 +3263,10 @@ void DAGTypeLegalizer::ExpandIntRes_MINMAX(SDNode *N,
32333263
SplitInteger(Result, Lo, Hi);
32343264
}
32353265

3266+
void DAGTypeLegalizer::ExpandIntRes_CMP(SDNode *N, SDValue &Lo, SDValue &Hi) {
3267+
assert(false && "fixme");
3268+
}
3269+
32363270
void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
32373271
SDValue &Lo, SDValue &Hi) {
32383272
SDLoc dl(N);
@@ -5137,6 +5171,9 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
51375171
case ISD::RETURNADDR:
51385172
case ISD::FRAMEADDR: Res = ExpandIntOp_RETURNADDR(N); break;
51395173

5174+
case ISD::SCMP:
5175+
case ISD::UCMP: Res = ExpandIntOp_CMP(N); break;
5176+
51405177
case ISD::ATOMIC_STORE: Res = ExpandIntOp_ATOMIC_STORE(N); break;
51415178
case ISD::STACKMAP:
51425179
Res = ExpandIntOp_STACKMAP(N, OpNo);
@@ -5398,6 +5435,10 @@ SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) {
53985435
return SDValue(DAG.UpdateNodeOperands(N, N->getOperand(0), Lo), 0);
53995436
}
54005437

5438+
SDValue DAGTypeLegalizer::ExpandIntOp_CMP(SDNode *N) {
5439+
assert(false && "fixme");
5440+
}
5441+
54015442
SDValue DAGTypeLegalizer::ExpandIntOp_RETURNADDR(SDNode *N) {
54025443
// The argument of RETURNADDR / FRAMEADDR builtin is 32 bit contant. This
54035444
// surely makes pretty nice problems on 8/16 bit targets. Just truncate this

llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
324324
SDValue PromoteIntRes_Overflow(SDNode *N);
325325
SDValue PromoteIntRes_FFREXP(SDNode *N);
326326
SDValue PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo);
327+
SDValue PromoteIntRes_CMP(SDNode *N);
327328
SDValue PromoteIntRes_Select(SDNode *N);
328329
SDValue PromoteIntRes_SELECT_CC(SDNode *N);
329330
SDValue PromoteIntRes_SETCC(SDNode *N);
@@ -375,6 +376,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
375376
SDValue PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo);
376377
SDValue PromoteIntOp_SETCC(SDNode *N, unsigned OpNo);
377378
SDValue PromoteIntOp_Shift(SDNode *N);
379+
SDValue PromoteIntOp_CMP(SDNode *N);
378380
SDValue PromoteIntOp_FunnelShift(SDNode *N);
379381
SDValue PromoteIntOp_SIGN_EXTEND(SDNode *N);
380382
SDValue PromoteIntOp_VP_SIGN_EXTEND(SDNode *N);
@@ -457,6 +459,8 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
457459

458460
void ExpandIntRes_MINMAX (SDNode *N, SDValue &Lo, SDValue &Hi);
459461

462+
void ExpandIntRes_CMP (SDNode *N, SDValue &Lo, SDValue &Hi);
463+
460464
void ExpandIntRes_SADDSUBO (SDNode *N, SDValue &Lo, SDValue &Hi);
461465
void ExpandIntRes_UADDSUBO (SDNode *N, SDValue &Lo, SDValue &Hi);
462466
void ExpandIntRes_XMULO (SDNode *N, SDValue &Lo, SDValue &Hi);
@@ -485,6 +489,7 @@ class LLVM_LIBRARY_VISIBILITY DAGTypeLegalizer {
485489
SDValue ExpandIntOp_SETCC(SDNode *N);
486490
SDValue ExpandIntOp_SETCCCARRY(SDNode *N);
487491
SDValue ExpandIntOp_Shift(SDNode *N);
492+
SDValue ExpandIntOp_CMP(SDNode *N);
488493
SDValue ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
489494
SDValue ExpandIntOp_TRUNCATE(SDNode *N);
490495
SDValue ExpandIntOp_XINT_TO_FP(SDNode *N);

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7143,6 +7143,22 @@ void SelectionDAGBuilder::visitIntrinsicCall(const CallInst &I,
71437143
setValue(&I, DAG.getNode(ISD::ABS, sdl, Op1.getValueType(), Op1));
71447144
return;
71457145
}
7146+
case Intrinsic::scmp: {
7147+
SDValue Op1 = getValue(I.getArgOperand(0));
7148+
SDValue Op2 = getValue(I.getArgOperand(1));
7149+
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
7150+
I.getType());
7151+
setValue(&I, DAG.getNode(ISD::SCMP, sdl, DestVT, Op1, Op2));
7152+
break;
7153+
}
7154+
case Intrinsic::ucmp: {
7155+
SDValue Op1 = getValue(I.getArgOperand(0));
7156+
SDValue Op2 = getValue(I.getArgOperand(1));
7157+
EVT DestVT = DAG.getTargetLoweringInfo().getValueType(DAG.getDataLayout(),
7158+
I.getType());
7159+
setValue(&I, DAG.getNode(ISD::UCMP, sdl, DestVT, Op1, Op2));
7160+
break;
7161+
}
71467162
case Intrinsic::stacksave: {
71477163
SDValue Op = getRoot();
71487164
EVT VT = TLI.getValueType(DAG.getDataLayout(), I.getType());

llvm/lib/CodeGen/SelectionDAG/SelectionDAGDumper.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
289289
case ISD::SMAX: return "smax";
290290
case ISD::UMIN: return "umin";
291291
case ISD::UMAX: return "umax";
292+
case ISD::SCMP: return "scmp";
293+
case ISD::UCMP: return "ucmp";
292294

293295
case ISD::FLDEXP: return "fldexp";
294296
case ISD::STRICT_FLDEXP: return "strict_fldexp";

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10274,6 +10274,27 @@ SDValue TargetLowering::expandAddSubSat(SDNode *Node, SelectionDAG &DAG) const {
1027410274
return DAG.getSelect(dl, VT, Overflow, Result, SumDiff);
1027510275
}
1027610276

10277+
SDValue TargetLowering::expandCmp(SDNode *Node, SelectionDAG &DAG) const {
10278+
unsigned Opcode = Node->getOpcode();
10279+
SDValue LHS = Node->getOperand(0);
10280+
SDValue RHS = Node->getOperand(1);
10281+
EVT VT = LHS.getValueType();
10282+
EVT ResVT = Node->getValueType(0);
10283+
EVT BoolVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
10284+
SDLoc dl(Node);
10285+
10286+
auto LTPredicate = (Opcode == ISD::UCMP ? ISD::SETULT : ISD::SETLT);
10287+
auto GTPredicate = (Opcode == ISD::UCMP ? ISD::SETUGT : ISD::SETGT);
10288+
10289+
SDValue IsLT = DAG.getSetCC(dl, BoolVT, LHS, RHS, LTPredicate);
10290+
SDValue IsGT = DAG.getSetCC(dl, BoolVT, LHS, RHS, GTPredicate);
10291+
SDValue SelectZeroOrOne =
10292+
DAG.getSelect(dl, ResVT, IsGT, DAG.getConstant(1, dl, ResVT),
10293+
DAG.getConstant(0, dl, ResVT));
10294+
return DAG.getSelect(dl, ResVT, IsLT, DAG.getConstant(-1, dl, ResVT),
10295+
SelectZeroOrOne);
10296+
}
10297+
1027710298
SDValue TargetLowering::expandShlSat(SDNode *Node, SelectionDAG &DAG) const {
1027810299
unsigned Opcode = Node->getOpcode();
1027910300
bool IsSigned = Opcode == ISD::SSHLSAT;

llvm/lib/CodeGen/TargetLoweringBase.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,9 @@ void TargetLoweringBase::initActions() {
909909
setOperationAction({ISD::ADDC, ISD::ADDE, ISD::SUBC, ISD::SUBE}, VT,
910910
Expand);
911911

912+
// [US]CMP default to expand
913+
setOperationAction({ISD::UCMP, ISD::SCMP}, VT, Expand);
914+
912915
// Halving adds
913916
setOperationAction(
914917
{ISD::AVGFLOORS, ISD::AVGFLOORU, ISD::AVGCEILS, ISD::AVGCEILU}, VT,

0 commit comments

Comments
 (0)