[llvm] [WebAssembly] Unstackify operands for removed terminators (PR #149432)
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 18 19:57:38 PDT 2025
aheejin wrote:
@nikic
> Hm, couldn't this still potentially cause issues with `tee` instructions? That is, if a register does stay unstackified and it happens to be the first result of `tee`?
The only case I can think of is a really contrived case like this:
(I've removed all `implicit` arguments for readability, so this may not run with `llc` out of the box)
```mir
bb.0:
successors: %bb.1; %bb.1
%0:i32 = CALL @foo
%1:i32 = CONST_I32 -1
%2:i32 = XOR_I32 %0:i32, %1:i32
BR_IF %bb.1, %2:i32
BR_IF %bb.1, %2:i32
BR_IF %bb.1, %2:i32
bb.1:
; predecessors: %bb.0
RETURN
```
Because `%2` is used in both `CALL @use` and `BR_IF`, we will get a `TEE`:
```mir
bb.0:
successors: %bb.1; %bb.1
%0:i32 = CALL @foo
%1:i32 = CONST_I32 -1
%4:i32 = XOR_I32 %0:i32, %1:i32
%3:i32, %2:i32 = TEE_I32 %4:i32
BR_IF %bb.1, %3:i32
BR_IF %bb.1, %2:i32
BR_IF %bb.1, %2:i32
bb.1:
; predecessors: %bb.0
RETURN
```
with `%4` and `%3` stackified. (See [this](https://github.com/llvm/llvm-project/blob/cfddb401db111c53f0a345c2a590974487a96bb9/llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp#L644-L663) for how it's done)
If all these `BR_IF`s get removed in CFGSort I think the situation you are worried about can occur. If I run this from RegStackify, this fails in here:
https://github.com/llvm/llvm-project/blob/cfddb401db111c53f0a345c2a590974487a96bb9/llvm/lib/CodeGen/MachineBasicBlock.cpp#L706
So I think it's OK to assume that this kind of code is not generated without manually modifying mir files.
In valid code, there will be only one `BR_IF`, so the code could be something like
```mir
bb.0:
successors: %bb.1; %bb.1
%0:i32 = CALL @foo
%1:i32 = CONST_I32 -1
%2:i32 = XOR_I32 %0:i32, %1:i32
CALL @use, %2:i32
CALL @use, %2:i32
BR_IF %bb.1, %2:i32
bb.1:
; predecessors: %bb.0
RETURN
```
```mir
bb.0:
successors: %bb.1; %bb.1
%0:i32 = CALL @foo
%1:i32 = CONST_I32 -1
%4:i32 = XOR_I32 %0:i32, %1:i32
%3:i32, %2:i32 = TEE_I32 %4:i32
CALL @use, %3:i32
CALL @use, %2:i32
BR_IF %bb.1, %2:i32
bb.1:
; predecessors: %bb.0
RETURN
```
with `%4` and `%3` stackified.
In this case, even if the `BR_IF` is removed, its operand (%2) is not the stackified register.
https://github.com/llvm/llvm-project/pull/149432
More information about the llvm-commits
mailing list