Behavior of lifetime intrinsics depends on code that is never executed
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
Behavior of lifetime intrinsics depends on instructions that are yet to be executed or are never executed, with calamitous consequences.
Consider allocations `a` and `b`. Their lifetimes are disjoint, except for a single code path where they do overlap. This code path is executed only when allocations have been observed to have the same address -- an impossibility. On the one hand this code path must be dead, on the other hand removing it might change the behavior because lifetimes are no longer overlapping.
An [Alive2](https://alive2.llvm.org/ce/z/xB9o52) example demonstrating surprising consequences. In the example, it is invalid to replace `%1` with `1` despite preceding assumption `call void @llvm.assume(i1 %1)`. The nature of this specific failure might be an implementation detail of Alive2, but I hope conveys the overall sense of the issue.
```llvm
define void @src() {
%a = alloca ptr
%b = alloca ptr
call void @llvm.lifetime.start.p0(ptr %a)
call void @llvm.lifetime.end.p0(ptr %a)
call void @llvm.lifetime.start.p0(ptr %b)
call void @llvm.lifetime.end.p0(ptr %b)
%1 = icmp ne ptr %a, %b
call void @llvm.assume(i1 %1)
br i1 %1, label %bb2, label %bb1
bb1:
call void @llvm.lifetime.start.p0(ptr %a)
call void @llvm.lifetime.start.p0(ptr %b)
call void @llvm.lifetime.end.p0(ptr %b)
call void @llvm.lifetime.end.p0(ptr %a)
br label %bb2
bb2:
ret void
}
define void @tgt() {
%a = alloca ptr
%b = alloca ptr
call void @llvm.lifetime.start.p0(ptr %a)
call void @llvm.lifetime.end.p0(ptr %a)
call void @llvm.lifetime.start.p0(ptr %b)
call void @llvm.lifetime.end.p0(ptr %b)
%1 = icmp ne ptr %a, %b
call void @llvm.assume(i1 %1)
br i1 1, label %bb2, label %bb1
bb1:
call void @llvm.lifetime.start.p0(ptr %a)
call void @llvm.lifetime.start.p0(ptr %b)
call void @llvm.lifetime.end.p0(ptr %b)
call void @llvm.lifetime.end.p0(ptr %a)
br label %bb2
bb2:
ret void
}
```
```
Transformation doesn't verify!
ERROR: Source is more defined than target
```
Contributor guide
Research direction
The issue does not name an implementation file, entry point, or test. Begin with the LLVM IR lifetime.start/lifetime.end and llvm.assume example and reproduce it in the linked Alive2 case; a concrete completion criterion is not specified.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 20/100