diff options
author | Chris Lattner <sabre@nondot.org> | 2005-04-30 04:43:14 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-04-30 04:43:14 +0000 |
commit | f76e7dc8d8ac1855ef59698e82c757548ef4ca65 (patch) | |
tree | d25fcd81cc078454229b5115bb0d7fbc591d6052 | |
parent | ac766dca8229d927fb569497b43bc4efd6afcd4a (diff) |
Codegen and legalize sin/cos/llvm.sqrt as FSIN/FCOS/FSQRT calls. This patch
was contributed by Morten Ofstad, with some minor tweaks and bug fixes added
by me.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21636 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 31 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 25 |
2 files changed, 53 insertions, 3 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index b8d07d0cbf..52570824c3 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1003,12 +1003,15 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { case TargetLowering::Custom: assert(0 && "Cannot promote/custom handle this yet!"); case TargetLowering::Expand: - if (Node->getOpcode() == ISD::FNEG) { + switch(Node->getOpcode()) { + 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), Tmp2, Tmp1)); - } else if (Node->getOpcode() == ISD::FABS) { + break; + } + case ISD::FABS: { // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). MVT::ValueType VT = Node->getValueType(0); Tmp2 = DAG.getConstantFP(0.0, VT); @@ -1016,7 +1019,29 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { Tmp3 = DAG.getNode(ISD::FNEG, VT, Tmp1); Result = DAG.getNode(ISD::SELECT, VT, Tmp2, Tmp1, Tmp3); Result = LegalizeOp(Result); - } else { + break; + } + case ISD::FSQRT: + case ISD::FSIN: + case ISD::FCOS: { + MVT::ValueType VT = Node->getValueType(0); + Type *T = VT == MVT::f32 ? Type::FloatTy : Type::DoubleTy; + const char *FnName = 0; + switch(Node->getOpcode()) { + case ISD::FSQRT: FnName = VT == MVT::f32 ? "sqrtf" : "sqrt"; break; + case ISD::FSIN: FnName = VT == MVT::f32 ? "sinf" : "sin"; break; + case ISD::FCOS: FnName = VT == MVT::f32 ? "cosf" : "cos"; break; + default: assert(0 && "Unreachable!"); + } + std::vector<std::pair<SDOperand, const Type*> > Args; + Args.push_back(std::make_pair(Tmp1, T)); + std::pair<SDOperand,SDOperand> CallResult = + TLI.LowerCallTo(DAG.getEntryNode(), T, false, + DAG.getExternalSymbol(FnName, VT), Args, DAG); + Result = LegalizeOp(CallResult.first); + break; + } + default: assert(0 && "Unreachable!"); } break; diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 295dd35c57..20483d4814 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -656,6 +656,24 @@ void SelectionDAGLowering::visitCall(CallInst &I) { return; } } + else if (F->getName() == "sin" || F->getName() == "sinf") { + if (I.getNumOperands() == 2 && // Basic sanity checks. + I.getOperand(1)->getType()->isFloatingPoint() && + I.getType() == I.getOperand(1)->getType()) { + SDOperand Tmp = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp)); + return; + } + } + else if (F->getName() == "cos" || F->getName() == "cosf") { + if (I.getNumOperands() == 2 && // Basic sanity checks. + I.getOperand(1)->getType()->isFloatingPoint() && + I.getType() == I.getOperand(1)->getType()) { + SDOperand Tmp = getValue(I.getOperand(1)); + setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp)); + return; + } + } break; case Intrinsic::vastart: visitVAStart(I); return; case Intrinsic::vaend: visitVAEnd(I); return; @@ -677,6 +695,13 @@ void SelectionDAGLowering::visitCall(CallInst &I) { setValue(&I, DAG.getSetCC(ISD::SETUO, MVT::i1,getValue(I.getOperand(1)), getValue(I.getOperand(2)))); return; + + case Intrinsic::sqrt: + setValue(&I, DAG.getNode(ISD::FSQRT, + getValue(I.getOperand(1)).getValueType(), + getValue(I.getOperand(1)))); + return; + case Intrinsic::pcmarker: { SDOperand Num = getValue(I.getOperand(1)); DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Num)); |