https://github.com/andykaylor updated 
https://github.com/llvm/llvm-project/pull/168463

>From 905d166769141a8c30def3c0ca8290340d88fdce Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Mon, 17 Nov 2025 16:17:31 -0800
Subject: [PATCH 1/2] [CIR] Mark globals as constants

We previously added support for marking GlobalOp operations as constant,
but the handling to actually do so was left mostly unimplemented. This
fills in the missing pieces.
---
 clang/include/clang/CIR/MissingFeatures.h     |  1 -
 clang/lib/CIR/CodeGen/CIRGenDecl.cpp          |  2 +-
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        |  9 ++-
 .../CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp |  4 +-
 clang/test/CIR/CodeGen/constant-inits.cpp     | 60 +++++++++----------
 clang/test/CIR/CodeGen/global-constant.c      | 20 +++++++
 .../CIR/CodeGen/record-zero-init-padding.c    | 16 ++---
 clang/test/CIR/CodeGen/vtt.cpp                | 14 ++---
 8 files changed, 74 insertions(+), 52 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/global-constant.c

diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index d93ee2675b366..0cb567a9a8f5a 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -29,7 +29,6 @@ struct MissingFeatures {
 
   // Unhandled global/linkage information.
   static bool opGlobalThreadLocal() { return false; }
-  static bool opGlobalConstant() { return false; }
   static bool opGlobalWeakRef() { return false; }
   static bool opGlobalUnnamedAddr() { return false; }
   static bool opGlobalSection() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp 
b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 325875d10d6ea..6b25959d43d45 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -526,7 +526,7 @@ cir::GlobalOp CIRGenFunction::addInitializerToStaticVarDecl(
   bool needsDtor =
       d.needsDestruction(getContext()) == QualType::DK_cxx_destructor;
 
-  assert(!cir::MissingFeatures::opGlobalConstant());
+  gv.setConstant(d.getType().isConstantStorage(getContext(), true, 
!needsDtor));
   gv.setInitialValueAttr(init);
 
   emitter.finalize(gv);
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index c1f2581eb96e3..9a5c1508c7fff 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -675,7 +675,9 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, 
mlir::Type ty,
       errorNYI(d->getSourceRange(), "OpenMP target global variable");
 
     gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
-    assert(!cir::MissingFeatures::opGlobalConstant());
+    // FIXME: This code is overly simple and should be merged with other global
+    // handling.
+    gv.setConstant(d->getType().isConstantStorage(astContext, false, false));
 
     setLinkageForGV(gv, d);
 
@@ -864,7 +866,10 @@ void CIRGenModule::emitGlobalVarDefinition(const 
clang::VarDecl *vd,
   if (emitter)
     emitter->finalize(gv);
 
-  assert(!cir::MissingFeatures::opGlobalConstant());
+  // If it is safe to mark the global 'constant', do so now.
+  gv.setConstant((vd->hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
+                 (!needsGlobalCtor && !needsGlobalDtor &&
+                  vd->getType().isConstantStorage(astContext, true, true)));
   assert(!cir::MissingFeatures::opGlobalSection());
 
   // Set CIR's linkage type as appropriate.
diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp 
b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
index 92434d730eb31..0095efcb4e266 100644
--- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
+++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
@@ -1995,7 +1995,6 @@ void 
CIRToLLVMGlobalOpLowering::setupRegionInitializedLLVMGlobalOp(
   //        attributes are available on cir.global ops. This duplicates code
   //        in CIRToLLVMGlobalOpLowering::matchAndRewrite() but that will go
   //        away when the placeholders are no longer needed.
-  assert(!cir::MissingFeatures::opGlobalConstant());
   const bool isConst = op.getConstant();
   assert(!cir::MissingFeatures::addressSpace());
   const unsigned addrSpace = 0;
@@ -2055,8 +2054,7 @@ mlir::LogicalResult 
CIRToLLVMGlobalOpLowering::matchAndRewrite(
       convertTypeForMemory(*getTypeConverter(), dataLayout, cirSymType);
   // FIXME: These default values are placeholders until the the equivalent
   //        attributes are available on cir.global ops.
-  assert(!cir::MissingFeatures::opGlobalConstant());
-  const bool isConst = false;
+  const bool isConst = op.getConstant();
   assert(!cir::MissingFeatures::addressSpace());
   const unsigned addrSpace = 0;
   const bool isDsoLocal = op.getDsoLocal();
diff --git a/clang/test/CIR/CodeGen/constant-inits.cpp 
b/clang/test/CIR/CodeGen/constant-inits.cpp
index d5a7bb9d57251..ef9802de405c1 100644
--- a/clang/test/CIR/CodeGen/constant-inits.cpp
+++ b/clang/test/CIR/CodeGen/constant-inits.cpp
@@ -105,57 +105,57 @@ void function() {
 // CIR-DAG: !rec_anon_struct = !cir.record<struct  {!u8i, !u8i, !u8i, !u8i}>
 // CIR-DAG: !rec_anon_struct1 = !cir.record<struct  {!u8i, !u8i, 
!cir.array<!u8i x 2>}>
 
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE1e = 
#cir.zero : !rec_empty
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE1s = 
#cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : !s32i}> : !rec_simple
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE2p1 = 
#cir.const_record<{#cir.int<10> : !s32i, #cir.int<20> : !s32i, 
#cir.const_array<[#cir.int<99> : !s8i, #cir.int<88> : !s8i, #cir.int<77> : 
!s8i]> : !cir.array<!s8i x 3>, #cir.int<40> : !s32i}> : !rec_Point
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE2p2 = 
#cir.const_record<{#cir.int<123> : !s8i, #cir.int<456> : !s32i}> : !rec_packed
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE3paa = 
#cir.const_record<{#cir.int<1> : !s16i, #cir.int<2> : !s8i, 
#cir.fp<3.000000e+00> : !cir.float, #cir.zero : !u8i}> : !rec_packed_and_aligned
+// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE1e 
= #cir.zero : !rec_empty
+// CIR-DAG: cir.global "private" constant internal dso_local @_ZZ8functionvE1s 
= #cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : !s32i}> : !rec_simple
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE2p1 = #cir.const_record<{#cir.int<10> : !s32i, #cir.int<20> : 
!s32i, #cir.const_array<[#cir.int<99> : !s8i, #cir.int<88> : !s8i, #cir.int<77> 
: !s8i]> : !cir.array<!s8i x 3>, #cir.int<40> : !s32i}> : !rec_Point
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE2p2 = #cir.const_record<{#cir.int<123> : !s8i, #cir.int<456> : 
!s32i}> : !rec_packed
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE3paa = #cir.const_record<{#cir.int<1> : !s16i, #cir.int<2> : 
!s8i, #cir.fp<3.000000e+00> : !cir.float, #cir.zero : !u8i}> : 
!rec_packed_and_aligned
 
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5array = 
#cir.const_array<[
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE5array = #cir.const_array<[
 // CIR-DAG-SAME:   #cir.const_record<{#cir.int<123> : !s32i, #cir.int<456> : 
!s32i, #cir.const_array<[#cir.int<11> : !s8i, #cir.int<22> : !s8i, #cir.int<33> 
: !s8i]> : !cir.array<!s8i x 3>, #cir.int<789> : !s32i}> : !rec_Point
 // CIR-DAG-SAME:   #cir.const_record<{#cir.int<10> : !s32i, #cir.int<20> : 
!s32i, #cir.zero : !cir.array<!s8i x 3>, #cir.int<40> : !s32i}> : !rec_Point
 // CIR-DAG-SAME: ]> : !cir.array<!rec_Point x 2>
 
-// CIR-DAG: cir.global "private" internal dso_local 
@_ZZ8functionvE12simple_array = #cir.const_array<[
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE12simple_array = #cir.const_array<[
 // CIR-DAG-SAME:   #cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : 
!s32i}> : !rec_simple,
 // CIR-DAG-SAME:   #cir.const_record<{#cir.int<1111> : !s32i, #cir.int<2222> : 
!s32i}> : !rec_simple,
 // CIR-DAG-SAME:   #cir.const_record<{#cir.int<0> : !s32i, #cir.int<-1> : 
