diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2024-01-19 18:17:45 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2024-01-22 11:44:51 +0000 |
commit | c1729c8df2e2d0e9ef3c039df78f2711ea8fe65c (patch) | |
tree | 0af110d3fe33d5cd3e52c7bc1283f8f6cf3381a3 | |
parent | a590f2315f45615920f244dcce12a7e169148da7 (diff) | |
download | llvm-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.cpp | 62 |
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) { |