Fold x-0 to x in unsafe-fp-math mode. This comes up in the

testcase from PR3376, and in fact is sufficient to completely
avoid the problem in that testcase.

There's an underlying problem though; TLI.isOperationLegal
considers Custom to be Legal, which might be ok in some
cases, but that's what DAGCombiner is using in many places
to test if something is legal when LegalOperations is true.
When DAGCombiner is running after legalize, this isn't
sufficient. I'll address this in a separate commit.

llvm-svn: 62860
This commit is contained in:
Dan Gohman 2009-01-23 19:10:37 +00:00
parent 5da47ad57b
commit 1275e28ded
2 changed files with 19 additions and 9 deletions

View File

@ -3853,6 +3853,9 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) {
// fold (fsub c1, c2) -> c1-c2
if (N0CFP && N1CFP && VT != MVT::ppcf128)
return DAG.getNode(ISD::FSUB, VT, N0, N1);
// fold (A-0) -> A
if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero())
return N0;
// fold (0-B) -> -B
if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) {
if (isNegatibleForFree(N1, LegalOperations))

View File

@ -2402,15 +2402,22 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
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;
if (UnsafeFPMath) {
if (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;
} else if (Opcode == ISD::FSUB) {
// 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!");