diff options
author | Dan Gohman <gohman@apple.com> | 2009-05-24 18:02:35 +0000 |
---|---|---|
committer | Dan Gohman <gohman@apple.com> | 2009-05-24 18:02:35 +0000 |
commit | 4766abff89d597b0a5cc0089c04a1ed5e1d20f44 (patch) | |
tree | 6e11e2a558a5c974977a2e73b05ac7748dc54f54 /lib | |
parent | 965475183bac7678e2b6c9d39f64fb7e30580757 (diff) | |
download | external_llvm-4766abff89d597b0a5cc0089c04a1ed5e1d20f44.zip external_llvm-4766abff89d597b0a5cc0089c04a1ed5e1d20f44.tar.gz external_llvm-4766abff89d597b0a5cc0089c04a1ed5e1d20f44.tar.bz2 |
When the low bits of one operand of an add are zero, that number
of low bits of the other operand are preserved in the output.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72365 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/ValueTracking.cpp | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 3c21e20..29ff8aa 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -343,22 +343,43 @@ void llvm::ComputeMaskedBits(Value *V, const APInt &Mask, } // fall through case Instruction::Add: { - // Output known-0 bits are known if clear or set in both the low clear bits - // common to both LHS & RHS. For example, 8+(X<<3) is known to have the - // low 3 bits clear. - APInt Mask2 = APInt::getLowBitsSet(BitWidth, Mask.countTrailingOnes()); - ComputeMaskedBits(I->getOperand(0), Mask2, KnownZero2, KnownOne2, TD, + // If one of the operands has trailing zeros, than the bits that the + // other operand has in those bit positions will be preserved in the + // result. For an add, this works with either operand. For a subtract, + // this only works if the known zeros are in the right operand. + APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); + APInt Mask2 = APInt::getLowBitsSet(BitWidth, + BitWidth - Mask.countLeadingZeros()); + ComputeMaskedBits(I->getOperand(0), Mask2, LHSKnownZero, LHSKnownOne, TD, Depth+1); - assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); - unsigned KnownZeroOut = KnownZero2.countTrailingOnes(); + assert((LHSKnownZero & LHSKnownOne) == 0 && + "Bits known to be one AND zero?"); + unsigned LHSKnownZeroOut = LHSKnownZero.countTrailingOnes(); ComputeMaskedBits(I->getOperand(1), Mask2, KnownZero2, KnownOne2, TD, Depth+1); assert((KnownZero2 & KnownOne2) == 0 && "Bits known to be one AND zero?"); - KnownZeroOut = std::min(KnownZeroOut, - KnownZero2.countTrailingOnes()); + unsigned RHSKnownZeroOut = KnownZero2.countTrailingOnes(); - KnownZero |= APInt::getLowBitsSet(BitWidth, KnownZeroOut); + // Determine which operand has more trailing zeros, and use that + // many bits from the other operand. + if (LHSKnownZeroOut > RHSKnownZeroOut) { + if (getOpcode(I) == Instruction::Add) { + APInt Mask = APInt::getLowBitsSet(BitWidth, LHSKnownZeroOut); + KnownZero |= KnownZero2 & Mask; + KnownOne |= KnownOne2 & Mask; + } else { + // If the known zeros are in the left operand for a subtract, + // fall back to the minimum known zeros in both operands. + KnownZero |= APInt::getLowBitsSet(BitWidth, + std::min(LHSKnownZeroOut, + RHSKnownZeroOut)); + } + } else if (RHSKnownZeroOut >= LHSKnownZeroOut) { + APInt Mask = APInt::getLowBitsSet(BitWidth, RHSKnownZeroOut); + KnownZero |= LHSKnownZero & Mask; + KnownOne |= LHSKnownOne & Mask; + } return; } case Instruction::SRem: |