[PATCH] D148347: [AArch64] Handle vector with two different values
JinGu Kang via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 17 10:03:14 PDT 2023
jaykang10 added a comment.
In D148347#4274366 <https://reviews.llvm.org/D148347#4274366>, @jaykang10 wrote:
> In D148347#4274325 <https://reviews.llvm.org/D148347#4274325>, @efriedma wrote:
>
>> An 16xi8 BUILD_VECTOR of constants should lower to something reasonable (worst case, a constant pool load).
>
> I have seen the constant pool and load...and I was not sure it is good enough or not...
It is a patch which reproduce the constant pool and load from the intrinsic example... Maybe, my implementation could be wrong...
diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index fb41dfd8f245..089e51a5b981 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -12236,6 +12236,8 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op,
unsigned NumUndefLanes = 0;
SDValue Value;
SDValue ConstantValue;
+ SmallPtrSet<SDNode *, 16> DifferentValueSet;
+ SmallVector<SDValue, 16> BitMaskVec;
for (unsigned i = 0; i < NumElts; ++i) {
SDValue V = Op.getOperand(i);
if (V.getOpcode() != ISD::EXTRACT_VECTOR_ELT)
@@ -12263,6 +12265,15 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op,
usesOnlyOneValue = false;
++NumDifferentLanes;
}
+
+ // Keep different values on vector.
+ DifferentValueSet.insert(V.getNode());
+ // Keep the lanes of the first value with bitmask. The bitmask will be valid
+ // only if the DifferentValueSet's size is 2.
+ if (V == Value)
+ BitMaskVec.push_back(DAG.getTargetConstant(1, dl, MVT::i8));
+ else
+ BitMaskVec.push_back(DAG.getTargetConstant(0, dl, MVT::i8));
}
if (!Value.getNode()) {
@@ -12454,6 +12465,22 @@ SDValue AArch64TargetLowering::LowerBUILD_VECTOR(SDValue Op,
return Shuffle;
}
+ // If vector consists of two different values, generate two DUPs and VSELECT.
+ if (DifferentValueSet.size() == 2) {
+ SmallVector<SDValue, 2> Vals;
+ for (auto *Val : DifferentValueSet)
+ Vals.push_back(SDValue(Val, 0));
+ SmallVector<SDValue, 8> Ops1(NumElts, Vals[0]);
+ SmallVector<SDValue, 8> Ops2(NumElts, Vals[1]);
+ SDValue DUP1 = LowerBUILD_VECTOR(DAG.getBuildVector(VT, dl, Ops1), DAG);
+ SDValue DUP2 = LowerBUILD_VECTOR(DAG.getBuildVector(VT, dl, Ops2), DAG);
+ SDValue VCOND = DAG.getBuildVector(VT, dl, BitMaskVec);
+ if (SDValue Res = LowerBUILD_VECTOR(VCOND, DAG))
+ VCOND = Res;
+ SDValue VSELECT = DAG.getNode(ISD::VSELECT, dl, VT, VCOND, DUP1, DUP2);
+ return VSELECT;
+ }
+
if (PreferDUPAndInsert) {
// First, build a constant vector with the common element.
SmallVector<SDValue, 8> Ops(NumElts, Value);
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D148347/new/
https://reviews.llvm.org/D148347
More information about the llvm-commits
mailing list