Skip to content

Commit 7b3e943

Browse files
authored
Reapply: [Float2Int] Resolve FIXME: Pick the smallest legal type that fits (#86337)
Originally reverted because of a bug in Range that is now fixed (#86041), we can reland this commit. Tests have been added to ensure the miscompile that caused the revert does not happen again.
1 parent a83ed04 commit 7b3e943

File tree

4 files changed

+334
-69
lines changed

4 files changed

+334
-69
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: 19 additions & 10 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.
@@ -374,15 +374,23 @@ bool Float2IntPass::validateAndTransform() {
374374
LLVM_DEBUG(dbgs() << "F2I: Value not guaranteed to be representable!\n");
375375
continue;
376376
}
377-
if (MinBW > 64) {
378-
LLVM_DEBUG(
379-
dbgs() << "F2I: Value requires more than 64 bits to represent!\n");
380-
continue;
381-
}
382377

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

387395
for (auto MI = ECs.member_begin(It), ME = ECs.member_end();
388396
MI != ME; ++MI)
@@ -489,7 +497,8 @@ bool Float2IntPass::runImpl(Function &F, const DominatorTree &DT) {
489497
walkBackwards();
490498
walkForwards();
491499

492-
bool Modified = validateAndTransform();
500+
const DataLayout &DL = F.getParent()->getDataLayout();
501+
bool Modified = validateAndTransform(DL);
493502
if (Modified)
494503
cleanup();
495504
return Modified;

0 commit comments

Comments
 (0)