diff options
author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-03-05 00:02:00 +0000 |
---|---|---|
committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2014-03-05 00:02:00 +0000 |
commit | 34fae3adef064533271387aed32b2b1ccfa6d6cf (patch) | |
tree | 66db2a7818cadddadd28a8429f7cd1a8bdea374f /lib | |
parent | 175c634d88e260f378e97ce5fc7b2010a6255a94 (diff) | |
download | llvm-34fae3adef064533271387aed32b2b1ccfa6d6cf.tar.gz llvm-34fae3adef064533271387aed32b2b1ccfa6d6cf.tar.bz2 llvm-34fae3adef064533271387aed32b2b1ccfa6d6cf.tar.xz |
Allow constant folding of fma and fmuladd
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@202914 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/ConstantFolding.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp index 10f8e4ed68..254f2d9f50 100644 --- a/lib/Analysis/ConstantFolding.cpp +++ b/lib/Analysis/ConstantFolding.cpp @@ -1193,6 +1193,8 @@ bool llvm::canConstantFoldCallTo(const Function *F) { case Intrinsic::ctpop: case Intrinsic::ctlz: case Intrinsic::cttz: + case Intrinsic::fma: + case Intrinsic::fmuladd: case Intrinsic::sadd_with_overflow: case Intrinsic::uadd_with_overflow: case Intrinsic::ssub_with_overflow: @@ -1615,5 +1617,30 @@ llvm::ConstantFoldCall(Function *F, ArrayRef<Constant *> Operands, } return 0; } + + if (Operands.size() != 3) + return 0; + + if (const ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) { + if (const ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) { + if (const ConstantFP *Op3 = dyn_cast<ConstantFP>(Operands[2])) { + switch (F->getIntrinsicID()) { + default: break; + case Intrinsic::fma: + case Intrinsic::fmuladd: { + APFloat V = Op1->getValueAPF(); + APFloat::opStatus s = V.fusedMultiplyAdd(Op2->getValueAPF(), + Op3->getValueAPF(), + APFloat::rmNearestTiesToEven); + if (s != APFloat::opInvalidOp) + return ConstantFP::get(Ty->getContext(), V); + + return 0; + } + } + } + } + } + return 0; } |