[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp LegalizeDAG.cpp SelectionDAG.cpp SelectionDAGISel.cpp

Chris Lattner lattner at cs.uiuc.edu
Wed Sep 28 15:28:29 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

DAGCombiner.cpp updated: 1.13 -> 1.14
LegalizeDAG.cpp updated: 1.186 -> 1.187
SelectionDAG.cpp updated: 1.193 -> 1.194
SelectionDAGISel.cpp updated: 1.84 -> 1.85
---
Log message:

Add FP versions of the binary operators, keeping the int and fp worlds seperate.

Though I have done extensive testing, it is possible that this will break
things in configs I can't test.  Please let me know if this causes a problem
and I'll fix it ASAP.


---
Diffs of the changes:  (+209 -87)

 DAGCombiner.cpp      |  143 ++++++++++++++++++++++++++++++++++-----------------
 LegalizeDAG.cpp      |   45 ++++++++++++----
 SelectionDAG.cpp     |   61 ++++++++++++++-------
 SelectionDAGISel.cpp |   47 ++++++++++++----
 4 files changed, 209 insertions(+), 87 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.13 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.14
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.13	Mon Sep 19 17:34:01 2005
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp	Wed Sep 28 17:28:18 2005
@@ -115,6 +115,12 @@
     SDOperand visitZERO_EXTEND(SDNode *N);
     SDOperand visitSIGN_EXTEND_INREG(SDNode *N);
     SDOperand visitTRUNCATE(SDNode *N);
+
+    SDOperand visitFADD(SDNode *N);
+    SDOperand visitFSUB(SDNode *N);
+    SDOperand visitFMUL(SDNode *N);
+    SDOperand visitFDIV(SDNode *N);
+    SDOperand visitFREM(SDNode *N);
     SDOperand visitSINT_TO_FP(SDNode *N);
     SDOperand visitUINT_TO_FP(SDNode *N);
     SDOperand visitFP_TO_SINT(SDNode *N);
@@ -341,6 +347,11 @@
   case ISD::ZERO_EXTEND:        return visitZERO_EXTEND(N);
   case ISD::SIGN_EXTEND_INREG:  return visitSIGN_EXTEND_INREG(N);
   case ISD::TRUNCATE:           return visitTRUNCATE(N);
+  case ISD::FADD:               return visitFADD(N);
+  case ISD::FSUB:               return visitFSUB(N);
+  case ISD::FMUL:               return visitFMUL(N);
+  case ISD::FDIV:               return visitFDIV(N);
+  case ISD::FREM:               return visitFREM(N);
   case ISD::SINT_TO_FP:         return visitSINT_TO_FP(N);
   case ISD::UINT_TO_FP:         return visitUINT_TO_FP(N);
   case ISD::FP_TO_SINT:         return visitFP_TO_SINT(N);
@@ -375,8 +386,6 @@
   SDOperand N1 = N->getOperand(1);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
-  ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
-  ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
   MVT::ValueType VT = N0.getValueType();
   
   // fold (add c1, c2) -> c1+c2
@@ -390,9 +399,6 @@
   // fold (add x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
-  // fold floating point (add c1, c2) -> c1+c2
-  if (N0CFP && N1CFP)
-    return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(), VT);
   // fold (add (add x, c1), c2) -> (add x, c1+c2)
   if (N1C && N0.getOpcode() == ISD::ADD) {
     ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
@@ -404,12 +410,6 @@
       return DAG.getNode(ISD::ADD, VT, N0.getOperand(0),
                          DAG.getConstant(N1C->getValue()+N01C->getValue(), VT));
   }
-  // fold (A + (-B)) -> A-B
-  if (N1.getOpcode() == ISD::FNEG)
-    return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(0));
-  // fold ((-A) + B) -> B-A
-  if (N0.getOpcode() == ISD::FNEG)
-    return DAG.getNode(ISD::SUB, VT, N1, N0.getOperand(0));
   // fold ((0-A) + B) -> B-A
   if (N0.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N0.getOperand(0)) &&
       cast<ConstantSDNode>(N0.getOperand(0))->isNullValue())
