[x86] Missed optimization: `MEMBARRIER` pseudo-instruction prevents branch folding and elimination
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
[Godbolt](https://godbolt.org/z/zW8jrE44n)
```llvm
define noundef ptr reality(ptr noundef nonnull align 8 captures(none) %0, ptr noundef %1) unnamed_addr {
%3 = ptrtoint ptr %1 to i64
%4 = atomicrmw xchg ptr %0, i64 %3 release, align 8
%5 = inttoptr i64 %4 to ptr
%6 = icmp eq ptr %5, null
br i1 %6, label %8, label %7
7:
fence acquire
br label %8
8:
%9 = inttoptr i64 %4 to ptr
ret ptr %9
}
```
As you can see in the Godbolt, this assembles to something like this:
```asm
reality:
mov rax, rsi
xchg qword ptr [rdi], rax
test rax, rax
je .LBB1_2
.LBB1_2:
ret
```
Directly before the lowering to assembly, the IR looks like:
```llvm
# Machine code for function reality: NoPHIs, TracksLiveness, NoVRegs, TiedOpsRewritten, TracksDebugUserValues
Function Live Ins: $rdi, $rsi
bb.0.start:
successors: %bb.2(0x30000000), %bb.1(0x50000000); %bb.2(37.50%), %bb.1(62.50%)
liveins: $rdi, $rsi
$rax = MOV64rr $rsi
renamable $rax = XCHG64rm killed renamable $rax(tied-def 0), killed renamable $rdi, 1, $noreg, 0, $noreg :: (load store release (s64) on %ir.x)
TEST64rr renamable $rax, renamable $rax, implicit-def $eflags
JCC_1 %bb.2, 4, implicit $eflags
bb.1.bb2:
; predecessors: %bb.0
successors: %bb.2(0x80000000); %bb.2(100.00%)
liveins: $rax
MEMBARRIER
bb.2.bb4:
; predecessors: %bb.0, %bb.1
liveins: $rax
RET64 $rax
# End machine code for function reality.
```
Looking at the opt passes briefly, I believe the culprit is the `MEMBARRIER` pseudo not being destroyed before final CFG cleanup, obscuring the fact that label `bb.1.bb2` (corresponding directly to block `7` in the original IR) is empty and should be eliminated.
Contributor guide
Research direction
Start with the Godbolt reproducer and inspect the opt passes around final CFG cleanup. Follow the x86 MEMBARRIER pseudo-instruction shown in the machine code and determine why the empty branch block remains. Done means the equivalent branch is folded or eliminated in the generated assembly without changing the required barrier semantics.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100