[CIR] Handle static local var decl constants (#190699)

This adds the handling for the case where the address of a static local
variable is used to initialize another static local. In this case, the
address of the first variable is emitted as a constant in the
initializer of the second variable.
This commit is contained in:
Andy Kaylor 2026-04-06 16:13:23 -07:00 committed by GitHub
parent 228b6ae560
commit aedd4e0850
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 21 additions and 6 deletions

View File

@ -1402,9 +1402,10 @@ ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
return cgm.getAddrOfGlobalVarAttr(vd);
if (vd->isLocalVarDecl()) {
cgm.errorNYI(vd->getSourceRange(),
"ConstantLValueEmitter: local var decl");
return {};
cir::GlobalLinkageKind linkage =
cgm.getCIRLinkageVarDefinition(vd, /*IsConstant=*/false);
return cgm.getBuilder().getGlobalViewAttr(
cgm.getOrCreateStaticVarDecl(*vd, linkage));
}
}
}

View File

@ -3,6 +3,20 @@
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o - | FileCheck %s --check-prefix=LLVM
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=OGCG
void use_static_decl() {
static int x = 42;
static int *p = &x;
}
// CIR-DAG: cir.global "private" internal dso_local @_ZZ15use_static_declvE1p = #cir.global_view<@_ZZ15use_static_declvE1x> : !cir.ptr<!s32i>
// CIR-DAG: cir.global "private" internal dso_local @_ZZ15use_static_declvE1x = #cir.int<42> : !s32i
// LLVM-DAG: @_ZZ15use_static_declvE1p = internal global ptr @_ZZ15use_static_declvE1x
// LLVM-DAG: @_ZZ15use_static_declvE1x = internal global i32 42
// OGCG-DAG: @_ZZ15use_static_declvE1x = internal global i32 42
// OGCG-DAG: @_ZZ15use_static_declvE1p = internal global ptr @_ZZ15use_static_declvE1x
class A {
public:
A();
@ -24,7 +38,7 @@ void f() {
// CIR-BEFORE-LPP: cir.call @_Z3useP1A(%[[VAR]])
// CIR-BEFORE-LPP: cir.return
// CIR: cir.global "private" internal dso_local @_ZGVZ1fvE1a = #cir.int<0> : !s64i
// CIR-DAG: cir.global "private" internal dso_local @_ZGVZ1fvE1a = #cir.int<0> : !s64i
// CIR: cir.func{{.*}}@_Z1fv()
// CIR: %[[ADDR:.*]] = cir.get_global static_local @_ZZ1fvE1a : !cir.ptr<!rec_A>
// CIR: %[[GUARD:.*]] = cir.get_global @_ZGVZ1fvE1a : !cir.ptr<!s64i>
@ -40,7 +54,7 @@ void f() {
// CIR: cir.call @_Z3useP1A(%[[ADDR]])
// CIR: cir.return
// LLVM: @_ZGVZ1fvE1a = internal global i64 0
// LLVM-DAG: @_ZGVZ1fvE1a = internal global i64 0
// LLVM: define{{.*}}void @_Z1fv()
// LLVM: %[[GUARD:.*]] = load atomic i8, ptr @_ZGVZ1fvE1a acquire
// LLVM: %[[IS_UNINIT:.*]] = icmp eq i8 %[[GUARD]], 0
@ -51,7 +65,7 @@ void f() {
// LLVM: call void @_Z3useP1A(ptr {{.*}}@_ZZ1fvE1a)
// LLVM: ret void
// OGCG: @_ZGVZ1fvE1a = internal global i64 0
// OGCG-DAG: @_ZGVZ1fvE1a = internal global i64 0
// OGCG: define{{.*}}void @_Z1fv()
// OGCG: %[[GUARD:.*]] = load atomic i8, ptr @_ZGVZ1fvE1a acquire
// OGCG: %[[IS_UNINIT:.*]] = icmp eq i8 %[[GUARD]], 0