Skip to content

Commit 0cd8063

Browse files
committed
[AArch64] Genereate CCMP from And CSel
LLVM has a couple of ways of producing ccmp - either from chains in isel or from a later ifcvt style pass. This adds a simple DAG combine to capture more cases, converting and(csel(0, 1, cc0), csel(0, 1, cc1)) into a csel(ccmp(.., cc0)), depending on cc1 (a SUBS in this case). Differential Revision: https://reviews.llvm.org/D118327
1 parent 8af8119 commit 0cd8063

File tree

6 files changed

+297
-460
lines changed

6 files changed

+297
-460
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14068,11 +14068,62 @@ static SDValue performSVEAndCombine(SDNode *N,
1406814068
return SDValue();
1406914069
}
1407014070

14071+
// Given a tree of and(csel(0, 1, cc0), csel(0, 1, cc1)), we may be able to
14072+
// convert to csel(ccmp(.., cc0)), depending on cc1.
14073+
static SDValue PerformANDCSELCombine(SDNode *N, SelectionDAG &DAG) {
14074+
EVT VT = N->getValueType(0);
14075+
SDValue CSel0 = N->getOperand(0);
14076+
SDValue CSel1 = N->getOperand(1);
14077+
14078+
if (CSel0.getOpcode() != AArch64ISD::CSEL ||
14079+
CSel1.getOpcode() != AArch64ISD::CSEL)
14080+
return SDValue();
14081+
14082+
if (!CSel0->hasOneUse() || !CSel1->hasOneUse())
14083+
return SDValue();
14084+
14085+
if (!isNullConstant(CSel0.getOperand(0)) ||
14086+
!isOneConstant(CSel0.getOperand(1)) ||
14087+
!isNullConstant(CSel1.getOperand(0)) ||
14088+
!isOneConstant(CSel1.getOperand(1)))
14089+
return SDValue();
14090+
14091+
SDValue Cmp0 = CSel0.getOperand(3);
14092+
SDValue Cmp1 = CSel1.getOperand(3);
14093+
AArch64CC::CondCode CC0 = (AArch64CC::CondCode)CSel0.getConstantOperandVal(2);
14094+
AArch64CC::CondCode CC1 = (AArch64CC::CondCode)CSel1.getConstantOperandVal(2);
14095+
if (!Cmp0->hasOneUse() || !Cmp1->hasOneUse())
14096+
return SDValue();
14097+
if (Cmp1.getOpcode() != AArch64ISD::SUBS &&
14098+
Cmp0.getOpcode() == AArch64ISD::SUBS) {
14099+
std::swap(Cmp0, Cmp1);
14100+
std::swap(CC0, CC1);
14101+
}
14102+
14103+
if (Cmp1.getOpcode() != AArch64ISD::SUBS)
14104+
return SDValue();
14105+
14106+
SDLoc DL(N);
14107+
AArch64CC::CondCode InvCC0 = AArch64CC::getInvertedCondCode(CC0);
14108+
SDValue Condition = DAG.getConstant(InvCC0, DL, MVT_CC);
14109+
unsigned NZCV = AArch64CC::getNZCVToSatisfyCondCode(CC1);
14110+
SDValue NZCVOp = DAG.getConstant(NZCV, DL, MVT::i32);
14111+
SDValue CCmp = DAG.getNode(AArch64ISD::CCMP, DL, MVT_CC, Cmp1.getOperand(0),
14112+
Cmp1.getOperand(1), NZCVOp, Condition, Cmp0);
14113+
return DAG.getNode(AArch64ISD::CSEL, DL, VT, CSel0.getOperand(0),
14114+
CSel0.getOperand(1), DAG.getConstant(CC1, DL, MVT::i32),
14115+
CCmp);
14116+
}
14117+
1407114118
static SDValue performANDCombine(SDNode *N,
1407214119
TargetLowering::DAGCombinerInfo &DCI) {
1407314120
SelectionDAG &DAG = DCI.DAG;
1407414121
SDValue LHS = N->getOperand(0);
1407514122
EVT VT = N->getValueType(0);
14123+
14124+
if (SDValue R = PerformANDCSELCombine(N, DAG))
14125+
return R;
14126+
1407614127
if (!VT.isVector() || !DAG.getTargetLoweringInfo().isTypeLegal(VT))
1407714128
return SDValue();
1407814129

0 commit comments

Comments
 (0)