Author: David Rivera Date: 2026-10-08T01:57:37-04:00 New Revision: b22be3443558a3834e1d7d444c02e2f32bad2ef2
URL: https://github.com/llvm/llvm-project/commit/b22be3443558a3834e1d7d444c02e2f32bad2ef2 DIFF: https://github.com/llvm/llvm-project/commit/b22be3443558a3834e1d7d444c02e2f32bad2ef2.diff LOG: [CIR] Print the initial value of globals with a ctor region (#229565) Globals were not printing their initializer when a ctor region existed for the op. So round tripping the serialized op before running LoweringPrepareo on a .cir module was throwing this error from the verifier: ```sh error: 'cir.global' op symbol declaration cannot have public visibility ``` The global lost its initial value on the round trip. Once LoweringPrepare moved the ctor region out, had no initial value and no regions, so it looked like a public declaration. The initial value is now printed before the ctor region, the same way the dtor region already works: ```mlir cir.global external @s = #cir.zero : !rec_S ctor { ... } ``` The old `= ctor : type { ... }` form no longer parses, and the verifier requires an initial value on any global with a ctor region. Claude assisted with this patch. Added: Modified: clang/lib/CIR/Dialect/IR/CIRDialect.cpp clang/test/CIR/CodeGen/builtin-call.cpp clang/test/CIR/CodeGen/global-constant-storage.cpp clang/test/CIR/CodeGen/global-init-order.cpp clang/test/CIR/CodeGen/global-init.cpp clang/test/CIR/CodeGen/global-temp-dtor.cpp clang/test/CIR/CodeGen/global-tls-dyn-init.cpp clang/test/CIR/CodeGen/global-tls-dynamic-vs-static.cpp clang/test/CIR/CodeGen/global-tls-simple-init.cpp clang/test/CIR/CodeGen/global-tls-templates.cpp clang/test/CIR/CodeGen/pointer-to-data-member.cpp clang/test/CIR/CodeGen/pointer-to-member-func.cpp clang/test/CIR/CodeGen/unions-with-zero-init.cpp clang/test/CIR/CodeGenCXX/global-refs.cpp clang/test/CIR/CodeGenCXX/init-priority-attr.cpp clang/test/CIR/CodeGenCXX/typeid.cpp clang/test/CIR/CodeGenCXX/zero_init_bases.cpp clang/test/CIR/IR/global-init.cir clang/test/CIR/IR/invalid-global.cir clang/test/CIR/IR/invalid-static-local.cir clang/unittests/CIR/ControlFlowTest.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index a97606a5a9bd7..2c5b785d5fc34 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -2371,6 +2371,12 @@ mlir::LogicalResult cir::GlobalOp::verify() { return failure(); } + // The initial value can't be recomputed from the type once the ctor is + // lowered (e.g. a null member pointer becomes -1 after CXXABILowering). + if (!getCtorRegion().empty() && !getInitialValue().has_value()) + return emitOpError( + "cannot have a constructor region without an initial value"); + std::optional<DynamicInitInfoAttr> info = getDynamicInitInfo(); if ((getDynamicInitGuard().has_value()) && (!info || info->getLocal()) && @@ -2519,17 +2525,14 @@ static void printGlobalOpTypeAndInitialValue(OpAsmPrinter &p, cir::GlobalOp op, } p << "= "; + if (initAttr) + printConstant(p, initAttr); + if (!ctorRegion.empty()) { - p << "ctor "; - printType(); - p << " "; + p << " ctor "; p.printRegion(ctorRegion, /*printEntryBlockArgs=*/false, /*printBlockTerminators=*/false); - } else { - // This also prints the type... - if (initAttr) - printConstant(p, initAttr); } if (!dtorRegion.empty()) { @@ -2552,26 +2555,24 @@ static ParseResult parseGlobalOpTypeAndInitialValue(OpAsmParser &parser, if (parser.parseColonType(opTy)) return failure(); } else { - // Parse contructor, example: - // cir.global @rgb = ctor : type { ... } + // Parse constant with initializer, examples: + // cir.global @y = 3.400000e+00 : f32 + // cir.global @rgb = #cir.const_array<[...] : !cir.array<i8 x 3>> + if (parseConstantValue(parser, initialValueAttr).failed()) + return failure(); + + assert(mlir::isa<mlir::TypedAttr>(initialValueAttr) && + "Non-typed attrs shouldn't appear here."); + opTy = mlir::cast<mlir::TypedAttr>(initialValueAttr).getType(); + + // Parse constructor, example: + // cir.global @rgb = #cir.zero : type ctor { ... } if (!parser.parseOptionalKeyword("ctor")) { - if (parser.parseColonType(opTy)) - return failure(); auto parseLoc = parser.getCurrentLocation(); if (parser.parseRegion(ctorRegion, /*arguments=*/{}, /*argTypes=*/{})) return failure(); if (ensureRegionTerm(parser, ctorRegion, parseLoc).failed()) return failure(); - } else { - // Parse constant with initializer, examples: - // cir.global @y = 3.400000e+00 : f32 - // cir.global @rgb = #cir.const_array<[...] : !cir.array<i8 x 3>> - if (parseConstantValue(parser, initialValueAttr).failed()) - return failure(); - - assert(mlir::isa<mlir::TypedAttr>(initialValueAttr) && - "Non-typed attrs shouldn't appear here."); - opTy = mlir::cast<mlir::TypedAttr>(initialValueAttr).getType(); } // Parse destructor, example: diff --git a/clang/test/CIR/CodeGen/builtin-call.cpp b/clang/test/CIR/CodeGen/builtin-call.cpp index 5d84d0e762223..e647852521b41 100644 --- a/clang/test/CIR/CodeGen/builtin-call.cpp +++ b/clang/test/CIR/CodeGen/builtin-call.cpp @@ -14,7 +14,7 @@ const double parsed = strtod(str, nullptr); // LLVM: @_ZL6parsed = internal global double 0.000000e+00, align 8 // LLVM: @v = global ptr null, align 8 -// CIR-BEFORE-LPP: cir.global "private" internal dso_local @_ZL6parsed = ctor : !cir.double { +// CIR-BEFORE-LPP: cir.global "private" internal dso_local @_ZL6parsed = #cir.fp<0.000000e+00> : !cir.double ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global @_ZL6parsed : !cir.ptr<!cir.double> // CIR-BEFORE-LPP: %[[GET_BUILTIN:.*]] = cir.get_global @strtod : !cir.ptr<!cir.func<(!cir.ptr<!s8i>, !cir.ptr<!cir.ptr<!s8i>>) -> !cir.double>> // CIR-BEFORE-LPP: %[[GET_STR:.*]] = cir.get_global @str : !cir.ptr<!cir.ptr<!s8i>> @@ -50,7 +50,7 @@ void *memcpy(void *a, const void *b, size_t c) { } const void* v = memcpy(nullptr, nullptr, 1); -// CIR-BEFORE-LPP: cir.global external @v = ctor : !cir.ptr<!void> { +// CIR-BEFORE-LPP: cir.global external @v = #cir.ptr<null> : !cir.ptr<!void> ctor { // CIR-BEFORE-LPP: %[[GET_V:.*]] = cir.get_global @v : !cir.ptr<!cir.ptr<!void>> // CIR-BEFORE-LPP: %[[NULL1:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void> // CIR-BEFORE-LPP: %[[NULL2:.*]] = cir.const #cir.ptr<null> : !cir.ptr<!void> diff --git a/clang/test/CIR/CodeGen/global-constant-storage.cpp b/clang/test/CIR/CodeGen/global-constant-storage.cpp index 64b75c69f2971..e9ae3151401dd 100644 --- a/clang/test/CIR/CodeGen/global-constant-storage.cpp +++ b/clang/test/CIR/CodeGen/global-constant-storage.cpp @@ -52,27 +52,27 @@ const C c; // CIR checks before LoweringPrepare transformation - globals have ctor regions // Test case 'a' - before LoweringPrepare -// CIR-BEFORE-LPP: cir.global external @a = ctor : !rec_A { +// CIR-BEFORE-LPP: cir.global external @a = #cir.zero : !rec_A ctor { // CIR-BEFORE-LPP: %[[OBJ:.*]] = cir.get_global @a : !cir.ptr<!rec_A> // CIR-BEFORE-LPP: cir.call @_ZN1AC1Ev(%[[OBJ]]) : (!cir.ptr<!rec_A> {{.*}}) -> () // CIR-BEFORE-LPP: %[[OBJ2:.*]] = cir.get_global @a : !cir.ptr<!rec_A> // CIR-BEFORE-LPP: } // Test case 'a2' - before LoweringPrepare -// CIR-BEFORE-LPP: cir.global external @a2 = ctor : !rec_A2 { +// CIR-BEFORE-LPP: cir.global external @a2 = #cir.zero : !rec_A2 ctor { // CIR-BEFORE-LPP: %[[OBJ:.*]] = cir.get_global @a2 : !cir.ptr<!rec_A2> // CIR-BEFORE-LPP: cir.call @_ZN2A2C1Ev(%[[OBJ]]) : (!cir.ptr<!rec_A2> {{.*}}) -> () // CIR-BEFORE-LPP: %[[OBJ2:.*]] = cir.get_global @a2 : !cir.ptr<!rec_A2> // CIR-BEFORE-LPP: } // Test case 'b' - before LoweringPrepare -// CIR-BEFORE-LPP: cir.global external @b = ctor : !rec_B { +// CIR-BEFORE-LPP: cir.global external @b = #cir.zero : !rec_B ctor { // CIR-BEFORE-LPP: %[[OBJ:.*]] = cir.get_global @b : !cir.ptr<!rec_B> // CIR-BEFORE-LPP: cir.call @_ZN1BC1Ev(%[[OBJ]]) : (!cir.ptr<!rec_B> {{.*}}) -> () // CIR-BEFORE-LPP: } // Test case 'c' - before LoweringPrepare (internal linkage) -// CIR-BEFORE-LPP: cir.global {{.*}} internal {{.*}} @_ZL1c = ctor : !rec_C { +// CIR-BEFORE-LPP: cir.global {{.*}} internal {{.*}} @_ZL1c = #cir.zero : !rec_C ctor { // CIR-BEFORE-LPP: %[[OBJ:.*]] = cir.get_global @_ZL1c : !cir.ptr<!rec_C> // CIR-BEFORE-LPP: cir.call @_ZN1CC1Ev(%[[OBJ]]) : (!cir.ptr<!rec_C> {{.*}}) -> () // CIR-BEFORE-LPP: %[[OBJ2:.*]] = cir.get_global @_ZL1c : !cir.ptr<!rec_C> diff --git a/clang/test/CIR/CodeGen/global-init-order.cpp b/clang/test/CIR/CodeGen/global-init-order.cpp index 41ab8f21abafc..7e2c1251e1360 100644 --- a/clang/test/CIR/CodeGen/global-init-order.cpp +++ b/clang/test/CIR/CodeGen/global-init-order.cpp @@ -21,11 +21,11 @@ NeedsCtor Holder::second; NeedsCtor Holder::first; // CIR-BEFORE-LPP: cir.global external @p = #cir.global_view<@_ZN6Holder5firstE> : !cir.ptr<!rec_NeedsCtor> -// CIR-BEFORE-LPP: cir.global external @_ZN6Holder6secondE = ctor : !rec_NeedsCtor { +// CIR-BEFORE-LPP: cir.global external @_ZN6Holder6secondE = #cir.zero : !rec_NeedsCtor ctor { // CIR-BEFORE-LPP: %[[THIS:.*]] = cir.get_global @_ZN6Holder6secondE : !cir.ptr<!rec_NeedsCtor> // CIR-BEFORE-LPP: cir.call @_ZN9NeedsCtorC1Ev(%[[THIS]]) // CIR-BEFORE-LPP: } -// CIR-BEFORE-LPP: cir.global external @_ZN6Holder5firstE = ctor : !rec_NeedsCtor { +// CIR-BEFORE-LPP: cir.global external @_ZN6Holder5firstE = #cir.zero : !rec_NeedsCtor ctor { // CIR-BEFORE-LPP: %[[THIS:.*]] = cir.get_global @_ZN6Holder5firstE : !cir.ptr<!rec_NeedsCtor> // CIR-BEFORE-LPP: cir.call @_ZN9NeedsCtorC1Ev(%[[THIS]]) // CIR-BEFORE-LPP: } diff --git a/clang/test/CIR/CodeGen/global-init.cpp b/clang/test/CIR/CodeGen/global-init.cpp index 7d54e911829b2..6696e73f5b1f5 100644 --- a/clang/test/CIR/CodeGen/global-init.cpp +++ b/clang/test/CIR/CodeGen/global-init.cpp @@ -37,7 +37,7 @@ struct NeedsCtor { NeedsCtor needsCtor; -// CIR-BEFORE-LPP: cir.global external @needsCtor = ctor : !rec_NeedsCtor { +// CIR-BEFORE-LPP: cir.global external @needsCtor = #cir.zero : !rec_NeedsCtor ctor { // CIR-BEFORE-LPP: %[[THIS:.*]] = cir.get_global @needsCtor : !cir.ptr<!rec_NeedsCtor> // CIR-BEFORE-LPP: cir.call @_ZN9NeedsCtorC1Ev(%[[THIS]]) : (!cir.ptr<!rec_NeedsCtor> {{.*}}) -> () @@ -85,7 +85,7 @@ struct NeedsCtorDtor { NeedsCtorDtor needsCtorDtor; -// CIR-BEFORE-LPP: cir.global external @needsCtorDtor = ctor : !rec_NeedsCtorDtor { +// CIR-BEFORE-LPP: cir.global external @needsCtorDtor = #cir.zero : !rec_NeedsCtorDtor ctor { // CIR-BEFORE-LPP: %[[THIS:.*]] = cir.get_global @needsCtorDtor : !cir.ptr<!rec_NeedsCtorDtor> // CIR-BEFORE-LPP: cir.call @_ZN13NeedsCtorDtorC1Ev(%[[THIS]]) : (!cir.ptr<!rec_NeedsCtorDtor> {{.*}}) -> () // CIR-BEFORE-LPP: } dtor { @@ -115,7 +115,7 @@ float num; float _Complex a = {num, num}; // CIR-BEFORE-LPP: cir.global external @num = #cir.fp<0.000000e+00> : !cir.float -// CIR-BEFORE-LPP: cir.global external @a = ctor : !cir.complex<!cir.float> { +// CIR-BEFORE-LPP: cir.global external @a = #cir.zero : !cir.complex<!cir.float> ctor { // CIR-BEFORE-LPP: %[[THIS:.*]] = cir.get_global @a : !cir.ptr<!cir.complex<!cir.float>> // CIR-BEFORE-LPP: %[[NUM:.*]] = cir.get_global @num : !cir.ptr<!cir.float> // CIR-BEFORE-LPP: %[[REAL:.*]] = cir.load{{.*}} %[[NUM]] : !cir.ptr<!cir.float>, !cir.float @@ -152,7 +152,7 @@ float _Complex a = {num, num}; float fp; int i = (int)fp; -// CIR-BEFORE-LPP: cir.global external @i = ctor : !s32i { +// CIR-BEFORE-LPP: cir.global external @i = #cir.int<0> : !s32i ctor { // CIR-BEFORE-LPP: %[[I:.*]] = cir.get_global @i : !cir.ptr<!s32i> // CIR-BEFORE-LPP: %[[FP:.*]] = cir.get_global @fp : !cir.ptr<!cir.float> // CIR-BEFORE-LPP: %[[FP_VAL:.*]] = cir.load{{.*}} %[[FP]] : !cir.ptr<!cir.float>, !cir.float @@ -271,7 +271,7 @@ ArrayDtor arrDtor[16]; int globalInt; double &&globalDoubleRef = static_cast<double &&>(globalInt); // CIR-BEFORE-LPP: cir.global external @globalInt = #cir.int<0> : !s32i -// CIR-BEFORE-LPP: cir.global external @globalDoubleRef = ctor : !cir.ptr<!cir.double> { +// CIR-BEFORE-LPP: cir.global external @globalDoubleRef = #cir.ptr<null> : !cir.ptr<!cir.double> ctor { // CIR-BEFORE-LPP: %[[GET_SELF:.*]] = cir.get_global @globalDoubleRef : !cir.ptr<!cir.ptr<!cir.double>> // CIR-BEFORE-LPP: %[[GET_BACKING_VAR:.*]] = cir.get_global @_ZGR15globalDoubleRef_ : !cir.ptr<!cir.double> // CIR-BEFORE-LPP: %[[GET_INT_VAR:.*]] = cir.get_global @globalInt : !cir.ptr<!s32i> diff --git a/clang/test/CIR/CodeGen/global-temp-dtor.cpp b/clang/test/CIR/CodeGen/global-temp-dtor.cpp index e34bb8b009aeb..7c267ffd0558e 100644 --- a/clang/test/CIR/CodeGen/global-temp-dtor.cpp +++ b/clang/test/CIR/CodeGen/global-temp-dtor.cpp @@ -24,7 +24,7 @@ typedef NonTrivial NonTrivialArr[2]; const NonTrivialArr &static_arr_ref = NonTrivialArr{}; thread_local const NonTrivialArr &thread_arr_ref = NonTrivialArr{}; -// CIR-BEFORE: cir.global external @static_ref = ctor : !cir.ptr<!rec_NonTrivial> { +// CIR-BEFORE: cir.global external @static_ref = #cir.ptr<null> : !cir.ptr<!rec_NonTrivial> ctor { // CIR-BEFORE: %[[STATIC_REF:.*]] = cir.get_global @static_ref // CIR-BEFORE: %[[REF_TEMP:.*]] = cir.get_global @_ZGR10static_ref_ // CIR-BEFORE: cir.call @_ZN10NonTrivialC1Ev(%[[REF_TEMP]]) @@ -47,7 +47,7 @@ thread_local const NonTrivialArr &thread_arr_ref = NonTrivialArr{}; // CIR: cir.call @__cxa_atexit // CIR: cir.global "private" internal @_ZGR10static_ref_ = #cir.zero : !rec_NonTrivial -// CIR-BEFORE: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW10thread_ref", "_ZTH10thread_ref"> @thread_ref = ctor : !cir.ptr<!rec_NonTrivial> { +// CIR-BEFORE: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW10thread_ref", "_ZTH10thread_ref"> @thread_ref = #cir.ptr<null> : !cir.ptr<!rec_NonTrivial> ctor { // CIR-BEFORE: %[[THREAD_REF:.*]] = cir.get_global thread_local @thread_ref // CIR-BEFORE: %[[REF_TEMP:.*]] = cir.get_global @_ZGR10thread_ref_ // CIR-BEFORE: cir.call @_ZN10NonTrivialC1Ev(%[[REF_TEMP]]) @@ -70,7 +70,7 @@ thread_local const NonTrivialArr &thread_arr_ref = NonTrivialArr{}; // CIR: cir.call @__cxa_thread_atexit // CIR: cir.global "private" internal tls_model = tls_dyn @_ZGR10thread_ref_ = #cir.zero : !rec_NonTrivial -// CIR-BEFORE: cir.global external @static_arr_ref = ctor : !cir.ptr<!cir.array<!rec_NonTrivial x 2>> { +// CIR-BEFORE: cir.global external @static_arr_ref = #cir.ptr<null> : !cir.ptr<!cir.array<!rec_NonTrivial x 2>> ctor { // CIR-BEFORE: %[[ARRAY_INIT_TEMP:.*]] = cir.alloca {{.*}}"arrayinit.temp" // CIR-BEFORE: %[[STATIC_ARR_REF:.*]] = cir.get_global @static_arr_ref // CIR-BEFORE: %[[STATIC_ARR_REF_TEMP:.*]] = cir.get_global @_ZGR14static_arr_ref_ @@ -108,7 +108,7 @@ thread_local const NonTrivialArr &thread_arr_ref = NonTrivialArr{}; // CIR: cir.call @__cxa_atexit // CIR: cir.global "private" internal @_ZGR14static_arr_ref_ = #cir.zero : !cir.array<!rec_NonTrivial x 2> -// CIR-BEFORE: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW14thread_arr_ref", "_ZTH14thread_arr_ref"> @thread_arr_ref = ctor : !cir.ptr<!cir.array<!rec_NonTrivial x 2>> { +// CIR-BEFORE: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW14thread_arr_ref", "_ZTH14thread_arr_ref"> @thread_arr_ref = #cir.ptr<null> : !cir.ptr<!cir.array<!rec_NonTrivial x 2>> ctor { // CIR-BEFORE: %[[ARRAY_INIT_TEMP:.*]] = cir.alloca {{.*}}"arrayinit.temp" // CIR-BEFORE: %[[THREAD_ARR_REF:.*]] = cir.get_global thread_local @thread_arr_ref // CIR-BEFORE: %[[THREAD_ARR_REF_TEMP:.*]] = cir.get_global @_ZGR14thread_arr_ref_ @@ -273,7 +273,7 @@ struct OwnsTemp { }; OwnsTemp owns_temp{ExtendedTemp()}; -// CIR-BEFORE: cir.global external @owns_temp = ctor : !rec_OwnsTemp { +// CIR-BEFORE: cir.global external @owns_temp = #cir.zero : !rec_OwnsTemp ctor { // CIR-BEFORE: } dtor { // CIR-BEFORE-NEXT: %[[OWNER:.*]] = cir.get_global @owns_temp // CIR-BEFORE-NEXT: cir.call @_ZN8OwnsTempD1Ev(%[[OWNER]]) diff --git a/clang/test/CIR/CodeGen/global-tls-dyn-init.cpp b/clang/test/CIR/CodeGen/global-tls-dyn-init.cpp index 4c23dedee6d38..0a0cc48035b0e 100644 --- a/clang/test/CIR/CodeGen/global-tls-dyn-init.cpp +++ b/clang/test/CIR/CodeGen/global-tls-dyn-init.cpp @@ -122,7 +122,7 @@ thread_local CtorDtor tls_cd = 5; // LLVM-BOTH: ret void thread_local CtorDtor tls_cd_dyn = get_i(); -// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW10tls_cd_dyn", "_ZTH10tls_cd_dyn"> @tls_cd_dyn = ctor : !rec_CtorDtor { +// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW10tls_cd_dyn", "_ZTH10tls_cd_dyn"> @tls_cd_dyn = #cir.zero : !rec_CtorDtor ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd_dyn : !cir.ptr<!rec_CtorDtor> // CIR-BEFORE-LPP: %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef}) // CIR-BEFORE-LPP: cir.call @_ZN8CtorDtorC1Ei(%[[GET_GLOB]], %[[CALL]]) : (!cir.ptr<!rec_CtorDtor> @@ -155,7 +155,7 @@ thread_local CtorDtor tls_cd_dyn = get_i(); // LLVM-BOTH: ret void thread_local CtorDtor &tls_cd_ref = tls_cd_dyn; -// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW10tls_cd_ref", "_ZTH10tls_cd_ref"> @tls_cd_ref = ctor : !cir.ptr<!rec_CtorDtor> { +// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW10tls_cd_ref", "_ZTH10tls_cd_ref"> @tls_cd_ref = #cir.ptr<null> : !cir.ptr<!rec_CtorDtor> ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd_ref : !cir.ptr<!cir.ptr<!rec_CtorDtor>> // CIR-BEFORE-LPP: %[[CALL:.*]] = cir.get_global thread_local @tls_cd_dyn : !cir.ptr<!rec_CtorDtor> // CIR-BEFORE-LPP: cir.store {{.*}}%[[CALL]], %[[GET_GLOB]] : !cir.ptr<!rec_CtorDtor>, !cir.ptr<!cir.ptr<!rec_CtorDtor>> @@ -182,7 +182,7 @@ thread_local CtorDtor &tls_cd_ref = tls_cd_dyn; // OGCG: } thread_local CtorDtor tls_cd_dyn_not_used = get_i(); -// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW19tls_cd_dyn_not_used", "_ZTH19tls_cd_dyn_not_used"> @tls_cd_dyn_not_used = ctor : !rec_CtorDtor { +// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW19tls_cd_dyn_not_used", "_ZTH19tls_cd_dyn_not_used"> @tls_cd_dyn_not_used = #cir.zero : !rec_CtorDtor ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_cd_dyn_not_used : !cir.ptr<!rec_CtorDtor> // CIR-BEFORE-LPP: %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef}) // CIR-BEFORE-LPP: cir.call @_ZN8CtorDtorC1Ei(%[[GET_GLOB]], %[[CALL]]) diff --git a/clang/test/CIR/CodeGen/global-tls-dynamic-vs-static.cpp b/clang/test/CIR/CodeGen/global-tls-dynamic-vs-static.cpp index 08d3a2d9ed4f3..c6442a0e3cc59 100644 --- a/clang/test/CIR/CodeGen/global-tls-dynamic-vs-static.cpp +++ b/clang/test/CIR/CodeGen/global-tls-dynamic-vs-static.cpp @@ -12,7 +12,7 @@ thread_local int d = f(); // CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn @a = #cir.int<5> : !s32i // CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn @b = #cir.int<5> : !s32i // CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW1c", "_ZTH1c"> @c = #cir.int<5> : !s32i -// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW1d", "_ZTH1d"> @d = ctor +// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW1d", "_ZTH1d"> @d = #cir.int<0> : !s32i ctor // CIR-DAG: cir.global external tls_model = tls_dyn @a = #cir.int<5> : !s32i // CIR-DAG: cir.global external tls_model = tls_dyn @b = #cir.int<5> : !s32i diff --git a/clang/test/CIR/CodeGen/global-tls-simple-init.cpp b/clang/test/CIR/CodeGen/global-tls-simple-init.cpp index 049e8fd9f16d7..af6c9fe8695dd 100644 --- a/clang/test/CIR/CodeGen/global-tls-simple-init.cpp +++ b/clang/test/CIR/CodeGen/global-tls-simple-init.cpp @@ -144,7 +144,7 @@ thread_local int tls_int = 5; // CIR: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW7tls_int", "_ZTH7tls_int"> @tls_int = #cir.int<5> : !s32i thread_local int tls_int_dyn = get_i(); -// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW11tls_int_dyn", "_ZTH11tls_int_dyn"> @tls_int_dyn = ctor : !s32i { +// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW11tls_int_dyn", "_ZTH11tls_int_dyn"> @tls_int_dyn = #cir.int<0> : !s32i ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_int_dyn : !cir.ptr<!s32i> // CIR-BEFORE-LPP: %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef}) // CIR-BEFORE-LPP: cir.store {{.*}}%[[CALL]], %[[GET_GLOB]] : !s32i, !cir.ptr<!s32i> @@ -164,7 +164,7 @@ thread_local int tls_int_dyn = get_i(); // LLVM-BOTH: ret void thread_local int &tls_int_ref = tls_int_dyn; -// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW11tls_int_ref", "_ZTH11tls_int_ref"> @tls_int_ref = ctor : !cir.ptr<!s32i> { +// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW11tls_int_ref", "_ZTH11tls_int_ref"> @tls_int_ref = #cir.ptr<null> : !cir.ptr<!s32i> ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_int_ref : !cir.ptr<!cir.ptr<!s32i>> // CIR-BEFORE-LPP: %[[GET_OTHER:.*]] = cir.get_global thread_local @tls_int_dyn : !cir.ptr<!s32i> // CIR-BEFORE-LPP: cir.store {{.*}}%[[GET_OTHER]], %[[GET_GLOB]] : !cir.ptr<!s32i>, !cir.ptr<!cir.ptr<!s32i>> @@ -189,7 +189,7 @@ thread_local int &tls_int_ref = tls_int_dyn; // OGCG: ret ptr %[[GET_GLOB]] thread_local int tls_int_self_init = tls_int_self_init + get_i(); -// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW17tls_int_self_init", "_ZTH17tls_int_self_init"> @tls_int_self_init = ctor : !s32i { +// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW17tls_int_self_init", "_ZTH17tls_int_self_init"> @tls_int_self_init = #cir.int<0> : !s32i ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @tls_int_self_init : !cir.ptr<!s32i> // CIR-BEFORE-LPP: %[[GET_SELF:.*]] = cir.get_global thread_local @tls_int_self_init : !cir.ptr<!s32i> // CIR-BEFORE-LPP: %[[LOAD_SELF:.*]] = cir.load {{.*}}%[[GET_SELF]] : !cir.ptr<!s32i>, !s32i @@ -227,7 +227,7 @@ extern thread_local int definitely_inited = 5; // CIR: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW17definitely_inited", "_ZTH17definitely_inited"> @definitely_inited = #cir.int<5> : !s32i extern thread_local int definitely_inited_dyn = get_i(); -// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW21definitely_inited_dyn", "_ZTH21definitely_inited_dyn"> @definitely_inited_dyn = ctor : !s32i { +// CIR-BEFORE-LPP: cir.global external tls_model = tls_dyn tls_refs = <"_ZTW21definitely_inited_dyn", "_ZTH21definitely_inited_dyn"> @definitely_inited_dyn = #cir.int<0> : !s32i ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @definitely_inited_dyn : !cir.ptr<!s32i> // CIR-BEFORE-LPP: %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef}) // CIR-BEFORE-LPP: cir.store {{.*}}%[[CALL]], %[[GET_GLOB]] : !s32i, !cir.ptr<!s32i> diff --git a/clang/test/CIR/CodeGen/global-tls-templates.cpp b/clang/test/CIR/CodeGen/global-tls-templates.cpp index 8c896a4acf0af..1022d296b0b79 100644 --- a/clang/test/CIR/CodeGen/global-tls-templates.cpp +++ b/clang/test/CIR/CodeGen/global-tls-templates.cpp @@ -13,13 +13,13 @@ struct CtorDtor { template<typename T> thread_local T tls_templ = {get_i()}; -// CIR-BEFORE-LPP-LABEL: cir.global linkonce_odr comdat tls_model = tls_dyn tls_refs = <"_ZTW9tls_templIiE", "_ZTH9tls_templIiE", "_ZGV9tls_templIiE"> dynamic_init_guard<"_ZGV9tls_templIiE"> @_Z9tls_templIiE = ctor : !s32i { +// CIR-BEFORE-LPP-LABEL: cir.global linkonce_odr comdat tls_model = tls_dyn tls_refs = <"_ZTW9tls_templIiE", "_ZTH9tls_templIiE", "_ZGV9tls_templIiE"> dynamic_init_guard<"_ZGV9tls_templIiE"> @_Z9tls_templIiE = #cir.int<0> : !s32i ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @_Z9tls_templIiE : !cir.ptr<!s32i> // CIR-BEFORE-LPP: %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef}) // CIR-BEFORE-LPP: cir.store{{.*}} %[[CALL]], %[[GET_GLOB]] : !s32i, !cir.ptr<!s32i> // CIR-BEFORE-LPP: } // -// CIR-BEFORE-LPP-LABEL: cir.global linkonce_odr comdat tls_model = tls_dyn tls_refs = <"_ZTW9tls_templI8CtorDtorE", "_ZTH9tls_templI8CtorDtorE", "_ZGV9tls_templI8CtorDtorE"> dynamic_init_guard<"_ZGV9tls_templI8CtorDtorE"> @_Z9tls_templI8CtorDtorE = ctor : !rec_CtorDtor { +// CIR-BEFORE-LPP-LABEL: cir.global linkonce_odr comdat tls_model = tls_dyn tls_refs = <"_ZTW9tls_templI8CtorDtorE", "_ZTH9tls_templI8CtorDtorE", "_ZGV9tls_templI8CtorDtorE"> dynamic_init_guard<"_ZGV9tls_templI8CtorDtorE"> @_Z9tls_templI8CtorDtorE = #cir.zero : !rec_CtorDtor ctor { // CIR-BEFORE-LPP: %[[GET_GLOB:.*]] = cir.get_global thread_local @_Z9tls_templI8CtorDtorE : !cir.ptr<!rec_CtorDtor> // CIR-BEFORE-LPP: %[[CALL:.*]] = cir.call @_Z5get_iv() : () -> (!s32i {llvm.noundef}) // CIR-BEFORE-LPP: cir.call @_ZN8CtorDtorC1Ei(%[[GET_GLOB]], %[[CALL]]) : (!cir.ptr<!rec_CtorDtor> diff --git a/clang/test/CIR/CodeGen/pointer-to-data-member.cpp b/clang/test/CIR/CodeGen/pointer-to-data-member.cpp index 46b3cb88fd1a4..f8e06fdf69a2d 100644 --- a/clang/test/CIR/CodeGen/pointer-to-data-member.cpp +++ b/clang/test/CIR/CodeGen/pointer-to-data-member.cpp @@ -30,7 +30,7 @@ auto test1() -> int Point::* { int Point::*pt_member_nested_region = test1(); -// CIR-BEFORE: cir.global external @pt_member_nested_region = ctor : !cir.data_member<!s32i in !rec_Point> { +// CIR-BEFORE: cir.global external @pt_member_nested_region = #cir.data_member<null> : !cir.data_member<!s32i in !rec_Point> ctor { // CIR-BEFORE: %[[MEMBER_PTR_ADDR:.*]] = cir.get_global @pt_member_nested_region : !cir.ptr<!cir.data_member<!s32i in !rec_Point>> // CIR-BEFORE: %[[MEMBER_PTR:.*]] = cir.call @_Z5test1v() : () -> !cir.data_member<!s32i in !rec_Point> // CIR-BEFORE: cir.store{{.*}} %[[MEMBER_PTR]], %[[MEMBER_PTR_ADDR]] : !cir.data_member<!s32i in !rec_Point>, !cir.ptr<!cir.data_member<!s32i in !rec_Point>> diff --git a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp index afe853c3423a9..65494afa5fd23 100644 --- a/clang/test/CIR/CodeGen/pointer-to-member-func.cpp +++ b/clang/test/CIR/CodeGen/pointer-to-member-func.cpp @@ -52,7 +52,7 @@ void (Foo::*m2_ptr)(int) = &Foo::m2; // Self-referencing PMF causes a null method. long (Foo::*pmf1)(int) = pmf1; -// CIR-BEFORE: @pmf1 = ctor : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i) -> !s64i> in !rec_Foo> { +// CIR-BEFORE: @pmf1 = #cir.method<null> : !cir.method<!cir.func<(!cir.ptr<!rec_Foo>, !s32i) -> !s64i> in !rec_Foo> ctor { // CIR-AFTER: cir.global external @pmf1 = #cir.const_record<{#cir.int<0> : !s64i, #cir.int<0> : !s64i}> // LLVM: @pmf1 = global { i64, i64 } zeroinitializer, align 8 // OGCG: @pmf1 = global { i64, i64 } zeroinitializer, align 8 diff --git a/clang/test/CIR/CodeGen/unions-with-zero-init.cpp b/clang/test/CIR/CodeGen/unions-with-zero-init.cpp index ebddb95c545eb..2b84c18925dae 100644 --- a/clang/test/CIR/CodeGen/unions-with-zero-init.cpp +++ b/clang/test/CIR/CodeGen/unions-with-zero-init.cpp @@ -66,7 +66,7 @@ auto use() { } union outer_aggregate{int S::*m; int i; } outer_a1 = { p }; -// CIR-BEFORE-LABEL: cir.global external @outer_a1 = ctor : !rec_outer_aggregate { +// CIR-BEFORE-LABEL: cir.global external @outer_a1 = #cir.const_record<{#cir.data_member<null> : !cir.data_member<!s32i in !rec_S>}> : !rec_outer_aggregate ctor { // CIR-BEFORE: %[[GET_GLOB:.*]] = cir.get_global @outer_a1 : !cir.ptr<!rec_outer_aggregate> // CIR-BEFORE: %[[GET_MEM:.*]] = cir.get_member %[[GET_GLOB]][0] {name = "m"} : !cir.ptr<!rec_outer_aggregate> -> !cir.ptr<!cir.data_member<!s32i in !rec_S>> // CIR-BEFORE: %[[GET_P:.*]] = cir.get_global @p : !cir.ptr<!cir.data_member<!s32i in !rec_S>> diff --git a/clang/test/CIR/CodeGenCXX/global-refs.cpp b/clang/test/CIR/CodeGenCXX/global-refs.cpp index 7843fad4de638..98a2e85e71ca0 100644 --- a/clang/test/CIR/CodeGenCXX/global-refs.cpp +++ b/clang/test/CIR/CodeGenCXX/global-refs.cpp @@ -51,7 +51,7 @@ const DefCtor &constDefCtorRef{}; // LLVM: @constDefCtorRef = constant ptr @_ZGR15constDefCtorRef_, align 8 WithCtor withCtor{}; -// CIR-BEFORE: cir.global external @withCtor = ctor : !rec_WithCtor { +// CIR-BEFORE: cir.global external @withCtor = #cir.zero : !rec_WithCtor ctor { // CIR-BEFORE-NEXT: %[[GET_GLOB:.*]] = cir.get_global @withCtor : !cir.ptr<!rec_WithCtor> // CIR-BEFORE-NEXT: cir.call @_ZN8WithCtorC1Ev(%[[GET_GLOB]]) : (!cir.ptr<!rec_WithCtor>{{.*}}) -> () // CIR-BEFORE-NEXT: } align(1) ast(#cir.var.decl.ast) @@ -68,7 +68,7 @@ WithCtor &withCtorRef = withCtor; // LLVM: @withCtorRef = constant ptr @withCtor, align 8 const WithCtor &constWithCtorRef{}; -// CIR-BEFORE: cir.global external @constWithCtorRef = ctor : !cir.ptr<!rec_WithCtor> { +// CIR-BEFORE: cir.global external @constWithCtorRef = #cir.ptr<null> : !cir.ptr<!rec_WithCtor> ctor { // CIR-BEFORE-NEXT: %[[GET_GLOB:.*]] = cir.get_global @constWithCtorRef : !cir.ptr<!cir.ptr<!rec_WithCtor>> // CIR-BEFORE-NEXT: %[[GET_GLOB_OBJ:.*]] = cir.get_global @_ZGR16constWithCtorRef_ : !cir.ptr<!rec_WithCtor> // CIR-BEFORE-NEXT: cir.call @_ZN8WithCtorC1Ev(%[[GET_GLOB_OBJ]]) : (!cir.ptr<!rec_WithCtor>{{.*}}) -> () @@ -85,7 +85,7 @@ const WithCtor &constWithCtorRef{}; // LLVM: @constWithCtorRef = global ptr null, align 8 const WithCtor &constWithCtorRef2{5}; -// CIR-BEFORE: cir.global external @constWithCtorRef2 = ctor : !cir.ptr<!rec_WithCtor> { +// CIR-BEFORE: cir.global external @constWithCtorRef2 = #cir.ptr<null> : !cir.ptr<!rec_WithCtor> ctor { // CIR-BEFORE-NEXT: %[[GET_GLOB:.*]] = cir.get_global @constWithCtorRef2 : !cir.ptr<!cir.ptr<!rec_WithCtor>> // CIR-BEFORE-NEXT: %[[GET_GLOB_OBJ:.*]] = cir.get_global @_ZGR17constWithCtorRef2_ : !cir.ptr<!rec_WithCtor> // CIR-BEFORE-NEXT: %[[FIVE:.*]] = cir.const #cir.int<5> : !s32i @@ -104,7 +104,7 @@ const WithCtor &constWithCtorRef2{5}; // LLVM: @constWithCtorRef2 = global ptr null, align 8 WithCtorDtor withCtorDtor{}; -// CIR-BEFORE: cir.global external @withCtorDtor = ctor : !rec_WithCtorDtor { +// CIR-BEFORE: cir.global external @withCtorDtor = #cir.zero : !rec_WithCtorDtor ctor { // CIR-BEFORE-NEXT: %[[GET_GLOB:.*]] = cir.get_global @withCtorDtor : !cir.ptr<!rec_WithCtorDtor> // CIR-BEFORE-NEXT: cir.call @_ZN12WithCtorDtorC1Ev(%[[GET_GLOB]]) : (!cir.ptr<!rec_WithCtorDtor>{{.*}}) -> () // CIR-BEFORE-NEXT: } dtor { diff --git a/clang/test/CIR/CodeGenCXX/init-priority-attr.cpp b/clang/test/CIR/CodeGenCXX/init-priority-attr.cpp index 60aeff885b3af..75e303a3b15ba 100644 --- a/clang/test/CIR/CodeGenCXX/init-priority-attr.cpp +++ b/clang/test/CIR/CodeGenCXX/init-priority-attr.cpp @@ -38,16 +38,16 @@ A C::a = A(); // Static inside of C. -// CIR-BEFORE-LPP: cir.global external @_ZN1C1aE = ctor : !rec_A { +// CIR-BEFORE-LPP: cir.global external @_ZN1C1aE = #cir.zero : !rec_A ctor { // CIR-BEFORE-LPP: } align(1) ast(#cir.var.decl.ast) -// CIR-BEFORE-LPP: cir.global external @c = ctor : !rec_C { +// CIR-BEFORE-LPP: cir.global external @c = #cir.zero : !rec_C ctor { // CIR-BEFORE-LPP: } align(1) ast(#cir.var.decl.ast) -// CIR-BEFORE-LPP: cir.global external @a1 = ctor : !rec_A1 { +// CIR-BEFORE-LPP: cir.global external @a1 = #cir.zero : !rec_A1 ctor { // CIR-BEFORE-LPP: } align(1) ast(#cir.var.decl.ast) init_priority(300) -// CIR-BEFORE-LPP: cir.global external @a = ctor : !rec_A { +// CIR-BEFORE-LPP: cir.global external @a = #cir.zero : !rec_A ctor { // CIR-BEFORE-LPP: } align(1) ast(#cir.var.decl.ast) init_priority(300) -// CIR-BEFORE-LPP: cir.global external @b = ctor : !rec_B { +// CIR-BEFORE-LPP: cir.global external @b = #cir.zero : !rec_B ctor { // CIR-BEFORE-LPP: } align(1) ast(#cir.var.decl.ast) init_priority(200) // CIR: cir.global_ctors = [#cir.global_ctor<"_GLOBAL__I_000200", 200>, #cir.global_ctor<"_GLOBAL__I_000300", 300>, #cir.global_ctor<"_GLOBAL__sub_I_[[FILENAME:.*]]", 65535>] diff --git a/clang/test/CIR/CodeGenCXX/typeid.cpp b/clang/test/CIR/CodeGenCXX/typeid.cpp index a4608bf6a0205..ec1c0e4f81cd0 100644 --- a/clang/test/CIR/CodeGenCXX/typeid.cpp +++ b/clang/test/CIR/CodeGenCXX/typeid.cpp @@ -34,7 +34,7 @@ extern A &a; // CIR-AFTER: cir.global external @_ZN5Test14a_tiE = #cir.ptr<null> : !cir.ptr<!rec_std3A3Atype_info> -// CIR-BEFORE: cir.global external @_ZN5Test14a_tiE = ctor : !cir.ptr<!rec_std3A3Atype_info> { +// CIR-BEFORE: cir.global external @_ZN5Test14a_tiE = #cir.ptr<null> : !cir.ptr<!rec_std3A3Atype_info> ctor { // CIR-AFTER: cir.func{{.*}}@__cxx_global_var_init() { // // CIR-NEXT: %[[GET_GLOB_ATI:.*]] = cir.get_global @_ZN5Test14a_tiE : !cir.ptr<!cir.ptr<!rec_std3A3Atype_info>> diff --git a/clang/test/CIR/CodeGenCXX/zero_init_bases.cpp b/clang/test/CIR/CodeGenCXX/zero_init_bases.cpp index 22508f0ed5c0c..03491faadfe1f 100644 --- a/clang/test/CIR/CodeGenCXX/zero_init_bases.cpp +++ b/clang/test/CIR/CodeGenCXX/zero_init_bases.cpp @@ -42,7 +42,7 @@ Inherits I2 {{1,2,3},{1.1, 2.2, 3.3}, 4, 5, 6}; // OGCG: @I2 = global { i32, i32, i32, float, float, float, i32, i32, i32 } { i32 1, i32 2, i32 3, float {{.*}}, float {{.*}}, float {{.*}}, i32 4, i32 5, i32 6 }, align 4 VirtualInherits VI; -// CIR-BEFORE: cir.global external @VI = ctor : !rec_VirtualInherits { +// CIR-BEFORE: cir.global external @VI = #cir.zero : !rec_VirtualInherits ctor { // CIR-BEFORE: %[[GET_GLOB:.*]] = cir.get_global @VI : !cir.ptr<!rec_VirtualInherits> // CIR-BEFORE: cir.call @_ZN15VirtualInheritsC1Ev(%[[GET_GLOB]]) nothrow : (!cir.ptr<!rec_VirtualInherits> {llvm.align = 8 : i64, llvm.dereferenceable = 20 : i64, llvm.nonnull, llvm.noundef}) -> () // CIR-BEFORE: } align(8) ast(#cir.var.decl.ast) diff --git a/clang/test/CIR/IR/global-init.cir b/clang/test/CIR/IR/global-init.cir index 3e0387ed52594..f73362e3b9ee8 100644 --- a/clang/test/CIR/IR/global-init.cir +++ b/clang/test/CIR/IR/global-init.cir @@ -1,6 +1,7 @@ // RUN: cir-opt %s --verify-roundtrip | FileCheck %s !u8i = !cir.int<u, 8> +!s64i = !cir.int<s, 64> !rec_NeedsCtor = !cir.struct<"NeedsCtor" {pad !u8i}> !rec_NeedsDtor = !cir.struct<"NeedsDtor" {pad !u8i}> @@ -8,11 +9,11 @@ module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { cir.func private @_ZN9NeedsCtorC1Ev(!cir.ptr<!rec_NeedsCtor>) - cir.global external @needsCtor = ctor : !rec_NeedsCtor { + cir.global external @needsCtor = #cir.zero : !rec_NeedsCtor ctor { %0 = cir.get_global @needsCtor : !cir.ptr<!rec_NeedsCtor> cir.call @_ZN9NeedsCtorC1Ev(%0) : (!cir.ptr<!rec_NeedsCtor>) -> () } - // CHECK: cir.global external @needsCtor = ctor : !rec_NeedsCtor { + // CHECK: cir.global external @needsCtor = #cir.zero : !rec_NeedsCtor ctor { // CHECK: %0 = cir.get_global @needsCtor : !cir.ptr<!rec_NeedsCtor> // CHECK: cir.call @_ZN9NeedsCtorC1Ev(%0) : (!cir.ptr<!rec_NeedsCtor>) -> () // CHECK: } @@ -29,7 +30,7 @@ module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { cir.func private @_ZN13NeedsCtorDtorC1Ev(!cir.ptr<!rec_NeedsCtorDtor>) cir.func private @_ZN13NeedsCtorDtorD1Ev(!cir.ptr<!rec_NeedsCtorDtor>) - cir.global external dso_local @needsCtorDtor = ctor : !rec_NeedsCtorDtor { + cir.global external dso_local @needsCtorDtor = #cir.zero : !rec_NeedsCtorDtor ctor { %0 = cir.get_global @needsCtorDtor : !cir.ptr<!rec_NeedsCtorDtor> cir.call @_ZN13NeedsCtorDtorC1Ev(%0) : (!cir.ptr<!rec_NeedsCtorDtor>) -> () } dtor { @@ -38,11 +39,25 @@ module attributes {cir.triple = "x86_64-unknown-linux-gnu"} { } // CHECK: cir.func private @_ZN13NeedsCtorDtorC1Ev(!cir.ptr<!rec_NeedsCtorDtor>) // CHECK: cir.func private @_ZN13NeedsCtorDtorD1Ev(!cir.ptr<!rec_NeedsCtorDtor>) - // CHECK: cir.global external dso_local @needsCtorDtor = ctor : !rec_NeedsCtorDtor { + // CHECK: cir.global external dso_local @needsCtorDtor = #cir.zero : !rec_NeedsCtorDtor ctor { // CHECK: %0 = cir.get_global @needsCtorDtor : !cir.ptr<!rec_NeedsCtorDtor> // CHECK: cir.call @_ZN13NeedsCtorDtorC1Ev(%0) : (!cir.ptr<!rec_NeedsCtorDtor>) -> () // CHECK: } dtor { // CHECK: %0 = cir.get_global @needsCtorDtor : !cir.ptr<!rec_NeedsCtorDtor> // CHECK: cir.call @_ZN13NeedsCtorDtorD1Ev(%0) : (!cir.ptr<!rec_NeedsCtorDtor>) -> () // CHECK: } + + // The initial value is kept alongside the ctor even when it is not zero, + // e.g. a null data member pointer after CXX ABI lowering. + cir.func private @_Z9getMemberv() -> !s64i + cir.global external @memberPtr = #cir.int<-1> : !s64i ctor { + %0 = cir.get_global @memberPtr : !cir.ptr<!s64i> + %1 = cir.call @_Z9getMemberv() : () -> !s64i + cir.store %1, %0 : !s64i, !cir.ptr<!s64i> + } + // CHECK: cir.global external @memberPtr = #cir.int<-1> : !s64i ctor { + // CHECK: %0 = cir.get_global @memberPtr : !cir.ptr<!s64i> + // CHECK: %1 = cir.call @_Z9getMemberv() : () -> !s64i + // CHECK: cir.store %1, %0 : !s64i, !cir.ptr<!s64i> + // CHECK: } } diff --git a/clang/test/CIR/IR/invalid-global.cir b/clang/test/CIR/IR/invalid-global.cir index dda5de7af9560..620cdbabb2c24 100644 --- a/clang/test/CIR/IR/invalid-global.cir +++ b/clang/test/CIR/IR/invalid-global.cir @@ -20,7 +20,7 @@ module { cir.global external @target = #cir.int<42> : !s32i // expected-error @below {{global alias shall not have an initializer or constructor/destructor regions}} -cir.global external @bad_alias_with_ctor alias(@target) = ctor : !s32i { +cir.global external @bad_alias_with_ctor alias(@target) = #cir.int<0> : !s32i ctor { cir.yield } @@ -60,3 +60,18 @@ module { cir.global external comdat(1) @bad_comdat = #cir.int<42> : !s32i } + +// ----- + +!s32i = !cir.int<s, 32> + +module { + +// The custom syntax always carries an initial value, so use the generic form. +// expected-error @below {{cannot have a constructor region without an initial value}} +"cir.global"() <{global_visibility = 0 : i32, linkage = #cir.linkage<external>, sym_name = "ctor_without_init", sym_type = !s32i}> ({ + cir.yield +}, { +}) : () -> () + +} diff --git a/clang/test/CIR/IR/invalid-static-local.cir b/clang/test/CIR/IR/invalid-static-local.cir index 31a7b1178d92e..6c3a73cb7984e 100644 --- a/clang/test/CIR/IR/invalid-static-local.cir +++ b/clang/test/CIR/IR/invalid-static-local.cir @@ -67,7 +67,7 @@ module { cir.global "private" internal dynamic_init_guard<"_ZGVZ1fvE1y"> @_ZZ1fvE1y : !s32i dynamic_init_info<local = true, tls = none, is_inline = false, tsk = undeclared> -cir.global "private" internal @_AnotherGlobal = ctor : !s32i { +cir.global "private" internal @_AnotherGlobal = #cir.int<0> : !s32i ctor { // expected-error @below {{'cir.local_init' op expects ancestor op 'cir.func'}} cir.local_init static_local @_ZZ1fvE1y ctor { cir.yield diff --git a/clang/unittests/CIR/ControlFlowTest.cpp b/clang/unittests/CIR/ControlFlowTest.cpp index 47312d5e8843a..51b22c620c0a1 100644 --- a/clang/unittests/CIR/ControlFlowTest.cpp +++ b/clang/unittests/CIR/ControlFlowTest.cpp @@ -543,7 +543,7 @@ TEST_F(CIRControlFlowTest, CleanupScopeOp) { TEST_F(CIRControlFlowTest, GlobalOpWithCtorAndDtor) { OwningOpRef<ModuleOp> module = parse(R"CIR( !s32i = !cir.int<s, 32> - cir.global external @g = ctor : !s32i { + cir.global external @g = #cir.int<0> : !s32i ctor { cir.yield } dtor { cir.yield _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
