<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 16 May 2014 01:42, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">On Thu, May 15, 2014 at 8:46 PM, Nick Lewycky <span dir="ltr"><<a href="mailto:nlewycky@google.com" target="_blank">nlewycky@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div>On 14 May 2014 21:47, David Majnemer <span dir="ltr"><<a href="mailto:david.majnemer@gmail.com" target="_blank">david.majnemer@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi nicholas,<br>
<br>
Analyze the range of values produced by ashr/lshr cst, %V when it is<br>
being used in an icmp.<br>
<br>
<a href="http://reviews.llvm.org/D3774" target="_blank">http://reviews.llvm.org/D3774</a><br>
<br>
Files:<br>
lib/Analysis/InstructionSimplify.cpp<br>
test/Transforms/InstSimplify/compare.ll<br>
<br>
Index: lib/Analysis/InstructionSimplify.cpp<br>
===================================================================<br>
--- lib/Analysis/InstructionSimplify.cpp<br>
+++ lib/Analysis/InstructionSimplify.cpp<br>
@@ -2001,7 +2001,7 @@<br>
<br>
// Many binary operators with constant RHS have easy to compute constant<br>
// range. Use them to check whether the comparison is a tautology.<br>
- uint32_t Width = CI->getBitWidth();<br>
+ unsigned Width = CI->getBitWidth();<br>
APInt Lower = APInt(Width, 0);<br>
APInt Upper = APInt(Width, 0);<br>
ConstantInt *CI2;<br>
@@ -2034,14 +2034,34 @@<br>
APInt NegOne = APInt::getAllOnesValue(Width);<br>
if (CI2->getValue().ult(Width))<br>
Upper = NegOne.lshr(CI2->getValue()) + 1;<br>
+ } else if (match(LHS, m_LShr(m_ConstantInt(CI2), m_Value()))) {<br>
+ // 'lshr CI2, x' produces [CI2 >> (Width-1), CI2].<br></blockquote><div><br></div></div></div><div>Isn't this [0, CI2]? For a given CI2, I can pick an x such that CI2 >> x = 0, right?</div>
</div></div></div></blockquote><div><br></div></div></div><div>Zero is not always possible. If the MSB is set, a single right shift will not be able to shift it out.</div></div></div></div></blockquote><div><br></div><div>
Aha! That's what I was missing.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ unsigned ShiftAmount = Width - 1;<br>
+ if (!CI2->isZero() && cast<BinaryOperator>(LHS)->isExact())<br>
+ ShiftAmount = CI2->getValue().countTrailingZeros();<br>
+ Lower = CI2->getValue().lshr(ShiftAmount);<br></blockquote></div></div></div></div></blockquote></div></div></div></div></div></blockquote><div><br></div><div>Just to check my understanding, Lower = 0 is CI2 is positive, 1 if CI2 is negative. Might be worth a comment.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ Upper = CI2->getValue() + 1;<br></blockquote><div><br></div></div><div>So if I'm thinking correctly, this should be a simple:</div><div><div> Upper = CI2->getValue() + 1;</div></div><div>except for the handling of 'exact' where 'lshr exact CI2, x' produces [CI2>>ctz(CI2), CI2]?</div>
<div><br></div><div>I feel like I'm missing something, and the same thing happens in the ashr case too.</div></div></div></div></blockquote></div></div></div></div></div></blockquote><div><br></div><div>LGTM</div><div>
<br></div><div>Nick</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="h5">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div>
} else if (match(LHS, m_AShr(m_Value(), m_ConstantInt(CI2)))) {<br>
// 'ashr x, CI2' produces [INT_MIN >> CI2, INT_MAX >> CI2].<br>
APInt IntMin = APInt::getSignedMinValue(Width);<br>
APInt IntMax = APInt::getSignedMaxValue(Width);<br>
if (CI2->getValue().ult(Width)) {<br>
Lower = IntMin.ashr(CI2->getValue());<br>
Upper = IntMax.ashr(CI2->getValue()) + 1;<br>
}<br>
+ } else if (match(LHS, m_AShr(m_ConstantInt(CI2), m_Value()))) {<br>
+ unsigned ShiftAmount = Width - 1;<br>
+ if (!CI2->isZero() && cast<BinaryOperator>(LHS)->isExact())<br>
+ ShiftAmount = CI2->getValue().countTrailingZeros();<br>
+ if (CI2->isNegative()) {<br>
+ // 'ashr CI2, x' produces [CI2, CI2 >> (Width-1)]<br>
+ Lower = CI2->getValue();<br>
+ Upper = CI2->getValue().ashr(ShiftAmount) + 1;<br>
+ } else {<br>
+ // 'ashr CI2, x' produces [CI2 >> (Width-1), CI2]<br>
+ Lower = CI2->getValue().ashr(ShiftAmount);<br>
+ Upper = CI2->getValue() + 1;<br>
+ }<br>
} else if (match(LHS, m_Or(m_Value(), m_ConstantInt(CI2)))) {<br>
// 'or x, CI2' produces [CI2, UINT_MAX].<br>
Lower = CI2->getValue();<br>
Index: test/Transforms/InstSimplify/compare.ll<br>
===================================================================<br>
--- test/Transforms/InstSimplify/compare.ll<br>
+++ test/Transforms/InstSimplify/compare.ll<br>
@@ -817,3 +817,43 @@<br>
; CHECK-LABEL: @compare_always_false_ne<br>
; CHECK-NEXT: ret i1 true<br>
}<br>
+<br>
+define i1 @lshr_ugt_false(i32 %a) {<br>
+ %shr = lshr i32 1, %a<br>
+ %cmp = icmp ugt i32 %shr, 1<br>
+ ret i1 %cmp<br>
+; CHECK-LABEL: @lshr_ugt_false<br>
+; CHECK-NEXT: ret i1 false<br>
+}<br>
+<br>
+define i1 @exact_lshr_ugt_false(i32 %a) {<br>
+ %shr = lshr exact i32 30, %a<br>
+ %cmp = icmp ult i32 %shr, 15<br>
+ ret i1 %cmp<br>
+; CHECK-LABEL: @exact_lshr_ugt_false<br>
+; CHECK-NEXT: ret i1 false<br>
+}<br>
+<br>
+define i1 @lshr_sgt_false(i32 %a) {<br>
+ %shr = lshr i32 1, %a<br>
+ %cmp = icmp sgt i32 %shr, 1<br>
+ ret i1 %cmp<br>
+; CHECK-LABEL: @lshr_sgt_false<br>
+; CHECK-NEXT: ret i1 false<br>
+}<br>
+<br>
+define i1 @ashr_sgt_false(i32 %a) {<br>
+ %shr = ashr i32 -30, %a<br>
+ %cmp = icmp sgt i32 %shr, -1<br>
+ ret i1 %cmp<br>
+; CHECK-LABEL: @ashr_sgt_false<br>
+; CHECK-NEXT: ret i1 false<br>
+}<br>
+<br>
+define i1 @exact_ashr_sgt_false(i32 %a) {<br>
+ %shr = ashr exact i32 -30, %a<br>
+ %cmp = icmp sgt i32 %shr, -15<br>
+ ret i1 %cmp<br>
+; CHECK-LABEL: @exact_ashr_sgt_false<br>
+; CHECK-NEXT: ret i1 false<br>
+}<br>
<br></div></div>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div></div></div>