Skip to content

Conversation

@sunfishcode
Copy link
Member

This adds code to recognize "wasm32-wasip1", "wasm32-wasip2", and "wasm32-wasip3" as explicit targets, and adds a deprecation warning when the "wasm32-wasi" target is used, pointing users to the "wasm32-wasip1" target.

Fixes #165344.

I'm filing this as a draft PR for now, as I've only just now proposed to make this change in #165344.

@github-actions
Copy link

github-actions bot commented Oct 28, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

This adds code to recognize "wasm32-wasip1", "wasm32-wasip2", and
"wasm32-wasip3" as explicit targets, and adds a deprecation warning
when the "wasm32-wasi" target is used, pointing users to the
"wasm32-wasip1" target.

Fixes llvm#165344.
@sunfishcode sunfishcode force-pushed the sunfishcode/wasi-targets branch from 65f4b8b to e98789d Compare November 15, 2025 02:14
@sunfishcode sunfishcode marked this pull request as ready for review November 15, 2025 02:14
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Nov 15, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 15, 2025

@llvm/pr-subscribers-clang-driver

@llvm/pr-subscribers-clang

Author: Dan Gohman (sunfishcode)

Changes

This adds code to recognize "wasm32-wasip1", "wasm32-wasip2", and "wasm32-wasip3" as explicit targets, and adds a deprecation warning when the "wasm32-wasi" target is used, pointing users to the "wasm32-wasip1" target.

Fixes #165344.

I'm filing this as a draft PR for now, as I've only just now proposed to make this change in #165344.


Full diff: https://github.com/llvm/llvm-project/pull/165345.diff

10 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+4)
  • (modified) clang/lib/Basic/Targets.cpp (+22-8)
  • (modified) clang/lib/Basic/Targets/OSTargets.h (+33-2)
  • (modified) clang/lib/Driver/ToolChains/WebAssembly.cpp (+6)
  • (modified) clang/lib/Lex/InitHeaderSearch.cpp (+3)
  • (modified) clang/test/Preprocessor/init.c (+23-8)
  • (modified) llvm/docs/ReleaseNotes.md (+4)
  • (modified) llvm/include/llvm/TargetParser/Triple.h (+6-2)
  • (modified) llvm/lib/TargetParser/Triple.cpp (+9)
  • (modified) llvm/unittests/TargetParser/TripleTest.cpp (+36)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ad54872913d55..6fe9dd03c4bc1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -637,6 +637,10 @@ WebAssembly Support
 
 - Fix a bug so that ``__has_attribute(musttail)`` is no longer true when WebAssembly's tail-call is not enabled. (#GH163256)
 
+- The `wasm32-wasi` target has been renamed to `wasm32-wasip1`. The old
+  option is still recognized, though by default will emit a deprecation
+  warning.
+
 AVR Support
 ^^^^^^^^^^^
 
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index f39c698b5d734..35c6e278da35b 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -702,10 +702,17 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
         !Triple.isOSBinFormatWasm())
       return nullptr;
     switch (os) {
-      case llvm::Triple::WASI:
-      return std::make_unique<WASITargetInfo<WebAssembly32TargetInfo>>(Triple,
-                                                                       Opts);
-      case llvm::Triple::Emscripten:
+    case llvm::Triple::WASI: // Treat "wasi" as "wasip1" for now.
+    case llvm::Triple::WASIp1:
+      return std::make_unique<WASIP1TargetInfo<WebAssembly32TargetInfo>>(Triple,
+                                                                         Opts);
+    case llvm::Triple::WASIp2:
+      return std::make_unique<WASIP2TargetInfo<WebAssembly32TargetInfo>>(Triple,
+                                                                         Opts);
+    case llvm::Triple::WASIp3:
+      return std::make_unique<WASIP3TargetInfo<WebAssembly32TargetInfo>>(Triple,
+                                                                         Opts);
+    case llvm::Triple::Emscripten:
       return std::make_unique<EmscriptenTargetInfo<WebAssembly32TargetInfo>>(
           Triple, Opts);
 
@@ -724,10 +731,17 @@ std::unique_ptr<TargetInfo> AllocateTarget(const llvm::Triple &Triple,
         !Triple.isOSBinFormatWasm())
       return nullptr;
     switch (os) {
-      case llvm::Triple::WASI:
-      return std::make_unique<WASITargetInfo<WebAssembly64TargetInfo>>(Triple,
-                                                                       Opts);
-      case llvm::Triple::Emscripten:
+    case llvm::Triple::WASI: // Treat "wasi" as "wasip1" for now.
+    case llvm::Triple::WASIp1:
+      return std::make_unique<WASIP1TargetInfo<WebAssembly64TargetInfo>>(Triple,
+                                                                         Opts);
+    case llvm::Triple::WASIp2:
+      return std::make_unique<WASIP2TargetInfo<WebAssembly64TargetInfo>>(Triple,
+                                                                         Opts);
+    case llvm::Triple::WASIp3:
+      return std::make_unique<WASIP3TargetInfo<WebAssembly64TargetInfo>>(Triple,
+                                                                         Opts);
+    case llvm::Triple::Emscripten:
       return std::make_unique<EmscriptenTargetInfo<WebAssembly64TargetInfo>>(
           Triple, Opts);
       case llvm::Triple::UnknownOS:
diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h
index 4d81c9a83714d..3b7a08213962b 100644
--- a/clang/lib/Basic/Targets/OSTargets.h
+++ b/clang/lib/Basic/Targets/OSTargets.h
@@ -940,14 +940,45 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyOSTargetInfo
   }
 };
 
