[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