Skip to content

Commit 6f272d1

Browse files
committed
[AArch64] Move tryCombineToBSL. NFC
This is for #151855, to make the changes more obvious.
1 parent ff616a1 commit 6f272d1

File tree

1 file changed

+100
-100
lines changed

1 file changed

+100
-100
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 100 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -14742,6 +14742,106 @@ static SDValue tryLowerToSLI(SDNode *N, SelectionDAG &DAG) {
1474214742
return ResultSLI;
1474314743
}
1474414744

14745+
static SDValue tryCombineToBSL(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
14746+
const AArch64TargetLowering &TLI) {
14747+
EVT VT = N->getValueType(0);
14748+
SelectionDAG &DAG = DCI.DAG;
14749+
SDLoc DL(N);
14750+
const auto &Subtarget = DAG.getSubtarget<AArch64Subtarget>();
14751+
14752+
if (!VT.isVector())
14753+
return SDValue();
14754+
14755+
if (VT.isScalableVector() && !Subtarget.hasSVE2())
14756+
return SDValue();
14757+
14758+
if (VT.isFixedLengthVector() &&
14759+
(!Subtarget.isNeonAvailable() || TLI.useSVEForFixedLengthVectorVT(VT)))
14760+
return SDValue();
14761+
14762+
SDValue N0 = N->getOperand(0);
14763+
if (N0.getOpcode() != ISD::AND)
14764+
return SDValue();
14765+
14766+
SDValue N1 = N->getOperand(1);
14767+
if (N1.getOpcode() != ISD::AND)
14768+
return SDValue();
14769+
14770+
// InstCombine does (not (neg a)) => (add a -1).
14771+
// Try: (or (and (neg a) b) (and (add a -1) c)) => (bsl (neg a) b c)
14772+
// Loop over all combinations of AND operands.
14773+
for (int i = 1; i >= 0; --i) {
14774+
for (int j = 1; j >= 0; --j) {
14775+
SDValue O0 = N0->getOperand(i);
14776+
SDValue O1 = N1->getOperand(j);
14777+
SDValue Sub, Add, SubSibling, AddSibling;
14778+
14779+
// Find a SUB and an ADD operand, one from each AND.
14780+
if (O0.getOpcode() == ISD::SUB && O1.getOpcode() == ISD::ADD) {
14781+
Sub = O0;
14782+
Add = O1;
14783+
SubSibling = N0->getOperand(1 - i);
14784+
AddSibling = N1->getOperand(1 - j);
14785+
} else if (O0.getOpcode() == ISD::ADD && O1.getOpcode() == ISD::SUB) {
14786+
Add = O0;
14787+
Sub = O1;
14788+
AddSibling = N0->getOperand(1 - i);
14789+
SubSibling = N1->getOperand(1 - j);
14790+
} else
14791+
continue;
14792+
14793+
if (!ISD::isConstantSplatVectorAllZeros(Sub.getOperand(0).getNode()))
14794+
continue;
14795+
14796+
// Constant ones is always righthand operand of the Add.
14797+
if (!ISD::isConstantSplatVectorAllOnes(Add.getOperand(1).getNode()))
14798+
continue;
14799+
14800+
if (Sub.getOperand(1) != Add.getOperand(0))
14801+
continue;
14802+
14803+
return DAG.getNode(AArch64ISD::BSP, DL, VT, Sub, SubSibling, AddSibling);
14804+
}
14805+
}
14806+
14807+
// (or (and a b) (and (not a) c)) => (bsl a b c)
14808+
// We only have to look for constant vectors here since the general, variable
14809+
// case can be handled in TableGen.
14810+
unsigned Bits = VT.getScalarSizeInBits();
14811+
uint64_t BitMask = Bits == 64 ? -1ULL : ((1ULL << Bits) - 1);
14812+
for (int i = 1; i >= 0; --i)
14813+
for (int j = 1; j >= 0; --j) {
14814+
APInt Val1, Val2;
14815+
14816+
if (ISD::isConstantSplatVector(N0->getOperand(i).getNode(), Val1) &&
14817+
ISD::isConstantSplatVector(N1->getOperand(j).getNode(), Val2) &&
14818+
(BitMask & ~Val1.getZExtValue()) == Val2.getZExtValue()) {
14819+
return DAG.getNode(AArch64ISD::BSP, DL, VT, N0->getOperand(i),
14820+
N0->getOperand(1 - i), N1->getOperand(1 - j));
14821+
}
14822+
BuildVectorSDNode *BVN0 = dyn_cast<BuildVectorSDNode>(N0->getOperand(i));
14823+
BuildVectorSDNode *BVN1 = dyn_cast<BuildVectorSDNode>(N1->getOperand(j));
14824+
if (!BVN0 || !BVN1)
14825+
continue;
14826+
14827+
bool FoundMatch = true;
14828+
for (unsigned k = 0; k < VT.getVectorNumElements(); ++k) {
14829+
ConstantSDNode *CN0 = dyn_cast<ConstantSDNode>(BVN0->getOperand(k));
14830+
ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(BVN1->getOperand(k));
14831+
if (!CN0 || !CN1 ||
14832+
CN0->getZExtValue() != (BitMask & ~CN1->getZExtValue())) {
14833+
FoundMatch = false;
14834+
break;
14835+
}
14836+
}
14837+
if (FoundMatch)
14838+
return DAG.getNode(AArch64ISD::BSP, DL, VT, N0->getOperand(i),
14839+
N0->getOperand(1 - i), N1->getOperand(1 - j));
14840+
}
14841+
14842+
return SDValue();
14843+
}
14844+
1474514845
SDValue AArch64TargetLowering::LowerVectorOR(SDValue Op,
1474614846
SelectionDAG &DAG) const {
1474714847
if (useSVEForFixedLengthVectorVT(Op.getValueType(),
@@ -19419,106 +19519,6 @@ static SDValue performFpToIntCombine(SDNode *N, SelectionDAG &DAG,
1941919519
return FixConv;
1942019520
}
1942119521

19422-
static SDValue tryCombineToBSL(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
19423-
const AArch64TargetLowering &TLI) {
19424-
EVT VT = N->getValueType(0);
19425-
SelectionDAG &DAG = DCI.DAG;
19426-
SDLoc DL(N);
19427-
const auto &Subtarget = DAG.getSubtarget<AArch64Subtarget>();
19428-
19429-
if (!VT.isVector())
19430-
return SDValue();
19431-
19432-
if (VT.isScalableVector() && !Subtarget.hasSVE2())
19433-
return SDValue();
19434-
19435-
if (VT.isFixedLengthVector() &&
19436-
(!Subtarget.isNeonAvailable() || TLI.useSVEForFixedLengthVectorVT(VT)))
19437-
return SDValue();
19438-
19439-
SDValue N0 = N->getOperand(0);
19440-
if (N0.getOpcode() != ISD::AND)
19441-
return SDValue();
19442-
19443-
SDValue N1 = N->getOperand(1);
19444-
if (N1.getOpcode() != ISD::AND)
19445-
return SDValue();
19446-
19447-
// InstCombine does (not (neg a)) => (add a -1).
19448-
// Try: (or (and (neg a) b) (and (add a -1) c)) => (bsl (neg a) b c)
19449-
// Loop over all combinations of AND operands.
19450-
for (int i = 1; i >= 0; --i) {
19451-
for (int j = 1; j >= 0; --j) {
19452-
SDValue O0 = N0->getOperand(i);
19453-
SDValue O1 = N1->getOperand(j);
19454-
SDValue Sub, Add, SubSibling, AddSibling;
19455-
19456-
// Find a SUB and an ADD operand, one from each AND.
19457-
if (O0.getOpcode() == ISD::SUB && O1.getOpcode() == ISD::ADD) {
19458-
Sub = O0;
19459-
Add = O1;
19460-
SubSibling = N0->getOperand(1 - i);
19461-
AddSibling = N1->getOperand(1 - j);
19462-
} else if (O0.getOpcode() == ISD::ADD && O1.getOpcode() == ISD::SUB) {
19463-
Add = O0;
19464-
Sub = O1;
19465-
AddSibling = N0->getOperand(1 - i);
19466-
SubSibling = N1->getOperand(1 - j);
19467-
} else
19468-
continue;
19469-
19470-
if (!ISD::isConstantSplatVectorAllZeros(Sub.getOperand(0).getNode()))
19471-
continue;
19472-
19473-
// Constant ones is always righthand operand of the Add.
19474-
if (!ISD::isConstantSplatVectorAllOnes(Add.getOperand(1).getNode()))
19475-
continue;
19476-
19477-
if (Sub.getOperand(1) != Add.getOperand(0))
19478-
continue;
19479-
19480-
return DAG.getNode(AArch64ISD::BSP, DL, VT, Sub, SubSibling, AddSibling);
19481-
}
19482-
}
19483-
19484-
// (or (and a b) (and (not a) c)) => (bsl a b c)
19485-
// We only have to look for constant vectors here since the general, variable
19486-
// case can be handled in TableGen.
19487-
unsigned Bits = VT.getScalarSizeInBits();
19488-
uint64_t BitMask = Bits == 64 ? -1ULL : ((1ULL << Bits) - 1);
19489-
for (int i = 1; i >= 0; --i)
19490-
for (int j = 1; j >= 0; --j) {
19491-
APInt Val1, Val2;
19492-
19493-
if (ISD::isConstantSplatVector(N0->getOperand(i).getNode(), Val1) &&
19494-
ISD::isConstantSplatVector(N1->getOperand(j).getNode(), Val2) &&
19495-
(BitMask & ~Val1.getZExtValue()) == Val2.getZExtValue()) {
19496-
return DAG.getNode(AArch64ISD::BSP, DL, VT, N0->getOperand(i),
19497-
N0->getOperand(1 - i), N1->getOperand(1 - j));
19498-
}
19499-
BuildVectorSDNode *BVN0 = dyn_cast<BuildVectorSDNode>(N0->getOperand(i));
19500-
BuildVectorSDNode *BVN1 = dyn_cast<BuildVectorSDNode>(N1->getOperand(j));
19501-
if (!BVN0 || !BVN1)
19502-
continue;
19503-
19504-
bool FoundMatch = true;
19505-
for (unsigned k = 0; k < VT.getVectorNumElements(); ++k) {
19506-
ConstantSDNode *CN0 = dyn_cast<ConstantSDNode>(BVN0->getOperand(k));
19507-
ConstantSDNode *CN1 = dyn_cast<ConstantSDNode>(BVN1->getOperand(k));
19508-
if (!CN0 || !CN1 ||
19509-
CN0->getZExtValue() != (BitMask & ~CN1->getZExtValue())) {
19510-
FoundMatch = false;
19511-
break;
19512-
}
19513-
}
19514-
if (FoundMatch)
19515-
return DAG.getNode(AArch64ISD::BSP, DL, VT, N0->getOperand(i),
19516-
N0->getOperand(1 - i), N1->getOperand(1 - j));
19517-
}
19518-
19519-
return SDValue();
19520-
}
19521-
1952219522
// Given a tree of and/or(csel(0, 1, cc0), csel(0, 1, cc1)), we may be able to
1952319523
// convert to csel(ccmp(.., cc0)), depending on cc1:
1952419524

0 commit comments

Comments
 (0)