-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[LLVM][AArch64] Refactor lowering of fixed length integer setcc operations. #132434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2057,6 +2057,15 @@ void AArch64TargetLowering::addTypeForNEON(MVT VT) { | |
| setOperationAction(ISD::READ_REGISTER, MVT::i128, Custom); | ||
| setOperationAction(ISD::WRITE_REGISTER, MVT::i128, Custom); | ||
| } | ||
|
|
||
| if (VT.isInteger()) { | ||
| // Let common code emit inverted variants of compares we do support. | ||
| setCondCodeAction(ISD::SETNE, VT, Expand); | ||
| setCondCodeAction(ISD::SETLE, VT, Expand); | ||
| setCondCodeAction(ISD::SETLT, VT, Expand); | ||
| setCondCodeAction(ISD::SETULE, VT, Expand); | ||
| setCondCodeAction(ISD::SETULT, VT, Expand); | ||
| } | ||
| } | ||
|
|
||
| bool AArch64TargetLowering::shouldExpandGetActiveLaneMask(EVT ResVT, | ||
|
|
@@ -2581,31 +2590,21 @@ unsigned AArch64TargetLowering::ComputeNumSignBitsForTargetNode( | |
| unsigned VTBits = VT.getScalarSizeInBits(); | ||
| unsigned Opcode = Op.getOpcode(); | ||
| switch (Opcode) { | ||
| case AArch64ISD::CMEQ: | ||
| case AArch64ISD::CMGE: | ||
| case AArch64ISD::CMGT: | ||
| case AArch64ISD::CMHI: | ||
| case AArch64ISD::CMHS: | ||
| case AArch64ISD::FCMEQ: | ||
| case AArch64ISD::FCMGE: | ||
| case AArch64ISD::FCMGT: | ||
| case AArch64ISD::CMEQz: | ||
| case AArch64ISD::CMGEz: | ||
| case AArch64ISD::CMGTz: | ||
| case AArch64ISD::CMLEz: | ||
| case AArch64ISD::CMLTz: | ||
| case AArch64ISD::FCMEQz: | ||
| case AArch64ISD::FCMGEz: | ||
| case AArch64ISD::FCMGTz: | ||
| case AArch64ISD::FCMLEz: | ||
| case AArch64ISD::FCMLTz: | ||
| // Compares return either 0 or all-ones | ||
| return VTBits; | ||
| case AArch64ISD::VASHR: { | ||
| unsigned Tmp = | ||
| DAG.ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1); | ||
| return std::min<uint64_t>(Tmp + Op.getConstantOperandVal(1), VTBits); | ||
| } | ||
| case AArch64ISD::FCMEQ: | ||
| case AArch64ISD::FCMGE: | ||
| case AArch64ISD::FCMGT: | ||
| case AArch64ISD::FCMEQz: | ||
| case AArch64ISD::FCMGEz: | ||
| case AArch64ISD::FCMGTz: | ||
| case AArch64ISD::FCMLEz: | ||
| case AArch64ISD::FCMLTz: | ||
| // Compares return either 0 or all-ones | ||
| return VTBits; | ||
| case AArch64ISD::VASHR: { | ||
| unsigned Tmp = | ||
| DAG.ComputeNumSignBits(Op.getOperand(0), DemandedElts, Depth + 1); | ||
| return std::min<uint64_t>(Tmp + Op.getConstantOperandVal(1), VTBits); | ||
| } | ||
| } | ||
|
|
||
| return 1; | ||
|
|
@@ -2812,19 +2811,9 @@ const char *AArch64TargetLowering::getTargetNodeName(unsigned Opcode) const { | |
| MAKE_CASE(AArch64ISD::VASHR) | ||
| MAKE_CASE(AArch64ISD::VSLI) | ||
| MAKE_CASE(AArch64ISD::VSRI) | ||
| MAKE_CASE(AArch64ISD::CMEQ) | ||
| MAKE_CASE(AArch64ISD::CMGE) | ||
| MAKE_CASE(AArch64ISD::CMGT) | ||
| MAKE_CASE(AArch64ISD::CMHI) | ||
| MAKE_CASE(AArch64ISD::CMHS) | ||
| MAKE_CASE(AArch64ISD::FCMEQ) | ||
| MAKE_CASE(AArch64ISD::FCMGE) | ||
| MAKE_CASE(AArch64ISD::FCMGT) | ||
| MAKE_CASE(AArch64ISD::CMEQz) | ||
| MAKE_CASE(AArch64ISD::CMGEz) | ||
| MAKE_CASE(AArch64ISD::CMGTz) | ||
| MAKE_CASE(AArch64ISD::CMLEz) | ||
| MAKE_CASE(AArch64ISD::CMLTz) | ||
| MAKE_CASE(AArch64ISD::FCMEQz) | ||
| MAKE_CASE(AArch64ISD::FCMGEz) | ||
| MAKE_CASE(AArch64ISD::FCMGTz) | ||
|
|
@@ -15814,9 +15803,6 @@ static SDValue EmitVectorComparison(SDValue LHS, SDValue RHS, | |
| SplatBitSize, HasAnyUndefs); | ||
|
|
||
| bool IsZero = IsCnst && SplatValue == 0; | ||
| bool IsOne = | ||
| IsCnst && SrcVT.getScalarSizeInBits() == SplatBitSize && SplatValue == 1; | ||
| bool IsMinusOne = IsCnst && SplatValue.isAllOnes(); | ||
|
|
||
| if (SrcVT.getVectorElementType().isFloatingPoint()) { | ||
| switch (CC) { | ||
|
|
@@ -15863,50 +15849,7 @@ static SDValue EmitVectorComparison(SDValue LHS, SDValue RHS, | |
| } | ||
| } | ||
|
|
||
| switch (CC) { | ||
| default: | ||
| return SDValue(); | ||
| case AArch64CC::NE: { | ||
| SDValue Cmeq; | ||
| if (IsZero) | ||
| Cmeq = DAG.getNode(AArch64ISD::CMEQz, dl, VT, LHS); | ||
| else | ||
| Cmeq = DAG.getNode(AArch64ISD::CMEQ, dl, VT, LHS, RHS); | ||
| return DAG.getNOT(dl, Cmeq, VT); | ||
| } | ||
| case AArch64CC::EQ: | ||
| if (IsZero) | ||
| return DAG.getNode(AArch64ISD::CMEQz, dl, VT, LHS); | ||
| return DAG.getNode(AArch64ISD::CMEQ, dl, VT, LHS, RHS); | ||
| case AArch64CC::GE: | ||
| if (IsZero) | ||
| return DAG.getNode(AArch64ISD::CMGEz, dl, VT, LHS); | ||
| return DAG.getNode(AArch64ISD::CMGE, dl, VT, LHS, RHS); | ||
| case AArch64CC::GT: | ||
| if (IsZero) | ||
| return DAG.getNode(AArch64ISD::CMGTz, dl, VT, LHS); | ||
| if (IsMinusOne) | ||
| return DAG.getNode(AArch64ISD::CMGEz, dl, VT, LHS); | ||
| return DAG.getNode(AArch64ISD::CMGT, dl, VT, LHS, RHS); | ||
| case AArch64CC::LE: | ||
| if (IsZero) | ||
| return DAG.getNode(AArch64ISD::CMLEz, dl, VT, LHS); | ||
| return DAG.getNode(AArch64ISD::CMGE, dl, VT, RHS, LHS); | ||
| case AArch64CC::LS: | ||
| return DAG.getNode(AArch64ISD::CMHS, dl, VT, RHS, LHS); | ||
| case AArch64CC::LO: | ||
| return DAG.getNode(AArch64ISD::CMHI, dl, VT, RHS, LHS); | ||
| case AArch64CC::LT: | ||
| if (IsZero) | ||
| return DAG.getNode(AArch64ISD::CMLTz, dl, VT, LHS); | ||
| if (IsOne) | ||
| return DAG.getNode(AArch64ISD::CMLEz, dl, VT, LHS); | ||
| return DAG.getNode(AArch64ISD::CMGT, dl, VT, RHS, LHS); | ||
| case AArch64CC::HI: | ||
| return DAG.getNode(AArch64ISD::CMHI, dl, VT, LHS, RHS); | ||
| case AArch64CC::HS: | ||
| return DAG.getNode(AArch64ISD::CMHS, dl, VT, LHS, RHS); | ||
| } | ||
| return SDValue(); | ||
| } | ||
|
|
||
| SDValue AArch64TargetLowering::LowerVSETCC(SDValue Op, | ||
|
|
@@ -15927,9 +15870,11 @@ SDValue AArch64TargetLowering::LowerVSETCC(SDValue Op, | |
| if (LHS.getValueType().getVectorElementType().isInteger()) { | ||
| assert(LHS.getValueType() == RHS.getValueType()); | ||
| AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC); | ||
| SDValue Cmp = | ||
| EmitVectorComparison(LHS, RHS, AArch64CC, false, CmpVT, dl, DAG); | ||
| return DAG.getSExtOrTrunc(Cmp, dl, Op.getValueType()); | ||
| if (SDValue Cmp = | ||
| EmitVectorComparison(LHS, RHS, AArch64CC, false, CmpVT, dl, DAG)) | ||
| return DAG.getSExtOrTrunc(Cmp, dl, Op.getValueType()); | ||
|
|
||
| return Op; | ||
| } | ||
|
|
||
| // Lower isnan(x) | isnan(never-nan) to x != x. | ||
|
|
@@ -18128,7 +18073,9 @@ static SDValue foldVectorXorShiftIntoCmp(SDNode *N, SelectionDAG &DAG, | |
| if (!ShiftAmt || ShiftAmt->getZExtValue() != ShiftEltTy.getSizeInBits() - 1) | ||
| return SDValue(); | ||
|
|
||
| return DAG.getNode(AArch64ISD::CMGEz, SDLoc(N), VT, Shift.getOperand(0)); | ||
| SDLoc DL(N); | ||
| SDValue Zero = DAG.getConstant(0, DL, Shift.getValueType()); | ||
| return DAG.getSetCC(DL, VT, Shift.getOperand(0), Zero, ISD::SETGE); | ||
| } | ||
|
|
||
| // Given a vecreduce_add node, detect the below pattern and convert it to the | ||
|
|
@@ -18739,7 +18686,8 @@ static SDValue performMulVectorCmpZeroCombine(SDNode *N, SelectionDAG &DAG) { | |
|
|
||
| SDLoc DL(N); | ||
| SDValue In = DAG.getNode(AArch64ISD::NVCAST, DL, HalfVT, Srl.getOperand(0)); | ||
| SDValue CM = DAG.getNode(AArch64ISD::CMLTz, DL, HalfVT, In); | ||
| SDValue Zero = DAG.getConstant(0, DL, In.getValueType()); | ||
| SDValue CM = DAG.getSetCC(DL, HalfVT, Zero, In, ISD::SETGT); | ||
| return DAG.getNode(AArch64ISD::NVCAST, DL, VT, CM); | ||
| } | ||
|
|
||
|
|
@@ -25268,6 +25216,14 @@ static SDValue performSETCCCombine(SDNode *N, | |
| if (SDValue V = performOrXorChainCombine(N, DAG)) | ||
| return V; | ||
|
|
||
| EVT CmpVT = LHS.getValueType(); | ||
|
|
||
| APInt SplatLHSVal; | ||
| if (CmpVT.isInteger() && Cond == ISD::SETGT && | ||
| ISD::isConstantSplatVector(LHS.getNode(), SplatLHSVal) && | ||
| SplatLHSVal.isOne()) | ||
| return DAG.getSetCC(DL, VT, DAG.getConstant(0, DL, CmpVT), RHS, ISD::SETGE); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I added this combine because it proved awkward to detect splat(1) across all the NEON types within a PatFrag. I think this is again because we're performing isel of constants during legalisation when it would be better to use splat_vector universally. Please let me know if you've a better solution, otherwise I'm happy to circle back after making the DAG more amenable.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably worth adding a comment explaining why you can't currently use a TableGen pattern for this. But seems fine. |
||
|
|
||
| return SDValue(); | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.