diff options
author | David Majnemer <david.majnemer@gmail.com> | 2014-08-27 18:03:46 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2014-08-27 18:03:46 +0000 |
commit | d6d1671c1eb241939b6d92687420a3f7ed56839f (patch) | |
tree | 1691a7a66bc0b9372d3bb4ccb4919a3a9ab45760 /llvm/lib/Analysis/InstructionSimplify.cpp | |
parent | 74a46c24f3be4a8a758d9c9d3d838b8851cb010d (diff) | |
download | llvm-d6d1671c1eb241939b6d92687420a3f7ed56839f.zip llvm-d6d1671c1eb241939b6d92687420a3f7ed56839f.tar.gz llvm-d6d1671c1eb241939b6d92687420a3f7ed56839f.tar.bz2 |
InstSimplify: Compute comparison ranges for left shift instructions
'shl nuw CI, x' produces [CI, CI << CLZ(CI)]
'shl nsw CI, x' produces [CI << CLO(CI)-1, CI] if CI is negative
'shl nsw CI, x' produces [CI, CI << CLZ(CI)-1] if CI is non-negative
llvm-svn: 216570
Diffstat (limited to 'llvm/lib/Analysis/InstructionSimplify.cpp')
-rw-r--r-- | llvm/lib/Analysis/InstructionSimplify.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 666e7f2..118579d 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -1993,6 +1993,22 @@ static Value *SimplifyICmpInst(unsigned Predicate, Value *LHS, Value *RHS, Upper = Upper + 1; assert(Upper != Lower && "Upper part of range has wrapped!"); } + } else if (match(LHS, m_NUWShl(m_ConstantInt(CI2), m_Value()))) { + // 'shl nuw CI2, x' produces [CI2, CI2 << CLZ(CI2)] + Lower = CI2->getValue(); + Upper = Lower.shl(Lower.countLeadingZeros()) + 1; + } else if (match(LHS, m_NSWShl(m_ConstantInt(CI2), m_Value()))) { + if (CI2->isNegative()) { + // 'shl nsw CI2, x' produces [CI2 << CLO(CI2)-1, CI2] + unsigned ShiftAmount = CI2->getValue().countLeadingOnes() - 1; + Lower = CI2->getValue().shl(ShiftAmount); + Upper = CI2->getValue() + 1; + } else { + // 'shl nsw CI2, x' produces [CI2, CI2 << CLZ(CI2)-1] + unsigned ShiftAmount = CI2->getValue().countLeadingZeros() - 1; + Lower = CI2->getValue(); + Upper = CI2->getValue().shl(ShiftAmount) + 1; + } } else if (match(LHS, m_LShr(m_Value(), m_ConstantInt(CI2)))) { // 'lshr x, CI2' produces [0, UINT_MAX >> CI2]. APInt NegOne = APInt::getAllOnesValue(Width); |