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

Chris Lattner lattner at cs.uiuc.edu
Sat Mar 4 21:09:50 PST 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

LegalizeDAG.cpp updated: 1.310 -> 1.311
SelectionDAG.cpp updated: 1.265 -> 1.266
SelectionDAGISel.cpp updated: 1.178 -> 1.179
---
Log message:

Codegen copysign[f] into a FCOPYSIGN node


---
Diffs of the changes:  (+63 -4)

 LegalizeDAG.cpp      |   46 ++++++++++++++++++++++++++++++++++++++++++++--
 SelectionDAG.cpp     |    8 +++++++-
 SelectionDAGISel.cpp |   13 ++++++++++++-
 3 files changed, 63 insertions(+), 4 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.310 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.311
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.310	Fri Mar  3 01:01:07 2006
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp	Sat Mar  4 23:09:38 2006
@@ -1775,7 +1775,48 @@
       break;
     }
     break;
-  
+    
+  case ISD::FCOPYSIGN:  // FCOPYSIGN does not require LHS/RHS to match type!
+    Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
+    switch (getTypeAction(Node->getOperand(1).getValueType())) {
+      case Expand: assert(0 && "Not possible");
+      case Legal:
+        Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS.
+        break;
+      case Promote:
+        Tmp2 = PromoteOp(Node->getOperand(1));  // Promote the RHS.
+        break;
+    }
+      
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+    
+    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+    default: assert(0 && "Operation not supported");
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+        break;
+    case TargetLowering::Legal: break;
+    case TargetLowering::Expand:
+      // Floating point mod -> fmod libcall.
+      const char *FnName;
+      if (Node->getValueType(0) == MVT::f32) {
+        FnName = "copysignf";
+        if (Tmp2.getValueType() != MVT::f32)  // Force operands to match type.
+          Result = DAG.UpdateNodeOperands(Result, Tmp1, 
+                                    DAG.getNode(ISD::FP_ROUND, MVT::f32, Tmp2));
+      } else {
+        FnName = "copysign";
+        if (Tmp2.getValueType() != MVT::f64)  // Force operands to match type.
+          Result = DAG.UpdateNodeOperands(Result, Tmp1, 
+                                   DAG.getNode(ISD::FP_EXTEND, MVT::f64, Tmp2));
+      }
+      SDOperand Dummy;
+      Result = ExpandLibCall(FnName, Node, Dummy);
+      break;
+    }
+    break;
+    
   case ISD::ADDC:
   case ISD::SUBC:
     Tmp1 = LegalizeOp(Node->getOperand(0));
@@ -2604,13 +2645,14 @@
     break;
   case ISD::FDIV:
   case ISD::FREM:
+  case ISD::FCOPYSIGN:
     // 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)
+    if (NoExcessFPPrecision && Node->getOpcode() != ISD::FCOPYSIGN)
       Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
                            DAG.getValueType(VT));
     break;


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.265 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.266
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.265	Fri Mar  3 00:42:32 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Sat Mar  4 23:09:38 2006
@@ -1152,7 +1152,12 @@
     assert(N1.getValueType() == N2.getValueType() &&
            N1.getValueType() == VT && "Binary operator types must match!");
     break;
-
+  case ISD::FCOPYSIGN:   // N1 and result must match.  N1/N2 need not match.
+    assert(N1.getValueType() == VT &&
+           MVT::isFloatingPoint(N1.getValueType()) && 
+           MVT::isFloatingPoint(N2.getValueType()) &&
+           "Invalid FCOPYSIGN!");
+    break;
   case ISD::SHL:
   case ISD::SRA:
   case ISD::SRL:
@@ -2635,6 +2640,7 @@
   case ISD::FMUL:   return "fmul";
   case ISD::FDIV:   return "fdiv";
   case ISD::FREM:   return "frem";
+  case ISD::FCOPYSIGN: return "fcopysign";
   case ISD::VADD:   return "vadd";
   case ISD::VSUB:   return "vsub";
   case ISD::VMUL:   return "vmul";


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.178 llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.179
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp:1.178	Fri Mar  3 01:01:07 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	Sat Mar  4 23:09:38 2006
@@ -1120,7 +1120,18 @@
           return;
       } else {    // Not an LLVM intrinsic.
         const std::string &Name = F->getName();
-        if (Name[0] == 'f' && (Name == "fabs" || Name == "fabsf")) {
+        if (Name[0] == 'c' && (Name == "copysign" || Name == "copysignf")) {
+          if (I.getNumOperands() == 3 &&   // Basic sanity checks.
+              I.getOperand(1)->getType()->isFloatingPoint() &&
+              I.getType() == I.getOperand(1)->getType() &&
+              I.getType() == I.getOperand(2)->getType()) {
+            SDOperand LHS = getValue(I.getOperand(1));
+            SDOperand RHS = getValue(I.getOperand(2));
+            setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(),
+                                     LHS, RHS));
+            return;
+          }
+        } else if (Name[0] == 'f' && (Name == "fabs" || Name == "fabsf")) {
           if (I.getNumOperands() == 2 &&   // Basic sanity checks.
               I.getOperand(1)->getType()->isFloatingPoint() &&
               I.getType() == I.getOperand(1)->getType()) {






More information about the llvm-commits mailing list