Author: lattner Date: Tue Jan 29 00:52:45 2008 New Revision: 46499 URL: http://llvm.org/viewvc/llvm-project?rev=46499&view=rev Log: eliminate additions of 0.0 when they are obviously dead. This has to be careful to avoid turning -0.0 + 0.0 -> -0.0 which is incorrect.
Added: llvm/trunk/test/Transforms/InstCombine/zero-point-zero-add.ll Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=46499&r1=46498&r2=46499&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Jan 29 00:52:45 2008 @@ -1943,6 +1943,48 @@ return ReplaceInstUsesWith(I, NewPN); } + +/// CannotBeNegativeZero - Return true if we can prove that the specified FP +/// value is never equal to -0.0. +/// +/// Note that this function will need to be revisited when we support nondefault +/// rounding modes! +/// +static bool CannotBeNegativeZero(const Value *V) { + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(V)) + return !CFP->getValueAPF().isNegZero(); + + // (add x, 0.0) is guaranteed to return +0.0, not -0.0. + if (const Instruction *I = dyn_cast<Instruction>(V)) { + if (I->getOpcode() == Instruction::Add && + isa<ConstantFP>(I->getOperand(1)) && + cast<ConstantFP>(I->getOperand(1))->isNullValue()) + return true; + + if (const IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) + if (II->getIntrinsicID() == Intrinsic::sqrt) + return CannotBeNegativeZero(II->getOperand(1)); + + if (const CallInst *CI = dyn_cast<CallInst>(I)) + if (const Function *F = CI->getCalledFunction()) { + if (F->isDeclaration()) { + switch (F->getNameLen()) { + case 3: // abs(x) != -0.0 + if (!strcmp(F->getNameStart(), "abs")) return true; + break; + case 4: // abs[lf](x) != -0.0 + if (!strcmp(F->getNameStart(), "absf")) return true; + if (!strcmp(F->getNameStart(), "absl")) return true; + break; + } + } + } + } + + return false; +} + + Instruction *InstCombiner::visitAdd(BinaryOperator &I) { bool Changed = SimplifyCommutative(I); Value *LHS = I.getOperand(0), *RHS = I.getOperand(1); @@ -2160,6 +2202,11 @@ return new SelectInst(SI->getCondition(), A, N); } } + + // Check for X+0.0. Simplify it to X if we know X is not -0.0. + if (ConstantFP *CFP = dyn_cast<ConstantFP>(RHS)) + if (CFP->getValueAPF().isPosZero() && CannotBeNegativeZero(LHS)) + return ReplaceInstUsesWith(I, LHS); return Changed ? &I : 0; } Added: llvm/trunk/test/Transforms/InstCombine/zero-point-zero-add.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/zero-point-zero-add.ll?rev=46499&view=auto ============================================================================== --- llvm/trunk/test/Transforms/InstCombine/zero-point-zero-add.ll (added) +++ llvm/trunk/test/Transforms/InstCombine/zero-point-zero-add.ll Tue Jan 29 00:52:45 2008 @@ -0,0 +1,15 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep 0.0 | count 1 + +declare double @abs(double) + +define double @test(double %X) { + %Y = add double %X, 0.0 ;; Should be a single add x, 0.0 + %Z = add double %Y, 0.0 + ret double %Z +} + +define double @test1(double %X) { + %Y = call double @abs(double %X) + %Z = add double %Y, 0.0 + ret double %Z +} _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits