31#define DEBUG_TYPE "nvptx-ir-peephole"
43 Value *OtherOperand =
nullptr;
44 bool IsFirstOperand =
false;
47 if (FMul0 && FMul0->getOpcode() == Instruction::FMul && FMul0->hasOneUse() &&
48 FMul0->hasAllowContract()) {
51 IsFirstOperand =
true;
52 }
else if (FMul1 && FMul1->getOpcode() == Instruction::FMul &&
53 FMul1->hasOneUse() && FMul1->hasAllowContract()) {
56 IsFirstOperand =
false;
61 bool IsFSub = BI->
getOpcode() == Instruction::FSub;
63 const char *
OpName = IsFSub ?
"FSub" :
"FAdd";
64 dbgs() <<
"Found " <<
OpName <<
" with FMul (single use) as "
65 << (IsFirstOperand ?
"first" :
"second") <<
" operand: " << *BI
77 FMA = Builder.CreateIntrinsic(Intrinsic::fma, {BI->
getType()},
78 {MulOp0, MulOp1, OtherOperand});
84 FMA = Builder.CreateIntrinsic(Intrinsic::fma, {BI->
getType()},
85 {MulOp0, MulOp1, NegOtherOp});
89 Builder.CreateFNegFMF(MulOp0,
FMul->getFastMathFlags());
90 FMA = Builder.CreateIntrinsic(Intrinsic::fma, {BI->
getType()},
91 {NegMulOp0, MulOp1, OtherOperand});
101 FMAInst->setFastMathFlags(NewFMF);
104 const char *
OpName = IsFSub ?
"FSub" :
"FAdd";
105 dbgs() <<
"Replacing " <<
OpName <<
" with FMA: " << *FMA <<
"\n";
109 FMul->eraseFromParent();
120 if (BI->getOpcode() != Instruction::FAdd &&
121 BI->getOpcode() != Instruction::FSub)
125 if (!BI->hasAllowContract())
129 if (!BI->getType()->isFloatTy() && !BI->getType()->isDoubleTy())
143 NVPTXIRPeephole() : FunctionPass(ID) {}
149char NVPTXIRPeephole::ID = 0;
156 return new NVPTXIRPeephole();
Expand Atomic instructions
static bool runOnFunction(Function &F, bool PostInlining)
static bool tryFoldBinaryFMul(BinaryOperator *BI)
static bool foldFMA(Function &F)
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
BinaryOps getOpcode() const
Represents analyses that only rely on functions' control flow.
Convenience struct for specifying and reasoning about fast-math flags.
static FastMathFlags intersectRewrite(FastMathFlags LHS, FastMathFlags RHS)
Intersect rewrite-based flags.
static FastMathFlags unionValue(FastMathFlags LHS, FastMathFlags RHS)
Union value flags.
FunctionPass class - This class is used to implement most global optimizations.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI FastMathFlags getFastMathFlags() const LLVM_READONLY
Convenience function for getting all the fast-math flags, which must be an operator which supports th...
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.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createNVPTXIRPeepholePass()
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)