@@ -418,9 +418,8 @@
   if (N1.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N1.getOperand(0)) &&
       cast<ConstantSDNode>(N1.getOperand(0))->isNullValue())
     return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(1));
-  // fold (A+(B-A)) -> B for non-fp types
-  if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1) &&
-      !MVT::isFloatingPoint(N1.getValueType()))
+  // fold (A+(B-A)) -> B
+  if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1))
     return N1.getOperand(0);
   return SDOperand();
 }
@@ -430,8 +429,6 @@
   SDOperand N1 = N->getOperand(1);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.Val);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
-  ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0.Val);
-  ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val);
   
   // fold (sub c1, c2) -> c1-c2
   if (N0C && N1C)
@@ -440,21 +437,12 @@
   // fold (sub x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
-  // fold floating point (sub c1, c2) -> c1-c2
-  if (N0CFP && N1CFP)
-    return DAG.getConstantFP(N0CFP->getValue() - N1CFP->getValue(),
-                             N->getValueType(0));
   // fold (A+B)-A -> B
-  if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1 &&
-      !MVT::isFloatingPoint(N1.getValueType()))
+  if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1)
     return N0.getOperand(1);
   // fold (A+B)-B -> A
-  if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1 &&
-      !MVT::isFloatingPoint(N1.getValueType()))
+  if (N0.getOpcode() == ISD::ADD && N0.getOperand(1) == N1)
     return N0.getOperand(0);
-  // fold (A-(-B)) -> A+B
-  if (N1.getOpcode() == ISD::FNEG)
-    return DAG.getNode(ISD::ADD, N0.getValueType(), N0, N1.getOperand(0));
   return SDOperand();
 }
 
@@ -463,8 +451,6 @@
   SDOperand N1 = N->getOperand(1);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
-  ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
-  ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
   MVT::ValueType VT = N0.getValueType();
   
   // fold (mul c1, c2) -> c1*c2
@@ -499,10 +485,6 @@
       return DAG.getNode(ISD::MUL, VT, N0.getOperand(0),
                          DAG.getConstant(N1C->getValue()*N01C->getValue(), VT));
   }
-  // fold floating point (mul c1, c2) -> c1*c2
-  if (N0CFP && N1CFP)
-    return DAG.getConstantFP(N0CFP->getValue() * N1CFP->getValue(),
-                             N->getValueType(0));
   return SDOperand();
 }
 
@@ -511,17 +493,11 @@
   SDOperand N1 = N->getOperand(1);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.Val);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);
-  ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0.Val);
-  ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1.Val);
 
   // fold (sdiv c1, c2) -> c1/c2
   if (N0C && N1C && !N1C->isNullValue())
     return DAG.getConstant(N0C->getSignExtended() / N1C->getSignExtended(),
                            N->getValueType(0));
-  // fold floating point (sdiv c1, c2) -> c1/c2
-  if (N0CFP && N1CFP)
-    return DAG.getConstantFP(N0CFP->getValue() / N1CFP->getValue(),
-                             N->getValueType(0));
   return SDOperand();
 }
 
@@ -548,17 +524,11 @@
   SDOperand N1 = N->getOperand(1);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1);
-  ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
-  ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
   
   // fold (srem c1, c2) -> c1%c2
   if (N0C && N1C && !N1C->isNullValue())
     return DAG.getConstant(N0C->getSignExtended() % N1C->getSignExtended(),
                            N->getValueType(0));
-  // fold floating point (srem c1, c2) -> fmod(c1, c2)
-  if (N0CFP && N1CFP)
-    return DAG.getConstantFP(fmod(N0CFP->getValue(),N1CFP->getValue()),
-                             N->getValueType(0));
   return SDOperand();
 }
 
@@ -1233,6 +1203,89 @@
   return SDOperand();
 }
 
