From 77b81fe487de709d41dfcc97bbb2941ae1bb80af Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 4 Jun 2009 17:12:12 +0000 Subject: [PATCH] Don't do the X * 0.0 -> 0.0 transformation in instcombine, because instcombine doesn't know when it's safe. To partially compensate for this, introduce new code to do this transformation in dagcombine, which can use UnsafeFPMath. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72872 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 3 +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 ++++++++----- lib/Transforms/Scalar/InstructionCombining.cpp | 10 +++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4c1710dd81f..5d1b2a3ea28 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4019,6 +4019,9 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { // fold (fmul A, 0) -> 0 if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) return N1; + // fold (fmul A, 0) -> 0, vector edition. + if (UnsafeFPMath && ISD::isBuildVectorAllZeros(N1.getNode())) + return N1; // fold (fmul X, 2.0) -> (fadd X, X) if (N1CFP && N1CFP->isExactlyValue(+2.0)) return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0, N0); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 2c645e42083..c2c884e8d17 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2807,16 +2807,19 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, case ISD::ADDC: case ISD::ADDE: case ISD::SUB: - case ISD::FADD: - case ISD::FSUB: - case ISD::FMUL: - case ISD::FDIV: - case ISD::FREM: case ISD::UDIV: case ISD::SDIV: case ISD::UREM: case ISD::SREM: return N2; // fold op(arg1, undef) -> undef + case ISD::FADD: + case ISD::FSUB: + case ISD::FMUL: + case ISD::FDIV: + case ISD::FREM: + if (UnsafeFPMath) + return N2; + break; case ISD::MUL: case ISD::AND: case ISD::SRL: diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index e6f854f1a56..8bb16f3de19 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -2585,7 +2585,9 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { bool Changed = SimplifyCommutative(I); Value *Op0 = I.getOperand(0); - if (isa(I.getOperand(1))) // undef * X -> 0 + // TODO: If Op1 is undef and Op0 is finite, return zero. + if (!I.getType()->isFPOrFPVector() && + isa(I.getOperand(1))) // undef * X -> 0 return ReplaceInstUsesWith(I, Constant::getNullValue(I.getType())); // Simplify mul instructions with a constant RHS... @@ -2612,16 +2614,14 @@ Instruction *InstCombiner::visitMul(BinaryOperator &I) { ConstantInt::get(Op0->getType(), Val.logBase2())); } } else if (ConstantFP *Op1F = dyn_cast(Op1)) { - if (Op1F->isNullValue()) - return ReplaceInstUsesWith(I, Op1); + // TODO: If Op1 is zero and Op0 is finite, return zero. // "In IEEE floating point, x*1 is not equivalent to x for nans. However, // ANSI says we can drop signals, so we can do this anyway." (from GCC) if (Op1F->isExactlyValue(1.0)) return ReplaceInstUsesWith(I, Op0); // Eliminate 'mul double %X, 1.0' } else if (isa(Op1->getType())) { - if (isa(Op1)) - return ReplaceInstUsesWith(I, Op1); + // TODO: If Op1 is all zeros and Op0 is all finite, return all zeros. if (ConstantVector *Op1V = dyn_cast(Op1)) { if (Op1V->isAllOnesValue()) // X * -1 == 0 - X