[LLVMbugs] [Bug 23603] New: invalid sinking of invariant loads in codegen
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Wed May 20 16:31:34 PDT 2015
https://llvm.org/bugs/show_bug.cgi?id=23603
Bug ID: 23603
Summary: invalid sinking of invariant loads in codegen
Product: libraries
Version: trunk
Hardware: PC
OS: All
Status: NEW
Severity: normal
Priority: P
Component: Common Code Generator Code
Assignee: unassignedbugs at nondot.org
Reporter: sanjoy at playingwithpointers.com
CC: llvmbugs at cs.uiuc.edu
Classification: Unclassified
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.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20150520/2742a359/attachment.html>
More information about the llvm-bugs
mailing list