+SDOperand DAGCombiner::visitFADD(SDNode *N) {
+  SDOperand N0 = N->getOperand(0);
+  SDOperand N1 = N->getOperand(1);
+  MVT::ValueType VT = N->getValueType(0);
+
+  if (ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0))
+    if (ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1)) {
+      // fold floating point (fadd c1, c2)
+      return DAG.getConstantFP(N0CFP->getValue() + N1CFP->getValue(),
+                               N->getValueType(0));
+    }
+  // fold (A + (-B)) -> A-B
+  if (N1.getOpcode() == ISD::FNEG)
+    return DAG.getNode(ISD::FSUB, VT, N0, N1.getOperand(0));
+  
+  // fold ((-A) + B) -> B-A
+  if (N0.getOpcode() == ISD::FNEG)
+    return DAG.getNode(ISD::FSUB, VT, N1, N0.getOperand(0));
+  
+  return SDOperand();
+}
+
+SDOperand DAGCombiner::visitFSUB(SDNode *N) {
+  SDOperand N0 = N->getOperand(0);
+  SDOperand N1 = N->getOperand(1);
+  MVT::ValueType VT = N->getValueType(0);
+
+  if (ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0))
+    if (ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1)) {
+      // fold floating point (fsub c1, c2)
+      return DAG.getConstantFP(N0CFP->getValue() - N1CFP->getValue(),
+                               N->getValueType(0));
+    }
+  // fold (A-(-B)) -> A+B
+  if (N1.getOpcode() == ISD::FNEG)
+    return DAG.getNode(ISD::FADD, N0.getValueType(), N0, N1.getOperand(0));
+  
+  return SDOperand();
+}
+
+SDOperand DAGCombiner::visitFMUL(SDNode *N) {
+  SDOperand N0 = N->getOperand(0);
+  SDOperand N1 = N->getOperand(1);
+  MVT::ValueType VT = N->getValueType(0);
+
+  if (ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0))
+    if (ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1)) {
+      // fold floating point (fmul c1, c2)
+      return DAG.getConstantFP(N0CFP->getValue() * N1CFP->getValue(),
+                               N->getValueType(0));
+    }
+  return SDOperand();
+}
+
+SDOperand DAGCombiner::visitFDIV(SDNode *N) {
+  SDOperand N0 = N->getOperand(0);
+  SDOperand N1 = N->getOperand(1);
+  MVT::ValueType VT = N->getValueType(0);
+
+  if (ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0))
+    if (ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1)) {
+      // fold floating point (fdiv c1, c2)
+      return DAG.getConstantFP(N0CFP->getValue() / N1CFP->getValue(),
+                               N->getValueType(0));
+    }
+  return SDOperand();
+}
+
+SDOperand DAGCombiner::visitFREM(SDNode *N) {
+  SDOperand N0 = N->getOperand(0);
+  SDOperand N1 = N->getOperand(1);
+  MVT::ValueType VT = N->getValueType(0);
+
+  if (ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0))
+    if (ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1)) {
+      // fold floating point (frem c1, c2) -> fmod(c1, c2)
+      return DAG.getConstantFP(fmod(N0CFP->getValue(),N1CFP->getValue()),
+                               N->getValueType(0));
+    }
+  return SDOperand();
+}
+
+
 SDOperand DAGCombiner::visitSINT_TO_FP(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
   ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.186 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.187
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.186	Fri Sep  9 19:20:18 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Wed Sep 28 17:28:18 2005
@@ -209,7 +209,7 @@
                                           : BitsToDouble(0x4330000000000000ULL),
                                      MVT::f64);
     // subtract the bias
-    SDOperand Sub = DAG.getNode(ISD::SUB, MVT::f64, Load, Bias);
+    SDOperand Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias);
     // final result
     SDOperand Result;
     // handle final rounding
@@ -1531,6 +1531,10 @@
   case ISD::SHL:
   case ISD::SRL:
   case ISD::SRA:
+  case ISD::FADD:
+  case ISD::FSUB:
+  case ISD::FMUL:
+  case ISD::FDIV:
     Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
     switch (getTypeAction(Node->getOperand(1).getValueType())) {
     case Expand: assert(0 && "Not possible");
@@ -1548,6 +1552,7 @@
 
   case ISD::UREM:
   case ISD::SREM:
+  case ISD::FREM:
     Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
     Tmp2 = LegalizeOp(Node->getOperand(1));   // RHS
     switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
@@ -1715,7 +1720,7 @@
       case ISD::FNEG: {
         // Expand Y = FNEG(X) ->  Y = SUB -0.0, X
         Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0));