!s32i}> : !rec_simple
 // CIR-DAG-SAME: ]> : !cir.array<!rec_simple x 3>
 
-// CIR-DAG: cir.global "private" internal dso_local 
@_ZZ8functionvE12packed_array = #cir.const_array<[
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE12packed_array = #cir.const_array<[
 // CIR-DAG-SAME:   #cir.const_record<{#cir.int<123> : !s8i, #cir.int<456> : 
!s32i}> : !rec_packed,
 // CIR-DAG-SAME:   #cir.const_record<{#cir.int<123> : !s8i, #cir.int<456> : 
!s32i}> : !rec_packed
 // CIR-DAG-SAME: ]> : !cir.array<!rec_packed x 2>
 
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE9paa_array 
= #cir.const_array<[
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE9paa_array = #cir.const_array<[
 // CIR-DAG-SAME:   #cir.const_record<{#cir.int<1> : !s16i, #cir.int<2> : !s8i, 
#cir.fp<3.000000e+00> : !cir.float, #cir.zero : !u8i}> : 
!rec_packed_and_aligned,
 // CIR-DAG-SAME:   #cir.zero : !rec_packed_and_aligned
 // CIR-DAG-SAME: ]> : !cir.array<!rec_packed_and_aligned x 2>
 
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf1 = 
#cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE6ba_bf1 = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<255> : !u8i,
 // CIR-DAG-SAME:   #cir.int<170> : !u8i,
 // CIR-DAG-SAME:   #cir.int<52> : !u8i,
 // CIR-DAG-SAME:   #cir.int<18> : !u8i
 // CIR-DAG-SAME: }> : !rec_anon_struct
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf2 = 
#cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE6ba_bf2 = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<255> : !u8i,
 // CIR-DAG-SAME:   #cir.int<127> : !u8i,
 // CIR-DAG-SAME:   #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i]> : 
