https://github.com/bcardosolopes updated https://github.com/llvm/llvm-project/pull/179826
>From 093dce7e02a8d55979812e850e0488709621d51a Mon Sep 17 00:00:00 2001 From: Bruno Cardoso Lopes <[email protected]> Date: Fri, 30 Jan 2026 22:47:52 -0800 Subject: [PATCH] [CIR] Add static_local attribute to GlobalOp and GetGlobalOp This attribute marks function-local static variables that require guarded initialization (e.g., C++ static local variables with non-constant initializers). It is used by CIRGen to communicate to LoweringPrepare which globals need guard variable emission. --- clang/include/clang/CIR/Dialect/IR/CIROps.td | 15 ++++++++++++++- clang/lib/CIR/Dialect/IR/CIRDialect.cpp | 4 ++++ clang/test/CIR/IR/invalid-static-local.cir | 16 ++++++++++++++++ clang/test/CIR/IR/static-local.cir | 19 +++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 clang/test/CIR/IR/invalid-static-local.cir create mode 100644 clang/test/CIR/IR/static-local.cir diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 20b85dd877d00..c37764ed70202 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -2335,6 +2335,10 @@ def CIR_GlobalOp : CIR_Op<"global", [ The `linkage` tracks C/C++ linkage types, currently very similar to LLVM's. Symbol visibility in `sym_visibility` is defined in terms of MLIR's visibility and verified to be in accordance to `linkage`. + + The `static_local` attribute indicates that this global represents a + function-local static variable that requires guarded initialization + (e.g., C++ static local variables with non-constant initializers). }]; // Note that both sym_name and sym_visibility are tied to Symbol trait. @@ -2353,6 +2357,7 @@ def CIR_GlobalOp : CIR_Op<"global", [ UnitAttr:$comdat, UnitAttr:$constant, UnitAttr:$dso_local, + UnitAttr:$static_local, OptionalAttr<I64Attr>:$alignment); let regions = (region MaxSizedRegion<1>:$ctorRegion, @@ -2366,6 +2371,7 @@ def CIR_GlobalOp : CIR_Op<"global", [ (`comdat` $comdat^)? ($tls_model^)? (`dso_local` $dso_local^)? + (`static_local` $static_local^)? $sym_name custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, $ctorRegion, $dtorRegion) @@ -2433,19 +2439,26 @@ def CIR_GetGlobalOp : CIR_Op<"get_global", [ Addresses of thread local globals can only be retrieved if this operation is marked `thread_local`, which indicates the address isn't constant. + The `static_local` attribute indicates that this global is a function-local + static variable that requires guarded initialization (e.g., C++ static + local variables with non-constant initializers). + Example: ```mlir %x = cir.get_global @gv : !cir.ptr<i32> ... %y = cir.get_global thread_local @tls_gv : !cir.ptr<i32> + ... + %w = cir.get_global static_local @func_static : !cir.ptr<i32> ``` }]; - let arguments = (ins FlatSymbolRefAttr:$name, UnitAttr:$tls); + let arguments = (ins FlatSymbolRefAttr:$name, UnitAttr:$tls, UnitAttr:$static_local); let results = (outs Res<CIR_PointerType, "", []>:$addr); let assemblyFormat = [{ (`thread_local` $tls^)? + (`static_local` $static_local^)? $name `:` qualified(type($addr)) attr-dict }]; } diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 9574851a0ae2c..c32f2c7aa62f9 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -1854,6 +1854,10 @@ cir::GetGlobalOp::verifySymbolUses(SymbolTableCollection &symbolTable) { // be marked with tls bits. if (getTls() && !g.getTlsModel()) return emitOpError("access to global not marked thread local"); + // Verify that for static local access, the global needs to be marked + // static_local. + if (getStaticLocal() && !g.getStaticLocal()) + return emitOpError("access to global not marked static local"); } else if (auto f = dyn_cast<FuncOp>(op)) { symTy = f.getFunctionType(); } else { diff --git a/clang/test/CIR/IR/invalid-static-local.cir b/clang/test/CIR/IR/invalid-static-local.cir new file mode 100644 index 0000000000000..cd458731252b7 --- /dev/null +++ b/clang/test/CIR/IR/invalid-static-local.cir @@ -0,0 +1,16 @@ +// RUN: cir-opt %s -verify-diagnostics -split-input-file + +!s32i = !cir.int<s, 32> + +module { + +// Global is not marked static_local, but get_global is +cir.global "private" internal @_ZZ1fvE1x : !s32i + +cir.func @test_static_local_mismatch() { + // expected-error @below {{access to global not marked static local}} + %0 = cir.get_global static_local @_ZZ1fvE1x : !cir.ptr<!s32i> + cir.return +} + +} diff --git a/clang/test/CIR/IR/static-local.cir b/clang/test/CIR/IR/static-local.cir new file mode 100644 index 0000000000000..d4c5a743358de --- /dev/null +++ b/clang/test/CIR/IR/static-local.cir @@ -0,0 +1,19 @@ +// RUN: cir-opt %s --verify-roundtrip | FileCheck %s + +!s32i = !cir.int<s, 32> + +module { + +// Test static_local attribute on global and get_global +cir.global "private" internal static_local @_ZZ1fvE1x : !s32i +// CHECK: cir.global "private" internal static_local @_ZZ1fvE1x : !s32i + +cir.func @test_static_local() { + %0 = cir.get_global static_local @_ZZ1fvE1x : !cir.ptr<!s32i> + cir.return +} +// CHECK: cir.func @test_static_local() +// CHECK: %{{.*}} = cir.get_global static_local @_ZZ1fvE1x : !cir.ptr<!s32i> +// CHECK: cir.return + +} _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
