Skip to content

Commit ea8d0a5

Browse files
committed
[Transforms] Resolve FIXME: Pick the smallest legal type that fits
Pick the type based on the smallest bit-width possible, using DataLayout.
1 parent 19146b9 commit ea8d0a5

File tree

3 files changed

+376
-19
lines changed

3 files changed

+376
-19
lines changed

llvm/include/llvm/Transforms/Scalar/Float2Int.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class Float2IntPass : public PassInfoMixin<Float2IntPass> {
4444
std::optional<ConstantRange> calcRange(Instruction *I);
4545
void walkBackwards();
4646
void walkForwards();
47-
bool validateAndTransform();
47+
bool validateAndTransform(const DataLayout &DL);
4848
Value *convert(Instruction *I, Type *ToTy);
4949
void cleanup();
5050

llvm/lib/Transforms/Scalar/Float2Int.cpp

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ void Float2IntPass::walkForwards() {
311311
}
312312

313313
// If there is a valid transform to be done, do it.
314-
bool Float2IntPass::validateAndTransform() {
314+
bool Float2IntPass::validateAndTransform(const DataLayout &DL) {
315315
bool MadeChange = false;
316316

317317
// Iterate over every disjoint partition of the def-use graph.
@@ -321,8 +321,8 @@ bool Float2IntPass::validateAndTransform() {
321321
Type *ConvertedToTy = nullptr;
322322

323323
// For every member of the partition, union all the ranges together.
324-
for (auto MI = ECs.member_begin(It), ME = ECs.member_end();
325-
MI != ME; ++MI) {
324+
for (auto MI = ECs.member_begin(It), ME = ECs.member_end(); MI != ME;
325+
++MI) {
326326
Instruction *I = *MI;
327327
auto SeenI = SeenInsts.find(I);
328328
if (SeenI == SeenInsts.end())
@@ -352,8 +352,8 @@ bool Float2IntPass::validateAndTransform() {
352352

353353
// If the set was empty, or we failed, or the range is poisonous,
354354
// bail out.
355-
if (ECs.member_begin(It) == ECs.member_end() || Fail ||
356-
R.isFullSet() || R.isSignWrappedSet())
355+
if (ECs.member_begin(It) == ECs.member_end() || Fail || R.isFullSet() ||
356+
R.isSignWrappedSet())
357357
continue;
358358
assert(ConvertedToTy && "Must have set the convertedtoty by this point!");
359359

@@ -370,24 +370,29 @@ bool Float2IntPass::validateAndTransform() {
370370
// Do we need more bits than are in the mantissa of the type we converted
371371
// to? semanticsPrecision returns the number of mantissa bits plus one
372372
// for the sign bit.
373-
unsigned MaxRepresentableBits
374-
= APFloat::semanticsPrecision(ConvertedToTy->getFltSemantics()) - 1;
373+
unsigned MaxRepresentableBits =
374+
APFloat::semanticsPrecision(ConvertedToTy->getFltSemantics()) - 1;
375375
if (MinBW > MaxRepresentableBits) {
376376
LLVM_DEBUG(dbgs() << "F2I: Value not guaranteed to be representable!\n");
377377
continue;
378378
}
379-
if (MinBW > 64) {
380-
LLVM_DEBUG(
381-
dbgs() << "F2I: Value requires more than 64 bits to represent!\n");
382-
continue;
383-
}
384379

385-
// OK, R is known to be representable. Now pick a type for it.
386-
// FIXME: Pick the smallest legal type that will fit.
387-
Type *Ty = (MinBW > 32) ? Type::getInt64Ty(*Ctx) : Type::getInt32Ty(*Ctx);
380+
// OK, R is known to be representable.
381+
// Pick the smallest legal type that will fit.
382+
Type *Ty = DL.getSmallestLegalIntType(*Ctx, MinBW);
383+
if (!Ty) {
384+
if (MinBW > 64) {
385+
LLVM_DEBUG(dbgs() << "F2I: Value requires more than bits to represent "
386+
"than the target supports!\n");
387+
continue;
388+
}
389+
390+
// Every supported target supports 64 and 32-bit
391+
// integers.
392+
Ty = (MinBW > 32) ? Type::getInt64Ty(*Ctx) : Type::getInt32Ty(*Ctx);
393+
}
388394

389-
for (auto MI = ECs.member_begin(It), ME = ECs.member_end();
390-
MI != ME; ++MI)
395+
for (auto MI = ECs.member_begin(It), ME = ECs.member_end(); MI != ME; ++MI)
391396
convert(*MI, Ty);
392397
MadeChange = true;
393398
}
@@ -491,7 +496,8 @@ bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) {
491496
walkBackwards();
492497
walkForwards();
493498

494-
bool Modified = validateAndTransform();
499+
const DataLayout &DL = F.getParent()->getDataLayout();
500+
bool Modified = validateAndTransform(DL);
495501
if (Modified)
496502
cleanup();
497503
return Modified;

0 commit comments

Comments
 (0)