!cir.array<!u8i x 2>
 // CIR-DAG-SAME: }> : !rec_anon_struct1
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE6ba_bf3 = 
#cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE6ba_bf3 = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<42> : !u8i
 // CIR-DAG-SAME: }> : !rec_single_byte_bitfield
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf1 = 
#cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE5p_bf1 = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<17> : !u8i,
 // CIR-DAG-SAME:   #cir.int<3> : !u8i,
 // CIR-DAG-SAME:   #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i]> : 
!cir.array<!u8i x 2>
 // CIR-DAG-SAME: }> : !rec_anon_struct1
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf2 = 
#cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE5p_bf2 = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<127> : !u8i,
 // CIR-DAG-SAME:   #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, 
#cir.zero : !u8i]> : !cir.array<!u8i x 3>
 // CIR-DAG-SAME: }> : !rec_signed_partial_bitfields
-// CIR-DAG: cir.global "private" internal dso_local @_ZZ8functionvE5p_bf3 = 
#cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@_ZZ8functionvE5p_bf3 = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<125> : !u8i
 // CIR-DAG-SAME: }> : !rec_mixed_partial_bitfields
 
@@ -163,21 +163,21 @@ void function() {
 // CIR:   cir.return
 
 
-// LLVM-DAG: @_ZZ8functionvE12packed_array = internal global [2 x 
%struct.packed] [%struct.packed <{ i8 123, i32 456 }>, %struct.packed <{ i8 
123, i32 456 }>]
-// LLVM-DAG: @_ZZ8functionvE12simple_array = internal global [3 x 
%struct.simple] [%struct.simple { i32 0, i32 -1 }, %struct.simple { i32 1111, 
i32 2222 }, %struct.simple { i32 0, i32 -1 }]
-// LLVM-DAG: @_ZZ8functionvE1e = internal global %struct.empty zeroinitializer
-// LLVM-DAG: @_ZZ8functionvE1s = internal global %struct.simple { i32 0, i32 
-1 }
-// LLVM-DAG: @_ZZ8functionvE2p1 = internal global %struct.Point { i32 10, i32 
20, [3 x i8] c"cXM", i32 40 }
-// LLVM-DAG: @_ZZ8functionvE2p2 = internal global %struct.packed <{ i8 123, 
i32 456 }>
-// LLVM-DAG: @_ZZ8functionvE3paa = internal global %struct.packed_and_aligned 
<{ i16 1, i8 2, float 3.000000e+00, i8 0 }>
-// LLVM-DAG: @_ZZ8functionvE5array = internal global [2 x %struct.Point] 
[%struct.Point { i32 123, i32 456, [3 x i8] c"\0B\16!", i32 789 }, 
%struct.Point { i32 10, i32 20, [3 x i8] zeroinitializer, i32 40 }]
-// LLVM-DAG: @_ZZ8functionvE9paa_array = internal global [2 x 
%struct.packed_and_aligned] [%struct.packed_and_aligned <{ i16 1, i8 2, float 
3.000000e+00, i8 0 }>, %struct.packed_and_aligned zeroinitializer]
-// LLVM-DAG: @_ZZ8functionvE6ba_bf1 = internal global { i8, i8, i8, i8 } { i8 
-1, i8 -86, i8 52, i8 18 }
-// LLVM-DAG: @_ZZ8functionvE6ba_bf2 = internal global { i8, i8, [2 x i8] } { 
i8 -1, i8 127, [2 x i8] zeroinitializer }
-// LLVM-DAG: @_ZZ8functionvE6ba_bf3 = internal global 
%struct.single_byte_bitfield { i8 42 }
-// LLVM-DAG: @_ZZ8functionvE5p_bf1 = internal global { i8, i8, [2 x i8] } { i8 
17, i8 3, [2 x i8] zeroinitializer }
-// LLVM-DAG: @_ZZ8functionvE5p_bf2 = internal global 
%struct.signed_partial_bitfields { i8 127, [3 x i8] zeroinitializer }
-// LLVM-DAG: @_ZZ8functionvE5p_bf3 = internal global 
%struct.mixed_partial_bitfields { i8 125 }
+// LLVM-DAG: @_ZZ8functionvE12packed_array = internal constant [2 x 
%struct.packed] [%struct.packed <{ i8 123, i32 456 }>, %struct.packed <{ i8 
123, i32 456 }>]
+// LLVM-DAG: @_ZZ8functionvE12simple_array = internal constant [3 x 
%struct.simple] [%struct.simple { i32 0, i32 -1 }, %struct.simple { i32 1111, 
i32 2222 }, %struct.simple { i32 0, i32 -1 }]
+// LLVM-DAG: @_ZZ8functionvE1e = internal constant %struct.empty 
zeroinitializer
+// LLVM-DAG: @_ZZ8functionvE1s = internal constant %struct.simple { i32 0, i32 
-1 }
+// LLVM-DAG: @_ZZ8functionvE2p1 = internal constant %struct.Point { i32 10, 
i32 20, [3 x i8] c"cXM", i32 40 }
+// LLVM-DAG: @_ZZ8functionvE2p2 = internal constant %struct.packed <{ i8 123, 
i32 456 }>
+// LLVM-DAG: @_ZZ8functionvE3paa = internal constant 
%struct.packed_and_aligned <{ i16 1, i8 2, float 3.000000e+00, i8 0 }>
+// LLVM-DAG: @_ZZ8functionvE5array = internal constant [2 x %struct.Point] 
[%struct.Point { i32 123, i32 456, [3 x i8] c"\0B\16!", i32 789 }, 
%struct.Point { i32 10, i32 20, [3 x i8] zeroinitializer, i32 40 }]
+// LLVM-DAG: @_ZZ8functionvE9paa_array = internal constant [2 x 
%struct.packed_and_aligned] [%struct.packed_and_aligned <{ i16 1, i8 2, float 
3.000000e+00, i8 0 }>, %struct.packed_and_aligned zeroinitializer]
+// LLVM-DAG: @_ZZ8functionvE6ba_bf1 = internal constant { i8, i8, i8, i8 } { 
i8 -1, i8 -86, i8 52, i8 18 }
+// LLVM-DAG: @_ZZ8functionvE6ba_bf2 = internal constant { i8, i8, [2 x i8] } { 
i8 -1, i8 127, [2 x i8] zeroinitializer }
+// LLVM-DAG: @_ZZ8functionvE6ba_bf3 = internal constant 
%struct.single_byte_bitfield { i8 42 }
+// LLVM-DAG: @_ZZ8functionvE5p_bf1 = internal constant { i8, i8, [2 x i8] } { 
i8 17, i8 3, [2 x i8] zeroinitializer }
+// LLVM-DAG: @_ZZ8functionvE5p_bf2 = internal constant 
%struct.signed_partial_bitfields { i8 127, [3 x i8] zeroinitializer }
+// LLVM-DAG: @_ZZ8functionvE5p_bf3 = internal constant 
%struct.mixed_partial_bitfields { i8 125 }
 
 // LLVM-LABEL: define{{.*}} void @_Z8functionv
 // LLVM:   ret void
