forked from OSchip/llvm-project
Don't create ISD::FNEG nodes after legalize if they aren't legal.
Simplify x+0 to x in unsafe-fp-math mode. This avoids a bunch of redundant work in many cases, because in unsafe-fp-math mode, ISD::FADD with a constant is considered free to negate, so the DAGCombiner often negates x+0 to -0-x thinking it's free, when in reality the end result is -x, which is more expensive than x. Also, combine x*0 to 0. This fixes PR3374. llvm-svn: 62789
This commit is contained in:
parent
f4013373cd
commit
1f3411de47
|
@ -3814,6 +3814,9 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
|
|||
// canonicalize constant to RHS
|
||||
if (N0CFP && !N1CFP)
|
||||
return DAG.getNode(ISD::FADD, VT, N1, N0);
|
||||
// fold (A + 0) -> A
|
||||
if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero())
|
||||
return N0;
|
||||
// fold (A + (-B)) -> A-B
|
||||
if (isNegatibleForFree(N1, LegalOperations) == 2)
|
||||
return DAG.getNode(ISD::FSUB, VT, N0,
|
||||
|
@ -3852,7 +3855,8 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
|
|||
if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) {
|
||||
if (isNegatibleForFree(N1, LegalOperations))
|
||||
return GetNegatedExpression(N1, DAG, LegalOperations);
|
||||
return DAG.getNode(ISD::FNEG, VT, N1);
|
||||
if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))
|
||||
return DAG.getNode(ISD::FNEG, VT, N1);
|
||||
}
|
||||
// fold (A-(-B)) -> A+B
|
||||
if (isNegatibleForFree(N1, LegalOperations))
|
||||
|
@ -3881,12 +3885,16 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) {
|
|||
// canonicalize constant to RHS
|
||||
if (N0CFP && !N1CFP)
|
||||
return DAG.getNode(ISD::FMUL, VT, N1, N0);
|
||||
// fold (A * 0) -> 0
|
||||
if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero())
|
||||
return N1;
|
||||
// fold (fmul X, 2.0) -> (fadd X, X)
|
||||
if (N1CFP && N1CFP->isExactlyValue(+2.0))
|
||||
return DAG.getNode(ISD::FADD, VT, N0, N0);
|
||||
// fold (fmul X, -1.0) -> (fneg X)
|
||||
if (N1CFP && N1CFP->isExactlyValue(-1.0))
|
||||
return DAG.getNode(ISD::FNEG, VT, N0);
|
||||
if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))
|
||||
return DAG.getNode(ISD::FNEG, VT, N0);
|
||||
|
||||
// -X * -Y -> X*Y
|
||||
if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) {
|
||||
|
@ -3970,10 +3978,13 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) {
|
|||
const APFloat& V = N1CFP->getValueAPF();
|
||||
// copysign(x, c1) -> fabs(x) iff ispos(c1)
|
||||
// copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1)
|
||||
if (!V.isNegative())
|
||||
return DAG.getNode(ISD::FABS, VT, N0);
|
||||
else
|
||||
return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0));
|
||||
if (!V.isNegative()) {
|
||||
if (!LegalOperations || TLI.isOperationLegal(ISD::FABS, VT))
|
||||
return DAG.getNode(ISD::FABS, VT, N0);
|
||||
} else {
|
||||
if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT))
|
||||
return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0));
|
||||
}
|
||||
}
|
||||
|
||||
// copysign(fabs(x), y) -> copysign(x, y)
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetData.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
@ -2391,16 +2392,26 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
|
|||
case ISD::UREM:
|
||||
case ISD::MULHU:
|
||||
case ISD::MULHS:
|
||||
assert(VT.isInteger() && "This operator does not apply to FP types!");
|
||||
// fall through
|
||||
case ISD::MUL:
|
||||
case ISD::SDIV:
|
||||
case ISD::SREM:
|
||||
assert(VT.isInteger() && "This operator does not apply to FP types!");
|
||||
// fall through
|
||||
case ISD::FADD:
|
||||
case ISD::FSUB:
|
||||
case ISD::FMUL:
|
||||
case ISD::FDIV:
|
||||
case ISD::FREM:
|
||||
if (UnsafeFPMath && Opcode == ISD::FADD) {
|
||||
// 0+x --> x
|
||||
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1))
|
||||
if (CFP->getValueAPF().isZero())
|
||||
return N2;
|
||||
// x+0 --> x
|
||||
if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N2))
|
||||
if (CFP->getValueAPF().isZero())
|
||||
return N1;
|
||||
}
|
||||
assert(N1.getValueType() == N2.getValueType() &&
|
||||
N1.getValueType() == VT && "Binary operator types must match!");
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue