From 847dc39fd80130a8f3c82d1b3711fd30d070b54e Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Wed, 31 Jan 2024 11:14:35 +0800 Subject: [PATCH 1/3] [WebAssembly] avoid to use explicit disabled feature In `CoalesceFeaturesAndStripAtomics`, feature string is converted to FeatureBitset and back to feature string. It will lose information about explicit diasbled features. --- .../WebAssembly/WebAssemblyTargetMachine.cpp | 10 +++++++-- .../CodeGen/WebAssembly/disable-feature.ll | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/WebAssembly/disable-feature.ll diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 2db1b6493cc47..0aadc6aca228d 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -200,7 +200,8 @@ class CoalesceFeaturesAndStripAtomics final : public ModulePass { bool runOnModule(Module &M) override { FeatureBitset Features = coalesceFeatures(M); - std::string FeatureStr = getFeatureString(Features); + std::string FeatureStr = + getFeatureString(Features, WasmTM->getTargetFeatureString()); WasmTM->setTargetFeatureString(FeatureStr); for (auto &F : M) replaceFeatures(F, FeatureStr); @@ -238,12 +239,17 @@ class CoalesceFeaturesAndStripAtomics final : public ModulePass { return Features; } - std::string getFeatureString(const FeatureBitset &Features) { + static std::string getFeatureString(const FeatureBitset &Features, + StringRef TargetFS) { std::string Ret; for (const SubtargetFeatureKV &KV : WebAssemblyFeatureKV) { if (Features[KV.Value]) Ret += (StringRef("+") + KV.Key + ",").str(); } + SubtargetFeatures TF{TargetFS}; + for (std::string const &F : TF.getFeatures()) + if (!SubtargetFeatures::isEnabled(F)) + Ret += F; return Ret; } diff --git a/llvm/test/CodeGen/WebAssembly/disable-feature.ll b/llvm/test/CodeGen/WebAssembly/disable-feature.ll new file mode 100644 index 0000000000000..a9b07e2aaed5d --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/disable-feature.ll @@ -0,0 +1,22 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mattr=-sign-ext | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +define i8 @ashr(i8 %v, i8 %x) { +; CHECK-LABEL: ashr: +; CHECK: .functype ashr (i32, i32) -> (i32) +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: i32.const 24 +; CHECK-NEXT: i32.shl +; CHECK-NEXT: i32.const 24 +; CHECK-NEXT: i32.shr_s +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32.const 255 +; CHECK-NEXT: i32.and +; CHECK-NEXT: i32.shr_s +; CHECK-NEXT: # fallthrough-return + %a = ashr i8 %v, %x + ret i8 %a +} From 633fa951a1d7fc0ec2b83dc502deb43c0e6fb6cf Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Wed, 31 Jan 2024 12:27:03 +0800 Subject: [PATCH 2/3] fix --- llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 0aadc6aca228d..981d28a739339 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -249,7 +249,7 @@ class CoalesceFeaturesAndStripAtomics final : public ModulePass { SubtargetFeatures TF{TargetFS}; for (std::string const &F : TF.getFeatures()) if (!SubtargetFeatures::isEnabled(F)) - Ret += F; + Ret += F + ","; return Ret; } From 3edcb02a9393a341ec49c8ff40cf64c34c15b7b9 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Wed, 31 Jan 2024 14:16:49 +0800 Subject: [PATCH 3/3] add test case --- .../CodeGen/WebAssembly/disable-feature.ll | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/llvm/test/CodeGen/WebAssembly/disable-feature.ll b/llvm/test/CodeGen/WebAssembly/disable-feature.ll index a9b07e2aaed5d..0684432a114df 100644 --- a/llvm/test/CodeGen/WebAssembly/disable-feature.ll +++ b/llvm/test/CodeGen/WebAssembly/disable-feature.ll @@ -1,11 +1,11 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py -; RUN: llc < %s -mattr=-sign-ext | FileCheck %s +; RUN: llc < %s -mattr=-sign-ext,-bulk-memory | FileCheck %s target triple = "wasm32-unknown-unknown" -define i8 @ashr(i8 %v, i8 %x) { -; CHECK-LABEL: ashr: -; CHECK: .functype ashr (i32, i32) -> (i32) +define i8 @not_use_extend8_s(i8 %v, i8 %x) { +; CHECK-LABEL: not_use_extend8_s: +; CHECK: .functype not_use_extend8_s (i32, i32) -> (i32) ; CHECK-NEXT: # %bb.0: ; CHECK-NEXT: local.get 0 ; CHECK-NEXT: i32.const 24 @@ -20,3 +20,34 @@ define i8 @ashr(i8 %v, i8 %x) { %a = ashr i8 %v, %x ret i8 %a } + +attributes #0 = { "target-features"="+bulk-memory," } + +declare void @llvm.memset.p0.i32(ptr, i8, i32, i1) + +define void @lower_bulk_memory(i8 %val) #0 { +; CHECK-LABEL: lower_bulk_memory: +; CHECK: .functype lower_bulk_memory (i32) -> () +; CHECK-NEXT: .local i32 +; CHECK-NEXT: # %bb.0: +; CHECK-NEXT: global.get __stack_pointer +; CHECK-NEXT: i32.const 112 +; CHECK-NEXT: i32.sub +; CHECK-NEXT: local.tee 1 +; CHECK-NEXT: global.set __stack_pointer +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32.const 12 +; CHECK-NEXT: i32.add +; CHECK-NEXT: local.get 0 +; CHECK-NEXT: i32.const 100 +; CHECK-NEXT: call memset +; CHECK-NEXT: drop +; CHECK-NEXT: local.get 1 +; CHECK-NEXT: i32.const 112 +; CHECK-NEXT: i32.add +; CHECK-NEXT: global.set __stack_pointer +; CHECK-NEXT: # fallthrough-return + %a = alloca [100 x i8] + call void @llvm.memset.p0.i32(ptr %a, i8 %val, i32 100, i1 false) + ret void +}