[PATCH] Fix miscompile due to StackColoring incorrectly merging stack slots

Mark Seaborn mseaborn at chromium.org
Wed May 15 11:54:17 PDT 2013


On 15 May 2013 11:34, Shuxin Yang <shuxin.llvm at gmail.com> wrote:

> On 5/15/13 11:23 AM, Mark Seaborn wrote:
>
>> Fix miscompile due to StackColoring incorrectly merging stack slots
>>
>> IR optimisation passes can result in a basic block that contains:
>>
>>   llvm.lifetime.start(%buf)
>>   ...
>>   llvm.lifetime.end(%buf)
>>   ...
>>   llvm.lifetime.start(%buf)
>>
>>  Just curious, why "buf" was dead, and is resurrected later on?
>

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.

An example of this happening from loop unrolling is:

void use_buffer(char *buf);

static inline void foo(void) {
  char buf[1000];
  use_buffer(buf);
}

void test() {
  int i;
  for (i = 0; i < 2; i++) {
    foo();
  }
}

This produces:

$ clang lifetime_unroll.c -S -o - -emit-llvm -O2
define void @test() nounwind uwtable {
  %buf.i = alloca [1000 x i8], align 16
  %1 = getelementptr inbounds [1000 x i8]* %buf.i, i64 0, i64 0
  call void @llvm.lifetime.start(i64 -1, i8* %1) nounwind
  call void @use_buffer(i8* %1) nounwind
  call void @llvm.lifetime.end(i64 -1, i8* %1) nounwind
  call void @llvm.lifetime.start(i64 -1, i8* %1) nounwind
  call void @use_buffer(i8* %1) nounwind
  call void @llvm.lifetime.end(i64 -1, i8* %1) nounwind
  ret void
}

Cheers,
Mark
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130515/6e14c1db/attachment.html>


More information about the llvm-commits mailing list