summaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
authorOwen Anderson <resistor@mac.com>2013-05-09 22:27:13 +0000
committerOwen Anderson <resistor@mac.com>2013-05-09 22:27:13 +0000
commit58dcd200b7f0ea01160b6159e0363cc96b1b83d9 (patch)
tree00da3ebfab570918388b978ff1163604411376d7 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp
parent2c694171a597a90c1b7c95b8704ff0d010f9ce3c (diff)
downloadllvm-58dcd200b7f0ea01160b6159e0363cc96b1b83d9.tar.gz
llvm-58dcd200b7f0ea01160b6159e0363cc96b1b83d9.tar.bz2
llvm-58dcd200b7f0ea01160b6159e0363cc96b1b83d9.tar.xz
Teach SelectionDAG to constant fold all-constant FMA nodes the same way that it constant folds FADD, FMUL, etc.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181555 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp15
1 files changed, 15 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 15235c8ac3..f2c512dec7 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -3261,6 +3261,21 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, EVT VT,
// Perform various simplifications.
ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode());
switch (Opcode) {
+ case ISD::FMA: {
+ ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
+ ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2);
+ ConstantFPSDNode *N3CFP = dyn_cast<ConstantFPSDNode>(N3);
+ if (N1CFP && N2CFP && N3CFP) {
+ APFloat V1 = N1CFP->getValueAPF();
+ const APFloat &V2 = N2CFP->getValueAPF();
+ const APFloat &V3 = N3CFP->getValueAPF();
+ APFloat::opStatus s =
+ V1.fusedMultiplyAdd(V2, V3, APFloat::rmNearestTiesToEven);
+ if (s != APFloat::opInvalidOp)
+ return getConstantFP(V1, VT);
+ }
+ break;
+ }
case ISD::CONCAT_VECTORS:
// A CONCAT_VECTOR with all operands BUILD_VECTOR can be simplified to
// one big BUILD_VECTOR.