mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-03-20 11:32:33 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46499 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cca1867ab7
commit
2454a2e0c3
@ -1943,6 +1943,48 @@ Instruction *InstCombiner::FoldOpIntoPhi(Instruction &I) {
|
||||
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 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) {
|
||||
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;
|
||||
}
|
||||
|
15
test/Transforms/InstCombine/zero-point-zero-add.ll
Normal file
15
test/Transforms/InstCombine/zero-point-zero-add.ll
Normal file
@ -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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user