<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - StackColoring can wrongly merge stack slots due to incorrect liveness calculation"
   href="http://llvm.org/bugs/show_bug.cgi?id=15707">15707</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>StackColoring can wrongly merge stack slots due to incorrect liveness calculation
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>tools
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>llc
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>mseaborn@chromium.org
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>StackColoring::calculateLiveIntervals() does not correctly handle the case
where the following sequence occurs in a basic block:

  llvm.lifetime.start(%buf)
  ...
  llvm.lifetime.end(%buf)
  ...
  llvm.lifetime.start(%buf)

calculateLiveIntervals() ignores the second lifetime.start() and regards %buf
as not being live after the lifetime.end().  This will cause StackColoring to
merge stack slots that shouldn't be merged.


Example:

declare void @llvm.lifetime.start(i64, i8*)
declare void @llvm.lifetime.end(i64, i8*)

declare void @ext(i8*)

define void @foo() {
  %buf1 = alloca i8, i32 10000, align 16
  %buf2 = alloca i8, i32 10000, align 16

  call void @llvm.lifetime.start(i64 -1, i8* %buf1)
  call void @llvm.lifetime.end(i64 -1, i8* %buf1)

  call void @llvm.lifetime.start(i64 -1, i8* %buf1)
  call void @llvm.lifetime.start(i64 -1, i8* %buf2)
  call void @ext(i8* %buf1)
  call void @ext(i8* %buf2)
  ret void
}


Expected output:

$ llc -mtriple=x86_64-none-gnu llvm_lifetime_bug.ll -O1 -o -
...
    subq    $20008, %rsp            # imm = 0x4E28
.Ltmp1:
    .cfi_def_cfa_offset 20016
    leaq    10000(%rsp), %rdi
    callq    ext
    leaq    (%rsp), %rdi
    callq    ext
    addq    $20008, %rsp            # imm = 0x4E28
    ret

Actual output:

$ llc -mtriple=x86_64-none-gnu llvm_lifetime_bug.ll -O1 -o -
...
    subq    $10008, %rsp            # imm = 0x2718
.Ltmp1:
    .cfi_def_cfa_offset 10016
    leaq    (%rsp), %rdi
    callq    ext
    leaq    (%rsp), %rdi
    callq    ext
    addq    $10008, %rsp            # imm = 0x2718
    ret


The following change fixes the bug:

@@ -434,10 +446,8 @@ void StackColoring::calculateLiveIntervals(unsigned
NumSlots) {
     if (Alive.any()) {
       for (int pos = Alive.find_first(); pos != -1;
            pos = Alive.find_next(pos)) {
-        if (!Starts[pos].isValid())
-          Starts[pos] = Indexes->getMBBStartIdx(MBB);
-        if (!Finishes[pos].isValid())
-          Finishes[pos] = Indexes->getMBBEndIdx(MBB);
+        Starts[pos] = Indexes->getMBBStartIdx(MBB);
+        Finishes[pos] = Indexes->getMBBEndIdx(MBB);
       }
     }</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>