summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-04-09 05:15:53 +0000
committerChris Lattner <sabre@nondot.org>2005-04-09 05:15:53 +0000
commit59723e96987bdbfbada75fdbf1742f6a28d90d7d (patch)
tree73530ec60c3f57870f65d95fc7345d2f8b02596c /lib/CodeGen
parent2e6027ccabc7c32e3bdd36b96e6e70c8f4c86fa2 (diff)
downloadllvm-59723e96987bdbfbada75fdbf1742f6a28d90d7d.tar.gz
llvm-59723e96987bdbfbada75fdbf1742f6a28d90d7d.tar.bz2
llvm-59723e96987bdbfbada75fdbf1742f6a28d90d7d.tar.xz
recognize some patterns as fabs operations, so that fabs at the source level
is deconstructed then reconstructed here. This catches 19 fabs's in 177.mesa 9 in 168.wupwise, 5 in 171.swim, 3 in 172.mgrid, and 14 in 173.applu out of specfp2000. This allows the X86 code generator to make MUCH better code than before for each of these and saves one instr on ppc. This depends on the previous CFE patch to expose these correctly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21171 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-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)