-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WebAssembly] Enable multivalue and reference-types in generic CPU config #80923
Conversation
This enables nontrapping-fptoint, multivlaue, reference-types, and bulk-memory in `-mcpu=generic` configuration. These proposals have been standardized and supported in all major browsers for several years at this point: https://github.com/WebAssembly/proposals/blob/main/finished-proposals.md
@llvm/pr-subscribers-clang Author: Heejin Ahn (aheejin) ChangesThis enables nontrapping-fptoint, multivlaue, reference-types, and bulk-memory in Full diff: https://github.com/llvm/llvm-project/pull/80923.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 802c44b6c86080..5a07dcca106876 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -259,6 +259,10 @@ AIX Support
WebAssembly Support
^^^^^^^^^^^^^^^^^^^
+The -mcpu=generic configuration now enables nontrapping-fptoint, multivalue,
+reference-types, and bulk-memory.These proposals are standardized and available
+in all major engines.
+
AVR Support
^^^^^^^^^^^
diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp
index f1c925d90cb649..38fe4013090f40 100644
--- a/clang/lib/Basic/Targets/WebAssembly.cpp
+++ b/clang/lib/Basic/Targets/WebAssembly.cpp
@@ -147,19 +147,25 @@ void WebAssemblyTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
bool WebAssemblyTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
- if (CPU == "bleeding-edge") {
- Features["nontrapping-fptoint"] = true;
+ auto addGenericFeatures = [&]() {
Features["sign-ext"] = true;
+ Features["mutable-globals"] = true;
+ Features["nontrapping-fptoint"] = true;
Features["bulk-memory"] = true;
+ Features["reference-types"] = true;
+ Features["multivalue"] = true;
+ };
+ auto addBleedingEdgeFeatures = [&]() {
Features["atomics"] = true;
- Features["mutable-globals"] = true;
Features["tail-call"] = true;
- Features["reference-types"] = true;
Features["multimemory"] = true;
setSIMDLevel(Features, SIMD128, true);
+ };
+ if (CPU == "bleeding-edge") {
+ addGenericFeatures();
+ addBleedingEdgeFeatures();
} else if (CPU == "generic") {
- Features["sign-ext"] = true;
- Features["mutable-globals"] = true;
+ addGenericFeatures();
}
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
diff --git a/clang/test/Preprocessor/wasm-target-features.c b/clang/test/Preprocessor/wasm-target-features.c
index eccd432aa8eee6..5834e6d183bc9c 100644
--- a/clang/test/Preprocessor/wasm-target-features.c
+++ b/clang/test/Preprocessor/wasm-target-features.c
@@ -155,15 +155,15 @@
//
// GENERIC-DAG:#define __wasm_sign_ext__ 1{{$}}
// GENERIC-DAG:#define __wasm_mutable_globals__ 1{{$}}
-// GENERIC-NOT:#define __wasm_nontrapping_fptoint__ 1{{$}}
-// GENERIC-NOT:#define __wasm_bulk_memory__ 1{{$}}
+// GENERIC-DAG:#define __wasm_nontrapping_fptoint__ 1{{$}}
+// GENERIC-DAG:#define __wasm_bulk_memory__ 1{{$}}
+// GENERIC-DAG:#define __wasm_multivalue__ 1{{$}}
+// GENERIC-DAG:#define __wasm_reference_types__ 1{{$}}
// GENERIC-NOT:#define __wasm_simd128__ 1{{$}}
// GENERIC-NOT:#define __wasm_atomics__ 1{{$}}
// GENERIC-NOT:#define __wasm_tail_call__ 1{{$}}
// GENERIC-NOT:#define __wasm_multimemory__ 1{{$}}
// GENERIC-NOT:#define __wasm_exception_handling__ 1{{$}}
-// GENERIC-NOT:#define __wasm_multivalue__ 1{{$}}
-// GENERIC-NOT:#define __wasm_reference_types__ 1{{$}}
// GENERIC-NOT:#define __wasm_extended_const__ 1{{$}}
// RUN: %clang -E -dM %s -o - 2>&1 \
|
@llvm/pr-subscribers-backend-webassembly Author: Heejin Ahn (aheejin) ChangesThis enables nontrapping-fptoint, multivlaue, reference-types, and bulk-memory in Full diff: https://github.com/llvm/llvm-project/pull/80923.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 802c44b6c86080..5a07dcca106876 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -259,6 +259,10 @@ AIX Support
WebAssembly Support
^^^^^^^^^^^^^^^^^^^
+The -mcpu=generic configuration now enables nontrapping-fptoint, multivalue,
+reference-types, and bulk-memory.These proposals are standardized and available
+in all major engines.
+
AVR Support
^^^^^^^^^^^
diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp
index f1c925d90cb649..38fe4013090f40 100644
--- a/clang/lib/Basic/Targets/WebAssembly.cpp
+++ b/clang/lib/Basic/Targets/WebAssembly.cpp
@@ -147,19 +147,25 @@ void WebAssemblyTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
bool WebAssemblyTargetInfo::initFeatureMap(
llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
const std::vector<std::string> &FeaturesVec) const {
- if (CPU == "bleeding-edge") {
- Features["nontrapping-fptoint"] = true;
+ auto addGenericFeatures = [&]() {
Features["sign-ext"] = true;
+ Features["mutable-globals"] = true;
+ Features["nontrapping-fptoint"] = true;
Features["bulk-memory"] = true;
+ Features["reference-types"] = true;
+ Features["multivalue"] = true;
+ };
+ auto addBleedingEdgeFeatures = [&]() {
Features["atomics"] = true;
- Features["mutable-globals"] = true;
Features["tail-call"] = true;
- Features["reference-types"] = true;
Features["multimemory"] = true;
setSIMDLevel(Features, SIMD128, true);
+ };
+ if (CPU == "bleeding-edge") {
+ addGenericFeatures();
+ addBleedingEdgeFeatures();
} else if (CPU == "generic") {
- Features["sign-ext"] = true;
- Features["mutable-globals"] = true;
+ addGenericFeatures();
}
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
diff --git a/clang/test/Preprocessor/wasm-target-features.c b/clang/test/Preprocessor/wasm-target-features.c
index eccd432aa8eee6..5834e6d183bc9c 100644
--- a/clang/test/Preprocessor/wasm-target-features.c
+++ b/clang/test/Preprocessor/wasm-target-features.c
@@ -155,15 +155,15 @@
//
// GENERIC-DAG:#define __wasm_sign_ext__ 1{{$}}
// GENERIC-DAG:#define __wasm_mutable_globals__ 1{{$}}
-// GENERIC-NOT:#define __wasm_nontrapping_fptoint__ 1{{$}}
-// GENERIC-NOT:#define __wasm_bulk_memory__ 1{{$}}
+// GENERIC-DAG:#define __wasm_nontrapping_fptoint__ 1{{$}}
+// GENERIC-DAG:#define __wasm_bulk_memory__ 1{{$}}
+// GENERIC-DAG:#define __wasm_multivalue__ 1{{$}}
+// GENERIC-DAG:#define __wasm_reference_types__ 1{{$}}
// GENERIC-NOT:#define __wasm_simd128__ 1{{$}}
// GENERIC-NOT:#define __wasm_atomics__ 1{{$}}
// GENERIC-NOT:#define __wasm_tail_call__ 1{{$}}
// GENERIC-NOT:#define __wasm_multimemory__ 1{{$}}
// GENERIC-NOT:#define __wasm_exception_handling__ 1{{$}}
-// GENERIC-NOT:#define __wasm_multivalue__ 1{{$}}
-// GENERIC-NOT:#define __wasm_reference_types__ 1{{$}}
// GENERIC-NOT:#define __wasm_extended_const__ 1{{$}}
// RUN: %clang -E -dM %s -o - 2>&1 \
|
Tried running Emscripten tests, and some of them fail with reference-types or bulk-memory. I haven't investigated the causes yet, but it could be better to start with the other two (nontrapping-fptoint and multivalue). |
No need to block these on emscripten failures.. I'm sure we can find and fix those. We should make this decision based on current browser stats and release dates I think, |
clang/docs/ReleaseNotes.rst
Outdated
@@ -259,6 +259,10 @@ AIX Support | |||
WebAssembly Support | |||
^^^^^^^^^^^^^^^^^^^ | |||
|
|||
The -mcpu=generic configuration now enables nontrapping-fptoint, multivalue, | |||
reference-types, and bulk-memory.These proposals are standardized and available | |||
in all major engines. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also mention that enabling multivalue here just means enabling the language feauture, and not changing the ABI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
We plan to enable multivalue in the features section soon (llvm#80923) for other reasons, such as the feature having been standardized for many years and other features being developed (e.g. EH) depending on it. This is separate from enabling Clang experimental multivalue ABI (`-Xclang -target-abi -Xclang experimental-mv`), but it turned out we generate some multivalue code in the backend as well if it is enabled in the features section. Given that our backend multivalue generation still has not been much used nor tested, and enabling the feature in the features section can be a separate decision from how much multialue (including none) we decide to generate for now, I'd like to temporarily disable the actual generation of multivalue in our backend. To do that, this adds an internal flag `-wasm-emit-multivalue` that defaults to false. All our existing multivalue tests can use this to test multivalue code. This flag can be removed later when we are confident the multivalue generation is well tested.
We plan to enable multivalue in the features section soon (#80923) for other reasons, such as the feature having been standardized for many years and other features being developed (e.g. EH) depending on it. This is separate from enabling Clang experimental multivalue ABI (`-Xclang -target-abi -Xclang experimental-mv`), but it turned out we generate some multivalue code in the backend as well if it is enabled in the features section. Given that our backend multivalue generation still has not been much used nor tested, and enabling the feature in the features section can be a separate decision from how much multialue (including none) we decide to generate for now, I'd like to temporarily disable the actual generation of multivalue in our backend. To do that, this adds an internal flag `-wasm-emit-multivalue` that defaults to false. All our existing multivalue tests can use this to test multivalue code. This flag can be removed later when we are confident the multivalue generation is well tested.
This first tried to enable four features (reference-types, multivalue, bulk-memory, and nontrapping-fptoint), but I think now we can enable the two first: reference-types and multivalue. These two were actually the first motivation I started this (these are necessary for the new EH spec adopted in Oct 2023). I believe I ran all emscripten tests with these two enabled and I don't think more tests fail than the current status quo. (We have some tests failing even now in the modes that are not regularly checked by CI, but enabling these two doesn't change that.) Usually, when we enable new features, we provide corresponding lowering passes in Binaryen to support legacy users. But I don't think that's necessary or even possible for these two. You can lower neither all multivalue-returning functions away (especially when they are imported or exported), nor reference types away. But I think it's fine, given that these two features are not really generated unless you opt into it, for example, by explicitly using I'll modify this PR to enable the two features (multivalue and reference-types) first. That way I think we can land this soon. WDYT? |
cc @kripken too (You didn't show up in the reviewers list, so I couldn't add you) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Enabling multivalue and reference-types first sgtm.
After this lands does that mean that all object files will have |
I think "generic" is the default CPU so object files will have it enabled by default. You can still specify "mvp" as the CPU as before to avoid it. |
}; | ||
auto addBleedingEdgeFeatures = [&]() { | ||
addGenericFeatures(); | ||
Features["nontrapping-fptoint"] = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like this was enabled in Safari in September 2021. Should we enable this by default as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see, if we think we would need a Binaryen lowering pass first, then proceeding without this SGTM.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit sad not to see this added, since this is the one that can actually improve codegen. If we know we want to enable to this, is there any downside to doing two different rounds (i.e. are there advantages to waiting on this until we have the lowering pass in place?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MV and reftypes are required to use exnref, that's the thing that's on the critical path here. So yes, we definitely want to land these two without blocking on nontrapping-fptoint.
Relatedly (to nontrapping-fptoint, but unrelatedly to this PR), I prototyped a Binaryen pass to lower away LLVM's use of nontrapping-fptoint* which is what would allow us to improve codegen. I think it works, but I discovered that some of emscripten's tests fail when we enable nontrapping fptoint, and I haven't yet looked at why that's the case (either a bug in emscripten's tests, or a bug in V8's implementation of nontrapping fptoint). We'd need to also fix that to unblock enabling this.
** (This isn't exactly the same as a full lowering of nontrapping-fptoint as spec'ed, because it takes advantage of knowledge of the semantics of LLVM's fptosi intrinsics)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(also LGTM FTR)
Co-authored-by: Alon Zakai <alonzakai@gmail.com>
llvm/llvm-project#80923 enabled multivalue and reference-types by default. Even though this is an LLVM change, given that we release emsdk with all LLVM/Binaryen/Emscripten versions, it could be worth mentioning in the ChangeLog.
llvm/llvm-project#80923 enabled multivalue and reference-types by default. Even though this is an LLVM change, given that we release emsdk with all LLVM/Binaryen/Emscripten versions, it could be worth mentioning in the ChangeLog.
llvm#80923 newly enabled multivalue and reference-types in the generic CPU. But enabling reference-types ended up breaking up Wasm's Chromium CI (https://chromium-review.googlesource.com/c/emscripten-releases/+/5500231) because the way the table index is encoded different from MVP (u32) vs. reference-types (LEB), which caused different encodings for `call_indirect`. And Chromium CI's and Emscripten's minimum required node version is v16, which does not yet support reference-types, which does not recognize that table index encoding. reference-types is first supported in node v17.2. We knew the current minimum required node for Emscripten (v16) did not support reference-types, but thought it was fine because unless you explicitly use `__funcref` or `__externref` things would be fine, and if you want to use them explicitly, you would have a newer node. But it turned out it also affected the encoding of `call_indirect`. While we are discussing the potential solutions, I will disable reference-types to unblock the rolls.
#80923 newly enabled multivalue and reference-types in the generic CPU. But enabling reference-types ended up breaking up Wasm's Chromium CI (https://chromium-review.googlesource.com/c/emscripten-releases/+/5500231) because the way the table index is encoded is different from MVP (u32) vs. reference-types (LEB), which caused different encodings for `call_indirect`. And Chromium CI's and Emscripten's minimum required node version is v16, which does not yet support reference-types, which does not recognize that table index encoding. reference-types is first supported in node v17.2. We knew the current minimum required node for Emscripten (v16) did not support reference-types, but thought it was fine because unless you explicitly use `__funcref` or `__externref` things would be fine, and if you want to use them explicitly, you would have a newer node. But it turned out it also affected the encoding of `call_indirect`. While we are discussing the potential solutions, I will disable reference-types to unblock the rolls.
I submitted emscripten-core#21853 before landing llvm/llvm-project#80923, so the previous version (3.1.59) was released before the LLVM change actually landed. And then we decided to disable reference-types temporarily (llvm/llvm-project#90792) while the node version is being resolved (emscripten-core/emsdk#1173 (comment)). This moves the entry to the current release and only mentions multivalue is the newly enabled feature.
I submitted #21853 before landing llvm/llvm-project#80923, so the previous version (3.1.59) was released before the LLVM change actually landed. And then we decided to disable reference-types temporarily (llvm/llvm-project#90792) while the node version is being resolved (emscripten-core/emsdk#1173 (comment)). This moves the entry to the current release and only mentions multivalue is the newly enabled feature.
This enables multivalue and reference-types in
-mcpu=generic
configuration. These proposals have been standardized and supported in all major browsers for several years at this point: https://github.com/WebAssembly/proposals/blob/main/finished-proposals.md