Fold x-0 to x in unsafe-fp-math mode. This comes up in the
authorDan Gohman <gohman@apple.com>
Fri, 23 Jan 2009 19:10:37 +0000 (19:10 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 23 Jan 2009 19:10:37 +0000 (19:10 +0000)
testcase from PR3376, and in fact is sufficient to completely
avoid the problem in that testcase.

There's an underlying problem though; TLI.isOperationLegal
considers Custom to be Legal, which might be ok in some
cases, but that's what DAGCombiner is using in many places
to test if something is legal when LegalOperations is true.
When DAGCombiner is running after legalize, this isn't
sufficient. I'll address this in a separate commit.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62860 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/DAGCombiner.cpp
lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 7e8e46fba50f1e504f79b9c2f8342ddc8ed69340..e4b24f1aaff657af00be310beac9ff7e3da3fe94 100644 (file)
@@ -3853,6 +3853,9 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
   // fold (fsub c1, c2) -> c1-c2
   if (N0CFP && N1CFP && VT != MVT::ppcf128)
     return DAG.getNode(ISD::FSUB, VT, N0, N1);
+  // fold (A-0) -> A
+  if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero())
+    return N0;
   // fold (0-B) -> -B
   if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) {
     if (isNegatibleForFree(N1, LegalOperations))
index 29744862089df008a242c40a91032e1f3420358e..6d1fdd23407d69c29273a4e1e21d486fa36d35bc 100644 (file)
@@ -2402,15 +2402,22 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
   case ISD::FMUL:
   case ISD::FDIV:
   case ISD::FREM:
-    if (UnsafeFPMath && Opcode == ISD::FADD) {
-      // 0+x --> x
-      if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1))
-        if (CFP->getValueAPF().isZero())
-          return N2;
-      // x+0 --> x
-      if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N2))
-        if (CFP->getValueAPF().isZero())
-          return N1;
+    if (UnsafeFPMath) {
+      if (Opcode == ISD::FADD) {
+        // 0+x --> x
+        if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1))
+          if (CFP->getValueAPF().isZero())
+            return N2;
+        // x+0 --> x
+        if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N2))
+          if (CFP->getValueAPF().isZero())
+            return N1;
+      } else if (Opcode == ISD::FSUB) {
+        // x-0 --> x
+        if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N2))
+          if (CFP->getValueAPF().isZero())
+            return N1;
+      }
     }
     assert(N1.getValueType() == N2.getValueType() &&
            N1.getValueType() == VT && "Binary operator types must match!");