llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-backend-webassembly Author: Matt Arsenault (arsenm) <details> <summary>Changes</summary> Previously this relied on the TargetABI MCOptions field and ignored the IR flag. Co-authored-by: Claude (Claude-Opus-4.8) <noreply@<!-- -->anthropic.com> --- Full diff: https://github.com/llvm/llvm-project/pull/224312.diff 10 Files Affected: - (modified) clang/lib/CodeGen/CodeGenModule.cpp (+1-1) - (added) clang/test/CodeGen/WebAssembly/target-abi-module-flag.c (+14) - (modified) llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp (+4-2) - (modified) llvm/lib/Target/WebAssembly/WebAssemblyCoalesceFeaturesAndStripAtomics.cpp (+2-1) - (modified) llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp (+4-3) - (modified) llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h (+7-1) - (modified) llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp (+11-6) - (modified) llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h (+2-5) - (modified) llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp (+2-4) - (added) llvm/test/CodeGen/WebAssembly/multivalue-module-abi.ll (+17) ``````````diff diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6fd2c8533eb061..3520e10dcda091 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1518,7 +1518,7 @@ void CodeGenModule::Release() { // non-empty value. if (StringRef ABIStr = Target.getABI(); !ABIStr.empty() && (T.isARM() || T.isThumb() || T.isRISCV() || - T.isPPC() || T.isLoongArch())) { + T.isPPC() || T.isLoongArch() || T.isWasm())) { getModule().addModuleFlag(llvm::Module::Error, "target-abi", llvm::MDString::get(VMContext, ABIStr)); } diff --git a/clang/test/CodeGen/WebAssembly/target-abi-module-flag.c b/clang/test/CodeGen/WebAssembly/target-abi-module-flag.c new file mode 100644 index 00000000000000..e0de201e7a67a8 --- /dev/null +++ b/clang/test/CodeGen/WebAssembly/target-abi-module-flag.c @@ -0,0 +1,14 @@ +// Check that clang emits the "target-abi" module flag for WebAssembly + +// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-abi experimental-mv -emit-llvm -o - %s | FileCheck --check-prefix=MULTIVALUE %s +// RUN: %clang_cc1 -triple wasm64-unknown-unknown -target-abi experimental-mv -emit-llvm -o - %s | FileCheck --check-prefix=MULTIVALUE %s +// RUN: %clang_cc1 -triple wasm32-unknown-unknown -target-abi mvp -emit-llvm -o - %s | FileCheck --check-prefix=MVP %s + +// No -target-abi: WebAssembly's default ABI is empty, so no flag is emitted. +// RUN: %clang_cc1 -triple wasm32-unknown-unknown -emit-llvm -o - %s | FileCheck --check-prefix=NONE %s + +// MULTIVALUE: !{i32 1, !"target-abi", !"experimental-mv"} +// MVP: !{i32 1, !"target-abi", !"mvp"} +// NONE-NOT: !"target-abi" + +int x; diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 6bb03c614af191..c20c6675f970cf 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -225,7 +225,8 @@ void WebAssemblyAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { // module-wide subtarget to compute legal value types. auto &WasmTM = static_cast<const WebAssemblyTargetMachine &>(TM); const WebAssemblySubtarget *ST = WasmTM.getSubtargetImpl( - WasmTM.getTargetCPU(), WasmTM.getTargetFeatureString()); + WasmTM.getTargetCPU(), WasmTM.getTargetFeatureString(), + WasmTM.getTargetABIName(*GV->getParent()) == "experimental-mv"); const WebAssemblyTargetLowering &TLI = *ST->getTargetLowering(); computeLegalValueVTs(TLI, GV->getParent()->getContext(), GV->getDataLayout(), GlobalVT, VTs); @@ -612,7 +613,8 @@ void WebAssemblyAsmPrinter::EmitTargetFeatures(Module &M) { // If we never compiled a single function, Subtarget is null. if (!Subtarget) { Subtarget = static_cast<WebAssemblyTargetMachine &>(TM).getSubtargetImpl( - TM.getTargetCPU(), TM.getTargetFeatureString()); + TM.getTargetCPU(), TM.getTargetFeatureString(), + TM.getTargetABIName(M) == "experimental-mv"); } for (const SubtargetFeatureKV &KV : Subtarget->getAllProcessorFeatures()) { EmitFeature(KV.key()); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyCoalesceFeaturesAndStripAtomics.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyCoalesceFeaturesAndStripAtomics.cpp index 08479e0f27617f..92eeff4bc477bc 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyCoalesceFeaturesAndStripAtomics.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyCoalesceFeaturesAndStripAtomics.cpp @@ -177,7 +177,8 @@ static bool coalesceFeaturesAndStripAtomics(Module &M, // In cooperative threading mode, thread locals are meaningful even without // atomics. const WebAssemblySubtarget *ST = WasmTM->getSubtargetImpl( - WasmTM->getTargetCPU(), WasmTM->getTargetFeatureString()); + WasmTM->getTargetCPU(), WasmTM->getTargetFeatureString(), + WasmTM->getTargetABIName(M) == "experimental-mv"); bool CooperativeThreading = ST->hasCooperativeMultithreading(); if (!Features[WebAssembly::FeatureAtomics]) { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp index 1f964259fd4cad..b16b47ccb5a86e 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.cpp @@ -52,10 +52,11 @@ WebAssemblySubtarget::initializeSubtargetDependencies(StringRef CPU, WebAssemblySubtarget::WebAssemblySubtarget(const Triple &TT, StringRef CPU, StringRef FS, - const TargetMachine &TM) + const TargetMachine &TM, + bool UsesMultivalueABI) : WebAssemblyGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS), - TargetTriple(TT), InstrInfo(initializeSubtargetDependencies(CPU, FS)), - TLInfo(TM, *this) { + TargetTriple(TT), UsesMultivalueABI(UsesMultivalueABI), + InstrInfo(initializeSubtargetDependencies(CPU, FS)), TLInfo(TM, *this) { CallLoweringInfo.reset(new WebAssemblyCallLowering(*getTargetLowering())); Legalizer.reset(new WebAssemblyLegalizerInfo(*this)); auto *RBI = new WebAssemblyRegisterBankInfo(*getRegisterInfo()); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h index 149c49dd344731..f9ecf561134f03 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblySubtarget.h @@ -63,6 +63,10 @@ class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo { /// What processor and OS we're targeting. Triple TargetTriple; + /// Whether the multivalue ABI is in use, derived from the "target-abi" module + /// flag. + bool UsesMultivalueABI = false; + WebAssemblyFrameLowering FrameLowering; WebAssemblyInstrInfo InstrInfo; WebAssemblySelectionDAGInfo TSInfo; @@ -80,7 +84,7 @@ class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo { /// This constructor initializes the data members to match that /// of the specified triple. WebAssemblySubtarget(const Triple &TT, StringRef CPU, StringRef FS, - const TargetMachine &TM); + const TargetMachine &TM, bool UsesMultivalueABI); const WebAssemblySelectionDAGInfo *getSelectionDAGInfo() const override { return &TSInfo; @@ -130,6 +134,8 @@ class WebAssemblySubtarget final : public WebAssemblyGenSubtargetInfo { bool hasTailCall() const { return HasTailCall; } bool hasWideArithmetic() const { return HasWideArithmetic; } + bool usesMultivalueABI() const { return UsesMultivalueABI; } + /// Parses features string setting specified subtarget options. Definition of /// function is auto generated by tblgen. void ParseSubtargetFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS); diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp index 066e8329e7f39d..a732049357a7f9 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.cpp @@ -190,8 +190,7 @@ WebAssemblyTargetMachine::WebAssemblyTargetMachine( : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options, getEffectiveRelocModel(RM), getEffectiveCodeModel(CM, CodeModel::Large), OL), - TLOF(new WebAssemblyTargetObjectFile()), - UsesMultivalueABI(Options.MCOptions.getABIName() == "experimental-mv") { + TLOF(new WebAssemblyTargetObjectFile()) { // WebAssembly type-checks instructions, but a noreturn function with a return // type that doesn't match the context will cause a check failure. So we lower // LLVM 'unreachable' to ISD::TRAP and then lower that to WebAssembly's @@ -221,10 +220,13 @@ WebAssemblyTargetMachine::WebAssemblyTargetMachine( WebAssemblyTargetMachine::~WebAssemblyTargetMachine() = default; // anchor. const WebAssemblySubtarget * -WebAssemblyTargetMachine::getSubtargetImpl(StringRef CPU, StringRef FS) const { - auto &I = SubtargetMap[CPU.str() + FS.str()]; +WebAssemblyTargetMachine::getSubtargetImpl(StringRef CPU, StringRef FS, + bool UsesMultivalueABI) const { + auto &I = + SubtargetMap[CPU.str() + FS.str() + (UsesMultivalueABI ? "+mv" : "")]; if (!I) { - I = std::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this); + I = std::make_unique<WebAssemblySubtarget>(TargetTriple, CPU, FS, *this, + UsesMultivalueABI); } return I.get(); } @@ -237,7 +239,10 @@ WebAssemblyTargetMachine::getSubtargetImpl(const Function &F) const { StringRef CPU = CPUAttr.isValid() ? CPUAttr.getValueAsString() : TargetCPU; StringRef FS = FSAttr.isValid() ? FSAttr.getValueAsString() : TargetFS; - return getSubtargetImpl(CPU, FS); + bool UsesMultivalueABI = + getTargetABIName(*F.getParent()) == "experimental-mv"; + + return getSubtargetImpl(CPU, FS, UsesMultivalueABI); } namespace { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h index f21dc4b81dda45..cb35cea91de324 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h +++ b/llvm/lib/Target/WebAssembly/WebAssemblyTargetMachine.h @@ -33,7 +33,6 @@ extern cl::opt<bool> WasmUseLegacyEH; // Legacy Wasm EH class WebAssemblyTargetMachine final : public CodeGenTargetMachineImpl { std::unique_ptr<TargetLoweringObjectFile> TLOF; mutable StringMap<std::unique_ptr<WebAssemblySubtarget>> SubtargetMap; - bool UsesMultivalueABI = false; public: WebAssemblyTargetMachine(const Target &T, const Triple &TT, StringRef CPU, @@ -44,8 +43,8 @@ class WebAssemblyTargetMachine final : public CodeGenTargetMachineImpl { ~WebAssemblyTargetMachine() override; - const WebAssemblySubtarget *getSubtargetImpl(StringRef CPU, - StringRef FS) const; + const WebAssemblySubtarget *getSubtargetImpl(StringRef CPU, StringRef FS, + bool UsesMultivalueABI) const; const WebAssemblySubtarget * getSubtargetImpl(const Function &F) const override; @@ -72,8 +71,6 @@ class WebAssemblyTargetMachine final : public CodeGenTargetMachineImpl { SMDiagnostic &Error, SMRange &SourceRange) const override; - bool usesMultivalueABI() const { return UsesMultivalueABI; } - void registerPassBuilderCallbacks(PassBuilder &PbB) override; Error buildCodeGenPipeline(ModulePassManager &MPM, ModuleAnalysisManager &MAM, diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp index ac8df67fe7557c..4c0a776e3a750f 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyUtilities.cpp @@ -13,7 +13,7 @@ #include "WebAssemblyUtilities.h" #include "WebAssemblyMachineFunctionInfo.h" -#include "WebAssemblyTargetMachine.h" +#include "WebAssemblySubtarget.h" #include "llvm/CodeGen/MachineInstr.h" #include "llvm/IR/Function.h" #include "llvm/MC/MCContext.h" @@ -185,9 +185,7 @@ unsigned WebAssembly::getCopyOpcodeForRegClass(const TargetRegisterClass *RC) { bool WebAssembly::canLowerMultivalueReturn( const WebAssemblySubtarget *Subtarget) { - const auto &TM = static_cast<const WebAssemblyTargetMachine &>( - Subtarget->getTargetLowering()->getTargetMachine()); - return Subtarget->hasMultivalue() && TM.usesMultivalueABI(); + return Subtarget->hasMultivalue() && Subtarget->usesMultivalueABI(); } bool WebAssembly::canLowerReturn(size_t ResultSize, diff --git a/llvm/test/CodeGen/WebAssembly/multivalue-module-abi.ll b/llvm/test/CodeGen/WebAssembly/multivalue-module-abi.ll new file mode 100644 index 00000000000000..c27e464ef55c56 --- /dev/null +++ b/llvm/test/CodeGen/WebAssembly/multivalue-module-abi.ll @@ -0,0 +1,17 @@ +; RUN: llc -mattr=+multivalue < %s | FileCheck %s + +; Test that the multivalue ABI can be selected via the "target-abi" +; module flag + +target triple = "wasm32-unknown-unknown" + +%pair = type { i32, i64 } + +; CHECK-LABEL: pair_const: +; CHECK-NEXT: .functype pair_const () -> (i32, i64) +define %pair @pair_const() { + ret %pair { i32 42, i64 42 } +} + +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"target-abi", !"experimental-mv"} `````````` </details> https://github.com/llvm/llvm-project/pull/224312 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
