<div dir="ltr"><div><div><div><div class="gmail_extra"><div class="gmail_quote">On 15 May 2013 11:34, Shuxin Yang <span dir="ltr"><<a href="mailto:shuxin.llvm@gmail.com" target="_blank">shuxin.llvm@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im">
On 5/15/13 11:23 AM, Mark Seaborn wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Fix miscompile due to StackColoring incorrectly merging stack slots<br>
<br>
IR optimisation passes can result in a basic block that contains:<br>
<br>
  llvm.lifetime.start(%buf)<br>
  ...<br>
  llvm.lifetime.end(%buf)<br>
  ...<br>
  llvm.lifetime.start(%buf)<br>
<br>
</blockquote></div>
Just curious, why "buf" was dead, and is resurrected later on?<br>
</blockquote></div><br></div>Do you mean, which IR optimisation passes can cause this to happen?  I did not track down exactly which IR transformations produced this.  I'd expect that any pass which duplicates code could do this, e.g. loop unrolling.  I suspect there is an IR pass which merges alloca stack slots, too, because in the case where I encountered this bug I was seeing separate allocas having been merged.<br>
<br></div>An example of this happening from loop unrolling is:<br><br>void use_buffer(char *buf);<br><br>static inline void foo(void) {<br>  char buf[1000];<br>  use_buffer(buf);<br>}<br><br>void test() {<br>  int i;<br>  for (i = 0; i < 2; i++) {<br>
    foo();<br>  }<br>}<br><br></div>This produces:<br><br>$ clang lifetime_unroll.c -S -o - -emit-llvm -O2<br>define void @test() nounwind uwtable {<br>  %buf.i = alloca [1000 x i8], align 16<br>  %1 = getelementptr inbounds [1000 x i8]* %buf.i, i64 0, i64 0<br>
  call void @llvm.lifetime.start(i64 -1, i8* %1) nounwind<br>  call void @use_buffer(i8* %1) nounwind<br>  call void @llvm.lifetime.end(i64 -1, i8* %1) nounwind<br>  call void @llvm.lifetime.start(i64 -1, i8* %1) nounwind<br>
  call void @use_buffer(i8* %1) nounwind<br>  call void @llvm.lifetime.end(i64 -1, i8* %1) nounwind<br>  ret void<br>}<br><br></div>Cheers,<br>Mark<br><br></div>