-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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 simd128 when relaxed-simd is set in AsmPrinter #99803
Conversation
Even though in `Subtarget` we defined `SIMDLevel` as a number so `hasRelaxedSIMD` automatically means `hasSIMD128`, https://github.com/llvm/llvm-project/blob/0caf0c93e759816663af52e8632d1c3953dbc715/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h#L36-L40 https://github.com/llvm/llvm-project/blob/0caf0c93e759816663af52e8632d1c3953dbc715/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h#L107 specifying only `relaxed-simd` feature on a program that needs `simd128` instructions to compile fails, because of this query in `AsmPrinter`: https://github.com/llvm/llvm-project/blob/d0d05aec3b6792136a9f75eb85dd2ea66005ae12/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp#L644-L645 This `verifyInstructionPredicates` function (and other functions called by this function) is generated by https://github.com/llvm/llvm-project/blob/main/llvm/utils/TableGen/InstrInfoEmitter.cpp, and looks like this (you can check it in the `lib/Target/WebAssembly/WebAssemblyGenInstrInfo.inc` in your build directory): ```cpp void verifyInstructionPredicates( unsigned Opcode, const FeatureBitset &Features) { FeatureBitset AvailableFeatures = computeAvailableFeatures(Features); FeatureBitset RequiredFeatures = computeRequiredFeatures(Opcode); FeatureBitset MissingFeatures = (AvailableFeatures & RequiredFeatures) ^ RequiredFeatures; ... } ``` And `computeAvailableFeatures` there is just a set query, like this: ```cpp inline FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) { FeatureBitset Features; if (FB[WebAssembly::FeatureAtomics]) Features.set(Feature_HasAtomicsBit); if (FB[WebAssembly::FeatureBulkMemory]) Features.set(Feature_HasBulkMemoryBit); if (FB[WebAssembly::FeatureExceptionHandling]) Features.set(Feature_HasExceptionHandlingBit); ... ``` So this is how currently `HasSIMD128` is defined: https://github.com/llvm/llvm-project/blob/0caf0c93e759816663af52e8632d1c3953dbc715/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td#L79-L81 The things being checked in this `computeAvailableFeatures`, and in turn in `AsmPrinter`, are `AssemblerPredicate`s. These only check which bits are set in the features set and are different from `Predicate`s, which can call `Subtarget` functions like `Subtarget->hasSIMD128()`. But apparently we can use `all_of` and `any_of` directives in `AssemblerPredicate`, and we can make `simd128`'s `AssemblerPredicate` set in `relaxed-simd` is set by the condition as an 'or' of the two. Fixes llvm#98502.
@llvm/pr-subscribers-backend-webassembly Author: Heejin Ahn (aheejin) ChangesEven though in llvm-project/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h Lines 36 to 40 in 0caf0c9
specifying only llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp Lines 644 to 645 in d0d05ae
This void verifyInstructionPredicates(
unsigned Opcode, const FeatureBitset &Features) {
FeatureBitset AvailableFeatures = computeAvailableFeatures(Features);
FeatureBitset RequiredFeatures = computeRequiredFeatures(Opcode);
FeatureBitset MissingFeatures =
(AvailableFeatures & RequiredFeatures) ^
RequiredFeatures;
...
} And inline FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) {
FeatureBitset Features;
if (FB[WebAssembly::FeatureAtomics])
Features.set(Feature_HasAtomicsBit);
if (FB[WebAssembly::FeatureBulkMemory])
Features.set(Feature_HasBulkMemoryBit);
if (FB[WebAssembly::FeatureExceptionHandling])
Features.set(Feature_HasExceptionHandlingBit);
... So this is how currently llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td Lines 79 to 81 in 0caf0c9
The things being checked in this But apparently we can use Fixes #98502. Full diff: https://github.com/llvm/llvm-project/pull/99803.diff 2 Files Affected:
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
index 3d37eb2fa27bc..bb36ce7650183 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
@@ -78,7 +78,7 @@ def HasSignExt :
def HasSIMD128 :
Predicate<"Subtarget->hasSIMD128()">,
- AssemblerPredicate<(all_of FeatureSIMD128), "simd128">;
+ AssemblerPredicate<(any_of FeatureSIMD128, FeatureRelaxedSIMD), "simd128">;
def HasTailCall :
Predicate<"Subtarget->hasTailCall()">,
diff --git a/llvm/test/CodeGen/WebAssembly/simd-asm-pred.ll b/llvm/test/CodeGen/WebAssembly/simd-asm-pred.ll
new file mode 100644
index 0000000000000..f022c3e745125
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/simd-asm-pred.ll
@@ -0,0 +1,24 @@
+; RUN: llc < %s -verify-machineinstrs -mattr=+relaxed-simd | FileCheck %s
+
+; Test that setting "relaxed-simd" target feature set also implies 'simd128' in
+; AssemblerPredicate, which is used to verify instructions in AsmPrinter.
+
+target triple = "wasm32-unknown-unknown"
+
+declare <2 x i64> @llvm.wasm.relaxed.laneselect.v2i64(<2 x i64>, <2 x i64>, <2 x i64>)
+
+; The compiled result of this function uses LOCAL_GET_V128, which is predicated
+; on the 'simd128' feature. We should be able to compile this when only
+; 'relaxed-simd' is set, which implies 'simd128'.
+define <2 x i64> @test(<2 x i64>, <2 x i64>, <2 x i64>) #0 {
+; CHECK-LABEL: test:
+; CHECK: .functype test (v128, v128, v128) -> (v128)
+; CHECK-NEXT: # %bb.0:
+; CHECK-NEXT: local.get 0
+; CHECK-NEXT: local.get 1
+; CHECK-NEXT: local.get 2
+; CHECK-NEXT: i64x2.relaxed_laneselect
+start:
+ %_4 = tail call <2 x i64> @llvm.wasm.relaxed.laneselect.v2i64(<2 x i64> %0, <2 x i64> %1, <2 x i64> %2) #3
+ ret <2 x i64> %_4
+}
|
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.
Thanks, @aheejin!
Will merge this; the CI failure doesn't seem to be related. |
…99803) Summary: Even though in `Subtarget` we defined `SIMDLevel` as a number so `hasRelaxedSIMD` automatically means `hasSIMD128`, https://github.com/llvm/llvm-project/blob/0caf0c93e759816663af52e8632d1c3953dbc715/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h#L36-L40 https://github.com/llvm/llvm-project/blob/0caf0c93e759816663af52e8632d1c3953dbc715/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h#L107 specifying only `relaxed-simd` feature on a program that needs `simd128` instructions to compile fails, because of this query in `AsmPrinter`: https://github.com/llvm/llvm-project/blob/d0d05aec3b6792136a9f75eb85dd2ea66005ae12/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp#L644-L645 This `verifyInstructionPredicates` function (and other functions called by this function) is generated by https://github.com/llvm/llvm-project/blob/main/llvm/utils/TableGen/InstrInfoEmitter.cpp, and looks like this (you can check it in the `lib/Target/WebAssembly/WebAssemblyGenInstrInfo.inc` in your build directory): ```cpp void verifyInstructionPredicates( unsigned Opcode, const FeatureBitset &Features) { FeatureBitset AvailableFeatures = computeAvailableFeatures(Features); FeatureBitset RequiredFeatures = computeRequiredFeatures(Opcode); FeatureBitset MissingFeatures = (AvailableFeatures & RequiredFeatures) ^ RequiredFeatures; ... } ``` And `computeAvailableFeatures` is just a set query, like this: ```cpp inline FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) { FeatureBitset Features; if (FB[WebAssembly::FeatureAtomics]) Features.set(Feature_HasAtomicsBit); if (FB[WebAssembly::FeatureBulkMemory]) Features.set(Feature_HasBulkMemoryBit); if (FB[WebAssembly::FeatureExceptionHandling]) Features.set(Feature_HasExceptionHandlingBit); ... ``` So this is how currently `HasSIMD128` is defined: https://github.com/llvm/llvm-project/blob/0caf0c93e759816663af52e8632d1c3953dbc715/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td#L79-L81 The things being checked in this `computeAvailableFeatures`, and in turn in `AsmPrinter`, are `AssemblerPredicate`s. These only check which bits are set in the features set and are different from `Predicate`s, which can call `Subtarget` functions like `Subtarget->hasSIMD128()`. But apparently we can use `all_of` and `any_of` directives in `AssemblerPredicate`, and we can make `simd128`'s `AssemblerPredicate` set in `relaxed-simd` is set by the condition as an 'or' of the two. Fixes #98502. Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D60250795
Even though in
Subtarget
we definedSIMDLevel
as a number sohasRelaxedSIMD
automatically meanshasSIMD128
,llvm-project/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
Lines 36 to 40 in 0caf0c9
llvm-project/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h
Line 107 in 0caf0c9
specifying only
relaxed-simd
feature on a program that needssimd128
instructions to compile fails, because of this query inAsmPrinter
:llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
Lines 644 to 645 in d0d05ae
This
verifyInstructionPredicates
function (and other functions called by this function) is generated byhttps://github.com/llvm/llvm-project/blob/main/llvm/utils/TableGen/InstrInfoEmitter.cpp, and looks like this (you can check it in the
lib/Target/WebAssembly/WebAssemblyGenInstrInfo.inc
in your build directory):And
computeAvailableFeatures
is just a set query, like this:So this is how currently
HasSIMD128
is defined:llvm-project/llvm/lib/Target/WebAssembly/WebAssemblyInstrInfo.td
Lines 79 to 81 in 0caf0c9
The things being checked in this
computeAvailableFeatures
, and in turn inAsmPrinter
, areAssemblerPredicate
s. These only check which bits are set in the features set and are different fromPredicate
s, which can callSubtarget
functions likeSubtarget->hasSIMD128()
.But apparently we can use
all_of
andany_of
directives inAssemblerPredicate
, and we can makesimd128
'sAssemblerPredicate
set inrelaxed-simd
is set by the condition as an 'or' of the two.Fixes #98502.