aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2009-05-24 10:21:20 +0000
committerEli Friedman <eli.friedman@gmail.com>2009-05-24 10:21:20 +0000
commited2f8c557a86612ee14fea25e7be2d3c1445951a (patch)
tree36a7395b5688cc2d8c0670b5851636637637fc72 /lib/CodeGen
parent2c235010312f72622acd4b7bb70f87cf31a982f6 (diff)
downloadexternal_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.cpp51
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;
}