[llvm] [WebAssembly] Use SubtargetFeature's Implies field (PR #206643)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 29 21:46:18 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-webassembly
Author: Heejin Ahn (aheejin)
<details>
<summary>Changes</summary>
This makes use of `SubtargetFeature`'s `Implies` field, which lets us define feature dependencies:
https://github.com/llvm/llvm-project/blob/442c59c75ca384db53a6d6d81686b17ea4b397c3/llvm/include/llvm/Target/Target.td#L568-L571 and removes C++ code that specified feature dependencies.
These are the dependencies specified. EH dependencies are currently only specified in clang options, and others are specified in `WebAssemblySuttarget.cpp`.
- exception-handling implies multivalue and reference-types
- bulk-memory implifes bulk-memory-opt
- gc implies reference-types
- reference-types implies call-indirect-overlong
The features in `WebAssembly.td` were sorted in the alphabetical order, but this changes it because implied features have to come before the implying feature, e.g., multivalue and reference-types have to come before exception-handling.
---
One semantic difference from the current code, is, when reference-types implies call-indirect-overlong,
```console
llc -mattr=+reference-types,-call-indirect-overlong
```
this currently forces call-indirect-overlong to be true despite there is `-call-indirect-overlong`, because
https://github.com/llvm/llvm-project/blob/442c59c75ca384db53a6d6d81686b17ea4b397c3/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp#L63-L67
But with the `Implies` field, disabling call-indirect-overlong disabled both features, because TableGen thinks reference-types depends on call-indirect-overlong, so without call-indirect-overlong, reference-types can't be enabled. This is not exactly true with the relationship of reference-types and call-indirect-overlong, but generally makes sense for true dependencies, like exception-handling implying (=depending on) multivalue and reference-types.
Also this wouldn't really affect the end users because these are `llc` flags.
---
Full diff: https://github.com/llvm/llvm-project/pull/206643.diff
4 Files Affected:
- (modified) llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp (+1-12)
- (modified) llvm/lib/Target/WebAssembly/WebAssembly.td (+19-15)
- (modified) llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp (-22)
- (modified) llvm/test/MC/WebAssembly/function-alias.ll (+1-1)
``````````diff
diff --git a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
index f52833408fddb..475c73c6f81b2 100644
--- a/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
+++ b/llvm/lib/Target/WebAssembly/AsmParser/WebAssemblyAsmParser.cpp
@@ -305,18 +305,7 @@ class WebAssemblyAsmParser final : public MCTargetAsmParser {
: MCTargetAsmParser(STI, MII), Parser(Parser), Lexer(Parser.getLexer()),
Is64(STI.getTargetTriple().isArch64Bit()), TC(Parser, MII, Is64),
SkipTypeCheck(Parser.getContext().getTargetOptions().MCNoTypeCheck) {
- FeatureBitset FBS = ComputeAvailableFeatures(STI.getFeatureBits());
-
- // bulk-memory implies bulk-memory-opt
- if (FBS.test(WebAssembly::FeatureBulkMemory)) {
- FBS.set(WebAssembly::FeatureBulkMemoryOpt);
- }
- // reference-types implies call-indirect-overlong
- if (FBS.test(WebAssembly::FeatureReferenceTypes)) {
- FBS.set(WebAssembly::FeatureCallIndirectOverlong);
- }
-
- setAvailableFeatures(FBS);
+ setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
// Don't type check if this is inline asm, since that is a naked sequence of
// instructions without a function/locals decl.
auto &SM = Parser.getSourceManager();
diff --git a/llvm/lib/Target/WebAssembly/WebAssembly.td b/llvm/lib/Target/WebAssembly/WebAssembly.td
index 06cf468d02eba..979c3dd716ec4 100644
--- a/llvm/lib/Target/WebAssembly/WebAssembly.td
+++ b/llvm/lib/Target/WebAssembly/WebAssembly.td
@@ -25,21 +25,33 @@ include "llvm/Target/Target.td"
def FeatureAtomics : SubtargetFeature<"atomics", "HasAtomics", "true",
"Enable Atomics">;
-def FeatureBulkMemory :
- SubtargetFeature<"bulk-memory", "HasBulkMemory", "true",
- "Enable bulk memory operations">;
-
def FeatureBulkMemoryOpt :
SubtargetFeature<"bulk-memory-opt", "HasBulkMemoryOpt", "true",
"Enable bulk memory optimization operations">;
+def FeatureBulkMemory :
+ SubtargetFeature<"bulk-memory", "HasBulkMemory", "true",
+ "Enable bulk memory operations",
+ [FeatureBulkMemoryOpt]>;
+
def FeatureCallIndirectOverlong :
SubtargetFeature<"call-indirect-overlong", "HasCallIndirectOverlong", "true",
"Enable overlong encoding for call_indirect immediates">;
+def FeatureMultivalue :
+ SubtargetFeature<"multivalue",
+ "HasMultivalue", "true",
+ "Enable multivalue blocks, instructions, and functions">;
+
+def FeatureReferenceTypes :
+ SubtargetFeature<"reference-types", "HasReferenceTypes", "true",
+ "Enable reference types",
+ [FeatureCallIndirectOverlong]>;
+
def FeatureExceptionHandling :
SubtargetFeature<"exception-handling", "HasExceptionHandling", "true",
- "Enable Wasm exception handling">;
+ "Enable Wasm exception handling",
+ [FeatureMultivalue, FeatureReferenceTypes]>;
def FeatureExtendedConst :
SubtargetFeature<"extended-const", "HasExtendedConst", "true",
@@ -49,17 +61,13 @@ def FeatureFP16 :
SubtargetFeature<"fp16", "HasFP16", "true",
"Enable FP16 instructions">;
-def FeatureGC : SubtargetFeature<"gc", "HasGC", "true", "Enable wasm gc">;
+def FeatureGC : SubtargetFeature<"gc", "HasGC", "true", "Enable wasm gc",
+ [FeatureReferenceTypes]>;
def FeatureMultiMemory :
SubtargetFeature<"multimemory", "HasMultiMemory", "true",
"Enable multiple memories">;
-def FeatureMultivalue :
- SubtargetFeature<"multivalue",
- "HasMultivalue", "true",
- "Enable multivalue blocks, instructions, and functions">;
-
def FeatureMutableGlobals :
SubtargetFeature<"mutable-globals", "HasMutableGlobals", "true",
"Enable mutable globals">;
@@ -69,10 +77,6 @@ def FeatureNontrappingFPToInt :
"HasNontrappingFPToInt", "true",
"Enable non-trapping float-to-int conversion operators">;
-def FeatureReferenceTypes :
- SubtargetFeature<"reference-types", "HasReferenceTypes", "true",
- "Enable reference types">;
-
def FeatureRelaxedAtomics :
SubtargetFeature<"relaxed-atomics", "HasRelaxedAtomics", "true",
"Enable relaxed-atomics proposal">;
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
index 9dea29fb0205d..0dcee7c660da4 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp
@@ -47,28 +47,6 @@ WebAssemblySubtarget::initializeSubtargetDependencies(StringRef CPU,
HasLibcallThreadContext = true;
}
- FeatureBitset Bits = getFeatureBits();
-
- // bulk-memory implies bulk-memory-opt
- if (HasBulkMemory) {
- HasBulkMemoryOpt = true;
- Bits.set(WebAssembly::FeatureBulkMemoryOpt);
- }
-
- // gc implies reference-types
- if (HasGC) {
- HasReferenceTypes = true;
- }
-
- // reference-types implies call-indirect-overlong
- if (HasReferenceTypes) {
- HasCallIndirectOverlong = true;
- Bits.set(WebAssembly::FeatureCallIndirectOverlong);
- }
-
- // In case we changed any bits, update `MCSubtargetInfo`'s `FeatureBitset`.
- setFeatureBits(Bits);
-
return *this;
}
diff --git a/llvm/test/MC/WebAssembly/function-alias.ll b/llvm/test/MC/WebAssembly/function-alias.ll
index 3f76516a9bcc8..8aea27138765c 100644
--- a/llvm/test/MC/WebAssembly/function-alias.ll
+++ b/llvm/test/MC/WebAssembly/function-alias.ll
@@ -1,5 +1,5 @@
; RUN: llc -filetype=obj %s -mattr=-reference-types,-call-indirect-overlong -o - | llvm-readobj --symbols - | FileCheck %s
-; RUN: llc -filetype=obj %s -mattr=+reference-types,-call-indirect-overlong -o - | llvm-readobj --symbols - | FileCheck --check-prefix=REF %s
+; RUN: llc -filetype=obj %s -mattr=+reference-types -o - | llvm-readobj --symbols - | FileCheck --check-prefix=REF %s
target triple = "wasm32-unknown-unknown-wasm"
``````````
</details>
https://github.com/llvm/llvm-project/pull/206643
More information about the llvm-commits
mailing list