-        Result = LegalizeOp(DAG.getNode(ISD::SUB, Node->getValueType(0),
+        Result = LegalizeOp(DAG.getNode(ISD::FSUB, Node->getValueType(0),
                                         Tmp2, Tmp1));
         break;
       }
@@ -1840,7 +1845,7 @@
                             Node->getOperand(0), Tmp2, ISD::SETLT);
           True = DAG.getNode(ISD::FP_TO_SINT, NVT, Node->getOperand(0));
           False = DAG.getNode(ISD::FP_TO_SINT, NVT,
-                              DAG.getNode(ISD::SUB, VT, Node->getOperand(0),
+                              DAG.getNode(ISD::FSUB, VT, Node->getOperand(0),
                                           Tmp2));
           False = DAG.getNode(ISD::XOR, NVT, False, 
                               DAG.getConstant(1ULL << ShiftAmt, NVT));
@@ -2193,19 +2198,29 @@
   case ISD::SUB:
   case ISD::MUL:
     // The input may have strange things in the top bits of the registers, but
-    // these operations don't care.  They may have wierd bits going out, but
+    // these operations don't care.  They may have weird bits going out, but
     // that too is okay if they are integer operations.
     Tmp1 = PromoteOp(Node->getOperand(0));
     Tmp2 = PromoteOp(Node->getOperand(1));
     assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT);
     Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
-
-    // However, if this is a floating point operation, they will give excess
-    // precision that we may not be able to tolerate.  If we DO allow excess
-    // precision, just leave it, otherwise excise it.
+    break;
+  case ISD::FADD:
+  case ISD::FSUB:
+  case ISD::FMUL:
+    // The input may have strange things in the top bits of the registers, but
+    // these operations don't care.
+    Tmp1 = PromoteOp(Node->getOperand(0));
+    Tmp2 = PromoteOp(Node->getOperand(1));
+    assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT);
+    Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+    
+    // Floating point operations will give excess precision that we may not be
+    // able to tolerate.  If we DO allow excess precision, just leave it,
+    // otherwise excise it.
     // FIXME: Why would we need to round FP ops more than integer ones?
     //     Is Round(Add(Add(A,B),C)) != Round(Add(Round(Add(A,B)), C))
-    if (MVT::isFloatingPoint(NVT) && NoExcessFPPrecision)
+    if (NoExcessFPPrecision)
       Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
                            DAG.getValueType(VT));
     break;
@@ -2228,6 +2243,18 @@
       Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
                            DAG.getValueType(VT));
     break;
+  case ISD::FDIV:
+  case ISD::FREM:
+    // These operators require that their input be fp extended.
+    Tmp1 = PromoteOp(Node->getOperand(0));
+    Tmp2 = PromoteOp(Node->getOperand(1));
+    Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
+    
+    // Perform FP_ROUND: this is probably overly pessimistic.
+    if (NoExcessFPPrecision)
+      Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+                           DAG.getValueType(VT));
+    break;
 
   case ISD::UDIV:
   case ISD::UREM:


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.193 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.194
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.193	Thu Sep 22 19:55:52 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Wed Sep 28 17:28:18 2005
@@ -36,6 +36,8 @@
   switch (Opcode) {
   case ISD::ADD:
   case ISD::MUL:
+  case ISD::FADD:
+  case ISD::FMUL:
   case ISD::AND:
   case ISD::OR:
   case ISD::XOR: return true;
@@ -869,8 +871,7 @@
       return getSetCC(VT, N1, N2, NewCond);
   }
 
