<div dir="ltr">This change seems to be causing a miscompile which makes sanitizer bots red: <div><a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux">http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux</a><br></div><div><br></div>I've confirmed by checking out r219834 (this revision) and r219833 (previous one) and running <div>ninja Asan-x86_64-inline-Test && ./projects/compiler-rt/lib/asan/tests/Asan-x86_64-inline-Test  --gtest_filter=AddressSanitizerInterface.PushAndPopWithPoisoningTest<br></div><div><br></div><div>Please fix or revert ASAP. </div><div><br></div><div>--kcc </div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 15, 2014 at 12:25 PM, Sanjoy Das <span dir="ltr"><<a href="mailto:sanjoy@playingwithpointers.com" target="_blank">sanjoy@playingwithpointers.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: sanjoy<br>
Date: Wed Oct 15 14:25:28 2014<br>
New Revision: 219834<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=219834&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=219834&view=rev</a><br>
Log:<br>
Teach ScalarEvolution to sharpen range information.<br>
<br>
If x is known to have the range [a, b) in a loop predicated by (icmp<br>
ne x, a), its range can be sharpened to [a + 1, b).  Get<br>
ScalarEvolution and hence IndVars to exploit this fact.<br>
<br>
This change triggers an optimization to widen-loop-comp.ll, so it had<br>
to be edited to get it to pass.<br>
<br>
phabricator: <a href="http://reviews.llvm.org/D5639" target="_blank">http://reviews.llvm.org/D5639</a><br>
<br>
<br>
Added:<br>
    llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll<br>
Modified:<br>
    llvm/trunk/lib/Analysis/ScalarEvolution.cpp<br>
    llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll<br>
<br>
Modified: llvm/trunk/lib/Analysis/ScalarEvolution.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=219834&r1=219833&r2=219834&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ScalarEvolution.cpp?rev=219834&r1=219833&r2=219834&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Analysis/ScalarEvolution.cpp (original)<br>
+++ llvm/trunk/lib/Analysis/ScalarEvolution.cpp Wed Oct 15 14:25:28 2014<br>
@@ -6782,6 +6782,44 @@ bool ScalarEvolution::isImpliedCond(ICmp<br>
                                    RHS, LHS, FoundLHS, FoundRHS);<br>
   }<br>
<br>
+  if (FoundPred == ICmpInst::ICMP_NE) {<br>
+    // If we are predicated on something with range [a, b) known not<br>
+    // equal to a, the range can be sharpened to [a + 1, b).  Use this<br>
+    // fact.<br>
+    auto CheckRange = [this, Pred, LHS, RHS](const SCEV *C, const SCEV *V) {<br>
+      if (!isa<SCEVConstant>(C)) return false;<br>
+<br>
+      ConstantInt *CI = cast<SCEVConstant>(C)->getValue();<br>
+      APInt Min = ICmpInst::isSigned(Pred) ?<br>
+        getSignedRange(V).getSignedMin() : getUnsignedRange(V).getUnsignedMin();<br>
+<br>
+      if (Min!= CI->getValue()) return false; // nothing to sharpen<br>
+      Min++;<br>
+<br>
+      // We know V >= Min, in the same signedness as in Pred.  We can<br>
+      // use this to simplify slt and ult.  If the range had a single<br>
+      // value, Min, we now know that FoundValue can never be true;<br>
+      // and any answer is a correct answer.<br>
+<br>
+      switch (Pred) {<br>
+        case ICmpInst::ICMP_SGT:<br>
+        case ICmpInst::ICMP_UGT:<br>
+          return isImpliedCondOperands(Pred, LHS, RHS, V, getConstant(Min));<br>
+<br>
+        default:<br>
+          llvm_unreachable("don't call with predicates other than ICMP_SGT "<br>
+                           "and ICMP_UGT");<br>
+      }<br>
+    };<br>
+<br>
+    if ((Pred == ICmpInst::ICMP_SGT) || (Pred == ICmpInst::ICMP_UGT)) {<br>
+      // Inequality is reflexive -- check both the combinations.<br>
+      if (CheckRange(FoundLHS, FoundRHS) || CheckRange(FoundRHS, FoundLHS)) {<br>
+        return true;<br>
+      }<br>
+    }<br>
+  }<br>
+<br>
   // Check whether the actual condition is beyond sufficient.<br>
   if (FoundPred == ICmpInst::ICMP_EQ)<br>
     if (ICmpInst::isTrueWhenEqual(Pred))<br>
<br>
Added: llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll?rev=219834&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll?rev=219834&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll (added)<br>
+++ llvm/trunk/test/Transforms/IndVarSimplify/sharpen-range-metadata.ll Wed Oct 15 14:25:28 2014<br>
@@ -0,0 +1,39 @@<br>
+;; RUN: opt -S < %s -indvars | FileCheck %s<br>
+<br>
+;; Check if llvm can narrow !range metadata based on loop entry<br>
+;; predicates.<br>
+<br>
+declare void @abort()<br>
+<br>
+define i1 @bounded_below(i32* nocapture readonly %buffer) {<br>
+entry:<br>
+  %length = load i32* %buffer, !range !0<br>
+  %entry.pred = icmp eq i32 %length, 0<br>
+  br i1 %entry.pred, label %abort, label %loop.preheader<br>
+<br>
+loop.preheader:<br>
+  br label %loop<br>
+<br>
+loop:<br>
+  %idx = phi i32 [ %idx.inc, %loop.next ], [ 0, %loop.preheader ]<br>
+  %oob.pred = icmp slt i32 %idx, %length<br>
+  br i1 %oob.pred, label %loop.next, label %oob<br>
+; CHECK: br i1 true, label %loop.next, label %oob<br>
+<br>
+loop.next:<br>
+  %idx.inc = add i32 %idx, 1<br>
+  %exit.pred = icmp slt i32 %idx.inc, %length<br>
+  br i1 %exit.pred, label %loop, label %abort.loopexit<br>
+<br>
+abort.loopexit:<br>
+  br label %abort<br>
+<br>
+abort:<br>
+  ret i1 false<br>
+<br>
+oob:<br>
+  tail call void @abort()<br>
+  ret i1 false<br>
+}<br>
+<br>
+!0 = metadata !{i32 0, i32 100}<br>
<br>
Modified: llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll?rev=219834&r1=219833&r2=219834&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll?rev=219834&r1=219833&r2=219834&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll (original)<br>
+++ llvm/trunk/test/Transforms/IndVarSimplify/widen-loop-comp.ll Wed Oct 15 14:25:28 2014<br>
@@ -67,8 +67,7 @@ for.end:<br>
 define void @test2([8 x i8]* %a, i8* %b, i8 %limit) {<br>
 entry:<br>
   %conv = zext i8 %limit to i32<br>
-  %cmp23 = icmp eq i8 %limit, 0<br>
-  br i1 %cmp23, label %for.cond1.preheader, label %<a href="http://for.cond1.preheader.us" target="_blank">for.cond1.preheader.us</a><br>
+  br i1 undef, label %for.cond1.preheader, label %<a href="http://for.cond1.preheader.us" target="_blank">for.cond1.preheader.us</a><br>
<br>
 <a href="http://for.cond1.preheader.us" target="_blank">for.cond1.preheader.us</a>:<br>
   %<a href="http://storemerge5.us" target="_blank">storemerge5.us</a> = phi i32 [ 0, %entry ], [ %<a href="http://inc14.us" target="_blank">inc14.us</a>, %<a href="http://for.inc13.us" target="_blank">for.inc13.us</a> ]<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>
</blockquote></div><br></div>