28#define DEBUG_TYPE "float2int"
75 case Instruction::FAdd:
return Instruction::Add;
76 case Instruction::FSub:
return Instruction::Sub;
77 case Instruction::FMul:
return Instruction::Mul;
84 for (BasicBlock &BB :
F) {
90 for (Instruction &
I : BB) {
93 switch (
I.getOpcode()) {
95 case Instruction::FPToUI:
96 case Instruction::FPToSI:
99 case Instruction::FCmp:
112 SeenInsts.insert_or_assign(
I, std::move(R));
117 return ConstantRange::getFull(MaxIntegerBW + 1);
120 return ConstantRange::getEmpty(MaxIntegerBW + 1);
123 if (
R.getBitWidth() > MaxIntegerBW + 1)
142void Float2IntPass::walkBackwards() {
143 std::deque<Instruction*> Worklist(Roots.begin(), Roots.end());
144 while (!Worklist.empty()) {
148 if (SeenInsts.contains(
I))
152 switch (
I->getOpcode()) {
159 case Instruction::UIToFP:
160 case Instruction::SIToFP: {
163 unsigned BW =
I->getOperand(0)->getType()->getPrimitiveSizeInBits();
164 auto Input = ConstantRange::getFull(BW);
166 seen(
I, validateRange(Input.castOp(CastOp, MaxIntegerBW+1)));
170 case Instruction::FNeg:
171 case Instruction::FAdd:
172 case Instruction::FSub:
173 case Instruction::FMul:
174 case Instruction::FPToUI:
175 case Instruction::FPToSI:
176 case Instruction::FCmp:
177 seen(
I, unknownRange());
181 for (
Value *O :
I->operands()) {
184 ECs.unionSets(
I, OI);
185 if (SeenInsts.find(
I)->second != badRange())
186 Worklist.push_back(OI);
197std::optional<ConstantRange> Float2IntPass::calcRange(
Instruction *
I) {
199 for (
Value *O :
I->operands()) {
201 auto OpIt = SeenInsts.find(OI);
202 assert(OpIt != SeenInsts.end() &&
"def not seen before use!");
203 if (OpIt->second == unknownRange())
216 const APFloat &
F = CF->getValueAPF();
223 !
I->hasNoSignedZeros()))
247 switch (
I->getOpcode()) {
250 case Instruction::UIToFP:
251 case Instruction::SIToFP:
254 case Instruction::FNeg: {
255 assert(OpRanges.
size() == 1 &&
"FNeg is a unary operator!");
256 unsigned Size = OpRanges[0].getBitWidth();
258 return Zero.sub(OpRanges[0]);
261 case Instruction::FAdd:
262 case Instruction::FSub:
263 case Instruction::FMul: {
264 assert(OpRanges.
size() == 2 &&
"its a binary operator!");
266 return OpRanges[0].binaryOp(BinOp, OpRanges[1]);
273 case Instruction::FPToUI:
274 case Instruction::FPToSI: {
275 assert(OpRanges.
size() == 1 &&
"FPTo[US]I is a unary operator!");
279 return OpRanges[0].castOp(CastOp, MaxIntegerBW+1);
282 case Instruction::FCmp:
283 assert(OpRanges.
size() == 2 &&
"FCmp is a binary operator!");
284 return OpRanges[0].unionWith(OpRanges[1]);
290void Float2IntPass::walkForwards() {
291 std::deque<Instruction *> Worklist;
292 for (
const auto &Pair : SeenInsts)
293 if (Pair.second == unknownRange())
294 Worklist.push_back(Pair.first);
296 while (!Worklist.empty()) {
300 if (std::optional<ConstantRange>
Range = calcRange(
I))
303 Worklist.push_front(
I);
308bool Float2IntPass::validateAndTransform(
const DataLayout &
DL) {
309 bool MadeChange =
false;
312 for (
const auto &
E : ECs) {
316 ConstantRange
R(MaxIntegerBW + 1,
false);
318 Type *ConvertedToTy =
nullptr;
321 for (Instruction *
I : ECs.members(*
E)) {
322 auto *SeenI = SeenInsts.find(
I);
323 if (SeenI == SeenInsts.end())
326 R =
R.unionWith(SeenI->second);
331 if (!Roots.contains(
I)) {
334 ConvertedToTy =
I->getType();
335 for (User *U :
I->users()) {
337 if (!UI || !SeenInsts.contains(UI)) {
350 if (ECs.member_begin(*
E) == ECs.member_end() ||
Fail ||
R.isFullSet() ||
351 R.isSignWrappedSet())
353 assert(ConvertedToTy &&
"Must have set the convertedtoty by this point!");
357 unsigned MinBW =
R.getMinSignedBits() + 1;
358 LLVM_DEBUG(
dbgs() <<
"F2I: MinBitwidth=" << MinBW <<
", R: " << R <<
"\n");
366 unsigned MaxRepresentableBits
368 if (MinBW > MaxRepresentableBits) {
369 LLVM_DEBUG(
dbgs() <<
"F2I: Value not guaranteed to be representable!\n");
375 Type *Ty =
DL.getSmallestLegalIntType(*Ctx, MinBW);
381 }
else if (MinBW <= 64) {
384 LLVM_DEBUG(
dbgs() <<
"F2I: Value requires more bits to represent than "
385 "the target supports!\n");
390 for (Instruction *
I : ECs.members(*
E))
399 if (
auto It = ConvertedInsts.find(
I); It != ConvertedInsts.end())
403 SmallVector<Value*,4> NewOperands;
404 for (
Value *V :
I->operands()) {
406 if (
I->getOpcode() == Instruction::UIToFP ||
407 I->getOpcode() == Instruction::SIToFP) {
410 NewOperands.
push_back(convert(VI, ToTy));
414 CF->getValueAPF().convertToInteger(Val,
417 NewOperands.
push_back(ConstantInt::get(ToTy, Val));
425 Value *NewV =
nullptr;
426 switch (
I->getOpcode()) {
429 case Instruction::FPToUI:
430 NewV = IRB.CreateZExtOrTrunc(NewOperands[0],
I->getType());
433 case Instruction::FPToSI:
434 NewV = IRB.CreateSExtOrTrunc(NewOperands[0],
I->getType());
437 case Instruction::FCmp: {
440 NewV = IRB.CreateICmp(
P, NewOperands[0], NewOperands[1],
I->getName());
444 case Instruction::UIToFP:
445 NewV = IRB.CreateZExtOrTrunc(NewOperands[0], ToTy);
448 case Instruction::SIToFP:
449 NewV = IRB.CreateSExtOrTrunc(NewOperands[0], ToTy);
452 case Instruction::FNeg:
453 NewV = IRB.CreateNeg(NewOperands[0],
I->getName());
456 case Instruction::FAdd:
457 case Instruction::FSub:
458 case Instruction::FMul:
460 NewOperands[0], NewOperands[1],
467 I->replaceAllUsesWith(NewV);
469 ConvertedInsts[
I] = NewV;
474void Float2IntPass::cleanup() {
475 for (
auto &
I :
reverse(ConvertedInsts))
476 I.first->eraseFromParent();
480 LLVM_DEBUG(
dbgs() <<
"F2I: Looking at function " <<
F.getName() <<
"\n");
484 ConvertedInsts.clear();
487 MaxIntegerBW = ScalarOptions::Global.float2int_max_integer_bw;
488 Ctx = &
F.getParent()->getContext();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
This file implements the APSInt class, which is a simple class that represents an arbitrary sized int...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static CmpInst::Predicate mapFCmpPred(CmpInst::Predicate P)
static Instruction::BinaryOps mapBinOpcode(unsigned Opcode)
This is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file defines the SmallVector class.
static constexpr roundingMode rmNearestTiesToEven
static LLVM_ABI unsigned int semanticsPrecision(const fltSemantics &)
opStatus
IEEE-754R 7: Default exception handling.
opStatus roundToIntegral(roundingMode RM)
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represents analyses that only rely on functions' control flow.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
This class represents a range of values.
A parsed version of the target data layout string in and methods for querying it.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
This represents a collection of equivalence classes and supports three efficient operations: insert a...
LLVM_ABI bool runImpl(Function &F, const DominatorTree &DT)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
void push_back(const T &Elt)
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI const fltSemantics & getFltSemantics() const
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.