-  if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
-      MVT::isInteger(N1.getValueType())) {
+  if (Cond == ISD::SETEQ || Cond == ISD::SETNE) {
     if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB ||
         N1.getOpcode() == ISD::XOR) {
       // Simplify (X+Y) == (X+Z) -->  Y == Z
@@ -1187,8 +1188,8 @@
     }
     break;
   case ISD::FNEG:
-    if (OpOpcode == ISD::SUB)   // -(X-Y) -> (Y-X)
-      return getNode(ISD::SUB, VT, Operand.Val->getOperand(1),
+    if (OpOpcode == ISD::FSUB)   // -(X-Y) -> (Y-X)
+      return getNode(ISD::FSUB, VT, Operand.Val->getOperand(1),
                      Operand.Val->getOperand(0));
     if (OpOpcode == ISD::FNEG)  // --X -> X
       return Operand.Val->getOperand(0);
@@ -1236,6 +1237,13 @@
   case ISD::MUL:
   case ISD::SDIV:
   case ISD::SREM:
+    assert(MVT::isInteger(N1.getValueType()) && "Should use F* for FP ops");
+    // fall through.
+  case ISD::FADD:
+  case ISD::FSUB:
+  case ISD::FMUL:
+  case ISD::FDIV:
+  case ISD::FREM:
     assert(N1.getValueType() == N2.getValueType() &&
            N1.getValueType() == VT && "Binary operator types must match!");
     break;
@@ -1513,13 +1521,13 @@
     if (N2CFP) {
       double C1 = N1CFP->getValue(), C2 = N2CFP->getValue();
       switch (Opcode) {
-      case ISD::ADD: return getConstantFP(C1 + C2, VT);
-      case ISD::SUB: return getConstantFP(C1 - C2, VT);
-      case ISD::MUL: return getConstantFP(C1 * C2, VT);
-      case ISD::SDIV:
+      case ISD::FADD: return getConstantFP(C1 + C2, VT);
+      case ISD::FSUB: return getConstantFP(C1 - C2, VT);
+      case ISD::FMUL: return getConstantFP(C1 * C2, VT);
+      case ISD::FDIV:
         if (C2) return getConstantFP(C1 / C2, VT);
         break;
-      case ISD::SREM :
+      case ISD::FREM :
         if (C2) return getConstantFP(fmod(C1, C2), VT);
         break;
       default: break;
@@ -1623,33 +1631,39 @@
     break;
   case ISD::ADD:
     if (!CombinerEnabled) {
-    if (N2.getOpcode() == ISD::FNEG)          // (A+ (-B) -> A-B
-      return getNode(ISD::SUB, VT, N1, N2.getOperand(0));
-    if (N1.getOpcode() == ISD::FNEG)          // ((-A)+B) -> B-A
-      return getNode(ISD::SUB, VT, N2, N1.getOperand(0));
     if (N1.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N1.getOperand(0)) &&
         cast<ConstantSDNode>(N1.getOperand(0))->getValue() == 0)
       return getNode(ISD::SUB, VT, N2, N1.getOperand(1)); // (0-A)+B -> B-A
     if (N2.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N2.getOperand(0)) &&
         cast<ConstantSDNode>(N2.getOperand(0))->getValue() == 0)
       return getNode(ISD::SUB, VT, N1, N2.getOperand(1)); // A+(0-B) -> A-B
-    if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1) &&
-        !MVT::isFloatingPoint(N2.getValueType()))
+    if (N2.getOpcode() == ISD::SUB && N1 == N2.Val->getOperand(1))
       return N2.Val->getOperand(0); // A+(B-A) -> B
     }
     break;
+  case ISD::FADD:
+    if (!CombinerEnabled) {
+    if (N2.getOpcode() == ISD::FNEG)          // (A+ (-B) -> A-B
+      return getNode(ISD::FSUB, VT, N1, N2.getOperand(0));
+    if (N1.getOpcode() == ISD::FNEG)          // ((-A)+B) -> B-A
+      return getNode(ISD::FSUB, VT, N2, N1.getOperand(0));
+    }
+    break;
+    
   case ISD::SUB:
     if (!CombinerEnabled) {
     if (N1.getOpcode() == ISD::ADD) {
-      if (N1.Val->getOperand(0) == N2 &&
-          !MVT::isFloatingPoint(N2.getValueType()))
+      if (N1.Val->getOperand(0) == N2)
         return N1.Val->getOperand(1);         // (A+B)-A == B
-      if (N1.Val->getOperand(1) == N2 &&
-          !MVT::isFloatingPoint(N2.getValueType()))
+      if (N1.Val->getOperand(1) == N2)
         return N1.Val->getOperand(0);         // (A+B)-B == A
     }
+    }
+    break;
+  case ISD::FSUB:
+    if (!CombinerEnabled) {
     if (N2.getOpcode() == ISD::FNEG)          // (A- (-B) -> A+B
-      return getNode(ISD::ADD, VT, N1, N2.getOperand(0));
+      return getNode(ISD::FADD, VT, N1, N2.getOperand(0));
     }
     break;
   case ISD::FP_ROUND_INREG:
