Skip to content

Commit 1616643

Browse files
[AArch64] Refactor creation of a shuffle mask for TBL (NFC)
1 parent ae86278 commit 1616643

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
@@ -15756,48 +15756,51 @@ bool AArch64TargetLowering::shouldSinkOperands(
1575615756
return false;
1575715757
}
1575815758

15759-
static bool createTblShuffleForZExt(ZExtInst *ZExt, FixedVectorType *DstTy,
15760-
bool IsLittleEndian) {
15761-
Value *Op = ZExt->getOperand(0);
15762-
auto *SrcTy = cast<FixedVectorType>(Op->getType());
15763-
auto SrcWidth = cast<IntegerType>(SrcTy->getElementType())->getBitWidth();
15764-
auto DstWidth = cast<IntegerType>(DstTy->getElementType())->getBitWidth();
15759+
static bool createTblShuffleMask(unsigned SrcWidth, unsigned DstWidth,
15760+
unsigned NumElts, bool IsLittleEndian,
15761+
SmallVectorImpl<int> &Mask) {
1576515762
if (DstWidth % 8 != 0 || DstWidth <= 16 || DstWidth >= 64)
1576615763
return false;
1576715764

15768-
assert(DstWidth % SrcWidth == 0 &&
15769-
"TBL lowering is not supported for a ZExt instruction with this "
15770-
"source & destination element type.");
15771-
unsigned ZExtFactor = DstWidth / SrcWidth;
15765+
if (DstWidth % SrcWidth != 0)
15766+
return false;
15767+
15768+
unsigned Factor = DstWidth / SrcWidth;
15769+
unsigned MaskLen = NumElts * Factor;
15770+
15771+
Mask.clear();
15772+
Mask.resize(MaskLen, NumElts);
15773+
15774+
unsigned SrcIndex = 0;
15775+
for (unsigned I = 0; I < MaskLen; I += Factor)
15776+
Mask[I] = SrcIndex++;
15777+
15778+
if (!IsLittleEndian)
15779+
std::rotate(Mask.rbegin(), Mask.rbegin() + Factor - 1, Mask.rend());
15780+
15781+
return true;
15782+
}
15783+
15784+
static Value *createTblShuffleForZExt(IRBuilderBase &Builder, Value *Op,
15785+
FixedVectorType *ZExtTy,
15786+
FixedVectorType *DstTy,
15787+
bool IsLittleEndian) {
15788+
auto *SrcTy = cast<FixedVectorType>(Op->getType());
1577215789
unsigned NumElts = SrcTy->getNumElements();
15773-
IRBuilder<> Builder(ZExt);
15790+
auto SrcWidth = cast<IntegerType>(SrcTy->getElementType())->getBitWidth();
15791+
auto DstWidth = cast<IntegerType>(DstTy->getElementType())->getBitWidth();
15792+
1577415793
SmallVector<int> Mask;
15775-
// Create a mask that selects <0,...,Op[i]> for each lane of the destination
15776-
// vector to replace the original ZExt. This can later be lowered to a set of
15777-
// tbl instructions.
15778-
for (unsigned i = 0; i < NumElts * ZExtFactor; i++) {
15779-
if (IsLittleEndian) {
15780-
if (i % ZExtFactor == 0)
15781-
Mask.push_back(i / ZExtFactor);
15782-
else
15783-
Mask.push_back(NumElts);
15784-
} else {
15785-
if ((i + 1) % ZExtFactor == 0)
15786-
Mask.push_back((i - ZExtFactor + 1) / ZExtFactor);
15787-
else
15788-
Mask.push_back(NumElts);
15789-
}
15790-
}
15794+
if (!createTblShuffleMask(SrcWidth, DstWidth, NumElts, IsLittleEndian, Mask))
15795+
return nullptr;
1579115796

1579215797
auto *FirstEltZero = Builder.CreateInsertElement(
1579315798
PoisonValue::get(SrcTy), Builder.getInt8(0), uint64_t(0));
1579415799
Value *Result = Builder.CreateShuffleVector(Op, FirstEltZero, Mask);
1579515800
Result = Builder.CreateBitCast(Result, DstTy);
15796-
if (DstTy != ZExt->getType())
15797-
Result = Builder.CreateZExt(Result, ZExt->getType());
15798-
ZExt->replaceAllUsesWith(Result);
15799-
ZExt->eraseFromParent();
15800-
return true;
15801+
if (DstTy != ZExtTy)
15802+
Result = Builder.CreateZExt(Result, ZExtTy);
15803+
return Result;
1580115804
}
1580215805

1580315806
static void createTblForTrunc(TruncInst *TI, bool IsLittleEndian) {
@@ -15962,21 +15965,30 @@ bool AArch64TargetLowering::optimizeExtendOrTruncateConversion(
1596215965

1596315966
DstTy = TruncDstType;
1596415967
}
15965-
15966-
return createTblShuffleForZExt(ZExt, DstTy, Subtarget->isLittleEndian());
15968+
IRBuilder<> Builder(ZExt);
15969+
Value *Result = createTblShuffleForZExt(
15970+
Builder, ZExt->getOperand(0), cast<FixedVectorType>(ZExt->getType()),
15971+
DstTy, Subtarget->isLittleEndian());
15972+
if (!Result)
15973+
return false;
15974+
ZExt->replaceAllUsesWith(Result);
15975+
ZExt->eraseFromParent();
15976+
return true;
1596715977
}
1596815978

1596915979
auto *UIToFP = dyn_cast<UIToFPInst>(I);
1597015980
if (UIToFP && SrcTy->getElementType()->isIntegerTy(8) &&
1597115981
DstTy->getElementType()->isFloatTy()) {
1597215982
IRBuilder<> Builder(I);
15973-
auto *ZExt = cast<ZExtInst>(
15974-
Builder.CreateZExt(I->getOperand(0), VectorType::getInteger(DstTy)));
15983+
Value *ZExt = createTblShuffleForZExt(
15984+
Builder, I->getOperand(0), FixedVectorType::getInteger(DstTy),
15985+
FixedVectorType::getInteger(DstTy), Subtarget->isLittleEndian());
15986+
if (!ZExt)
15987+
return false;
1597515988
auto *UI = Builder.CreateUIToFP(ZExt, DstTy);
1597615989
I->replaceAllUsesWith(UI);
1597715990
I->eraseFromParent();
15978-
return createTblShuffleForZExt(ZExt, cast<FixedVectorType>(ZExt->getType()),
15979-
Subtarget->isLittleEndian());
15991+
return true;
1598015992
}
1598115993

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

0 commit comments

Comments
 (0)