Skip to content

Commit bb2a1e3

Browse files
[AArch64] Refactor creation of a shuffle mask for TBL (NFC)
1 parent 27e9e12 commit bb2a1e3

File tree

1 file changed

+50
-38
lines changed

1 file changed

+50
-38
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15710,48 +15710,51 @@ bool AArch64TargetLowering::shouldSinkOperands(
1571015710
return false;
1571115711
}
1571215712

15713-
static bool createTblShuffleForZExt(ZExtInst *ZExt, FixedVectorType *DstTy,
15714-
bool IsLittleEndian) {
15715-
Value *Op = ZExt->getOperand(0);
15716-
auto *SrcTy = cast<FixedVectorType>(Op->getType());
15717-
auto SrcWidth = cast<IntegerType>(SrcTy->getElementType())->getBitWidth();
15718-
auto DstWidth = cast<IntegerType>(DstTy->getElementType())->getBitWidth();
15713+
static bool createTblShuffleMask(unsigned SrcWidth, unsigned DstWidth,
15714+
unsigned NumElts, bool IsLittleEndian,
15715+
SmallVectorImpl<int> &Mask) {
1571915716
if (DstWidth % 8 != 0 || DstWidth <= 16 || DstWidth >= 64)
1572015717
return false;
1572115718

15722-
assert(DstWidth % SrcWidth == 0 &&
15723-
"TBL lowering is not supported for a ZExt instruction with this "
15724-
"source & destination element type.");
15725-
unsigned ZExtFactor = DstWidth / SrcWidth;
15719+
if (DstWidth % SrcWidth != 0)
15720+
return false;
15721+
15722+
unsigned Factor = DstWidth / SrcWidth;
15723+
unsigned MaskLen = NumElts * Factor;
15724+
15725+
Mask.clear();
15726+
Mask.resize(MaskLen, NumElts);
15727+
15728+
unsigned SrcIndex = 0;
15729+
for (unsigned I = 0; I < MaskLen; I += Factor)
15730+
Mask[I] = SrcIndex++;
15731+
15732+
if (!IsLittleEndian)
15733+
std::rotate(Mask.rbegin(), Mask.rbegin() + Factor - 1, Mask.rend());
15734+
15735+
return true;
15736+
}
15737+
15738+
static Value *createTblShuffleForZExt(IRBuilderBase &Builder, Value *Op,
15739+
FixedVectorType *ZExtTy,
15740+
FixedVectorType *DstTy,
15741+
bool IsLittleEndian) {
15742+
auto *SrcTy = cast<FixedVectorType>(Op->getType());
1572615743
unsigned NumElts = SrcTy->getNumElements();
15727-
IRBuilder<> Builder(ZExt);
15744+
auto SrcWidth = cast<IntegerType>(SrcTy->getElementType())->getBitWidth();
15745+
auto DstWidth = cast<IntegerType>(DstTy->getElementType())->getBitWidth();
15746+
1572815747
SmallVector<int> Mask;
15729-
// Create a mask that selects <0,...,Op[i]> for each lane of the destination
15730-
// vector to replace the original ZExt. This can later be lowered to a set of
15731-
// tbl instructions.
15732-
for (unsigned i = 0; i < NumElts * ZExtFactor; i++) {
15733-
if (IsLittleEndian) {
15734-
if (i % ZExtFactor == 0)
15735-
Mask.push_back(i / ZExtFactor);
15736-
else
15737-
Mask.push_back(NumElts);
15738-
} else {
15739-
if ((i + 1) % ZExtFactor == 0)
15740-
Mask.push_back((i - ZExtFactor + 1) / ZExtFactor);
15741-
else
15742-
Mask.push_back(NumElts);
15743-
}
15744-
}
15748+
if (!createTblShuffleMask(SrcWidth, DstWidth, NumElts, IsLittleEndian, Mask))
15749+
return nullptr;
1574515750

1574615751
auto *FirstEltZero = Builder.CreateInsertElement(
1574715752
PoisonValue::get(SrcTy), Builder.getInt8(0), uint64_t(0));
1574815753
Value *Result = Builder.CreateShuffleVector(Op, FirstEltZero, Mask);
1574915754
Result = Builder.CreateBitCast(Result, DstTy);
15750-
if (DstTy != ZExt->getType())
15751-
Result = Builder.CreateZExt(Result, ZExt->getType());
15752-
ZExt->replaceAllUsesWith(Result);
15753-
ZExt->eraseFromParent();
15754-
return true;
15755+
if (DstTy != ZExtTy)
15756+
Result = Builder.CreateZExt(Result, ZExtTy);
15757+
return Result;
1575515758
}
1575615759

1575715760
static void createTblForTrunc(TruncInst *TI, bool IsLittleEndian) {
@@ -15916,21 +15919,30 @@ bool AArch64TargetLowering::optimizeExtendOrTruncateConversion(
1591615919

1591715920
DstTy = TruncDstType;
1591815921
}
15919-
15920-
return createTblShuffleForZExt(ZExt, DstTy, Subtarget->isLittleEndian());
15922+
IRBuilder<> Builder(ZExt);
15923+
Value *Result = createTblShuffleForZExt(
15924+
Builder, ZExt->getOperand(0), cast<FixedVectorType>(ZExt->getType()),
15925+
DstTy, Subtarget->isLittleEndian());
15926+
if (!Result)
15927+
return false;
15928+
ZExt->replaceAllUsesWith(Result);
15929+
ZExt->eraseFromParent();
15930+
return true;
1592115931
}
1592215932

1592315933
auto *UIToFP = dyn_cast<UIToFPInst>(I);
1592415934
if (UIToFP && SrcTy->getElementType()->isIntegerTy(8) &&
1592515935
DstTy->getElementType()->isFloatTy()) {
1592615936
IRBuilder<> Builder(I);
15927-
auto *ZExt = cast<ZExtInst>(
15928-
Builder.CreateZExt(I->getOperand(0), VectorType::getInteger(DstTy)));
15937+
Value *ZExt = createTblShuffleForZExt(
15938+
Builder, I->getOperand(0), FixedVectorType::getInteger(DstTy),
15939+
FixedVectorType::getInteger(DstTy), Subtarget->isLittleEndian());
15940+
if (!ZExt)
15941+
return false;
1592915942
auto *UI = Builder.CreateUIToFP(ZExt, DstTy);
1593015943
I->replaceAllUsesWith(UI);
1593115944
I->eraseFromParent();
15932-
return createTblShuffleForZExt(ZExt, cast<FixedVectorType>(ZExt->getType()),
15933-
Subtarget->isLittleEndian());
15945+
return true;
1593415946
}
1593515947

1593615948
// Convert 'fptoui <(8|16) x float> to <(8|16) x i8>' to a wide fptoui

0 commit comments

Comments
 (0)