mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-24 02:38:42 +00:00
Add some simple copysign folds
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26543 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a09f848c11
commit
12d830346b
@ -195,6 +195,7 @@ namespace {
|
||||
SDOperand visitFMUL(SDNode *N);
|
||||
SDOperand visitFDIV(SDNode *N);
|
||||
SDOperand visitFREM(SDNode *N);
|
||||
SDOperand visitFCOPYSIGN(SDNode *N);
|
||||
SDOperand visitSINT_TO_FP(SDNode *N);
|
||||
SDOperand visitUINT_TO_FP(SDNode *N);
|
||||
SDOperand visitFP_TO_SINT(SDNode *N);
|
||||
@ -627,6 +628,7 @@ SDOperand DAGCombiner::visit(SDNode *N) {
|
||||
case ISD::FMUL: return visitFMUL(N);
|
||||
case ISD::FDIV: return visitFDIV(N);
|
||||
case ISD::FREM: return visitFREM(N);
|
||||
case ISD::FCOPYSIGN: return visitFCOPYSIGN(N);
|
||||
case ISD::SINT_TO_FP: return visitSINT_TO_FP(N);
|
||||
case ISD::UINT_TO_FP: return visitUINT_TO_FP(N);
|
||||
case ISD::FP_TO_SINT: return visitFP_TO_SINT(N);
|
||||
@ -1999,6 +2001,54 @@ SDOperand DAGCombiner::visitFREM(SDNode *N) {
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
SDOperand DAGCombiner::visitFCOPYSIGN(SDNode *N) {
|
||||
SDOperand N0 = N->getOperand(0);
|
||||
SDOperand N1 = N->getOperand(1);
|
||||
ConstantFPSDNode *N0CFP = dyn_cast<ConstantFPSDNode>(N0);
|
||||
ConstantFPSDNode *N1CFP = dyn_cast<ConstantFPSDNode>(N1);
|
||||
MVT::ValueType VT = N->getValueType(0);
|
||||
|
||||
if (N0CFP && N1CFP) // Constant fold
|
||||
return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1);
|
||||
|
||||
if (N1CFP) {
|
||||
// copysign(x, c1) -> fabs(x) iff ispos(c1)
|
||||
// copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1)
|
||||
union {
|
||||
double d;
|
||||
int64_t i;
|
||||
} u;
|
||||
u.d = N1CFP->getValue();
|
||||
if (u.i >= 0)
|
||||
return DAG.getNode(ISD::FABS, VT, N0);
|
||||
else
|
||||
return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0));
|
||||
}
|
||||
|
||||
// copysign(fabs(x), y) -> copysign(x, y)
|
||||
// copysign(fneg(x), y) -> copysign(x, y)
|
||||
// copysign(copysign(x,z), y) -> copysign(x, y)
|
||||
if (N0.getOpcode() == ISD::FABS || N0.getOpcode() == ISD::FNEG ||
|
||||
N0.getOpcode() == ISD::FCOPYSIGN)
|
||||
return DAG.getNode(ISD::FCOPYSIGN, VT, N0.getOperand(0), N1);
|
||||
|
||||
// copysign(x, abs(y)) -> abs(x)
|
||||
if (N1.getOpcode() == ISD::FABS)
|
||||
return DAG.getNode(ISD::FABS, VT, N0);
|
||||
|
||||
// copysign(x, copysign(y,z)) -> copysign(x, z)
|
||||
if (N1.getOpcode() == ISD::FCOPYSIGN)
|
||||
return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1.getOperand(1));
|
||||
|
||||
// copysign(x, fp_extend(y)) -> copysign(x, y)
|
||||
// copysign(x, fp_round(y)) -> copysign(x, y)
|
||||
if (N1.getOpcode() == ISD::FP_EXTEND || N1.getOpcode() == ISD::FP_ROUND)
|
||||
return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1.getOperand(0));
|
||||
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
|
||||
|
||||
SDOperand DAGCombiner::visitSINT_TO_FP(SDNode *N) {
|
||||
SDOperand N0 = N->getOperand(0);
|
||||
@ -2089,11 +2139,11 @@ SDOperand DAGCombiner::visitFNEG(SDNode *N) {
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FNEG, VT, N0);
|
||||
// fold (fneg (sub x, y)) -> (sub y, x)
|
||||
if (N->getOperand(0).getOpcode() == ISD::SUB)
|
||||
return DAG.getNode(ISD::SUB, VT, N->getOperand(1), N->getOperand(0));
|
||||
if (N0.getOpcode() == ISD::SUB)
|
||||
return DAG.getNode(ISD::SUB, VT, N0.getOperand(1), N0.getOperand(0));
|
||||
// fold (fneg (fneg x)) -> x
|
||||
if (N->getOperand(0).getOpcode() == ISD::FNEG)
|
||||
return N->getOperand(0).getOperand(0);
|
||||
if (N0.getOpcode() == ISD::FNEG)
|
||||
return N0.getOperand(0);
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
@ -2106,11 +2156,13 @@ SDOperand DAGCombiner::visitFABS(SDNode *N) {
|
||||
if (N0CFP)
|
||||
return DAG.getNode(ISD::FABS, VT, N0);
|
||||
// fold (fabs (fabs x)) -> (fabs x)
|
||||
if (N->getOperand(0).getOpcode() == ISD::FABS)
|
||||
if (N0.getOpcode() == ISD::FABS)
|
||||
return N->getOperand(0);
|
||||
// fold (fabs (fneg x)) -> (fabs x)
|
||||
if (N->getOperand(0).getOpcode() == ISD::FNEG)
|
||||
return DAG.getNode(ISD::FABS, VT, N->getOperand(0).getOperand(0));
|
||||
// fold (fabs (fcopysign x, y)) -> (fabs x)
|
||||
if (N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FCOPYSIGN)
|
||||
return DAG.getNode(ISD::FABS, VT, N0.getOperand(0));
|
||||
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
|
@ -1250,6 +1250,8 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
|
||||
case ISD::FREM :
|
||||
if (C2) return getConstantFP(fmod(C1, C2), VT);
|
||||
break;
|
||||
case ISD::FCOPYSIGN:
|
||||
return getConstantFP(copysign(C1, C2), VT);
|
||||
default: break;
|
||||
}
|
||||
} else { // Cannonicalize constant to RHS if commutative
|
||||
|
Loading…
x
Reference in New Issue
Block a user