aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-04-30 04:43:14 +0000
committerChris Lattner <sabre@nondot.org>2005-04-30 04:43:14 +0000
commitf76e7dc8d8ac1855ef59698e82c757548ef4ca65 (patch)
treed25fcd81cc078454229b5115bb0d7fbc591d6052
parentac766dca8229d927fb569497b43bc4efd6afcd4a (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.cpp31
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp25
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));