diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-05-24 10:21:20 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-05-24 10:21:20 +0000 |
commit | ed2f8c557a86612ee14fea25e7be2d3c1445951a (patch) | |
tree | 36a7395b5688cc2d8c0670b5851636637637fc72 /lib/CodeGen | |
parent | 2c235010312f72622acd4b7bb70f87cf31a982f6 (diff) | |
download | external_llvm-ed2f8c557a86612ee14fea25e7be2d3c1445951a.zip external_llvm-ed2f8c557a86612ee14fea25e7be2d3c1445951a.tar.gz external_llvm-ed2f8c557a86612ee14fea25e7be2d3c1445951a.tar.bz2 |
Rewrite ISD::FCOPYSIGN lowering to never use i64. Not really ideal, but
it's late, and I don't have any better ideas at the moment. Fixes PR4257.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72363 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 51 |
1 files changed, 21 insertions, 30 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index a3c499c..e86c719 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3142,36 +3142,27 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; case TargetLowering::Legal: break; case TargetLowering::Expand: { - // If this target supports fabs/fneg natively and select is cheap, - // do this efficiently. - if (!TLI.isSelectExpensive() && - TLI.getOperationAction(ISD::FABS, Tmp1.getValueType()) == - TargetLowering::Legal && - TLI.getOperationAction(ISD::FNEG, Tmp1.getValueType()) == - TargetLowering::Legal) { - // Get the sign bit of the RHS. - MVT IVT = - Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64; - SDValue SignBit = DAG.getNode(ISD::BIT_CONVERT, dl, IVT, Tmp2); - SignBit = DAG.getSetCC(dl, TLI.getSetCCResultType(IVT), - SignBit, DAG.getConstant(0, IVT), ISD::SETLT); - // Get the absolute value of the result. - SDValue AbsVal = DAG.getNode(ISD::FABS, dl, Tmp1.getValueType(), Tmp1); - // Select between the nabs and abs value based on the sign bit of - // the input. - Result = DAG.getNode(ISD::SELECT, dl, AbsVal.getValueType(), SignBit, - DAG.getNode(ISD::FNEG, dl, AbsVal.getValueType(), - AbsVal), - AbsVal); - Result = LegalizeOp(Result); - break; - } - - // Otherwise, do bitwise ops! - MVT NVT = - Node->getValueType(0) == MVT::f32 ? MVT::i32 : MVT::i64; - Result = ExpandFCOPYSIGNToBitwiseOps(Node, NVT, DAG, TLI); - Result = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0), Result); + assert((Tmp2.getValueType() == MVT::f32 || + Tmp2.getValueType() == MVT::f64) && isTypeLegal(MVT::i32) && + "Ugly special-cased code!"); + // Get the sign bit of the RHS. + SDValue StackPtr = DAG.CreateStackTemporary(Tmp2.getValueType()); + SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StackPtr, NULL, + 0); + if (Tmp2.getValueType() == MVT::f64 && TLI.isLittleEndian()) + StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), + StackPtr, DAG.getIntPtrConstant(4)); + SDValue SignBit = DAG.getLoad(MVT::i32, dl, Ch, StackPtr, NULL, 0); + SignBit = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i32), + SignBit, DAG.getConstant(0, MVT::i32), ISD::SETLT); + // Get the absolute value of the result. + SDValue AbsVal = DAG.getNode(ISD::FABS, dl, Tmp1.getValueType(), Tmp1); + // Select between the nabs and abs value based on the sign bit of + // the input. + Result = DAG.getNode(ISD::SELECT, dl, AbsVal.getValueType(), SignBit, + DAG.getNode(ISD::FNEG, dl, AbsVal.getValueType(), + AbsVal), + AbsVal); Result = LegalizeOp(Result); break; } |