Issue |
97252
|
Summary |
[DSE] misoptimized deleted store before non-inlined sync
|
Labels |
new issue
|
Assignees |
|
Reporter |
jacobly0
|
```llvm
@non_atomic = internal global i8 0
@atomic = internal global i8 0
define void @thread_a() {
store i8 1, ptr @non_atomic
call void @sync()
store i8 2, ptr @non_atomic
ret void
}
define internal void @sync() noinline {
store atomic i8 1, ptr @atomic seq_cst, align 1
br label %1
1:
%2 = load atomic i8, ptr @atomic seq_cst, align 1
%3 = icmp ne i8 %2, 0
br i1 %3, label %1, label %4
4:
ret void
}
define i8 @thread_b() {
br label %1
1:
%2 = load atomic i8, ptr @atomic seq_cst, align 1
%3 = icmp eq i8 %2, 0
br i1 %3, label %1, label %4
4:
%5 = load i8, ptr @non_atomic
store atomic i8 0, ptr @atomic seq_cst, align 1
ret i8 %5
}
```
```
$ opt --version
LLVM (http://llvm.org/):
LLVM version 18.1.5
DEBUG build with assertions.
Default target: x86_64-unknown-linux-gnu
Host CPU: znver4
$ opt repro.ll -passes='require<globals-aa>,function-attrs,dse' -debug-only dse
Trying to eliminate MemoryDefs killed by 1 = MemoryDef(liveOnEntry) ( store i8 1, ptr @non_atomic, align 1)
trying to get dominating access
visiting 0 = MemoryDef(liveOnEntry)
... found LiveOnEntryDef
finished walk
Trying to eliminate MemoryDefs killed by 3 = MemoryDef(2) ( store i8 2, ptr @non_atomic, align 1)
trying to get dominating access
visiting 2 = MemoryDef(1) ( call void @sync())
visiting 1 = MemoryDef(liveOnEntry) ( store i8 1, ptr @non_atomic, align 1)
Checking for reads of 1 = MemoryDef(liveOnEntry) ( store i8 1, ptr @non_atomic, align 1)
2 = MemoryDef(1) ( call void @sync())
3 = MemoryDef(2) ( store i8 2, ptr @non_atomic, align 1)
... skipping killing def/dom access
Checking if we can kill 1 = MemoryDef(liveOnEntry) ( store i8 1, ptr @non_atomic, align 1)
DSE: Remove Dead Store:
DEAD: store i8 1, ptr @non_atomic, align 1
KILLER: store i8 2, ptr @non_atomic, align 1
trying to get dominating access
visiting 0 = MemoryDef(liveOnEntry)
... found LiveOnEntryDef
finished walk
<snip>
```
```llvm
; ModuleID = 'repro.ll'
source_filename = "repro.ll"
@non_atomic = internal global i8 0
@atomic = internal global i8 0
; Function Attrs: nofree norecurse nounwind memory(readwrite, inaccessiblemem: none)
define void @thread_a() #0 {
call void @sync()
store i8 2, ptr @non_atomic, align 1
ret void
}
; Function Attrs: nofree noinline norecurse nounwind memory(readwrite, argmem: none, inaccessiblemem: none)
define internal void @sync() #1 {
store atomic i8 1, ptr @atomic seq_cst, align 1
br label %1
1: ; preds = %1, %0
%2 = load atomic i8, ptr @atomic seq_cst, align 1
%3 = icmp ne i8 %2, 0
br i1 %3, label %1, label %4
4: ; preds = %1
ret void
}
; Function Attrs: nofree norecurse nounwind memory(readwrite, argmem: none, inaccessiblemem: none)
define i8 @thread_b() #2 {
br label %1
1: ; preds = %1, %0
%2 = load atomic i8, ptr @atomic seq_cst, align 1
%3 = icmp eq i8 %2, 0
br i1 %3, label %1, label %4
4: ; preds = %1
%5 = load i8, ptr @non_atomic, align 1
store atomic i8 0, ptr @atomic seq_cst, align 1
ret i8 %5
}
attributes #0 = { nofree norecurse nounwind memory(readwrite, inaccessiblemem: none) }
attributes #1 = { nofree noinline norecurse nounwind memory(readwrite, argmem: none, inaccessiblemem: none) }
attributes #2 = { nofree norecurse nounwind memory(readwrite, argmem: none, inaccessiblemem: none) }
```
A store is deleted even though it happens-before a read of that value in another thread which happens-before the killer store, through the following happens-before chain:
* `store i8 1, ptr @non_atomic` in `@thread_a` (deleted store)
* `store atomic i8 1, ptr @atomic seq_cst` in `@thread_a` → `@sync`
* `%2 = load atomic i8, ptr @atomic seq_cst` that loads `1` in `@thread_b`
* `%5 = load i8, ptr @non_atomic` in `@thread_b` (misoptimization loads `0` instead of `1`)
* `store atomic i8 0, ptr @atomic seq_cst` in `@thread_b`
* `%2 = load atomic i8, ptr @atomic seq_cst` that loads `0` in `@thread_a` → `@sync`
* `store i8 2, ptr @non_atomic` in `@thread_a` (killer store)
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs