<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>