Skip to content

Commit 96e8d0f

Browse files
[AArch64] Refactor creation of a shuffle mask for TBL (NFC) (#92529)
... in preparation for #92528
1 parent 0432221 commit 96e8d0f

File tree

1 file changed

+47
-37
lines changed

1 file changed

+47
-37
lines changed

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15824,48 +15824,49 @@ bool AArch64TargetLowering::shouldSinkOperands(
1582415824
return false;
1582515825
}
1582615826

15827-
static bool createTblShuffleForZExt(ZExtInst *ZExt, FixedVectorType *DstTy,
15828-
bool IsLittleEndian) {
15829-
Value *Op = ZExt->getOperand(0);
15830-
auto *SrcTy = cast<FixedVectorType>(Op->getType());
15831-
auto SrcWidth = cast<IntegerType>(SrcTy->getElementType())->getBitWidth();
15832-
auto DstWidth = cast<IntegerType>(DstTy->getElementType())->getBitWidth();
15827+
static bool createTblShuffleMask(unsigned SrcWidth, unsigned DstWidth,
15828+
unsigned NumElts, bool IsLittleEndian,
15829+
SmallVectorImpl<int> &Mask) {
1583315830
if (DstWidth % 8 != 0 || DstWidth <= 16 || DstWidth >= 64)
1583415831
return false;
1583515832

1583615833
assert(DstWidth % SrcWidth == 0 &&
15837-
"TBL lowering is not supported for a ZExt instruction with this "
15838-
"source & destination element type.");
15839-
unsigned ZExtFactor = DstWidth / SrcWidth;
15834+
"TBL lowering is not supported for a conversion instruction with this "
15835+
"source and destination element type.");
15836+
15837+
unsigned Factor = DstWidth / SrcWidth;
15838+
unsigned MaskLen = NumElts * Factor;
15839+
15840+
Mask.clear();
15841+
Mask.resize(MaskLen, NumElts);
15842+
15843+
unsigned SrcIndex = 0;
15844+
for (unsigned I = IsLittleEndian ? 0 : Factor - 1; I < MaskLen; I += Factor)
15845+
Mask[I] = SrcIndex++;
15846+
15847+
return true;
15848+
}
15849+
15850+
static Value *createTblShuffleForZExt(IRBuilderBase &Builder, Value *Op,
15851+
FixedVectorType *ZExtTy,
15852+
FixedVectorType *DstTy,
15853+
bool IsLittleEndian) {
15854+
auto *SrcTy = cast<FixedVectorType>(Op->getType());
1584015855
unsigned NumElts = SrcTy->getNumElements();
15841-
IRBuilder<> Builder(ZExt);
15856+
auto SrcWidth = cast<IntegerType>(SrcTy->getElementType())->getBitWidth();
15857+
auto DstWidth = cast<IntegerType>(DstTy->getElementType())->getBitWidth();
15858+
1584215859
SmallVector<int> Mask;
15843-
// Create a mask that selects <0,...,Op[i]> for each lane of the destination
15844-
// vector to replace the original ZExt. This can later be lowered to a set of
15845-
// tbl instructions.
15846-
for (unsigned i = 0; i < NumElts * ZExtFactor; i++) {
15847-
if (IsLittleEndian) {
15848-
if (i % ZExtFactor == 0)
15849-
Mask.push_back(i / ZExtFactor);
15850-
else
15851-
Mask.push_back(NumElts);
15852-
} else {
15853-
if ((i + 1) % ZExtFactor == 0)
15854-
Mask.push_back((i - ZExtFactor + 1) / ZExtFactor);
15855-
else
15856-
Mask.push_back(NumElts);
15857-
}
15858-
}
15860+
if (!createTblShuffleMask(SrcWidth, DstWidth, NumElts, IsLittleEndian, Mask))
15861+
return nullptr;
1585915862

1586015863
auto *FirstEltZero = Builder.CreateInsertElement(
1586115864
PoisonValue::get(SrcTy), Builder.getInt8(0), uint64_t(0));
1586215865
Value *Result = Builder.CreateShuffleVector(Op, FirstEltZero, Mask);
1586315866
Result = Builder.CreateBitCast(Result, DstTy);
15864-
if (DstTy != ZExt->getType())
15865-
Result = Builder.CreateZExt(Result, ZExt->getType());
15866-
ZExt->replaceAllUsesWith(Result);
15867-
ZExt->eraseFromParent();
15868-
return true;
15867+
if (DstTy != ZExtTy)
15868+
Result = Builder.CreateZExt(Result, ZExtTy);
15869+
return Result;
1586915870
}
1587015871

1587115872
static void createTblForTrunc(TruncInst *TI, bool IsLittleEndian) {
@@ -16030,21 +16031,30 @@ bool AArch64TargetLowering::optimizeExtendOrTruncateConversion(
1603016031

1603116032
DstTy = TruncDstType;
1603216033
}
16033-
16034-
return createTblShuffleForZExt(ZExt, DstTy, Subtarget->isLittleEndian());
16034+
IRBuilder<> Builder(ZExt);
16035+
Value *Result = createTblShuffleForZExt(
16036+
Builder, ZExt->getOperand(0), cast<FixedVectorType>(ZExt->getType()),
16037+
DstTy, Subtarget->isLittleEndian());
16038+
if (!Result)
16039+
return false;
16040+
ZExt->replaceAllUsesWith(Result);
16041+
ZExt->eraseFromParent();
16042+
return true;
1603516043
}
1603616044

1603716045
auto *UIToFP = dyn_cast<UIToFPInst>(I);
1603816046
if (UIToFP && SrcTy->getElementType()->isIntegerTy(8) &&
1603916047
DstTy->getElementType()->isFloatTy()) {
1604016048
IRBuilder<> Builder(I);
16041-
auto *ZExt = cast<ZExtInst>(
16042-
Builder.CreateZExt(I->getOperand(0), VectorType::getInteger(DstTy)));
16049+
Value *ZExt = createTblShuffleForZExt(
16050+
Builder, I->getOperand(0), FixedVectorType::getInteger(DstTy),
16051+
FixedVectorType::getInteger(DstTy), Subtarget->isLittleEndian());
16052+
if (!ZExt)
16053+
return false;
1604316054
auto *UI = Builder.CreateUIToFP(ZExt, DstTy);
1604416055
I->replaceAllUsesWith(UI);
1604516056
I->eraseFromParent();
16046-
return createTblShuffleForZExt(ZExt, cast<FixedVectorType>(ZExt->getType()),
16047-
Subtarget->isLittleEndian());
16057+
return true;
1604816058
}
1604916059

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

0 commit comments

Comments
 (0)