[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