diff --git a/clang/test/CIR/CodeGen/global-constant.c 
b/clang/test/CIR/CodeGen/global-constant.c
new file mode 100644
index 0000000000000..588642c0c3faa
--- /dev/null
+++ b/clang/test/CIR/CodeGen/global-constant.c
@@ -0,0 +1,20 @@
+// 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-cir.ll
+// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
+// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s
+
+const int global_no_use = 12;
+// CIR: cir.global constant {{.*}}@global_no_use
+// LLVM: @global_no_use = constant
+// OGCG: @global_no_use = constant
+
+const float global_used = 1.2f;
+// CIR: cir.global constant {{.*}}@global_used
+// LLVM: @global_used = constant
+// OGCG: @global_used = constant
+
+float const * get_float_ptr() {
+  return &global_used;
+}
diff --git a/clang/test/CIR/CodeGen/record-zero-init-padding.c 
b/clang/test/CIR/CodeGen/record-zero-init-padding.c
index f131c9bbd069f..9c8daccb21a53 100644
--- a/clang/test/CIR/CodeGen/record-zero-init-padding.c
+++ b/clang/test/CIR/CodeGen/record-zero-init-padding.c
@@ -41,28 +41,28 @@ void test_zero_init_padding(void) {
 // CIR-DAG: !rec_anon_struct3 = !cir.record<struct  {!s8i, !cir.array<!u8i x 
3>, !s32i}>
 
 // paf: char + 3 bytes padding + int -> uses !rec_anon_struct3
