`FAKE_USE`s are essentially no-ops, so they have to be removed before running ExplicitLocals so that `drop`s will be correctly inserted to drop those values used by the `FAKE_USE`s. --- This is reapplication of #160228, which broke Wasm waterfall. This PR additionally prevents `FAKE_USE`s uses from being stackified. Previously, a 'def' whose first use was a `FAKE_USE` was able to be stackified as `TEE`: - Before ``` Reg = INST ... // Def FAKE_USE ..., Reg, ... // Insert INST ..., Reg, ... INST ..., Reg, ... ``` - After RegStackify ``` DefReg = INST ... // Def TeeReg, Reg = TEE ... DefReg FAKE_USE ..., TeeReg, ... // Insert INST ..., Reg, ... INST ..., Reg, ... ``` And this assumes `DefReg` and `TeeReg` are stackified. But this PR removes `FAKE_USE`s in the beginning of ExplicitLocals. And later in ExplicitLocals we have a routine to unstackify registers that have no uses left:7b28fcd2b1/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp (L257-L269)(This was added in #149626. Then it didn't seem it would trigger the same assertions for `TEE`s because it was fixing the bug where a terminator was removed in CFGSort (#149097). Details here: https://github.com/llvm/llvm-project/pull/149432#issuecomment-3091444141) - After `FAKE_USE` removal and unstackification ``` DefReg = INST ... TeeReg, Reg = TEE ... DefReg INST ..., Reg, ... INST ..., Reg, ... ``` And now `TeeReg` is unstackified. This triggered the assertion here, that `TeeReg` should be stackified:7b28fcd2b1/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp (L316)This prevents `FAKE_USE`s' uses from being stackified altogether, including `TEE` transformation. Even when it is not a `TEE` transformation and just a single use stackification, it does not trigger the assertion but there's no point stackifying it given that it will be deleted. --- Fixes https://github.com/emscripten-core/emscripten/issues/25301.
26 lines
782 B
LLVM
26 lines
782 B
LLVM
; RUN: llc < %s | llvm-mc -triple=wasm32-unknown-unknown
|
|
|
|
target triple = "wasm32-unknown-unknown"
|
|
|
|
define void @fake_use() {
|
|
%t = call i32 @foo()
|
|
tail call void (...) @llvm.fake.use(i32 %t)
|
|
ret void
|
|
}
|
|
|
|
; %t shouldn't be converted to TEE in RegStackify, because the FAKE_USE will be
|
|
; deleted in the beginning of ExplicitLocals.
|
|
define void @fake_use_no_tee() {
|
|
%t = call i32 @foo()
|
|
tail call void (...) @llvm.fake.use(i32 %t)
|
|
call void @use(i32 %t)
|
|
ret void
|
|
}
|
|
|
|
declare i32 @foo()
|
|
declare void @use(i32 %t)
|
|
; Function Attrs: mustprogress nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
|
|
declare void @llvm.fake.use(...) #0
|
|
|
|
attributes #0 = { mustprogress nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite) }
|