<div dir="ltr">+Duncan, who's been mucking about with llvm's ilist issues recently</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Nov 4, 2015 at 2:37 PM, Sanjoy Das via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">sanjoy created this revision.<br>
sanjoy added reviewers: chandlerc, reames.<br>
sanjoy added a subscriber: llvm-commits.<br>
<br>
This change fixes an iterator wraparound bug in<br>
`determinePointerReadAttrs`.<br>
<br>
Ideally, ++'ing off the `end()` of an iplist should result in a failed<br>
assert, but currently iplist seems to silently wrap to the head of the<br>
list on `end()++`.  This is why the bad behavior is difficult to<br>
demonstrate.<br>
<br>
<a href="http://reviews.llvm.org/D14350" rel="noreferrer" target="_blank">http://reviews.llvm.org/D14350</a><br>
<br>
Files:<br>
  lib/Transforms/IPO/FunctionAttrs.cpp<br>
  test/Transforms/FunctionAttrs/out-of-bounds-iterator-bug.ll<br>
<br>
Index: test/Transforms/FunctionAttrs/out-of-bounds-iterator-bug.ll<br>
===================================================================<br>
--- /dev/null<br>
+++ test/Transforms/FunctionAttrs/out-of-bounds-iterator-bug.ll<br>
@@ -0,0 +1,30 @@<br>
+; RUN: opt -functionattrs -S < %s | FileCheck %s<br>
+<br>
+; This checks for an iterator wraparound bug in FunctionAttrs.  The previous<br>
+; "incorrect" behavior was inferring readonly for the %x argument in @caller.<br>
+; Inferring readonly for %x *is* actually correct, since @va_func is marked<br>
+; readonly, but FunctionAttrs was inferring readonly for the wrong reasons (and<br>
+; we _need_ the readonly on @va_func to trigger the problematic code path).  It<br>
+; is possible that in the future FunctionAttrs becomes smart enough to infer<br>
+; readonly for %x for the right reasons, and at that point this test will have<br>
+; to be marked invalid.<br>
+<br>
+declare void @llvm.va_start(i8*)<br>
+declare void @llvm.va_end(i8*)<br>
+<br>
+define void @va_func(i32* readonly %b, ...) readonly nounwind {<br>
+; CHECK-LABEL: define void @va_func(i32* nocapture readonly %b, ...)<br>
+ entry:<br>
+  %valist = alloca i8<br>
+  call void @llvm.va_start(i8* %valist)<br>
+  call void @llvm.va_end(i8* %valist)<br>
+  %x = call i32 @caller(i32* %b)<br>
+  ret void<br>
+}<br>
+<br>
+define i32 @caller(i32* %x) {<br>
+; CHECK-LABEL: define i32 @caller(i32* nocapture %x)<br>
+ entry:<br>
+  call void(i32*,...) @va_func(i32* null, i32 0, i32 0, i32 0, i32* %x)<br>
+  ret i32 42<br>
+}<br>
Index: lib/Transforms/IPO/FunctionAttrs.cpp<br>
===================================================================<br>
--- lib/Transforms/IPO/FunctionAttrs.cpp<br>
+++ lib/Transforms/IPO/FunctionAttrs.cpp<br>
@@ -442,9 +442,11 @@<br>
<br>
       Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();<br>
       CallSite::arg_iterator B = CS.arg_begin(), E = CS.arg_end();<br>
-      for (CallSite::arg_iterator A = B; A != E; ++A, ++AI) {<br>
+      bool InVarArgSection = false;<br>
+      for (CallSite::arg_iterator A = B; A != E; ++A) {<br>
+        InVarArgSection |= (AI == AE);<br>
         if (A->get() == V) {<br>
-          if (AI == AE) {<br>
+          if (InVarArgSection) {<br>
             assert(F->isVarArg() &&<br>
                    "More params than args in non-varargs call.");<br>
             return Attribute::None;<br>
@@ -457,6 +459,8 @@<br>
           if (!CS.doesNotAccessMemory(A - B))<br>
             IsRead = true;<br>
         }<br>
+        if (!InVarArgSection)<br>
+          ++AI;<br>
       }<br>
       AddUsersToWorklistIfCapturing();<br>
       break;<br>
<br>
<br>
<br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br></div>