15 #define DEBUG_TYPE "float2int" 50 cl::desc(
"Max integer bitwidth to consider in float2int" 64 return Impl.runImpl(F);
78 INITIALIZE_PASS(Float2IntLegacyPass,
"float2int",
"Float to int",
false,
false)
113 case Instruction::FSub:
return Instruction::Sub;
114 case Instruction::FMul:
return Instruction::Mul;
122 if (isa<VectorType>(
I.getType()))
124 switch (
I.getOpcode()) {
126 case Instruction::FPToUI:
127 case Instruction::FPToSI:
130 case Instruction::FCmp:
142 auto IT = SeenInsts.find(I);
143 if (
IT != SeenInsts.end())
144 IT->second = std::move(R);
146 SeenInsts.insert(std::make_pair(I, std::move(R)));
177 std::deque<Instruction*> Worklist(Roots.
begin(), Roots.
end());
178 while (!Worklist.empty()) {
182 if (SeenInsts.find(I) != SeenInsts.end())
193 case Instruction::UIToFP:
194 case Instruction::SIToFP: {
200 seen(I, validateRange(Input.castOp(CastOp,
MaxIntegerBW+1)));
204 case Instruction::FAdd:
205 case Instruction::FSub:
206 case Instruction::FMul:
207 case Instruction::FPToUI:
208 case Instruction::FPToSI:
209 case Instruction::FCmp:
210 seen(I, unknownRange());
217 ECs.unionSets(I, OI);
218 if (SeenInsts.find(I)->second != badRange())
219 Worklist.push_back(OI);
220 }
else if (!isa<ConstantFP>(
O)) {
230 void Float2IntPass::walkForwards() {
231 for (
auto &It :
reverse(SeenInsts)) {
232 if (It.second != unknownRange())
236 std::function<ConstantRange(ArrayRef<ConstantRange>)>
Op;
240 case Instruction::UIToFP:
241 case Instruction::SIToFP:
244 case Instruction::FAdd:
245 case Instruction::FSub:
246 case Instruction::FMul:
248 assert(Ops.size() == 2 &&
"its a binary operator!");
250 return Ops[0].binaryOp(BinOp, Ops[1]);
258 case Instruction::FPToUI:
259 case Instruction::FPToSI:
261 assert(Ops.size() == 1 &&
"FPTo[US]I is a unary operator!");
269 case Instruction::FCmp:
271 assert(Ops.size() == 2 &&
"FCmp is a binary operator!");
272 return Ops[0].unionWith(Ops[1]);
281 assert(SeenInsts.find(OI) != SeenInsts.end() &&
282 "def not seen before use!");
283 OpRanges.
push_back(SeenInsts.find(OI)->second);
284 }
else if (
ConstantFP *CF = dyn_cast<ConstantFP>(
O)) {
294 const APFloat &F = CF->getValueAPF();
317 CF->getValueAPF().convertToInteger(Int,
328 seen(I,
Op(OpRanges));
333 bool Float2IntPass::validateAndTransform() {
334 bool MadeChange =
false;
337 for (
auto It = ECs.begin(),
E = ECs.end(); It !=
E; ++It) {
340 Type *ConvertedToTy =
nullptr;
343 for (
auto MI = ECs.member_begin(It), ME = ECs.member_end();
346 auto SeenI = SeenInsts.find(I);
347 if (SeenI == SeenInsts.end())
355 if (Roots.
count(I) == 0) {
361 if (!UI || SeenInsts.find(UI) == SeenInsts.end()) {
374 if (ECs.member_begin(It) == ECs.member_end() || Fail ||
377 assert(ConvertedToTy &&
"Must have set the convertedtoty by this point!");
383 LLVM_DEBUG(
dbgs() <<
"F2I: MinBitwidth=" << MinBW <<
", R: " << R <<
"\n");
391 unsigned MaxRepresentableBits
393 if (MinBW > MaxRepresentableBits) {
394 LLVM_DEBUG(
dbgs() <<
"F2I: Value not guaranteed to be representable!\n");
399 dbgs() <<
"F2I: Value requires more than 64 bits to represent!\n");
407 for (
auto MI = ECs.member_begin(It), ME = ECs.member_end();
417 if (ConvertedInsts.find(I) != ConvertedInsts.end())
419 return ConvertedInsts[I];
424 if (I->
getOpcode() == Instruction::UIToFP ||
429 }
else if (
ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
432 CF->getValueAPF().convertToInteger(Val,
443 Value *NewV =
nullptr;
447 case Instruction::FPToUI:
451 case Instruction::FPToSI:
455 case Instruction::FCmp: {
462 case Instruction::UIToFP:
466 case Instruction::SIToFP:
470 case Instruction::FAdd:
471 case Instruction::FSub:
472 case Instruction::FMul:
474 NewOperands[0], NewOperands[1],
483 ConvertedInsts[
I] = NewV;
488 void Float2IntPass::cleanup() {
489 for (
auto &I :
reverse(ConvertedInsts))
498 ConvertedInsts.clear();
505 walkBackwards(Roots);
508 bool Modified = validateAndTransform();
Legacy wrapper pass to provide the GlobalsAAResult object.
opStatus roundToIntegral(roundingMode RM)
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
static cl::opt< unsigned > MaxIntegerBW("float2int-max-integer-bw", cl::init(64), cl::Hidden, cl::desc("Max integer bitwidth to consider in float2int" "(default=64)"))
The largest integer type worth dealing with.
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
This class is the base class for the comparison instructions.
static bool runImpl(Function &F, TargetLibraryInfo &TLI, DominatorTree &DT)
This is the entry point for all transforms.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
bool hasNoSignedZeros() const
Determine whether the no-signed-zeros flag is set.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
ConstantRange unionWith(const ConstantRange &CR) const
Return the range that results from the union of this range with another range.
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
This class represents lattice values for constants.
const APInt & getUpper() const
Return the upper value for this range.
This is the interface for a simple mod/ref and alias analysis over globals.
void push_back(const T &Elt)
FunctionPass * createFloat2IntPass()
0 1 0 0 True if ordered and less than
1 1 1 0 True if unordered or not equal
static void cleanup(BlockFrequencyInfoImplBase &BFI)
Clear all memory not needed downstream.
static IntegerType * getInt64Ty(LLVMContext &C)
bool runImpl(Function &F)
1 0 0 1 True if unordered or equal
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
LLVMContext & getContext() const
Get the global data context.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
0 1 0 1 True if ordered and less than or equal
This file implements a class to represent arbitrary precision integral constant values and operations...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
Type * getType() const
All values are typed, get the type of this value.
Value * CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a SExt or Trunc from the integer value V to DestTy.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Value * getOperand(unsigned i) const
static CmpInst::Predicate mapFCmpPred(CmpInst::Predicate P)
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
A set of analyses that are preserved following a run of a transformation pass.
The instances of the Type class are immutable: once they are created, they are never changed...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool isSignWrappedSet() const
Return true if this set wraps around the INT_MIN of its bitwidth.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
ConstantFP - Floating Point Values [float, double].
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
Represent the analysis usage information of a pass.
Analysis pass providing a never-invalidated alias analysis result.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
bool isFullSet() const
Return true if this set contains all of the elements possible for this data-type. ...
void initializeFloat2IntLegacyPassPass(PassRegistry &)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
1 1 0 1 True if unordered, less than, or equal
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
0 0 1 0 True if ordered and greater than
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
1 1 0 0 True if unordered or less than
Module.h This file contains the declarations for the Module class.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This class represents a range of values.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
static unsigned int semanticsPrecision(const fltSemantics &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
iterator_range< user_iterator > users()
Represents analyses that only rely on functions' control flow.
static Instruction::BinaryOps mapBinOpcode(unsigned Opcode)
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate IT block based on arch"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT, "arm-no-restrict-it", "Allow IT blocks based on ARMv7")))
static IntegerType * getInt32Ty(LLVMContext &C)
void preserveSet()
Mark an analysis set as preserved.
StringRef getName() const
Return a constant reference to the value's name.
const APInt & getLower() const
Return the lower value for this range.
0 1 1 0 True if ordered and operands are unequal
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void preserve()
Mark an analysis as preserved.
1 0 1 0 True if unordered or greater than
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getMinSignedBits() const
Get the minimum bit size for this signed APInt.
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
0 0 0 1 True if ordered and equal
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
1 0 1 1 True if unordered, greater than, or equal
inst_range instructions(Function *F)
A container for analyses that lazily runs them and caches their results.
0 0 1 1 True if ordered and greater than or equal
cmpResult compare(const APFloat &RHS) const
const fltSemantics & getFltSemantics() const