@@ -2333,7 +2347,12 @@
   case ISD::SHL:    return "shl";
   case ISD::SRA:    return "sra";
   case ISD::SRL:    return "srl";
-
+  case ISD::FADD:   return "fadd";
+  case ISD::FSUB:   return "fsub";
+  case ISD::FMUL:   return "fmul";
+  case ISD::FDIV:   return "fdiv";
+  case ISD::FREM:   return "frem";
+    
   case ISD::SETCC:       return "setcc";
   case ISD::SELECT:      return "select";
   case ISD::SELECT_CC:   return "select_cc";


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.84 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.85
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.84	Tue Sep 27 17:15:53 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Wed Sep 28 17:28:18 2005
@@ -353,14 +353,34 @@
 
   //
   void visitBinary(User &I, unsigned Opcode, bool isShift = false);
-  void visitAdd(User &I) { visitBinary(I, ISD::ADD); }
+  void visitAdd(User &I) {
+    visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FADD : ISD::ADD);
+  }
   void visitSub(User &I);
-  void visitMul(User &I) { visitBinary(I, ISD::MUL); }
+  void visitMul(User &I) {
+    visitBinary(I, I.getType()->isFloatingPoint() ? ISD::FMUL : ISD::MUL);
+  }
   void visitDiv(User &I) {
-    visitBinary(I, I.getType()->isUnsigned() ? ISD::UDIV : ISD::SDIV);
+    unsigned Opc;
+    const Type *Ty = I.getType();
+    if (Ty->isFloatingPoint())
+      Opc = ISD::FDIV;
+    else if (Ty->isUnsigned())
+      Opc = ISD::UDIV;
+    else
+      Opc = ISD::SDIV;
+    visitBinary(I, Opc);
   }
   void visitRem(User &I) {
-    visitBinary(I, I.getType()->isUnsigned() ? ISD::UREM : ISD::SREM);
+    unsigned Opc;
+    const Type *Ty = I.getType();
+    if (Ty->isFloatingPoint())
+      Opc = ISD::FREM;
+    else if (Ty->isUnsigned())
+      Opc = ISD::UREM;
+    else
+      Opc = ISD::SREM;
+    visitBinary(I, Opc);
   }
   void visitAnd(User &I) { visitBinary(I, ISD::AND); }
   void visitOr (User &I) { visitBinary(I, ISD::OR); }
@@ -491,14 +511,17 @@
 
 void SelectionDAGLowering::visitSub(User &I) {
   // -0.0 - X --> fneg
-  if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
-    if (CFP->isExactlyValue(-0.0)) {
-      SDOperand Op2 = getValue(I.getOperand(1));
-      setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
-      return;
-    }
-
-  visitBinary(I, ISD::SUB);
+  if (I.getType()->isFloatingPoint()) {
+    if (ConstantFP *CFP = dyn_cast<ConstantFP>(I.getOperand(0)))
+      if (CFP->isExactlyValue(-0.0)) {
+        SDOperand Op2 = getValue(I.getOperand(1));
+        setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
+        return;
+      }
+    visitBinary(I, ISD::FSUB);
+  } else {
+    visitBinary(I, ISD::SUB);
+  }
 }
 
 void SelectionDAGLowering::visitBinary(User &I, unsigned Opcode, bool isShift) {






More information about the llvm-commits mailing list