<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/97252>97252</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[DSE] misoptimized deleted store before non-inlined sync
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
jacobly0
</td>
</tr>
</table>
<pre>
```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)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUWN9z2j4S_2vEyw6MLNv8eOAhCcld59K5m_Z6rxnZXmM1suRKMpT-9TeyjYFAAmmSu287HQj2_vjsZ1erlbi1YqkQ5yS-JvFiwGtXaDP_zlOdyA0dJDrbzMmYtv-lXJWELgi9IhFVWj1wp0uRAgkXIJRDo7iEpdQJlyCmQHvZy-SazwxzoRBWWmRAIuoKgzx74IRNCZsBmVy3YmCdNui1A8JuoHIGDjB1UpByKXtjdqPS1tD2dW-FvWjFoGuMdEAnixOI-8COvYHSQkkvtMPfue6YeRJH99Tij4fUOv-CS7FUEGyVEwOSJyiBsDjYBxOQ8GorRFjMGs6l5tnO02v8EBaHbdrSsgLVUOXNelG6B0YEjah_vIdr_1e0jzLaQ3kRt9O9WkiOauH_RAf-OEXH29ggLI53IA_QHZXl0wqirwnF096ij58yv13up3-yCHTlYDhcobFCq_bx_f1_PgNh08K5yofD7gi78_1ipM2y-TXbRdkId-oQTEfBKN7CWtxef_sbJLWQGayFK4Bbi8YJreyol8Gc19KB42aJjoRX8HM6fhhHw1o9Kr1WQylU_XO4VPVW4-_aOrj51zcv-0ut0ESHwRisjB5JCcPK-7MkXBA2MfijFgZJeNP2KjvknIS3hN3ktUo9piF3zljCbjKLhE1gmGFSL4dayQ34R42Tf5uNUEtwGlCKUijuED5jqc1mgbmFRyElZpBsIGgS378ibCrFCv-pbpUzm6bi2RTONr69VO_6nOsxLNFBphsY_glPU7R2KwYrYUXznJ7B0muMRiOAXNcqg_udhFfpJHKhhC0wgzWXj69kJDxCwY55eKZ1v4GHngV25D_o_T-3s-xx09v5wMzeFJg-eh-5NuD7owWdf6TDt5LyQk5_K6VtCdpHUVWeBl88_jvzpu8yXR6mtqdL5LBGSLlqND6OsMXXW991vmCpVwgL5Bl89Vb2ev7i9mrhZV5lv9P9x6f7-9svT7TP0_eXbAskvLFKVL7FvrgR7Y2h4TV81lkt8dOiQdZ07baXEzZphayuTYoPuZCoeImdHNvJsf3N-OMmWw_2rts44KrZOMIrUDo3iKC0wbQ21v9Vq7VQGZQNy4RN_apeG-HQZ1CoNjcikVhi2ZpQ2HN_Zn5mId0fnN44Hp8eK56d5s4w0M3IF1PBzfKAgYvJeWlUJywM_jdjOrzyn2evMpjZroLbkZKwmP4ZA_-pAN6haj68WE6ePVjILj6A_AGJPn2Uef9EX3a8OUb7UUed5tMP8SKpHdquP3rQk-t3bM3Qezz0FRz7-sgm-BwM9tsh_573Jxt7f5ljIUOJDjPAFSpwha6XBQgHBa8qVHaYYN7UQTPo-jnXFdzBisvaN3XgSrsCDbSLFdaFSIunuq7A9oBhWq8esytM48m_y7WUeu1nnSeKacGF2k1thF0BGdNzE9uYemA-1L29eEz9OLmNtYMxO2X4on3neR9jI5aF48botV-TrUiz2W2537p7dUcZ05Z8L2-9heAUjuSUows6wDOmPG2lsLpyohS_eLMj9ABoq2VdVxsdprPMvtBLLo3ojdTRd0nhuWHthVI8XBCzQTYPs1k44wOcB5NgNqXxOJoOivmY5knEMh4ls5AHUYg5y8eMRzGdslmUxgMxZ5RFdEIDGkYTNh3NppRmSZgljOaTeByRiGLJhRxt74YGwtoa57MJi9mg2VNscxnNmMI1NC_9hB4vBmbudYZJvbQkolJYZ3dWnHCyucX25614AbsqwQwOVhp061lpNWybbQaez0Ft5LxwrrL9_dVSuKJORqkuu8us7mtYGf0dU0fYXQPQEnbXBrCas_8GAAD___AN4Hw">