28#define DEBUG_TYPE "float2int"
46 cl::desc(
"Max integer bitwidth to consider in float2int"
81 case Instruction::FAdd:
return Instruction::Add;
82 case Instruction::FSub:
return Instruction::Sub;
83 case Instruction::FMul:
return Instruction::Mul;
97 if (isa<VectorType>(
I.getType()))
99 switch (
I.getOpcode()) {
101 case Instruction::FPToUI:
102 case Instruction::FPToSI:
105 case Instruction::FCmp:
118 auto IT = SeenInsts.find(
I);
119 if (
IT != SeenInsts.end())
120 IT->second = std::move(R);
122 SeenInsts.insert(std::make_pair(
I, std::move(R)));
152void Float2IntPass::walkBackwards() {
153 std::deque<Instruction*> Worklist(Roots.begin(), Roots.end());
154 while (!Worklist.empty()) {
158 if (SeenInsts.contains(
I))
162 switch (
I->getOpcode()) {
169 case Instruction::UIToFP:
170 case Instruction::SIToFP: {
173 unsigned BW =
I->getOperand(0)->getType()->getPrimitiveSizeInBits();
174 auto Input = ConstantRange::getFull(BW);
176 seen(
I, validateRange(Input.castOp(CastOp,
MaxIntegerBW+1)));
180 case Instruction::FNeg:
181 case Instruction::FAdd:
182 case Instruction::FSub:
183 case Instruction::FMul:
184 case Instruction::FPToUI:
185 case Instruction::FPToSI:
186 case Instruction::FCmp:
187 seen(
I, unknownRange());
191 for (
Value *O :
I->operands()) {
194 ECs.unionSets(
I, OI);
195 if (SeenInsts.find(
I)->second != badRange())
196 Worklist.push_back(OI);
197 }
else if (!isa<ConstantFP>(O)) {
207std::optional<ConstantRange> Float2IntPass::calcRange(
Instruction *
I) {
209 for (
Value *O :
I->operands()) {
211 auto OpIt = SeenInsts.find(OI);
212 assert(OpIt != SeenInsts.end() &&
"def not seen before use!");
213 if (OpIt->second == unknownRange())
216 }
else if (
ConstantFP *CF = dyn_cast<ConstantFP>(O)) {
226 const APFloat &
F = CF->getValueAPF();
232 (
F.isZero() &&
F.isNegative() && isa<FPMathOperator>(
I) &&
233 !
I->hasNoSignedZeros()))
244 CF->getValueAPF().convertToInteger(
Int,
253 switch (
I->getOpcode()) {
256 case Instruction::UIToFP:
257 case Instruction::SIToFP:
260 case Instruction::FNeg: {
261 assert(OpRanges.
size() == 1 &&
"FNeg is a unary operator!");
262 unsigned Size = OpRanges[0].getBitWidth();
264 return Zero.sub(OpRanges[0]);
267 case Instruction::FAdd:
268 case Instruction::FSub:
269 case Instruction::FMul: {
270 assert(OpRanges.
size() == 2 &&
"its a binary operator!");
272 return OpRanges[0].binaryOp(BinOp, OpRanges[1]);
279 case Instruction::FPToUI:
280 case Instruction::FPToSI: {
281 assert(OpRanges.
size() == 1 &&
"FPTo[US]I is a unary operator!");
288 case Instruction::FCmp:
289 assert(OpRanges.
size() == 2 &&
"FCmp is a binary operator!");
290 return OpRanges[0].unionWith(OpRanges[1]);
296void Float2IntPass::walkForwards() {
297 std::deque<Instruction *> Worklist;
298 for (
const auto &Pair : SeenInsts)
299 if (Pair.second == unknownRange())
302 while (!Worklist.empty()) {
306 if (std::optional<ConstantRange>
Range = calcRange(
I))
309 Worklist.push_front(
I);
314bool Float2IntPass::validateAndTransform(
const DataLayout &
DL) {
315 bool MadeChange =
false;
318 for (
auto It = ECs.begin(), E = ECs.end(); It != E; ++It) {
321 Type *ConvertedToTy =
nullptr;
324 for (
auto MI = ECs.member_begin(It), ME = ECs.member_end();
327 auto SeenI = SeenInsts.find(
I);
328 if (SeenI == SeenInsts.end())
331 R =
R.unionWith(SeenI->second);
336 if (!Roots.contains(
I)) {
339 ConvertedToTy =
I->getType();
340 for (
User *U :
I->users()) {
342 if (!UI || !SeenInsts.contains(UI)) {
355 if (ECs.member_begin(It) == ECs.member_end() ||
Fail ||
356 R.isFullSet() ||
R.isSignWrappedSet())
358 assert(ConvertedToTy &&
"Must have set the convertedtoty by this point!");
362 unsigned MinBW =
R.getMinSignedBits() + 1;
363 LLVM_DEBUG(
dbgs() <<
"F2I: MinBitwidth=" << MinBW <<
", R: " << R <<
"\n");
371 unsigned MaxRepresentableBits
373 if (MinBW > MaxRepresentableBits) {
374 LLVM_DEBUG(
dbgs() <<
"F2I: Value not guaranteed to be representable!\n");
380 Type *Ty =
DL.getSmallestLegalIntType(*Ctx, MinBW);
386 }
else if (MinBW <= 64) {
389 LLVM_DEBUG(
dbgs() <<
"F2I: Value requires more bits to represent than "
390 "the target supports!\n");
395 for (
auto MI = ECs.member_begin(It), ME = ECs.member_end();
405 if (ConvertedInsts.contains(
I))
407 return ConvertedInsts[
I];
410 for (
Value *V :
I->operands()) {
412 if (
I->getOpcode() == Instruction::UIToFP ||
413 I->getOpcode() == Instruction::SIToFP) {
415 }
else if (
Instruction *VI = dyn_cast<Instruction>(V)) {
417 }
else if (
ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
420 CF->getValueAPF().convertToInteger(Val,
423 NewOperands.
push_back(ConstantInt::get(ToTy, Val));
431 Value *NewV =
nullptr;
432 switch (
I->getOpcode()) {
435 case Instruction::FPToUI:
436 NewV = IRB.CreateZExtOrTrunc(NewOperands[0],
I->getType());
439 case Instruction::FPToSI:
440 NewV = IRB.CreateSExtOrTrunc(NewOperands[0],
I->getType());
443 case Instruction::FCmp: {
446 NewV = IRB.CreateICmp(
P, NewOperands[0], NewOperands[1],
I->getName());
450 case Instruction::UIToFP:
451 NewV = IRB.CreateZExtOrTrunc(NewOperands[0], ToTy);
454 case Instruction::SIToFP:
455 NewV = IRB.CreateSExtOrTrunc(NewOperands[0], ToTy);
458 case Instruction::FNeg:
459 NewV = IRB.CreateNeg(NewOperands[0],
I->getName());
462 case Instruction::FAdd:
463 case Instruction::FSub:
464 case Instruction::FMul:
466 NewOperands[0], NewOperands[1],
473 I->replaceAllUsesWith(NewV);
475 ConvertedInsts[
I] = NewV;
480void Float2IntPass::cleanup() {
481 for (
auto &
I :
reverse(ConvertedInsts))
482 I.first->eraseFromParent();
486 LLVM_DEBUG(
dbgs() <<
"F2I: Looking at function " <<
F.getName() <<
"\n");
490 ConvertedInsts.clear();
493 Ctx = &
F.getParent()->getContext();
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 cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
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)
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.
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))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
opStatus roundToIntegral(roundingMode RM)
static APInt getZero(unsigned numBits)
Get the '0' value for the specified bit-width.
An arbitrary precision integer that knows its signedness.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
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
ConstantFP - Floating Point Values [float, double].
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.
bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
bool runImpl(Function &F, const DominatorTree &DT)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
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.
void preserveSet()
Mark an analysis set as preserved.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
const fltSemantics & getFltSemantics() const
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
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.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static constexpr roundingMode rmNearestTiesToEven
static unsigned int semanticsPrecision(const fltSemantics &)