-// WASI target
+// WASIp1 target
 template <typename Target>
-class LLVM_LIBRARY_VISIBILITY WASITargetInfo
+class LLVM_LIBRARY_VISIBILITY WASIP1TargetInfo
     : public WebAssemblyOSTargetInfo<Target> {
   void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
                     MacroBuilder &Builder) const final {
     WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
     Builder.defineMacro("__wasi__");
+    Builder.defineMacro("__wasip1__");
+  }
+
+public:
+  using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo;
+};
+
+// WASIp2 target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY WASIP2TargetInfo
+    : public WebAssemblyOSTargetInfo<Target> {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const final {
+    WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
+    Builder.defineMacro("__wasi__");
+    Builder.defineMacro("__wasip2__");
+  }
+
+public:
+  using WebAssemblyOSTargetInfo<Target>::WebAssemblyOSTargetInfo;
+};
+
+// WASIp3 target
+template <typename Target>
+class LLVM_LIBRARY_VISIBILITY WASIP3TargetInfo
+    : public WebAssemblyOSTargetInfo<Target> {
+  void getOSDefines(const LangOptions &Opts, const llvm::Triple &Triple,
+                    MacroBuilder &Builder) const final {
+    WebAssemblyOSTargetInfo<Target>::getOSDefines(Opts, Triple, Builder);
+    Builder.defineMacro("__wasi__");
+    Builder.defineMacro("__wasip3__");
   }
 
 public:
diff --git a/clang/lib/Driver/ToolChains/WebAssembly.cpp b/clang/lib/Driver/ToolChains/WebAssembly.cpp
index 15c6f19e87fee..b5fa5760a46a0 100644
--- a/clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -265,6 +265,12 @@ WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
     }
     getFilePaths().push_back(SysRoot + "/lib/" + MultiarchTriple);
   }