-// CIR-DAG: cir.global "private" internal dso_local 
@test_zero_init_padding.paf = #cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@test_zero_init_padding.paf = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<1> : !s8i,
 // CIR-DAG-SAME:   #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, 
#cir.zero : !u8i]> : !cir.array<!u8i x 3>,
 // CIR-DAG-SAME:   #cir.int<42> : !s32i
 // CIR-DAG-SAME: }> : !rec_anon_struct3
 
 // bfp: unsigned bitfield byte + 3 bytes padding + int -> uses 
!rec_anon_struct2
-// CIR-DAG: cir.global "private" internal dso_local 
@test_zero_init_padding.bfp = #cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@test_zero_init_padding.bfp = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<17> : !u8i,
 // CIR-DAG-SAME:   #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, 
#cir.zero : !u8i]> : !cir.array<!u8i x 3>,
 // CIR-DAG-SAME:   #cir.int<99> : !s32i
 // CIR-DAG-SAME: }> : !rec_anon_struct2
 
 // tp: int + char + 3 bytes tail padding -> uses !rec_anon_struct1
-// CIR-DAG: cir.global "private" internal dso_local @test_zero_init_padding.tp 
= #cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@test_zero_init_padding.tp = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<10> : !s32i,
 // CIR-DAG-SAME:   #cir.int<20> : !s8i,
 // CIR-DAG-SAME:   #cir.const_array<[#cir.zero : !u8i, #cir.zero : !u8i, 
