From f167fc836688d9b01f7a9014b7ac5f2b86bbae29 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 23 Sep 2025 03:53:34 +0000 Subject: [PATCH 1/2] [WebAssembly] Remove FAKE_USEs before ExplicitLocals `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. Fixes https://github.com/emscripten-core/emscripten/issues/25301. --- .../WebAssembly/WebAssemblyExplicitLocals.cpp | 14 ++++++++++++++ llvm/test/CodeGen/WebAssembly/fake-use.ll | 15 +++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 llvm/test/CodeGen/WebAssembly/fake-use.ll diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index e6486e247209b..014cd99b9aa23 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -216,6 +216,18 @@ static MachineInstr *findStartOfTree(MachineOperand &MO, return Def; } +// FAKE_USEs are no-ops, so remove them here so that the values used by them +// will be correctly dropped later. +static void removeFakeUses(MachineFunction &MF) { + SmallVector ToDelete; + for (auto &MBB : MF) + for (auto &MI : MBB) + if (MI.isFakeUse()) + ToDelete.push_back(&MI); + for (auto *MI : ToDelete) + MI->eraseFromParent(); +} + bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { LLVM_DEBUG(dbgs() << "********** Make Locals Explicit **********\n" "********** Function: " @@ -226,6 +238,8 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { WebAssemblyFunctionInfo &MFI = *MF.getInfo(); const auto *TII = MF.getSubtarget().getInstrInfo(); + removeFakeUses(MF); + // Map non-stackified virtual registers to their local ids. DenseMap Reg2Local; diff --git a/llvm/test/CodeGen/WebAssembly/fake-use.ll b/llvm/test/CodeGen/WebAssembly/fake-use.ll new file mode 100644 index 0000000000000..d5732e628440a --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/fake-use.ll @@ -0,0 +1,15 @@ +; RUN: llc < %s | llvm-mc -triple=wasm32-unknown-unknown + +target triple = "wasm32-unknown-unknown" + +define void @fake_use_test() { + %t = call i32 @foo() + tail call void (...) @llvm.fake.use(i32 %t) + ret void +} + +declare void @foo() +; 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) } From ebd82bcc5d0d1017c2a2c2be82d11ecc98a3d0de Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 23 Sep 2025 04:27:31 +0000 Subject: [PATCH 2/2] clang-format --- llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index 014cd99b9aa23..5c3127e2d3dc6 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -219,7 +219,7 @@ static MachineInstr *findStartOfTree(MachineOperand &MO, // FAKE_USEs are no-ops, so remove them here so that the values used by them // will be correctly dropped later. static void removeFakeUses(MachineFunction &MF) { - SmallVector ToDelete; + SmallVector ToDelete; for (auto &MBB : MF) for (auto &MI : MBB) if (MI.isFakeUse())