Skip to content

Commit c1729c8

Browse files
committed
[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
1 parent a590f23 commit c1729c8

File tree

1 file changed

+38
-24
lines changed

1 file changed

+38
-24
lines changed

llvm/lib/Target/X86/X86FixupVectorConstants.cpp

+38-24
Original file line numberDiff line numberDiff line change
@@ -158,57 +158,71 @@ static std::optional<APInt> getSplatableConstant(const Constant *C,
158158
return std::nullopt;
159159
}
160160

161-
// Attempt to rebuild a normalized splat vector constant of the requested splat
162-
// width, built up of potentially smaller scalar values.
161+
// Split raw bits into a constant vector of elements of a specific bit width.
163162
// NOTE: We don't always bother converting to scalars if the vector length is 1.
164-
static Constant *rebuildSplatableConstant(const Constant *C,
165-
unsigned SplatBitWidth) {
166-
std::optional<APInt> Splat = getSplatableConstant(C, SplatBitWidth);
167-
if (!Splat)
168-
return nullptr;
169-
170-
// Determine scalar size to use for the constant splat vector, clamping as we
171-
// might have found a splat smaller than the original constant data.
172-
const Type *OriginalType = C->getType();
173-
Type *SclTy = OriginalType->getScalarType();
174-
unsigned NumSclBits = SclTy->getPrimitiveSizeInBits();
175-
NumSclBits = std::min<unsigned>(NumSclBits, SplatBitWidth);
176-
LLVMContext &Ctx = OriginalType->getContext();
163+
static Constant *rebuildConstant(LLVMContext &Ctx, Type *SclTy,
164+
const APInt &Bits, unsigned NumSclBits) {
165+
unsigned BitWidth = Bits.getBitWidth();
177166

178167
if (NumSclBits == 8) {
179168
SmallVector<uint8_t> RawBits;
180-
for (unsigned I = 0; I != SplatBitWidth; I += 8)
181-
RawBits.push_back(Splat->extractBits(8, I).getZExtValue());
169+
for (unsigned I = 0; I != BitWidth; I += 8)
170+
RawBits.push_back(Bits.extractBits(8, I).getZExtValue());
182171
return ConstantDataVector::get(Ctx, RawBits);
183172
}
184173

185174
if (NumSclBits == 16) {
186175
SmallVector<uint16_t> RawBits;
187-
for (unsigned I = 0; I != SplatBitWidth; I += 16)
188-
RawBits.push_back(Splat->extractBits(16, I).getZExtValue());
176+
for (unsigned I = 0; I != BitWidth; I += 16)
177+
RawBits.push_back(Bits.extractBits(16, I).getZExtValue());
189178
if (SclTy->is16bitFPTy())
190179
return ConstantDataVector::getFP(SclTy, RawBits);
191180
return ConstantDataVector::get(Ctx, RawBits);
192181
}
193182

194183
if (NumSclBits == 32) {
195184
SmallVector<uint32_t> RawBits;
196-
for (unsigned I = 0; I != SplatBitWidth; I += 32)
197-
RawBits.push_back(Splat->extractBits(32, I).getZExtValue());
185+
for (unsigned I = 0; I != BitWidth; I += 32)
186+
RawBits.push_back(Bits.extractBits(32, I).getZExtValue());
198187
if (SclTy->isFloatTy())
199188
return ConstantDataVector::getFP(SclTy, RawBits);
200189
return ConstantDataVector::get(Ctx, RawBits);
201190
}
202191

203-
// Fallback to i64 / double.
192+
assert(NumSclBits == 64 && "Unhandled vector element width");
193+
204194
SmallVector<uint64_t> RawBits;
205-
for (unsigned I = 0; I != SplatBitWidth; I += 64)
206-
RawBits.push_back(Splat->extractBits(64, I).getZExtValue());
195+
for (unsigned I = 0; I != BitWidth; I += 64)
196+
RawBits.push_back(Bits.extractBits(64, I).getZExtValue());
207197
if (SclTy->isDoubleTy())
208198
return ConstantDataVector::getFP(SclTy, RawBits);
209199
return ConstantDataVector::get(Ctx, RawBits);
210200
}
211201

202+
// Attempt to rebuild a normalized splat vector constant of the requested splat
203+
// width, built up of potentially smaller scalar values.
204+
static Constant *rebuildSplatableConstant(const Constant *C,
205+
unsigned SplatBitWidth) {
206+
std::optional<APInt> Splat = getSplatableConstant(C, SplatBitWidth);
207+
if (!Splat)
208+
return nullptr;
209+
210+
// Determine scalar size to use for the constant splat vector, clamping as we
211+
// might have found a splat smaller than the original constant data.
212+
const Type *OriginalType = C->getType();
213+
Type *SclTy = OriginalType->getScalarType();
214+
unsigned NumSclBits = SclTy->getPrimitiveSizeInBits();
215+
NumSclBits = std::min<unsigned>(NumSclBits, SplatBitWidth);
216+
217+
// Fallback to i64 / double.
218+
NumSclBits = (NumSclBits == 8 || NumSclBits == 16 || NumSclBits == 32)
219+
? NumSclBits
220+
: 64;
221+
222+
// Extract per-element bits.
223+
return rebuildConstant(OriginalType->getContext(), SclTy, *Splat, NumSclBits);
224+
}
225+
212226
bool X86FixupVectorConstantsPass::processInstruction(MachineFunction &MF,
213227
MachineBasicBlock &MBB,
214228
MachineInstr &MI) {

0 commit comments

Comments
 (0)