mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
Codegen copysign[f] into a FCOPYSIGN node
llvm-svn: 26542
This commit is contained in:
parent
6b0947c277
commit
4b4b3e6cbb
@ -1775,7 +1775,48 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ISD::FCOPYSIGN: // FCOPYSIGN does not require LHS/RHS to match type!
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
|
||||
switch (getTypeAction(Node->getOperand(1).getValueType())) {
|
||||
case Expand: assert(0 && "Not possible");
|
||||
case Legal:
|
||||
Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS.
|
||||
break;
|
||||
case Promote:
|
||||
Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the RHS.
|
||||
break;
|
||||
}
|
||||
|
||||
Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
|
||||
|
||||
switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
|
||||
default: assert(0 && "Operation not supported");
|
||||
case TargetLowering::Custom:
|
||||
Tmp1 = TLI.LowerOperation(Result, DAG);
|
||||
if (Tmp1.Val) Result = Tmp1;
|
||||
break;
|
||||
case TargetLowering::Legal: break;
|
||||
case TargetLowering::Expand:
|
||||
// Floating point mod -> fmod libcall.
|
||||
const char *FnName;
|
||||
if (Node->getValueType(0) == MVT::f32) {
|
||||
FnName = "copysignf";
|
||||
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, Dummy);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISD::ADDC:
|
||||
case ISD::SUBC:
|
||||
Tmp1 = LegalizeOp(Node->getOperand(0));
|
||||
@ -2604,13 +2645,14 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
|
||||
break;
|
||||
case ISD::FDIV:
|
||||
case ISD::FREM:
|
||||
case ISD::FCOPYSIGN:
|
||||
// These operators require that their input be fp extended.
|
||||
Tmp1 = PromoteOp(Node->getOperand(0));
|
||||
Tmp2 = PromoteOp(Node->getOperand(1));
|
||||
Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
|
||||
|
||||
// Perform FP_ROUND: this is probably overly pessimistic.
|
||||
if (NoExcessFPPrecision)
|
||||
if (NoExcessFPPrecision && Node->getOpcode() != ISD::FCOPYSIGN)
|
||||
Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
|
||||
DAG.getValueType(VT));
|
||||
break;
|
||||
|
@ -1152,7 +1152,12 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
assert(N1.getValueType() == N2.getValueType() &&
|
||||
N1.getValueType() == VT && "Binary operator types must match!");
|
||||
break;
|
||||
|
||||
case ISD::FCOPYSIGN: // N1 and result must match. N1/N2 need not match.
|
||||
assert(N1.getValueType() == VT &&
|
||||
MVT::isFloatingPoint(N1.getValueType()) &&
|
||||
MVT::isFloatingPoint(N2.getValueType()) &&
|
||||
"Invalid FCOPYSIGN!");
|
||||
break;
|
||||
case ISD::SHL:
|
||||
case ISD::SRA:
|
||||
case ISD::SRL:
|
||||
@ -2635,6 +2640,7 @@ const char *SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
case ISD::FMUL: return "fmul";
|
||||
case ISD::FDIV: return "fdiv";
|
||||
case ISD::FREM: return "frem";
|
||||
case ISD::FCOPYSIGN: return "fcopysign";
|
||||
case ISD::VADD: return "vadd";
|
||||
case ISD::VSUB: return "vsub";
|
||||
case ISD::VMUL: return "vmul";
|
||||
|
@ -1120,7 +1120,18 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
|
||||
return;
|
||||
} else { // Not an LLVM intrinsic.
|
||||
const std::string &Name = F->getName();
|
||||
if (Name[0] == 'f' && (Name == "fabs" || Name == "fabsf")) {
|
||||
if (Name[0] == 'c' && (Name == "copysign" || Name == "copysignf")) {
|
||||
if (I.getNumOperands() == 3 && // Basic sanity checks.
|
||||
I.getOperand(1)->getType()->isFloatingPoint() &&
|
||||
I.getType() == I.getOperand(1)->getType() &&
|
||||
I.getType() == I.getOperand(2)->getType()) {
|
||||
SDOperand LHS = getValue(I.getOperand(1));
|
||||
SDOperand RHS = getValue(I.getOperand(2));
|
||||
setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(),
|
||||
LHS, RHS));
|
||||
return;
|
||||
}
|
||||
} else if (Name[0] == 'f' && (Name == "fabs" || Name == "fabsf")) {
|
||||
if (I.getNumOperands() == 2 && // Basic sanity checks.
|
||||
I.getOperand(1)->getType()->isFloatingPoint() &&
|
||||
I.getType() == I.getOperand(1)->getType()) {
|
||||
|
Loading…
Reference in New Issue
Block a user