#cir.zero : !u8i]> : !cir.array<!u8i x 3>
 // CIR-DAG-SAME: }> : !rec_anon_struct1
 
 // mp: char + 1 byte padding + short + 4 bytes padding + long long -> uses 
!rec_anon_struct
-// CIR-DAG: cir.global "private" internal dso_local @test_zero_init_padding.mp 
= #cir.const_record<{
+// CIR-DAG: cir.global "private" constant internal dso_local 
@test_zero_init_padding.mp = #cir.const_record<{
 // CIR-DAG-SAME:   #cir.int<5> : !s8i,
 // CIR-DAG-SAME:   #cir.zero : !u8i,
 // CIR-DAG-SAME:   #cir.int<10> : !s16i,
@@ -73,10 +73,10 @@ void test_zero_init_padding(void) {
 // CIR-LABEL: cir.func {{.*}}@test_zero_init_padding
 // CIR:   cir.return
 
-// LLVM-DAG: @test_zero_init_padding.paf = internal global { i8, [3 x i8], i32 
} { i8 1, [3 x i8] zeroinitializer, i32 42 }
-// LLVM-DAG: @test_zero_init_padding.bfp = internal global { i8, [3 x i8], i32 
} { i8 17, [3 x i8] zeroinitializer, i32 99 }
-// LLVM-DAG: @test_zero_init_padding.tp = internal global { i32, i8, [3 x i8] 
} { i32 10, i8 20, [3 x i8] zeroinitializer }
-// LLVM-DAG: @test_zero_init_padding.mp = internal global { i8, i8, i16, [4 x 
i8], i64 } { i8 5, i8 0, i16 10, [4 x i8] zeroinitializer, i64 100 }
+// LLVM-DAG: @test_zero_init_padding.paf = internal constant { i8, [3 x i8], 
i32 } { i8 1, [3 x i8] zeroinitializer, i32 42 }
+// LLVM-DAG: @test_zero_init_padding.bfp = internal constant { i8, [3 x i8], 
i32 } { i8 17, [3 x i8] zeroinitializer, i32 99 }
+// LLVM-DAG: @test_zero_init_padding.tp = internal constant { i32, i8, [3 x 
i8] } { i32 10, i8 20, [3 x i8] zeroinitializer }
+// LLVM-DAG: @test_zero_init_padding.mp = internal constant { i8, i8, i16, [4 
x i8], i64 } { i8 5, i8 0, i16 10, [4 x i8] zeroinitializer, i64 100 }
 
 // LLVM-LABEL: define{{.*}} void @test_zero_init_padding
 // LLVM:   ret void
diff --git a/clang/test/CIR/CodeGen/vtt.cpp b/clang/test/CIR/CodeGen/vtt.cpp
index f9a62e37450cf..d0319b7adc126 100644
--- a/clang/test/CIR/CodeGen/vtt.cpp
+++ b/clang/test/CIR/CodeGen/vtt.cpp
@@ -5,12 +5,12 @@
 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fno-rtti -emit-llvm %s -o 
