<html>
    <head>
      <base href="https://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 --- - invalid sinking of invariant loads in codegen" href="https://urldefense.proofpoint.com/v2/url?u=https-3A__llvm.org_bugs_show-5Fbug.cgi-3Fid-3D23603&d=AwMBaQ&c=8hUWFZcy2Z-Za5rBPlktOQ&r=pF93YEPyB-J_PERP4DUZOJDzFVX5ZQ57vQk33wu0vio&m=mi8mYayvNi5W73yN1GQQXsTYlwsuIMDpleRmgXhvLEE&s=eLog0D7wldevshWpxbBCMe4-2vLTWWZpTZ7FtFUDNAg&e=">23603</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>invalid sinking of invariant loads in codegen
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

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

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

        <tr>
          <th>OS</th>
          <td>All
          </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>Common Code Generator Code
          </td>
        </tr>

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

        <tr>
          <th>Reporter</th>
          <td>sanjoy@playingwithpointers.com
          </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>Currently llc -O3 will codegen

```
declare void @g()

define void @f(i32* %x, i32 %c32, i32* %y) {
 entry:
  %v = load i32, i32* %x, !invariant.load !0
  call void @g()
  %c = icmp ne i32 %c32, 0
  br i1 %c, label %left, label %merge

 left:
  store i32 %v, i32* %y
  br label %merge

 merge:
  ret void
}

!0 = !{}
```


to

```
_f:                                     ## @f
    .cfi_startproc
## BB#0:                                ## %entry
    pushq    %rbp
Ltmp0:
    .cfi_def_cfa_offset 16
    pushq    %r14
Ltmp1:
    .cfi_def_cfa_offset 24
    pushq    %rbx
Ltmp2:
    .cfi_def_cfa_offset 32
Ltmp3:
    .cfi_offset %rbx, -32
Ltmp4:
    .cfi_offset %r14, -24
Ltmp5:
    .cfi_offset %rbp, -16
    movq    %rdx, %r14
    movl    %esi, %ebp
    movq    %rdi, %rbx
    callq    _g
    testl    %ebp, %ebp
    je    LBB0_2
## BB#1:                                ## %left
    movl    (%rbx), %eax  <- %v is loaded after the call to @g
    movl    %eax, (%r14)
LBB0_2:                                 ## %merge
    popq    %rbx
    popq    %r14
    popq    %rbp
    retq
    .cfi_endproc
```

This is problematic because the call to @g could have free'ed the
memory %x is based on.  The problematic predicate that allows this is
MachineInstr::isSafeToMove which returns true for invariant loads.

The fundamental problem seems to be that the MachineInstr /
SelectionDAG notion of invariant load is different from the LLVM
IR notion of invariant load with respect to dereferenceability.  The
IR notion of invariant_load only guarantees that all *non-faulting*
invariant loads result in the same value.  The MI notion of invariant
load guarantees that the load can be legally moved to any location
within its containing function.  The MI notion of invariant_load is
stronger than the IR notion of invariant_load -- an MI invariant_load
is an IR invariant_load + a guarantee that the location being loaded
from is dereferenceable throughout the function's (execution)
lifetime.

I think the right fix is to teach SelectionDAGBuilder to lower IR
invariant_loads to MI invariant_loads only if it can prove that the
location being loaded from is dereferenceable throughout the
function's lifetime.</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>