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
This commit is contained in:
Chris Lattner 2006-03-13 06:08:38 +00:00
parent ec9d0bc3ec
commit 994d8e6bd4
1 changed files with 25 additions and 2 deletions

View File

@ -1798,7 +1798,30 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
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";