+
+  if (getTriple().getOS() == llvm::Triple::WASI) {
+    D.Diag(diag::warn_drv_deprecated_custom)
+        << "--target=wasm32-wasi"
+        << "use --target=wasm32-wasip1 instead";
+  }
 }
 
 const char *WebAssembly::getDefaultLinker() const {
diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp
index 3e5f947a82cc3..e30925f4e548c 100644
--- a/clang/lib/Lex/InitHeaderSearch.cpp
+++ b/clang/lib/Lex/InitHeaderSearch.cpp
@@ -230,6 +230,9 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths(
   case llvm::Triple::Solaris:
   case llvm::Triple::UEFI:
   case llvm::Triple::WASI:
+  case llvm::Triple::WASIp1:
+  case llvm::Triple::WASIp2:
+  case llvm::Triple::WASIp3:
   case llvm::Triple::Win32:
   case llvm::Triple::ZOS:
     return false;
diff --git a/clang/test/Preprocessor/init.c b/clang/test/Preprocessor/init.c
index 4dea1b583a089..1adfd1aa26bc6 100644
--- a/clang/test/Preprocessor/init.c
+++ b/clang/test/Preprocessor/init.c
@@ -1656,12 +1656,24 @@
 // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm64-emscripten \
 // RUN:   < /dev/null \
 // RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64,EMSCRIPTEN %s
-// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm32-wasi \
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm32-wasip1 \
 // RUN:   < /dev/null \
-// RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32,WEBASSEMBLY-WASI %s
-// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm64-wasi \
+// RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32,WASI,WASIP1 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm64-wasip1 \
 // RUN:   < /dev/null \
-// RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64,WEBASSEMBLY-WASI %s
+// RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64,WASI,WASIP1 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm32-wasip2 \
+// RUN:   < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32,WASI,WASIP2 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm64-wasip2 \
+// RUN:   < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64,WASI,WASIP2 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm32-wasip3 \
+// RUN:   < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY32,WASI,WASIP3 %s
+// RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm64-wasip3 \
+// RUN:   < /dev/null \
+// RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY,WEBASSEMBLY64,WASI,WASIP3 %s
 // RUN: %clang_cc1 -E -dM -ffreestanding -fgnuc-version=4.2.1 -triple=wasm32-unknown-unknown -x c++ \
 // RUN:   < /dev/null \
 // RUN:   | FileCheck -match-full-lines -check-prefixes=WEBASSEMBLY-CXX %s
@@ -2079,11 +2091,14 @@
 // WEBASSEMBLY-NEXT:#define __clang_version__ "{{.*}}"
 // WEBASSEMBLY-NEXT:#define __clang_wide_literal_encoding__ {{.*}}
 // WEBASSEMBLY-NEXT:#define __llvm__ 1
-// WEBASSEMBLY-WASI-NOT:#define __unix
-// WEBASSEMBLY-WASI-NOT:#define __unix__
+// WASI-NOT:#define __unix
+// WASI-NOT:#define __unix__
 // EMSCRIPTEN-NEXT:#define __unix 1
 // EMSCRIPTEN-NEXT:#define __unix__ 1
-// WEBASSEMBLY-WASI-NEXT:#define __wasi__ 1
+// WASI-NEXT:#define __wasi__ 1
+// WASIP1-NEXT:#define __wasip1__ 1
+// WASIP2-NEXT:#define __wasip2__ 1
+// WASIP3-NEXT:#define __wasip3__ 1
 // WEBASSEMBLY-NOT:#define __wasm_simd128__
 // WEBASSEMBLY-NOT:#define __wasm_simd256__
 // WEBASSEMBLY-NOT:#define __wasm_simd512__
@@ -2098,7 +2113,7 @@
 // WEBASSEMBLY64-NEXT:#define __wasm64__ 1
 // WEBASSEMBLY-NEXT:#define __wasm__ 1
 // EMSCRIPTEN:#define unix 1
-// WEBASSEMBLY-WASI-NOT:#define unix 1
+// WASI-NOT:#define unix 1
 // WEBASSEMBLY-CXX-NOT:_REENTRANT
 // WEBASSEMBLY-CXX-NOT:__STDCPP_THREADS__
 // WEBASSEMBLY-CXX-ATOMICS:#define _REENTRANT 1
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index dc6191203e2b7..8eeb6c4d87b38 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -153,6 +153,10 @@ Changes to the RISC-V Backend
 Changes to the WebAssembly Backend
 ----------------------------------
 
+- The `wasm32-wasi` target has been renamed to `wasm32-wasip1`. The old
+  option is still recognized, though by default will emit a deprecation
+  warning.
+
 Changes to the Windows Target
 -----------------------------
 
diff --git a/llvm/include/llvm/TargetParser/Triple.h b/llvm/include/llvm/TargetParser/Triple.h
index 11b76cd183108..b5d8750c78b41 100644
--- a/llvm/include/llvm/TargetParser/Triple.h
+++ b/llvm/include/llvm/TargetParser/Triple.h
@@ -241,7 +241,10 @@ class Triple {
     AMDPAL,     // AMD PAL Runtime
     HermitCore, // HermitCore Unikernel/Multikernel
     Hurd,       // GNU/Hurd
-    WASI,       // Experimental WebAssembly OS
+    WASI,       // Deprecated alias of WASI 0.1; in the future will be WASI 1.0.
+    WASIp1,     // WASI 0.1
+    WASIp2,     // WASI 0.2
+    WASIp3,     // WASI 0.3
     Emscripten,
     ShaderModel, // DirectX ShaderModel
     LiteOS,
@@ -757,7 +760,8 @@ class Triple {
 
   /// Tests whether the OS is WASI.
   bool isOSWASI() const {
-    return getOS() == Triple::WASI;
+    return getOS() == Triple::WASI || getOS() == Triple::WASIp1 ||
+           getOS() == Triple::WASIp2 || getOS() == Triple::WASIp3;
   }
 
   /// Tests whether the OS is Emscripten.
diff --git a/llvm/lib/TargetParser/Triple.cpp b/llvm/lib/TargetParser/Triple.cpp
index 11ba9ee32f66a..6bde5935f8ccf 100644
--- a/llvm/lib/TargetParser/Triple.cpp
+++ b/llvm/lib/TargetParser/Triple.cpp
@@ -324,6 +324,12 @@ StringRef Triple::getOSTypeName(OSType Kind) {
   case TvOS: return "tvos";
   case UEFI: return "uefi";
   case WASI: return "wasi";
+  case WASIp1:
+    return "wasip1";
+  case WASIp2:
+    return "wasip2";
+  case WASIp3:
+    return "wasip3";
   case WatchOS: return "watchos";
   case Win32: return "windows";
   case ZOS: return "zos";
@@ -735,6 +741,9 @@ static Triple::OSType parseOS(StringRef OSName) {
       .StartsWith("amdpal", Triple::AMDPAL)
       .StartsWith("hermit", Triple::HermitCore)
       .StartsWith("hurd", Triple::Hurd)
+      .StartsWith("wasip1", Triple::WASIp1)
+      .StartsWith("wasip2", Triple::WASIp2)
+      .StartsWith("wasip3", Triple::WASIp3)
       .StartsWith("wasi", Triple::WASI)
       .StartsWith("emscripten", Triple::Emscripten)
       .StartsWith("shadermodel", Triple::ShaderModel)
diff --git a/llvm/unittests/TargetParser/TripleTest.cpp b/llvm/unittests/TargetParser/TripleTest.cpp
index df8284d7be66a..b2e498ee10b30 100644
--- a/llvm/unittests/TargetParser/TripleTest.cpp
+++ b/llvm/unittests/TargetParser/TripleTest.cpp
@@ -614,6 +614,24 @@ TEST(TripleTest, ParsedIDs) {
   EXPECT_EQ(Triple::WASI, T.getOS());
   EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
 
+  T = Triple("wasm32-unknown-wasip1");
+  EXPECT_EQ(Triple::wasm32, T.getArch());
+  EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+  EXPECT_EQ(Triple::WASIp1, T.getOS());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
+  T = Triple("wasm32-unknown-wasip2");
+  EXPECT_EQ(Triple::wasm32, T.getArch());
+  EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+  EXPECT_EQ(Triple::WASIp2, T.getOS());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
+  T = Triple("wasm32-unknown-wasip3");
+  EXPECT_EQ(Triple::wasm32, T.getArch());
+  EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+  EXPECT_EQ(Triple::WASIp3, T.getOS());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
   T = Triple("wasm64-unknown-unknown");
   EXPECT_EQ(Triple::wasm64, T.getArch());
   EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
@@ -626,6 +644,24 @@ TEST(TripleTest, ParsedIDs) {
   EXPECT_EQ(Triple::WASI, T.getOS());
   EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
 
+  T = Triple("wasm64-unknown-wasip1");
+  EXPECT_EQ(Triple::wasm64, T.getArch());
+  EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+  EXPECT_EQ(Triple::WASIp1, T.getOS());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
+  T = Triple("wasm64-unknown-wasip2");
+  EXPECT_EQ(Triple::wasm64, T.getArch());
+  EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+  EXPECT_EQ(Triple::WASIp2, T.getOS());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
+  T = Triple("wasm64-unknown-wasip3");
+  EXPECT_EQ(Triple::wasm64, T.getArch());
+  EXPECT_EQ(Triple::UnknownVendor, T.getVendor());
+  EXPECT_EQ(Triple::WASIp3, T.getOS());
+  EXPECT_EQ(Triple::UnknownEnvironment, T.getEnvironment());
+
   T = Triple("avr-unknown-unknown");
   EXPECT_EQ(Triple::avr, T.getArch());
   EXPECT_EQ(Triple::UnknownVendor, T.getVendor());

@sunfishcode
Copy link
Member Author

I've now marked this ready for review.

Copy link
Member

@dschuff dschuff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from the WebAssembly side.

Copy link

@ricochet ricochet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM from the WASI side 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:driver 'clang' and 'clang++' user-facing binaries. Not 'clang-cl' clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Rename wasm32-wasi to wasm32-wasip1

4 participants