aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 8918c45562..765ff1b758 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -952,6 +952,27 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
}
}
+ // If this is a selectcc, check to see if we can simplify the result.
+ if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(N1)) {
+ if (ConstantFPSDNode *CFP =
+ dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1)))
+ if (CFP->getValue() == 0.0) { // Allow either -0.0 or 0.0
+ // select (setg[te] X, +/-0.0), X, fneg(X) -> fabs
+ if ((SetCC->getCondition() == ISD::SETGE ||
+ SetCC->getCondition() == ISD::SETGT) &&
+ N2 == SetCC->getOperand(0) && N3.getOpcode() == ISD::FNEG &&
+ N3.getOperand(0) == N2)
+ return getNode(ISD::FABS, VT, N2);
+
+ // select (setl[te] X, +/-0.0), fneg(X), X -> fabs
+ if ((SetCC->getCondition() == ISD::SETLT ||
+ SetCC->getCondition() == ISD::SETLE) &&
+ N3 == SetCC->getOperand(0) && N2.getOpcode() == ISD::FNEG &&
+ N2.getOperand(0) == N3)
+ return getNode(ISD::FABS, VT, N3);
+ }
+
+ }
break;
case ISD::BRCOND:
if (N2C)