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

>From 08353a39097576500fa3516b121c87e7711d30b7 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Tue, 21 Oct 2025 15:17:45 -0700
Subject: [PATCH 1/2] [CIR] Handle overlapping values in constant init
 expressions

This adds handling for generating constant initializers in the case
where a value we are emitting overlaps with a previous constant,
such as can happen when initializing a structure with bitfields.
---
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 19 +++++++++++++++++--
 clang/test/CIR/CodeGen/struct-init.cpp       | 15 +++++++++++++++
 2 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 800262aac8fa4..8f05014811a1f 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -179,8 +179,23 @@ bool ConstantAggregateBuilder::add(mlir::TypedAttr 
typedAttr, CharUnits offset,
   }
 
   // Uncommon case: constant overlaps what we've already created.
-  cgm.errorNYI("overlapping constants");
-  return false;
+  std::optional<size_t> firstElemToReplace = splitAt(offset);
+  if (!firstElemToReplace)
+    return false;
+
+  CharUnits cSize = getSize(typedAttr);
+  std::optional<size_t> lastElemToReplace = splitAt(offset + cSize);
+  if (!lastElemToReplace)
+    return false;
+
+  assert((firstElemToReplace == lastElemToReplace || allowOverwrite) &&
+         "unexpectedly overwriting field");
+
+  Element newElt(typedAttr, offset);
+  replace(elements, *firstElemToReplace, *lastElemToReplace, {newElt});
+  size = std::max(size, offset + cSize);
+  naturalLayout = false;
+  return true;
 }
 
 bool ConstantAggregateBuilder::addBits(llvm::APInt bits, uint64_t offsetInBits,
diff --git a/clang/test/CIR/CodeGen/struct-init.cpp 
b/clang/test/CIR/CodeGen/struct-init.cpp
index cb509994d1cbf..9d6389f5ad977 100644
--- a/clang/test/CIR/CodeGen/struct-init.cpp
+++ b/clang/test/CIR/CodeGen/struct-init.cpp
@@ -5,6 +5,21 @@
 // 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
 
+struct O {
+  unsigned int a:4;
+  unsigned int b:14;
+  unsigned int c:14;
+};
+
+O overlapping_init = { 3, 2, 1 };
+
+// This is unintuitive. The bitfields are initialized using a struct of 
constants
+// that maps to the bitfields but splits the value into bytes.
+
+// CIR: cir.global external @overlapping_init = 
#cir.const_record<{#cir.int<35> : !u8i, #cir.int<0> : !u8i, #cir.int<4> : !u8i, 
#cir.int<0> : !u8i}> : !rec_anon_struct
+// LLVM: @overlapping_init = global { i8, i8, i8, i8 } { i8 35, i8 0, i8 4, i8 
0 }
+// OGCG: @overlapping_init = global { i8, i8, i8, i8 } { i8 35, i8 0, i8 4, i8 
0 }
+
 struct S {
   int a, b, c;
 };

>From f4a6bb74a767df0dd51177d75d214d8b7e0fdf28 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <[email protected]>
Date: Wed, 22 Oct 2025 14:02:25 -0700
Subject: [PATCH 2/2] Rename test struct

---
 clang/test/CIR/CodeGen/struct-init.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/clang/test/CIR/CodeGen/struct-init.cpp 
b/clang/test/CIR/CodeGen/struct-init.cpp
index 9d6389f5ad977..63e13dd708392 100644
--- a/clang/test/CIR/CodeGen/struct-init.cpp
+++ b/clang/test/CIR/CodeGen/struct-init.cpp
@@ -5,13 +5,13 @@
 // 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
 
-struct O {
+struct BitfieldStruct {
   unsigned int a:4;
   unsigned int b:14;
   unsigned int c:14;
 };
 
-O overlapping_init = { 3, 2, 1 };
+BitfieldStruct overlapping_init = { 3, 2, 1 };
 
 // This is unintuitive. The bitfields are initialized using a struct of 
constants
 // that maps to the bitfields but splits the value into bytes.

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

Reply via email to