%t.ll
 // RUN: FileCheck --check-prefixes=OGCG-NO-RTTI,OGCG-COMMON --input-file=%t.ll 
 %s
 
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t.cir
-// RUN: FileCheck --check-prefixes=CIR-RTTI,CIR-COMMON --input-file=%t.cir %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir.ll
-// RUN: FileCheck --check-prefixes=LLVM-RTTI,LLVM-COMMON 
--input-file=%t-cir.ll  %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll
-// RUN: FileCheck --check-prefixes=OGCG-RTTI,OGCG-COMMON --input-file=%t.ll  %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
%t-rtti.cir
+// RUN: FileCheck --check-prefixes=CIR-RTTI,CIR-COMMON 
--input-file=%t-rtti.cir %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
%t-cir-rtti.ll
+// RUN: FileCheck --check-prefixes=LLVM-RTTI,LLVM-COMMON 
--input-file=%t-cir-rtti.ll  %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t-rtti.ll
+// RUN: FileCheck --check-prefixes=OGCG-RTTI,OGCG-COMMON 
--input-file=%t-rtti.ll  %s
 
 // Note: This test will be expanded to verify VTT emission and VTT implicit
 // argument handling. For now, it's just test the record layout.
@@ -170,7 +170,7 @@ void D::y() {}
 
 // CIR-RTTI:  cir.global{{.*}} @_ZTI1B : !cir.ptr<!u8i>
 
-// LLVM-RTTI: @_ZTI1B = external global ptr
+// LLVM-RTTI: @_ZTI1B = external constant ptr
 
 // OGCG-RTTI: @_ZTI1B = external constant ptr
 

>From 64845c2ad9c62fcbfe36e537f7d174f83ea8dc1f Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Tue, 18 Nov 2025 10:41:20 -0800
Subject: [PATCH 2/2] Address review feedback

---
 clang/lib/CIR/CodeGen/CIRGenDecl.cpp   | 3 ++-
 clang/lib/CIR/CodeGen/CIRGenModule.cpp | 6 ++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp 
b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index 6b25959d43d45..e0e4f67df87b2 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -526,7 +526,8 @@ cir::GlobalOp CIRGenFunction::addInitializerToStaticVarDecl(
   bool needsDtor =
       d.needsDestruction(getContext()) == QualType::DK_cxx_destructor;
 
-  gv.setConstant(d.getType().isConstantStorage(getContext(), true, 
!needsDtor));
+  gv.setConstant(d.getType().isConstantStorage(
+      getContext(), /*ExcludeCtor=*/true, !needsDtor));
   gv.setInitialValueAttr(init);
 
   emitter.finalize(gv);
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 9a5c1508c7fff..4a82ea3121b60 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -677,7 +677,8 @@ CIRGenModule::getOrCreateCIRGlobal(StringRef mangledName, 
mlir::Type ty,
     gv.setAlignmentAttr(getSize(astContext.getDeclAlign(d)));
     // FIXME: This code is overly simple and should be merged with other global
     // handling.
-    gv.setConstant(d->getType().isConstantStorage(astContext, false, false));
+    gv.setConstant(d->getType().isConstantStorage(
+        astContext, /*ExcludeCtor=*/false, /*ExcludeDtor=*/false));
 
     setLinkageForGV(gv, d);
 
@@ -869,7 +870,8 @@ void CIRGenModule::emitGlobalVarDefinition(const 
clang::VarDecl *vd,
   // If it is safe to mark the global 'constant', do so now.
   gv.setConstant((vd->hasAttr<CUDAConstantAttr>() && langOpts.CUDAIsDevice) ||
                  (!needsGlobalCtor && !needsGlobalDtor &&
-                  vd->getType().isConstantStorage(astContext, true, true)));
+                  vd->getType().isConstantStorage(
+                      astContext, /*ExcludeCtor=*/true, 
/*ExcludeDtor=*/true)));
   assert(!cir::MissingFeatures::opGlobalSection());
 
   // Set CIR's linkage type as appropriate.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to