Skip to content

Commit e630ef0

Browse files
jlebarclaude
andcommitted
x86: +1 reproducible bug #194 — InstCombine alone CSEs distinct freezes
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 969e387 commit e630ef0

4 files changed

Lines changed: 39 additions & 0 deletions

File tree

‎x86/README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,4 @@ Goal: find ≥100 real bugs in the x86 path through the default LLVM pass pipeli
227227
| 191 | [191-vectorcombine-scalarizeLoad-infloop-on-strong-atomic](bugs/191-vectorcombine-scalarizeLoad-infloop-on-strong-atomic/) | VectorCombine scalarizeLoad | `monotonic`/`acquire`/`seq_cst` atomic vector load → opt hangs at 100% CPU (worklist re-pushes the surviving original load forever) | confirmed (hang) |
228228
| 192 | [192-simplifycfg-mergeCondStores-drops-nontemporal](bugs/192-simplifycfg-mergeCondStores-drops-nontemporal/) | **default SimplifyCFG** mergeConditionalStores | merged store drops `!nontemporal` when only one of the paired stores carried it | confirmed (opt diff) |
229229
| 193 | [193-simplifycfg-mergeCondStores-spreads-invariant-group](bugs/193-simplifycfg-mergeCondStores-spreads-invariant-group/) | **default SimplifyCFG** mergeConditionalStores | `!invariant.group` from one store leaks onto the merged store carrying the other branch's value | confirmed (opt diff) |
230+
| 194 | [194-instcombine-freeze-cse-distinct-instances](bugs/194-instcombine-freeze-cse-distinct-instances/) | **InstCombine** (default O2) | distinct `freeze` of same poison-able operand merged; fires WITHOUT GVN/EarlyCSE/NewGVN; sibling of #187/#188/#136 | confirmed (opt diff) |
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# 194 — InstCombine alone CSEs distinct `freeze` instructions of same poison-able operand
2+
3+
Component: InstCombine (default O2)
4+
5+
Same family as #187 (Standard GVN), #188 (EarlyCSE), #136 (NewGVN), but in **InstCombine** itself. InstCombine recognizes `freeze X; freeze X` as redundant when X is a single SSA value, even when X may produce poison — folds `f1 - f2 → 0`.
6+
7+
## Reproducer
8+
9+
```ll
10+
define i32 @f(i32 %x) {
11+
%s = shl i32 1, %x ; poison when x >= 32
12+
%f1 = freeze i32 %s
13+
%f2 = freeze i32 %s
14+
%d = sub i32 %f1, %f2
15+
ret i32 %d
16+
}
17+
```
18+
19+
`opt -passes=instcombine -S` → `ret i32 0`.
20+
21+
Per LangRef each freeze independently picks an arbitrary fixed value when its input is poison/undef. With `%x = 32`, `%s` is poison; `%f1` may pick e.g. `0x1234`, `%f2` may pick `0x5678`; `%d = -0x4444 ≠ 0`. InstCombine claims they're identical.
22+
23+
InstCombine is **the** workhorse of `-O2`; this bug fires unconditionally in the standard pipeline.
24+
25+
## Severity
26+
27+
Alive2-falsifiable. Affects code that uses `freeze` to safely consume a possibly-poison value multiple times (common idiom for promoting `select i1 poison` etc.).
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/usr/bin/env bash
2+
OPT=/home/orenamd@semianalysis.com/FuzzX/amdgpu/build/llvm-fuzzer/bin/opt
3+
echo "===== InstCombine alone CSEs two distinct freeze of poison-able operand ====="
4+
"$OPT" -passes=instcombine -S repro.ll | grep -E "define|freeze|sub|ret"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
define i32 @f(i32 %x) {
2+
%s = shl i32 1, %x ; poison when x >= 32
3+
%f1 = freeze i32 %s
4+
%f2 = freeze i32 %s
5+
%d = sub i32 %f1, %f2
6+
ret i32 %d
7+
}

0 commit comments

Comments
 (0)