From c00233238bf0b348e0d16d0aad55ff33367f99d6 Mon Sep 17 00:00:00 2001 From: 7mile Date: Wed, 2 Oct 2024 06:41:38 +0800 Subject: [PATCH] [CIR][CodeGen] Set constant properly for global variables (#904) Fix #801 (the remaining `constant` part). Actually the missing stage is CIRGen. There are two places where `GV.setConstant` is called: * `buildGlobalVarDefinition` * `getOrCreateCIRGlobal` Therefore, the primary test `global-constant.c` contains a global definition and a global declaration with use, which should be enough to cover the two paths. A test for OpenCL `constant` qualified global is also added. Some existing testcases need tweaking to avoid failure of missing constant. --- clang/lib/CIR/CodeGen/CIRGenModule.cpp | 9 +++--- clang/test/CIR/CodeGen/OpenCL/global.cl | 4 +++ .../CIR/CodeGen/cxx1z-inline-variables.cpp | 28 +++++++++---------- clang/test/CIR/CodeGen/global-constant.c | 16 +++++++++++ clang/test/CIR/CodeGen/globals.c | 2 +- clang/test/CIR/CodeGen/temporaries.cpp | 4 +-- 6 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 clang/test/CIR/CodeGen/global-constant.c diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 76bad240e9c5..68e8e93e5b77 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -947,9 +947,8 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef MangledName, mlir::Type Ty, // FIXME: This code is overly simple and should be merged with other global // handling. GV.setAlignmentAttr(getSize(astCtx.getDeclAlign(D))); - // TODO(cir): - // GV->setConstant(isTypeConstant(D->getType(), false)); - // setLinkageForGV(GV, D); + GV.setConstant(isTypeConstant(D->getType(), false, false)); + // TODO(cir): setLinkageForGV(GV, D); if (D->getTLSKind()) { if (D->getTLSKind() == VarDecl::TLS_Dynamic) @@ -1278,8 +1277,8 @@ void CIRGenModule::buildGlobalVarDefinition(const clang::VarDecl *D, emitter->finalize(GV); // TODO(cir): If it is safe to mark the global 'constant', do so now. - // GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor && - // isTypeConstant(D->getType(), true)); + GV.setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor && + isTypeConstant(D->getType(), true, true)); // If it is in a read-only section, mark it 'constant'. if (const SectionAttr *SA = D->getAttr()) diff --git a/clang/test/CIR/CodeGen/OpenCL/global.cl b/clang/test/CIR/CodeGen/OpenCL/global.cl index cab7378fd102..3ec7ee36fd80 100644 --- a/clang/test/CIR/CodeGen/OpenCL/global.cl +++ b/clang/test/CIR/CodeGen/OpenCL/global.cl @@ -11,6 +11,10 @@ global int b = 15; // CIR-DAG: cir.global external addrspace(offload_global) @b = #cir.int<15> : !s32i // LLVM-DAG: @b = addrspace(1) global i32 15 +constant int c[2] = {18, 21}; +// CIR-DAG: cir.global constant {{.*}}addrspace(offload_constant) {{.*}}@c +// LLVM-DAG: @c = addrspace(2) constant + kernel void test_get_global() { a = b; // CIR: %[[#ADDRB:]] = cir.get_global @b : !cir.ptr diff --git a/clang/test/CIR/CodeGen/cxx1z-inline-variables.cpp b/clang/test/CIR/CodeGen/cxx1z-inline-variables.cpp index 68cddd578767..8da371e6abe4 100644 --- a/clang/test/CIR/CodeGen/cxx1z-inline-variables.cpp +++ b/clang/test/CIR/CodeGen/cxx1z-inline-variables.cpp @@ -26,13 +26,13 @@ const int &compat_use_after_redecl1 = compat::c; const int &compat_use_after_redecl2 = compat::d; const int &compat_use_after_redecl3 = compat::g; -// CIR: cir.global weak_odr comdat @_ZN6compat1bE = #cir.int<2> : !s32i {alignment = 4 : i64} -// CIR: cir.global weak_odr comdat @_ZN6compat1aE = #cir.int<1> : !s32i {alignment = 4 : i64} -// CIR: cir.global weak_odr comdat @_ZN6compat1cE = #cir.int<3> : !s32i {alignment = 4 : i64} -// CIR: cir.global external @_ZN6compat1eE = #cir.int<5> : !s32i {alignment = 4 : i64} -// CIR: cir.global weak_odr comdat @_ZN6compat1fE = #cir.int<6> : !s32i {alignment = 4 : i64} -// CIR: cir.global linkonce_odr comdat @_ZN6compat1dE = #cir.int<4> : !s32i {alignment = 4 : i64} -// CIR: cir.global linkonce_odr comdat @_ZN6compat1gE = #cir.int<7> : !s32i {alignment = 4 : i64} +// CIR: cir.global constant weak_odr comdat @_ZN6compat1bE = #cir.int<2> : !s32i {alignment = 4 : i64} +// CIR: cir.global constant weak_odr comdat @_ZN6compat1aE = #cir.int<1> : !s32i {alignment = 4 : i64} +// CIR: cir.global constant weak_odr comdat @_ZN6compat1cE = #cir.int<3> : !s32i {alignment = 4 : i64} +// CIR: cir.global constant external @_ZN6compat1eE = #cir.int<5> : !s32i {alignment = 4 : i64} +// CIR: cir.global constant weak_odr comdat @_ZN6compat1fE = #cir.int<6> : !s32i {alignment = 4 : i64} +// CIR: cir.global constant linkonce_odr comdat @_ZN6compat1dE = #cir.int<4> : !s32i {alignment = 4 : i64} +// CIR: cir.global constant linkonce_odr comdat @_ZN6compat1gE = #cir.int<7> : !s32i {alignment = 4 : i64} // LLVM: $_ZN6compat1bE = comdat any // LLVM: $_ZN6compat1aE = comdat any @@ -41,10 +41,10 @@ const int &compat_use_after_redecl3 = compat::g; // LLVM: $_ZN6compat1dE = comdat any // LLVM: $_ZN6compat1gE = comdat any -// LLVM: @_ZN6compat1bE = weak_odr global i32 2, comdat, align 4 -// LLVM: @_ZN6compat1aE = weak_odr global i32 1, comdat, align 4 -// LLVM: @_ZN6compat1cE = weak_odr global i32 3, comdat, align 4 -// LLVM: @_ZN6compat1eE = global i32 5, align 4 -// LLVM: @_ZN6compat1fE = weak_odr global i32 6, comdat, align 4 -// LLVM: @_ZN6compat1dE = linkonce_odr global i32 4, comdat, align 4 -// LLVM: @_ZN6compat1gE = linkonce_odr global i32 7, comdat, align 4 +// LLVM: @_ZN6compat1bE = weak_odr constant i32 2, comdat, align 4 +// LLVM: @_ZN6compat1aE = weak_odr constant i32 1, comdat, align 4 +// LLVM: @_ZN6compat1cE = weak_odr constant i32 3, comdat, align 4 +// LLVM: @_ZN6compat1eE = constant i32 5, align 4 +// LLVM: @_ZN6compat1fE = weak_odr constant i32 6, comdat, align 4 +// LLVM: @_ZN6compat1dE = linkonce_odr constant i32 4, comdat, align 4 +// LLVM: @_ZN6compat1gE = linkonce_odr constant i32 7, comdat, align 4 diff --git a/clang/test/CIR/CodeGen/global-constant.c b/clang/test/CIR/CodeGen/global-constant.c new file mode 100644 index 000000000000..4301fcee7a7a --- /dev/null +++ b/clang/test/CIR/CodeGen/global-constant.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -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 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t.ll +// RUN: FileCheck --check-prefix=LLVM --input-file=%t.ll %s + +const int global_no_use = 12; +// CIR: cir.global constant {{.*}}@global_no_use +// LLVM: @global_no_use = constant + +const float global_used = 1.2f; +// CIR: cir.global constant {{.*}}@global_used +// LLVM: @global_used = constant + +float const * get_float_ptr() { + return &global_used; +} diff --git a/clang/test/CIR/CodeGen/globals.c b/clang/test/CIR/CodeGen/globals.c index 58d731f7e0fb..63b8f0b0ee48 100644 --- a/clang/test/CIR/CodeGen/globals.c +++ b/clang/test/CIR/CodeGen/globals.c @@ -93,7 +93,7 @@ struct Glob { } glob; double *const glob_ptr = &glob.b[1]; -// CHECK: cir.global external @glob_ptr = #cir.global_view<@glob, [2 : i32, 1 : i32]> : !cir.ptr +// CHECK: cir.global constant external @glob_ptr = #cir.global_view<@glob, [2 : i32, 1 : i32]> : !cir.ptr // TODO: test tentatives with internal linkage. diff --git a/clang/test/CIR/CodeGen/temporaries.cpp b/clang/test/CIR/CodeGen/temporaries.cpp index 1dafb75e8a70..23e0adb70b2d 100644 --- a/clang/test/CIR/CodeGen/temporaries.cpp +++ b/clang/test/CIR/CodeGen/temporaries.cpp @@ -32,8 +32,8 @@ const unsigned int n = 1234; const int &r = (const int&)n; // CHECK: cir.global "private" constant internal @_ZGR1r_ = #cir.int<1234> : !s32i -// CHECK-NEXT: cir.global external @r = #cir.global_view<@_ZGR1r_> : !cir.ptr {alignment = 8 : i64} +// CHECK-NEXT: cir.global constant external @r = #cir.global_view<@_ZGR1r_> : !cir.ptr {alignment = 8 : i64} // LLVM: @_ZGR1r_ = internal constant i32 1234, align 4 -// LLVM-NEXT: @r = global ptr @_ZGR1r_, align 8 +// LLVM-NEXT: @r = constant ptr @_ZGR1r_, align 8