diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 2db1b6493cc476..981d28a7393394 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 00000000000000..0684432a114dfc --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/disable-feature.ll @@ -0,0 +1,53 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mattr=-sign-ext,-bulk-memory | FileCheck %s + +target triple = "wasm32-unknown-unknown" + +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 +; 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 +} + +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 +}