aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2024-01-19 18:17:45 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2024-01-22 11:44:51 +0000
commitc1729c8df2e2d0e9ef3c039df78f2711ea8fe65c (patch)
tree0af110d3fe33d5cd3e52c7bc1283f8f6cf3381a3
parenta590f2315f45615920f244dcce12a7e169148da7 (diff)
downloadllvm-c1729c8df2e2d0e9ef3c039df78f2711ea8fe65c.zip
llvm-c1729c8df2e2d0e9ef3c039df78f2711ea8fe65c.tar.gz
llvm-c1729c8df2e2d0e9ef3c039df78f2711ea8fe65c.tar.bz2
[X86] X86FixupVectorConstants.cpp - pull out rebuildConstant helper for future patches. NFC.
Add helper to convert raw APInt bit stream into ConstantDataVector elements. This was used internally by rebuildSplatableConstant but will be reused in future patches for #73783 and #71078
-rw-r--r--llvm/lib/Target/X86/X86FixupVectorConstants.cpp62
1 files changed, 38 insertions, 24 deletions
diff --git a/llvm/lib/Target/X86/X86FixupVectorConstants.cpp b/llvm/lib/Target/X86/X86FixupVectorConstants.cpp
index 8fcf077..5ae41dc 100644
--- a/llvm/lib/Target/X86/X86FixupVectorConstants.cpp
+++ b/llvm/lib/Target/X86/X86FixupVectorConstants.cpp
@@ -158,34 +158,23 @@ static std::optional<APInt> getSplatableConstant(const Constant *C,
return std::nullopt;
}
-// Attempt to rebuild a normalized splat vector constant of the requested splat
-// width, built up of potentially smaller scalar values.
+// Split raw bits into a constant vector of elements of a specific bit width.
// NOTE: We don't always bother converting to scalars if the vector length is 1.
-static Constant *rebuildSplatableConstant(const Constant *C,
- unsigned SplatBitWidth) {
- std::optional<APInt> Splat = getSplatableConstant(C, SplatBitWidth);
- if (!Splat)
- return nullptr;
-
- // Determine scalar size to use for the constant splat vector, clamping as we
- // might have found a splat smaller than the original constant data.
- const Type *OriginalType = C->getType();
- Type *SclTy = OriginalType->getScalarType();
- unsigned NumSclBits = SclTy->getPrimitiveSizeInBits();
- NumSclBits = std::min<unsigned>(NumSclBits, SplatBitWidth);
- LLVMContext &Ctx = OriginalType->getContext();
+static Constant *rebuildConstant(LLVMContext &Ctx, Type *SclTy,
+ const APInt &Bits, unsigned NumSclBits) {
+ unsigned BitWidth = Bits.getBitWidth();
if (NumSclBits == 8) {
SmallVector<uint8_t> RawBits;
- for (unsigned I = 0; I != SplatBitWidth; I += 8)
- RawBits.push_back(Splat->extractBits(8, I).getZExtValue());
+ for (unsigned I = 0; I != BitWidth; I += 8)
+ RawBits.push_back(Bits.extractBits(8, I).getZExtValue());
return ConstantDataVector::get(Ctx, RawBits);
}
if (NumSclBits == 16) {
SmallVector<uint16_t> RawBits;
- for (unsigned I = 0; I != SplatBitWidth; I += 16)
- RawBits.push_back(Splat->extractBits(16, I).getZExtValue());
+ for (unsigned I = 0; I != BitWidth; I += 16)
+ RawBits.push_back(Bits.extractBits(16, I).getZExtValue());
if (SclTy->is16bitFPTy())
return ConstantDataVector::getFP(SclTy, RawBits);
return ConstantDataVector::get(Ctx, RawBits);
@@ -193,22 +182,47 @@ static Constant *rebuildSplatableConstant(const Constant *C,
if (NumSclBits == 32) {
SmallVector<uint32_t> RawBits;
- for (unsigned I = 0; I != SplatBitWidth; I += 32)
- RawBits.push_back(Splat->extractBits(32, I).getZExtValue());
+ for (unsigned I = 0; I != BitWidth; I += 32)
+ RawBits.push_back(Bits.extractBits(32, I).getZExtValue());
if (SclTy->isFloatTy())
return ConstantDataVector::getFP(SclTy, RawBits);
return ConstantDataVector::get(Ctx, RawBits);
}
- // Fallback to i64 / double.
+ assert(NumSclBits == 64 && "Unhandled vector element width");
+
SmallVector<uint64_t> RawBits;
- for (unsigned I = 0; I != SplatBitWidth; I += 64)
- RawBits.push_back(Splat->extractBits(64, I).getZExtValue());
+ for (unsigned I = 0; I != BitWidth; I += 64)
+ RawBits.push_back(Bits.extractBits(64, I).getZExtValue());
if (SclTy->isDoubleTy())
return ConstantDataVector::getFP(SclTy, RawBits);
return ConstantDataVector::get(Ctx, RawBits);
}
+// Attempt to rebuild a normalized splat vector constant of the requested splat
+// width, built up of potentially smaller scalar values.
+static Constant *rebuildSplatableConstant(const Constant *C,
+ unsigned SplatBitWidth) {
+ std::optional<APInt> Splat = getSplatableConstant(C, SplatBitWidth);
+ if (!Splat)
+ return nullptr;
+
+ // Determine scalar size to use for the constant splat vector, clamping as we
+ // might have found a splat smaller than the original constant data.
+ const Type *OriginalType = C->getType();
+ Type *SclTy = OriginalType->getScalarType();
+ unsigned NumSclBits = SclTy->getPrimitiveSizeInBits();
+ NumSclBits = std::min<unsigned>(NumSclBits, SplatBitWidth);
+
+ // Fallback to i64 / double.
+ NumSclBits = (NumSclBits == 8 || NumSclBits == 16 || NumSclBits == 32)
+ ? NumSclBits
+ : 64;
+
+ // Extract per-element bits.
+ return rebuildConstant(OriginalType->getContext(), SclTy, *Splat, NumSclBits);
+}
+
bool X86FixupVectorConstantsPass::processInstruction(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineInstr &MI) {