https://github.com/Changqing-JING updated https://github.com/llvm/llvm-project/pull/221909
>From cd8486de0e3d4fd9e8b61dddc00681aabf0c071f Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Tue, 8 Sep 2026 15:42:28 +0800 Subject: [PATCH 1/3] [Clang][WebAssembly] Add wasm_global declaration attribute --- clang/include/clang/Basic/Attr.td | 6 ++++++ clang/include/clang/Basic/AttrDocs.td | 12 ++++++++++++ clang/include/clang/Sema/SemaWasm.h | 1 + clang/lib/CodeGen/Targets/WebAssembly.cpp | 9 +++++++++ clang/lib/Sema/SemaDeclAttr.cpp | 3 +++ clang/lib/Sema/SemaWasm.cpp | 10 ++++++++++ .../WebAssembly/wasm-global-attribute.cpp | 16 ++++++++++++++++ .../llvm/Support}/WasmAddressSpaces.h | 14 ++++++-------- .../WebAssembly/Utils/WebAssemblyTypeUtilities.h | 2 +- .../Target/WebAssembly/WebAssemblyFastISel.cpp | 2 +- .../WebAssembly/WebAssemblyRefTypeMem2Local.cpp | 2 +- 11 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp rename llvm/{lib/Target/WebAssembly/Utils => include/llvm/Support}/WasmAddressSpaces.h (73%) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index a576411097b9d..f4c04614092ba 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2602,6 +2602,12 @@ def WebAssemblyImportName : InheritableAttr, let Subjects = SubjectList<[Function, GlobalVar], ErrorDiag>; } +def WebAssemblyGlobal : InheritableAttr, TargetSpecificAttr<TargetWebAssembly> { + let Spellings = [Clang<"wasm_global">]; + let Documentation = [WebAssemblyGlobalDocs]; + let Subjects = SubjectList<[GlobalVar], ErrorDiag>; +} + def NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 285cf02c047cd..23f3c688ea707 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7340,6 +7340,18 @@ request a specific field name be used instead. }]; } +def WebAssemblyGlobalDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +Clang supports the `[[clang::wasm_global]]` attribute for the WebAssembly +target. This attribute declares that a variable is stored as a WebAssembly +global rather than in linear memory. + +WebAssembly globals can be imported or exported using the +`import_module`, `import_name`, and `export_name` attributes. + }]; +} + def ArtificialDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Sema/SemaWasm.h b/clang/include/clang/Sema/SemaWasm.h index c70cda259029e..41245ef649e84 100644 --- a/clang/include/clang/Sema/SemaWasm.h +++ b/clang/include/clang/Sema/SemaWasm.h @@ -50,6 +50,7 @@ class SemaWasm : public SemaBase { void handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL); void handleWebAssemblyImportModuleAttr(Decl *D, const ParsedAttr &AL); void handleWebAssemblyImportNameAttr(Decl *D, const ParsedAttr &AL); + void handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL); }; } // namespace clang diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp index 8f6f58bfb807e..f51edfc620baa 100644 --- a/clang/lib/CodeGen/Targets/WebAssembly.cpp +++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp @@ -9,6 +9,7 @@ #include "ABIInfoImpl.h" #include "TargetInfo.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "llvm/Support/WasmAddressSpaces.h" using namespace clang; using namespace clang::CodeGen; @@ -55,6 +56,14 @@ class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo { std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false); } + LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, + const VarDecl *D) const override { + if (D && D->hasAttr<WebAssemblyGlobalAttr>()) + return getLangASFromTargetAS( + llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); + return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D); + } + void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const override { TargetCodeGenInfo::setTargetAttributes(D, GV, CGM); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index d4206acd060a0..0cca26219475a 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7750,6 +7750,9 @@ ProcessDeclAttribute(Sema &S, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_WebAssemblyImportName: S.Wasm().handleWebAssemblyImportNameAttr(D, AL); break; + case ParsedAttr::AT_WebAssemblyGlobal: + S.Wasm().handleWebAssemblyGlobalAttr(D, AL); + break; case ParsedAttr::AT_IBOutlet: S.ObjC().handleIBOutlet(D, AL); break; diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index cfc0a08a50e5a..d0fae91fa4727 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/TargetInfo.h" #include "clang/Sema/Attr.h" #include "clang/Sema/Sema.h" +#include "llvm/Support/WasmAddressSpaces.h" namespace clang { @@ -457,4 +458,13 @@ void SemaWasm::handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL) { D->addAttr(UsedAttr::CreateImplicit(Context)); } +void SemaWasm::handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL) { + ASTContext &Context = getASTContext(); + auto *VD = cast<VarDecl>(D); + VD->setType(Context.getAddrSpaceQualType( + VD->getType(), getLangASFromTargetAS( + llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR))); + D->addAttr(::new (Context) WebAssemblyGlobalAttr(Context, AL)); +} + } // namespace clang diff --git a/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp b/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp new file mode 100644 index 0000000000000..e61056d9ba848 --- /dev/null +++ b/clang/test/CodeGen/WebAssembly/wasm-global-attribute.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -triple wasm32-unknown-unknown-wasm -emit-llvm -o - %s | FileCheck %s + +extern "C" { +int exported_g [[clang::wasm_global]] = 42; + +extern const int imported_g [[clang::wasm_global]] + __attribute__((import_module("env"), import_name("imported_g"))); + +int get_import(void) { return imported_g; } +} + +// CHECK: @exported_g = addrspace(1) global i32 42, align 4 +// CHECK: @imported_g = external addrspace(1) constant i32, align 4 #0 +// CHECK: define{{.*}} @get_import() +// CHECK: load i32, ptr addrspace(1) @imported_g +// CHECK: attributes #0 = { "wasm-import-module"="env" "wasm-import-name"="imported_g" } \ No newline at end of file diff --git a/llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h b/llvm/include/llvm/Support/WasmAddressSpaces.h similarity index 73% rename from llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h rename to llvm/include/llvm/Support/WasmAddressSpaces.h index d2ab2c0f9e777..8738b4e88520d 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WasmAddressSpaces.h +++ b/llvm/include/llvm/Support/WasmAddressSpaces.h @@ -1,4 +1,4 @@ -//===--- llvm/CodeGen/WasmAddressSpaces.h -----------------------*- C++ -*-===// +//===---------------- WasmAddressSpaces.h ----------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,22 +6,21 @@ // //===----------------------------------------------------------------------===// // -// Address Spaces for WebAssembly Type Handling +// Address spaces for WebAssembly IR and type handling. // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WASMADDRESSSPACES_H -#define LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WASMADDRESSSPACES_H +#ifndef LLVM_SUPPORT_WASMADDRESSSPACES_H +#define LLVM_SUPPORT_WASMADDRESSSPACES_H namespace llvm { - namespace WebAssembly { enum WasmAddressSpace : unsigned { // Default address space, for pointers to linear memory (stack, heap, data). WASM_ADDRESS_SPACE_DEFAULT = 0, // A non-integral address space for pointers to named objects outside of - // linear memory: WebAssembly globals or WebAssembly locals. Loads and stores + // linear memory: WebAssembly globals or WebAssembly locals. Loads and stores // to these pointers are lowered to global.get / global.set or local.get / // local.set, as appropriate. WASM_ADDRESS_SPACE_VAR = 1 @@ -38,7 +37,6 @@ inline bool isValidAddressSpace(unsigned AS) { } } // namespace WebAssembly - } // namespace llvm -#endif // LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WASMADDRESSSPACES_H +#endif // LLVM_SUPPORT_WASMADDRESSSPACES_H \ No newline at end of file diff --git a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h index 47ba91df81161..72342393e410a 100644 --- a/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h +++ b/llvm/lib/Target/WebAssembly/Utils/WebAssemblyTypeUtilities.h @@ -16,11 +16,11 @@ #define LLVM_LIB_TARGET_WEBASSEMBLY_UTILS_WEBASSEMBLYTYPEUTILITIES_H #include "MCTargetDesc/WebAssemblyMCTypeUtilities.h" -#include "WasmAddressSpaces.h" #include "llvm/BinaryFormat/Wasm.h" #include "llvm/CodeGenTypes/MachineValueType.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/MC/MCSymbolWasm.h" +#include "llvm/Support/WasmAddressSpaces.h" namespace llvm { diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index db03f5874234c..075330081b5ca 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -16,7 +16,6 @@ //===----------------------------------------------------------------------===// #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" -#include "Utils/WasmAddressSpaces.h" #include "WebAssemblyMachineFunctionInfo.h" #include "WebAssemblySubtarget.h" #include "WebAssemblyUtilities.h" @@ -33,6 +32,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalVariable.h" +#include "llvm/Support/WasmAddressSpaces.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsWebAssembly.h" #include "llvm/IR/Operator.h" diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRefTypeMem2Local.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRefTypeMem2Local.cpp index 2c162308700af..6fdb04760514e 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyRefTypeMem2Local.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyRefTypeMem2Local.cpp @@ -12,7 +12,6 @@ /// //===----------------------------------------------------------------------===// -#include "Utils/WasmAddressSpaces.h" #include "Utils/WebAssemblyTypeUtilities.h" #include "WebAssembly.h" #include "llvm/IR/Analysis.h" @@ -22,6 +21,7 @@ #include "llvm/IR/PassManager.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Pass.h" +#include "llvm/Support/WasmAddressSpaces.h" using namespace llvm; #define DEBUG_TYPE "wasm-ref-type-mem2local" >From dbfb4e5ab68181c99c3c3f097dedad4a948aaf9a Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Tue, 8 Sep 2026 15:56:09 +0800 Subject: [PATCH 2/3] Fix --- clang/lib/CodeGen/Targets/WebAssembly.cpp | 3 +-- clang/lib/Sema/SemaWasm.cpp | 4 ++-- llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp index f51edfc620baa..05f2391dc7e38 100644 --- a/clang/lib/CodeGen/Targets/WebAssembly.cpp +++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp @@ -59,8 +59,7 @@ class WebAssemblyTargetCodeGenInfo final : public TargetCodeGenInfo { LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const override { if (D && D->hasAttr<WebAssemblyGlobalAttr>()) - return getLangASFromTargetAS( - llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); + return getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR); return TargetCodeGenInfo::getGlobalVarAddressSpace(CGM, D); } diff --git a/clang/lib/Sema/SemaWasm.cpp b/clang/lib/Sema/SemaWasm.cpp index d0fae91fa4727..42c8957585ea0 100644 --- a/clang/lib/Sema/SemaWasm.cpp +++ b/clang/lib/Sema/SemaWasm.cpp @@ -462,8 +462,8 @@ void SemaWasm::handleWebAssemblyGlobalAttr(Decl *D, const ParsedAttr &AL) { ASTContext &Context = getASTContext(); auto *VD = cast<VarDecl>(D); VD->setType(Context.getAddrSpaceQualType( - VD->getType(), getLangASFromTargetAS( - llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR))); + VD->getType(), + getLangASFromTargetAS(llvm::WebAssembly::WASM_ADDRESS_SPACE_VAR))); D->addAttr(::new (Context) WebAssemblyGlobalAttr(Context, AL)); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp index 075330081b5ca..3eea32411a808 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp @@ -32,10 +32,10 @@ #include "llvm/IR/Function.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalVariable.h" -#include "llvm/Support/WasmAddressSpaces.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicsWebAssembly.h" #include "llvm/IR/Operator.h" +#include "llvm/Support/WasmAddressSpaces.h" using namespace llvm; >From 6ef09373116ab5b09e2b306d92869ef8c9742f94 Mon Sep 17 00:00:00 2001 From: Changqing Jing <[email protected]> Date: Wed, 9 Sep 2026 14:51:25 +0800 Subject: [PATCH 3/3] fix --- clang/test/Misc/pragma-attribute-supported-attributes-list.test | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 8f8c1aa3d3f9c..2285f3602b863 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -236,6 +236,7 @@ // CHECK-NEXT: Weak (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record) // CHECK-NEXT: WeakRef (SubjectMatchRule_variable, SubjectMatchRule_function) // CHECK-NEXT: WebAssemblyExportName (SubjectMatchRule_function, SubjectMatchRule_variable_is_global) +// CHECK-NEXT: WebAssemblyGlobal (SubjectMatchRule_variable_is_global) // CHECK-NEXT: WebAssemblyImportModule (SubjectMatchRule_function, SubjectMatchRule_variable_is_global) // CHECK-NEXT: WebAssemblyImportName (SubjectMatchRule_function, SubjectMatchRule_variable_is_global) // CHECK-NEXT: WorkGroupSizeHint (SubjectMatchRule_function) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
