From cc8184b7fe1c54b7f090649750ff4eb5601c4731 Mon Sep 17 00:00:00 2001 From: Demetrius Kanios Date: Tue, 23 Jun 2026 00:51:22 -0700 Subject: [PATCH 1/3] Compiler tweaks for Wasm & WASI --- dmd/mangle/package.d | 17 +++++++++++++++++ driver/linker-gcc.cpp | 2 +- driver/main.cpp | 18 ++++++++++++++++++ gen/llvmhelpers.cpp | 6 +++++- gen/llvmhelpers.d | 1 + gen/runtime.cpp | 4 ++-- 6 files changed, 44 insertions(+), 4 deletions(-) diff --git a/dmd/mangle/package.d b/dmd/mangle/package.d index a6a80b7be7b..e7fe3de1b94 100644 --- a/dmd/mangle/package.d +++ b/dmd/mangle/package.d @@ -726,6 +726,23 @@ public: buf.writestring(fd.ident.toString()); return; } + + version (IN_LLVM) + { + import gen.llvmhelpers : isTargetWasm; + bool isWasm = isTargetWasm(); + } + else bool isWasm = false; + + if (fd.isCMain() && isWasm) + { + if (fd.parameters) + buf.writestring("__main_argc_argv"); + else + buf.writestring("__main_void"); + return; + } + visit(cast(Declaration)fd); } diff --git a/driver/linker-gcc.cpp b/driver/linker-gcc.cpp index 93cb97a4921..c9ad3aae0a5 100644 --- a/driver/linker-gcc.cpp +++ b/driver/linker-gcc.cpp @@ -810,7 +810,7 @@ int linkObjToBinaryGcc(llvm::StringRef outputPath, // exception: invoke (ld-compatible) linker directly for WebAssembly targets std::string tool; std::unique_ptr argsBuilder; - if (global.params.targetTriple->isOSBinFormatWasm()) { + if (global.params.targetTriple->isOSBinFormatWasm() && !global.params.targetTriple->isOSWASI()) { argsBuilder = std::make_unique(); tool = getProgram("wasm-ld", &opts::linker); } else { diff --git a/driver/main.cpp b/driver/main.cpp index 5700fa7204e..458e3026154 100644 --- a/driver/main.cpp +++ b/driver/main.cpp @@ -908,8 +908,26 @@ void registerPredefinedTargetVersions() { break; case llvm::Triple::WASI: VersionCondition::addPredefinedGlobalIdent("WASI"); + VersionCondition::addPredefinedGlobalIdent("WASIp1"); VersionCondition::addPredefinedGlobalIdent("CRuntime_WASI"); break; +#if LLVM_VERSION_MAJOR >= 22 + case llvm::Triple::WASIp1: + VersionCondition::addPredefinedGlobalIdent("WASI"); + VersionCondition::addPredefinedGlobalIdent("WASIp1"); + VersionCondition::addPredefinedGlobalIdent("CRuntime_WASI"); + break; + case llvm::Triple::WASIp2: + VersionCondition::addPredefinedGlobalIdent("WASI"); + VersionCondition::addPredefinedGlobalIdent("WASIp2"); + VersionCondition::addPredefinedGlobalIdent("CRuntime_WASI"); + break; + case llvm::Triple::WASIp3: + VersionCondition::addPredefinedGlobalIdent("WASI"); + VersionCondition::addPredefinedGlobalIdent("WASIp3"); + VersionCondition::addPredefinedGlobalIdent("CRuntime_WASI"); + break; +#endif case llvm::Triple::Emscripten: VersionCondition::addPredefinedGlobalIdent("Emscripten"); // Emscripten uses musl and libc++, so mimic a musl Linux platform: diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index aa2278a7b7f..655cb318b9f 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -71,6 +71,10 @@ llvm::cl::opt clThreadModel( bool isTargetWindowsMSVC() { return global.params.targetTriple->isWindowsMSVCEnvironment(); } +bool isTargetWasm() { + return global.params.targetTriple->isWasm(); +} + /****************************************************************************** * Global context @@ -289,7 +293,7 @@ void DtoCAssert(Module *M, Loc loc, LLValue *msg) { args.push_back(file); args.push_back(line); args.push_back(msg); - } else if (triple.isOSSolaris() || triple.isMusl() || + } else if (triple.isOSSolaris() || triple.isMusl() || triple.isOSWASI() || global.params.isUClibcEnvironment || triple.isGNUEnvironment()) { const auto irFunc = gIR->func(); diff --git a/gen/llvmhelpers.d b/gen/llvmhelpers.d index 932c3db9360..e724f1728a4 100644 --- a/gen/llvmhelpers.d +++ b/gen/llvmhelpers.d @@ -20,3 +20,4 @@ import dmd.dtemplate; extern (C++) void DtoSetFuncDeclIntrinsicName(TemplateInstance ti, TemplateDeclaration td, FuncDeclaration fd); extern (C++) bool isTargetWindowsMSVC(); +extern (C++) bool isTargetWasm(); diff --git a/gen/runtime.cpp b/gen/runtime.cpp index 70f9db81771..0ba32edb8c1 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -358,7 +358,7 @@ static const char *getCAssertFunctionName() { return "_assert"; } else if (triple.isOSSolaris()) { return "__assert_c99"; - } else if (triple.isMusl() || triple.isGNUEnvironment()) { + } else if (triple.isMusl() || triple.isGNUEnvironment() || triple.isOSWASI()) { return "__assert_fail"; } else if (global.params.isNewlibEnvironment) { return "__assert_func"; @@ -372,7 +372,7 @@ static std::vector getCAssertFunctionParamTypes() { const auto uint = Type::tuns32; if (triple.isOSDarwin() || triple.isOSFreeBSD() || triple.isOSSolaris() || - triple.isMusl() || global.params.isUClibcEnvironment || + triple.isMusl() || triple.isOSWASI() || global.params.isUClibcEnvironment || triple.isGNUEnvironment()) { return {voidPtr, voidPtr, uint, voidPtr}; } From 97ce2590dc7dcf2fc23a4eeb2244098c732dbd81 Mon Sep 17 00:00:00 2001 From: Demetrius Kanios Date: Tue, 23 Jun 2026 10:42:45 -0700 Subject: [PATCH 2/3] Undo mangle and fix tests. --- dmd/mangle/package.d | 17 ----------------- tests/codegen/wasi.d | 8 +++++++- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/dmd/mangle/package.d b/dmd/mangle/package.d index e7fe3de1b94..a6a80b7be7b 100644 --- a/dmd/mangle/package.d +++ b/dmd/mangle/package.d @@ -726,23 +726,6 @@ public: buf.writestring(fd.ident.toString()); return; } - - version (IN_LLVM) - { - import gen.llvmhelpers : isTargetWasm; - bool isWasm = isTargetWasm(); - } - else bool isWasm = false; - - if (fd.isCMain() && isWasm) - { - if (fd.parameters) - buf.writestring("__main_argc_argv"); - else - buf.writestring("__main_void"); - return; - } - visit(cast(Declaration)fd); } diff --git a/tests/codegen/wasi.d b/tests/codegen/wasi.d index 711100ae30a..ddc5cbd4763 100644 --- a/tests/codegen/wasi.d +++ b/tests/codegen/wasi.d @@ -1,8 +1,14 @@ // REQUIRES: target_WebAssembly, link_WebAssembly // emit textual IR *and* compile & link -// RUN: %ldc -mtriple=wasm32-unknown-wasi -output-ll -output-o -of=%t.wasm %s +// RUN: %ldc -mtriple=wasm32-unknown-wasi -Xcc=-nostdlib -output-ll -output-o -of=%t.wasm %s // RUN: FileCheck %s < %t.ll +// +// RUN: %ldc -mtriple=wasm32-unknown-wasip1 -Xcc=-nostdlib -output-ll -output-o -of=%t_p1.wasm %s +// RUN: FileCheck %s < %t_p1.ll +// +// RUN: %ldc -mtriple=wasm32-unknown-wasip2 -Xcc=-nostdlib -output-ll -output-o -of=%t_p2.wasm %s +// RUN: FileCheck %s < %t_p2.ll // test predefined versions: From 9c90b843fbb2e47513b069a4035d42f0a5a91785 Mon Sep 17 00:00:00 2001 From: Demetrius Kanios Date: Tue, 23 Jun 2026 13:13:36 -0700 Subject: [PATCH 3/3] Force the use of `wasm-ld`, rather than `wasm-component-ld`. --- tests/codegen/wasi.d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/codegen/wasi.d b/tests/codegen/wasi.d index ddc5cbd4763..1de6aa131fc 100644 --- a/tests/codegen/wasi.d +++ b/tests/codegen/wasi.d @@ -1,13 +1,13 @@ // REQUIRES: target_WebAssembly, link_WebAssembly // emit textual IR *and* compile & link -// RUN: %ldc -mtriple=wasm32-unknown-wasi -Xcc=-nostdlib -output-ll -output-o -of=%t.wasm %s +// RUN: %ldc -mtriple=wasm32-unknown-wasi --linker=lld -Xcc=-nostdlib -output-ll -output-o -of=%t.wasm %s // RUN: FileCheck %s < %t.ll // -// RUN: %ldc -mtriple=wasm32-unknown-wasip1 -Xcc=-nostdlib -output-ll -output-o -of=%t_p1.wasm %s +// RUN: %ldc -mtriple=wasm32-unknown-wasip1 --linker=lld -Xcc=-nostdlib -output-ll -output-o -of=%t_p1.wasm %s // RUN: FileCheck %s < %t_p1.ll // -// RUN: %ldc -mtriple=wasm32-unknown-wasip2 -Xcc=-nostdlib -output-ll -output-o -of=%t_p2.wasm %s +// RUN: %ldc -mtriple=wasm32-unknown-wasip2 --linker=lld -Xcc=-nostdlib -output-ll -output-o -of=%t_p2.wasm %s // RUN: FileCheck %s < %t_p2.ll