<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">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>Isn't this [0, CI2]? For a given CI2, I can pick an x such that CI2 >> x = 0, right?</div><div><br></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>
+      Upper = CI2->getValue() + 1;<br></blockquote><div><br></div><div>So if I'm thinking correctly, this should be a simple:</div><div>  Upper = CI2->getValue() + 1;</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><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">


     } 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>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">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>