llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Erich Keane (erichkeane) <details> <summary>Changes</summary> No real challenge to these, it is effectively a copy/paste of the classic codegen as it just requires we properly emit the holding variable. The rest falls out of the rest of our handling of variables. --- Full diff: https://github.com/llvm/llvm-project/pull/190364.diff 2 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+5-6) - (added) clang/test/CIR/CodeGen/global-decomp-decls.cpp (+114) ``````````diff diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index d7e7d435dce17..b88ba3dd91d61 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -1977,12 +1977,11 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) { case Decl::Var: case Decl::Decomposition: case Decl::VarTemplateSpecialization: { - auto *vd = cast<VarDecl>(decl); - if (isa<DecompositionDecl>(decl)) { - errorNYI(decl->getSourceRange(), "global variable decompositions"); - break; - } - emitGlobal(vd); + emitGlobal(cast<VarDecl>(decl)); + if (auto *decomp = dyn_cast<DecompositionDecl>(decl)) + for (auto *binding : decomp->flat_bindings()) + if (auto *holdingVar = binding->getHoldingVar()) + emitGlobal(holdingVar); break; } case Decl::OpenACCRoutine: diff --git a/clang/test/CIR/CodeGen/global-decomp-decls.cpp b/clang/test/CIR/CodeGen/global-decomp-decls.cpp new file mode 100644 index 0000000000000..74c7ad1f2d80e --- /dev/null +++ b/clang/test/CIR/CodeGen/global-decomp-decls.cpp @@ -0,0 +1,114 @@ +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --check-prefix=LLVM,LLVMCIR --input-file=%t-cir.ll %s +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=LLVM,OGCG --input-file=%t.ll %s + +template<typename T> +auto getT() { + return T{1, 2}; +} + +struct Type { int a, b, c; }; + +Type t{1,2,3}; + +// LLVM: @_ZDC2t12t22t3E = global %struct.Type zeroinitializer +// LLVM: @_ZDC3t113t123t13E = global ptr null +// LLVM: @_ZDC3dt13dt23dt3E = global %struct.DtorType zeroinitializer + +auto [t1, t2, t3] = t; +// CIR: cir.global external @_ZDC2t12t22t3E = #cir.zero : !rec_Type +// CIR: cir.func internal private @__cxx_global_var_init{{.*}}() +// CIR: %[[SB:.*]] = cir.get_global @_ZDC2t12t22t3E : !cir.ptr<!rec_Type> +// CIR: %[[T:.*]] = cir.get_global @t : !cir.ptr<!rec_Type> +// CIR: cir.copy %[[T]] to %[[SB]] : !cir.ptr<!rec_Type> + +// LLVM: define internal void @__cxx_global_var_init{{.*}}() +// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}@_ZDC2t12t22t3E, ptr {{.*}}@t, i64 12, i1 false) + +const auto & [t11, t12, t13] = getT<Type>(); +// CIR: cir.global external @_ZDC3t113t123t13E = #cir.ptr<null> : !cir.ptr<!rec_Type> +// CIR: cir.func internal private @__cxx_global_var_init{{.*}}() { +// CIR: %[[SB:.*]] = cir.get_global @_ZDC3t113t123t13E : !cir.ptr<!cir.ptr<!rec_Type>> +// CIR: %[[SB_REF:.*]] = cir.get_global @_ZGRDC3t113t123t13E_ : !cir.ptr<!rec_Type> +// CIR: %[[GETTCALL:.*]] = cir.call @_Z4getTI4TypeEDav() : () -> !rec_Type +// CIR: cir.store align(4) %[[GETTCALL]], %[[SB_REF]] : !rec_Type, !cir.ptr<!rec_Type> +// CIR: cir.store align(8) %[[SB_REF]], %[[SB]] : !cir.ptr<!rec_Type>, !cir.ptr<!cir.ptr<!rec_Type>> + +// LLVM: define internal void @__cxx_global_var_init{{.*}}() +// LLVMCIR: %[[GETTCALL:.*]] = call %struct.Type @_Z4getTI4TypeEDav() +// OGCG: %[[GETTCALL:.*]] = call { i64, i32 } @_Z4getTI4TypeEDav() +// LLVMCIR: store %struct.Type %[[GETTCALL]], ptr @_ZGRDC3t113t123t13E_, align 4 +// OGCG: store { i64, i32 } %call, ptr %[[COERCED_PTR:.*]], +// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 @_ZGRDC3t113t123t13E_, ptr align 8 %[[COERCED_PTR]], i64 12, i1 false) +// LLVM: store ptr @_ZGRDC3t113t123t13E_, ptr @_ZDC3t113t123t13E, align 8 + +struct DtorType { int a, b, c; ~DtorType(); }; + +DtorType dt; +auto [dt1, dt2, dt3] = dt; + +// CIR: cir.global external @_ZDC3dt13dt23dt3E = #cir.zero : !rec_DtorType +// CIR: cir.func internal private @__cxx_global_var_init{{.*}}() { +// CIR: %[[SB:.*]] = cir.get_global @_ZDC3dt13dt23dt3E : !cir.ptr<!rec_DtorType> +// CIR: %[[DT:.*]] = cir.get_global @dt : !cir.ptr<!rec_DtorType> +// CIR: cir.copy %[[DT]] to %[[SB]] : !cir.ptr<!rec_DtorType> +// CIR: %[[SB:.*]] = cir.get_global @_ZDC3dt13dt23dt3E : !cir.ptr<!rec_DtorType> +// CIR: %[[DTOR_PTR:.*]] = cir.get_global @_ZN8DtorTypeD1Ev : !cir.ptr<!cir.func<(!cir.ptr<!rec_DtorType>)>> +// CIR: %[[DTOR_PTR_CAST:.*]] = cir.cast bitcast %[[DTOR_PTR]] : !cir.ptr<!cir.func<(!cir.ptr<!rec_DtorType>)>> -> !cir.ptr<!cir.func<(!cir.ptr<!void>)>> +// CIR: %[[SB_VOIDPTR:.*]] = cir.cast bitcast %[[SB]] : !cir.ptr<!rec_DtorType> -> !cir.ptr<!void> +// CIR: %[[DSO_HANDLE:.*]] = cir.get_global @__dso_handle : !cir.ptr<i8> +// CIR: cir.call @__cxa_atexit(%[[DTOR_PTR_CAST]], %[[SB_VOIDPTR]], %[[DSO_HANDLE]]) : (!cir.ptr<!cir.func<(!cir.ptr<!void>)>>, !cir.ptr<!void>, !cir.ptr<i8>) -> () + +// LLVM: define internal void @__cxx_global_var_init{{.*}}() +// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr {{.*}}@_ZDC3dt13dt23dt3E, ptr {{.*}}@dt, i64 12, i1 false) +// LLVM: call {{.*}} @__cxa_atexit(ptr @_ZN8DtorTypeD1Ev, ptr @_ZDC3dt13dt23dt3E, ptr @__dso_handle) + +extern "C" int use() { + return t1 + t2 + t3 + + t11 + t12 + t13 + + dt1 + dt2 + dt3; + // CIR-LABEL: use() + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC2t12t22t3E : !cir.ptr<!rec_Type> + // CIR: cir.get_member %[[GET_GLOB]][0] {name = "a"} : !cir.ptr<!rec_Type> -> !cir.ptr<!s32i> + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC2t12t22t3E : !cir.ptr<!rec_Type> + // CIR: cir.get_member %[[GET_GLOB]][1] {name = "b"} : !cir.ptr<!rec_Type> -> !cir.ptr<!s32i> + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC2t12t22t3E : !cir.ptr<!rec_Type> + // CIR: cir.get_member %[[GET_GLOB]][2] {name = "c"} : !cir.ptr<!rec_Type> -> !cir.ptr<!s32i> + + // LLVM: load i32, ptr @_ZDC2t12t22t3E, align 4 + // LLVM: load i32, ptr getelementptr inbounds nuw (i8, ptr @_ZDC2t12t22t3E, i64 4), align 4 + // LLVM: load i32, ptr getelementptr inbounds nuw (i8, ptr @_ZDC2t12t22t3E, i64 8), align 4 + + // Extra load is because this is a reference. + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC3t113t123t13E : !cir.ptr<!cir.ptr<!rec_Type>> + // CIR: %[[LOAD_GLOB:.*]] = cir.load %[[GET_GLOB]] : !cir.ptr<!cir.ptr<!rec_Type>>, !cir.ptr<!rec_Type> + // CIR: cir.get_member %[[LOAD_GLOB]][0] {name = "a"} : !cir.ptr<!rec_Type> -> !cir.ptr<!s32i> + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC3t113t123t13E : !cir.ptr<!cir.ptr<!rec_Type>> + // CIR: %[[LOAD_GLOB:.*]] = cir.load %[[GET_GLOB]] : !cir.ptr<!cir.ptr<!rec_Type>>, !cir.ptr<!rec_Type> + // CIR: cir.get_member %[[LOAD_GLOB]][1] {name = "b"} : !cir.ptr<!rec_Type> -> !cir.ptr<!s32i> + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC3t113t123t13E : !cir.ptr<!cir.ptr<!rec_Type>> + // CIR: %[[LOAD_GLOB:.*]] = cir.load %[[GET_GLOB]] : !cir.ptr<!cir.ptr<!rec_Type>>, !cir.ptr<!rec_Type> + // CIR: cir.get_member %[[LOAD_GLOB]][2] {name = "c"} : !cir.ptr<!rec_Type> -> !cir.ptr<!s32i> + + // LLVM: %[[LOAD_REF:.*]] = load ptr, ptr @_ZDC3t113t123t13E, align 8 + // LLVM: getelementptr {{.*}}%struct.Type, ptr %[[LOAD_REF]], i32 0, i32 0 + // LLVM: %[[LOAD_REF:.*]] = load ptr, ptr @_ZDC3t113t123t13E, align 8 + // LLVM: getelementptr {{.*}}%struct.Type, ptr %[[LOAD_REF]], i32 0, i32 1 + // LLVM: %[[LOAD_REF:.*]] = load ptr, ptr @_ZDC3t113t123t13E, align 8 + // LLVM: etelementptr {{.*}}%struct.Type, ptr %[[LOAD_REF]], i32 0, i32 2 + + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC3dt13dt23dt3E : !cir.ptr<!rec_DtorType> + // CIR: cir.get_member %[[GET_GLOB]][0] {name = "a"} : !cir.ptr<!rec_DtorType> -> !cir.ptr<!s32i> + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC3dt13dt23dt3E : !cir.ptr<!rec_DtorType> + // CIR: cir.get_member %[[GET_GLOB]][1] {name = "b"} : !cir.ptr<!rec_DtorType> -> !cir.ptr<!s32i> + // CIR: %[[GET_GLOB:.*]] = cir.get_global @_ZDC3dt13dt23dt3E : !cir.ptr<!rec_DtorType> + // CIR: cir.get_member %[[GET_GLOB]][2] {name = "c"} : !cir.ptr<!rec_DtorType> -> !cir.ptr<!s32i> + + // LLVM: load i32, ptr @_ZDC3dt13dt23dt3E, align 4 + // LLVM: load i32, ptr getelementptr inbounds nuw (i8, ptr @_ZDC3dt13dt23dt3E, i64 4), align 4 + // LLVM: load i32, ptr getelementptr inbounds nuw (i8, ptr @_ZDC3dt13dt23dt3E, i64 8), align 4 +} + `````````` </details> https://github.com/llvm/llvm-project/pull/190364 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
