aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-03-13 06:08:38 +0000
committerChris Lattner <sabre@nondot.org>2006-03-13 06:08:38 +0000
commit8f4191d61978529e9e9d7ddc24dbcd528ef7dd4c (patch)
treef69c3ba4b799d332131cf718787f70d13b277da7 /lib/CodeGen
parent64ce964673ca5c71f46933d8699aa557fbc5f15a (diff)
For targets with FABS/FNEG support, lower copysign to an integer load,
a select and FABS/FNEG. This speeds up a trivial (aka stupid) copysign benchmark I wrote from 6.73s to 2.64s, woo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26723 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp27
1 files changed, 25 insertions, 2 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 5c3787e35f..a6d74c85e7 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1795,10 +1795,33 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
case TargetLowering::Custom:
Tmp1 = TLI.LowerOperation(Result, DAG);
if (Tmp1.Val) Result = Tmp1;
- break;
+ break;
case TargetLowering::Legal: break;
case TargetLowering::Expand:
- // Floating point mod -> fmod libcall.
+ // If this target supports fabs/fneg natively, do this efficiently.
+ if (TLI.isOperationLegal(ISD::FABS, Tmp1.getValueType()) &&
+ TLI.isOperationLegal(ISD::FNEG, Tmp1.getValueType())) {
+ // Get the sign bit of the RHS.
+ MVT::ValueType IVT =
+ Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64;
+ SDOperand SignBit = DAG.getNode(ISD::BIT_CONVERT, IVT, Tmp2);
+ SignBit = DAG.getSetCC(TLI.getSetCCResultTy(),
+ SignBit, DAG.getConstant(0, IVT), ISD::SETLT);
+ // Get the absolute value of the result.
+ SDOperand AbsVal = DAG.getNode(ISD::FABS, Tmp1.getValueType(), Tmp1);
+ // Select between the nabs and abs value based on the sign bit of
+ // the input.
+ Result = DAG.getNode(ISD::SELECT, AbsVal.getValueType(), SignBit,
+ DAG.getNode(ISD::FNEG, AbsVal.getValueType(),
+ AbsVal),
+ AbsVal);
+ Result = LegalizeOp(Result);
+ break;
+ }
+
+ // Otherwise, do bitwise ops!
+
+ // copysign -> copysignf/copysign libcall.
const char *FnName;
if (Node->getValueType(0) == MVT::f32) {
FnName = "copysignf";