diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-03-13 06:08:38 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-03-13 06:08:38 +0000 | 
| commit | 994d8e6bd4e3f474b0db6d71378c1bc466105ff8 (patch) | |
| tree | bc862f296d77f5c5409126c69fab57b4ebf92c28 /llvm/lib/CodeGen | |
| parent | ec9d0bc3ec06a893fa3dddc40b707e9bf2ae398b (diff) | |
| download | bcm5719-llvm-994d8e6bd4e3f474b0db6d71378c1bc466105ff8.tar.gz bcm5719-llvm-994d8e6bd4e3f474b0db6d71378c1bc466105ff8.zip | |
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.
llvm-svn: 26723
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 27 | 
1 files changed, 25 insertions, 2 deletions
| diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 5c3787e35f2..a6d74c85e7c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/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"; | 

