mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-08-13 23:26:25 +00:00
Expand fcopysign to a series of bitwise of operations when it's profitable to
do so. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32881 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -528,6 +528,35 @@ static SDOperand ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// ExpandFCOPYSIGNToBitwiseOps - Expands fcopysign to a series of bitwise
|
||||||
|
/// operations.
|
||||||
|
static
|
||||||
|
SDOperand ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT::ValueType NVT,
|
||||||
|
SelectionDAG &DAG, TargetLowering &TLI) {
|
||||||
|
MVT::ValueType SrcVT = Node->getOperand(1).getValueType();
|
||||||
|
MVT::ValueType SrcNVT = (SrcVT == MVT::f64) ? MVT::i64 : MVT::i32;
|
||||||
|
// First get the sign bit of second operand.
|
||||||
|
SDOperand Mask = (SrcVT == MVT::f64)
|
||||||
|
? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT)
|
||||||
|
: DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT);
|
||||||
|
Mask = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask);
|
||||||
|
SDOperand SignBit= DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Node->getOperand(1));
|
||||||
|
SignBit = DAG.getNode(ISD::AND, SrcNVT, SignBit, Mask);
|
||||||
|
// Shift right or sign-extend it if the two operands have different types.
|
||||||
|
int SizeDiff = MVT::getSizeInBits(SrcNVT) - MVT::getSizeInBits(NVT);
|
||||||
|
if (SizeDiff > 0) {
|
||||||
|
SignBit = DAG.getNode(ISD::SRL, SrcNVT, SignBit,
|
||||||
|
DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
|
||||||
|
SignBit = DAG.getNode(ISD::TRUNCATE, NVT, SignBit);
|
||||||
|
} else if (SizeDiff < 0)
|
||||||
|
SignBit = DAG.getNode(ISD::SIGN_EXTEND, NVT, SignBit);
|
||||||
|
// Or the first operand with the sign bit.
|
||||||
|
SDOperand Result = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0));
|
||||||
|
Result = DAG.getNode(ISD::OR, NVT, Result, SignBit);
|
||||||
|
return Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// LegalizeOp - We know that the specified value has a legal type.
|
/// LegalizeOp - We know that the specified value has a legal type.
|
||||||
/// Recursively ensure that the operands have legal types, then return the
|
/// Recursively ensure that the operands have legal types, then return the
|
||||||
/// result.
|
/// result.
|
||||||
@@ -2314,10 +2343,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
if (Tmp1.Val) Result = Tmp1;
|
if (Tmp1.Val) Result = Tmp1;
|
||||||
break;
|
break;
|
||||||
case TargetLowering::Legal: break;
|
case TargetLowering::Legal: break;
|
||||||
case TargetLowering::Expand:
|
case TargetLowering::Expand: {
|
||||||
// If this target supports fabs/fneg natively, do this efficiently.
|
// If this target supports fabs/fneg natively, do this efficiently.
|
||||||
if (TLI.isOperationLegal(ISD::FABS, Tmp1.getValueType()) &&
|
if (TLI.getOperationAction(ISD::FABS, Tmp1.getValueType()) ==
|
||||||
TLI.isOperationLegal(ISD::FNEG, Tmp1.getValueType())) {
|
TargetLowering::Legal &&
|
||||||
|
TLI.getOperationAction(ISD::FNEG, Tmp1.getValueType()) ==
|
||||||
|
TargetLowering::Legal) {
|
||||||
// Get the sign bit of the RHS.
|
// Get the sign bit of the RHS.
|
||||||
MVT::ValueType IVT =
|
MVT::ValueType IVT =
|
||||||
Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64;
|
Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64;
|
||||||
@@ -2337,24 +2368,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, do bitwise ops!
|
// Otherwise, do bitwise ops!
|
||||||
|
MVT::ValueType NVT =
|
||||||
// copysign -> copysignf/copysign libcall.
|
Node->getValueType(0) == MVT::f32 ? MVT::i32 : MVT::i64;
|
||||||
const char *FnName;
|
Result = ExpandFCOPYSIGNToBitwiseOps(Node, NVT, DAG, TLI);
|
||||||
if (Node->getValueType(0) == MVT::f32) {
|
Result = DAG.getNode(ISD::BIT_CONVERT, Node->getValueType(0), Result);
|
||||||
FnName = "copysignf";
|
Result = LegalizeOp(Result);
|
||||||
if (Tmp2.getValueType() != MVT::f32) // Force operands to match type.
|
|
||||||
Result = DAG.UpdateNodeOperands(Result, Tmp1,
|
|
||||||
DAG.getNode(ISD::FP_ROUND, MVT::f32, Tmp2));
|
|
||||||
} else {
|
|
||||||
FnName = "copysign";
|
|
||||||
if (Tmp2.getValueType() != MVT::f64) // Force operands to match type.
|
|
||||||
Result = DAG.UpdateNodeOperands(Result, Tmp1,
|
|
||||||
DAG.getNode(ISD::FP_EXTEND, MVT::f64, Tmp2));
|
|
||||||
}
|
|
||||||
SDOperand Dummy;
|
|
||||||
Result = ExpandLibCall(FnName, Node, false/*sign irrelevant*/, Dummy);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ISD::ADDC:
|
case ISD::ADDC:
|
||||||
@@ -5123,6 +5144,12 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
|
|||||||
ExpandOp(Lo, Lo, Hi);
|
ExpandOp(Lo, Lo, Hi);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ISD::FCOPYSIGN: {
|
||||||
|
Lo = ExpandFCOPYSIGNToBitwiseOps(Node, NVT, DAG, TLI);
|
||||||
|
if (getTypeAction(NVT) == Expand)
|
||||||
|
ExpandOp(Lo, Lo, Hi);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case ISD::SINT_TO_FP:
|
case ISD::SINT_TO_FP:
|
||||||
case ISD::UINT_TO_FP: {
|
case ISD::UINT_TO_FP: {
|
||||||
bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
|
bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
|
||||||
|
Reference in New Issue
Block a user