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()) { _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits