diff options
| author | Dan Gohman <gohman@apple.com> | 2009-06-04 17:12:12 +0000 | 
|---|---|---|
| committer | Dan Gohman <gohman@apple.com> | 2009-06-04 17:12:12 +0000 | 
| commit | 7b6b5dd9541a9f87947d1835e13dfb4086614f2e (patch) | |
| tree | 8992e019932e78848969b9a1751873ba92d13b20 /llvm/lib | |
| parent | 7dae11446fdcb938217cb22154959d1e0daec73a (diff) | |
| download | bcm5719-llvm-7b6b5dd9541a9f87947d1835e13dfb4086614f2e.tar.gz bcm5719-llvm-7b6b5dd9541a9f87947d1835e13dfb4086614f2e.zip  | |
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.
llvm-svn: 72872
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 3 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 10 | 
3 files changed, 16 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4c1710dd81f..5d1b2a3ea28 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/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/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 2c645e42083..c2c884e8d17 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/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/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index e6f854f1a56..8bb16f3de19 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/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<UndefValue>(I.getOperand(1)))              // undef * X -> 0 +  // TODO: If Op1 is undef and Op0 is finite, return zero. +  if (!I.getType()->isFPOrFPVector() && +      isa<UndefValue>(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<ConstantFP>(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<VectorType>(Op1->getType())) { -      if (isa<ConstantAggregateZero>(Op1)) -        return ReplaceInstUsesWith(I, Op1); +      // TODO: If Op1 is all zeros and Op0 is all finite, return all zeros.        if (ConstantVector *Op1V = dyn_cast<ConstantVector>(Op1)) {          if (Op1V->isAllOnesValue())              // X * -1 == 0 - X  | 

