[clang] [CIR] Emit Memset in emitNullInitialization for default inits case (PR #221029)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 4 10:53:32 PDT 2026
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/221029
>From 1d2c28d7a6ab94cdc903f8b88ab51fe29a35e4ef Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Wed, 2 Sep 2026 21:29:48 +0200
Subject: [PATCH 1/3] [CIR] Emit Memset in emitNullInitialization for default
inits case
---
clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 23 +++++++------
clang/test/CIR/CodeGen/delegating-ctor.cpp | 9 ++++--
.../CIR/CodeGen/implicit-value-init-expr.cpp | 28 ++++++++++------
clang/test/CIR/CodeGen/new.cpp | 32 +++++++++++++------
.../test/CIR/CodeGen/paren-list-agg-init.cpp | 7 ++--
5 files changed, 66 insertions(+), 33 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index 6ec51939e02dc..d576ee103c4d3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -1376,11 +1376,11 @@ void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
return;
// Cast the dest ptr to the appropriate i8 pointer type.
- if (builder.isInt8Ty(destPtr.getElementType())) {
- cgm.errorNYI(loc, "Cast the dest ptr to the appropriate i8 pointer type");
- }
+ if (!builder.isInt8Ty(destPtr.getElementType()))
+ destPtr = destPtr.withElementType(builder, sInt8Ty);
// Get size and alignment info for this aggregate.
+ mlir::IntegerAttr sizeVal;
const CharUnits size = getContext().getTypeSizeInChars(ty);
if (size.isZero()) {
// But note that getTypeInfo returns 0 for a VLA.
@@ -1390,6 +1390,8 @@ void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
} else {
return;
}
+ } else {
+ sizeVal = cgm.getSize(size);
}
// If the type contains a pointer to data member we can't memset it to zero.
@@ -1408,12 +1410,15 @@ void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
return;
}
- // In LLVM Codegen: otherwise, just memset the whole thing to zero using
- // Builder.CreateMemSet. In CIR just emit a store of #cir.zero to the
- // respective address.
- // Builder.CreateMemSet(DestPtr, Builder.getInt8(0), SizeVal, false);
- const mlir::Value zeroValue = builder.getNullValue(convertType(ty), loc);
- builder.createStore(loc, zeroValue, destPtr);
+ // Otherwise, just memset the whole thing to zero. This is legal
+ // because in LLVM, all default initializers (other than the ones we just
+ // handled above, and the case handled below) are guaranteed to have a bit
+ // pattern of all zeros.
+ mlir::Value zero = builder.getNullValue(builder.getUInt8Ty(), loc);
+ mlir::Value sizeValue =
+ builder.getConstAPInt(loc, cgm.uInt64Ty, sizeVal.getValue());
+ destPtr = destPtr.withElementType(builder, cgm.voidTy);
+ builder.createMemSet(loc, destPtr, zero, sizeValue);
}
CIRGenFunction::CIRGenFPOptionsRAII::CIRGenFPOptionsRAII(CIRGenFunction &cgf,
diff --git a/clang/test/CIR/CodeGen/delegating-ctor.cpp b/clang/test/CIR/CodeGen/delegating-ctor.cpp
index 20b05562eb0a4..9422c586b1efa 100644
--- a/clang/test/CIR/CodeGen/delegating-ctor.cpp
+++ b/clang/test/CIR/CodeGen/delegating-ctor.cpp
@@ -50,8 +50,11 @@ DelegatingWithZeroing::DelegatingWithZeroing(int) : DelegatingWithZeroing() {}
// CIR: cir.store{{.*}} %[[THIS_ARG]], %[[THIS_ADDR]]
// CIR: cir.store{{.*}} %[[I_ARG]], %[[I_ADDR]]
// CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
-// CIR: %[[ZERO:.*]] = cir.const #cir.zero : !rec_DelegatingWithZeroing
-// CIR: cir.store{{.*}} %[[ZERO]], %[[THIS]] : !rec_DelegatingWithZeroing, !cir.ptr<!rec_DelegatingWithZeroing>
+// CIR: %[[THIS_PTR_S8I:.*]] = cir.cast bitcast %[[THIS]] : !cir.ptr<!rec_DelegatingWithZeroing> -> !cir.ptr<!s8i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i loc(#loc47)
+// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !u64i loc(#loc47)
+// CIR: %[[THIS_VOID_PTR:.*]] = cir.cast bitcast %[[THIS_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void> loc(#loc15)
+// CIR: cir.libc.memset %[[CONST_4]] bytes at %[[THIS_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i loc(#loc47)
// LLVM: define {{.*}} void @_ZN21DelegatingWithZeroingC2Ei(ptr {{.*}} %[[THIS_ARG:.*]], i32 {{.*}} %[[I_ARG:.*]])
// LLVM: %[[THIS_ADDR:.*]] = alloca ptr
@@ -59,7 +62,7 @@ DelegatingWithZeroing::DelegatingWithZeroing(int) : DelegatingWithZeroing() {}
// LLVM: store ptr %[[THIS_ARG]], ptr %[[THIS_ADDR]]
// LLVM: store i32 %[[I_ARG]], ptr %[[I_ADDR]]
// LLVM: %[[THIS:.*]] = load ptr, ptr %[[THIS_ADDR]]
-// LLVM: store %struct.DelegatingWithZeroing zeroinitializer, ptr %[[THIS]]
+// LLVM: call void @llvm.memset.p0.i64(ptr align 4 %[[THIS]], i8 0, i64 4, i1 false)
// Note: OGCG elides the call to the default constructor.
diff --git a/clang/test/CIR/CodeGen/implicit-value-init-expr.cpp b/clang/test/CIR/CodeGen/implicit-value-init-expr.cpp
index df5f3de711bad..ec55cb32eec78 100644
--- a/clang/test/CIR/CodeGen/implicit-value-init-expr.cpp
+++ b/clang/test/CIR/CodeGen/implicit-value-init-expr.cpp
@@ -77,25 +77,35 @@ void test_aggregate() {
// CIR: cir.func {{.*}} @_ZN3FooC2Ev(
// CIR: %[[THIS:.*]] = cir.load %{{.*}}
+
// CIR: %[[BAR:.*]] = cir.get_member %[[THIS]][0] {name = "bar_"} : !cir.ptr<!rec_Foo> -> !cir.ptr<!cir.array<!s32i x 5>>
-// CIR: %[[ZERO:.*]] = cir.const #cir.zero : !cir.array<!s32i x 5>
-// CIR: cir.store{{.*}} %[[ZERO]], %[[BAR]] : !cir.array<!s32i x 5>, !cir.ptr<!cir.array<!s32i x 5>>
+// CIR: %[[BAR_PTR_S8I:.*]] = cir.cast bitcast %[[BAR]] : !cir.ptr<!cir.array<!s32i x 5>> -> !cir.ptr<!s8i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CIR: %[[CONST_20:.*]] = cir.const #cir.int<20> : !u64i
+// CIR: %[[BAR_VOID_PTR:.*]] = cir.cast bitcast %[[BAR_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR: cir.libc.memset %[[CONST_20]] bytes at %[[BAR_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR: %[[DBAR:.*]] = cir.get_member %[[THIS]][1] {name = "dbar_"} : !cir.ptr<!rec_Foo> -> !cir.ptr<!cir.array<!cir.double x 5>>
-// CIR: %[[ZERO:.*]] = cir.const #cir.zero : !cir.array<!cir.double x 5>
-// CIR: cir.store{{.*}} %[[ZERO]], %[[DBAR]] : !cir.array<!cir.double x 5>, !cir.ptr<!cir.array<!cir.double x 5>>
+// CIR: %[[DBAR_PTR_S8I:.*]] = cir.cast bitcast %[[DBAR]] : !cir.ptr<!cir.array<!cir.double x 5>> -> !cir.ptr<!s8i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CIR: %[[CONST_40:.*]] = cir.const #cir.int<40> : !u64i
+// CIR: %[[DBAR_VOID_PTR:.*]] = cir.cast bitcast %[[DBAR_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR: cir.libc.memset %[[CONST_40]] bytes at %[[DBAR_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR: %[[SBAR:.*]] = cir.get_member %[[THIS]][2] {name = "sbar_"} : !cir.ptr<!rec_Foo> -> !cir.ptr<!cir.array<!rec_S x 5>>
-// CIR: %[[ZERO:.*]] = cir.const #cir.zero : !cir.array<!rec_S x 5>
-// CIR: cir.store{{.*}} %[[ZERO]], %[[SBAR]] : !cir.array<!rec_S x 5>, !cir.ptr<!cir.array<!rec_S x 5>>
+// CIR: %[[SBAR_PTR_S8I:.*]] = cir.cast bitcast %[[SBAR]] : !cir.ptr<!cir.array<!rec_S x 5>> -> !cir.ptr<!s8i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CIR: %[[CONST_40:.*]] = cir.const #cir.int<40> : !u64i
+// CIR: %[[SBAR_VOID_PTR:.*]] = cir.cast bitcast %[[SBAR_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR: cir.libc.memset %[[CONST_40]] bytes at %[[SBAR_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR: cir.return
// LLVM: define {{.*}} void @_ZN3FooC2Ev(
// LLVM: %[[THIS:.*]] = load ptr, ptr
// LLVM: %[[BAR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %[[THIS]], i32 0, i32 0
-// LLVM: store [5 x i32] zeroinitializer, ptr %[[BAR]]
+// LLVM: call void @llvm.memset.p0.i64(ptr {{.*}}%[[BAR]], i8 0, i64 20, i1 false)
// LLVM: %[[DBAR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %[[THIS]], i32 0, i32 1
-// LLVM: store [5 x double] zeroinitializer, ptr %[[DBAR]]
+// LLVM: call void @llvm.memset.p0.i64(ptr {{.*}}%[[DBAR]], i8 0, i64 40, i1 false)
// LLVM: %[[SBAR:.*]] = getelementptr inbounds nuw %struct.Foo, ptr %[[THIS]], i32 0, i32 2
-// LLVM: store [5 x %struct.S] zeroinitializer, ptr %[[SBAR]]
+// LLVM: call void @llvm.memset.p0.i64(ptr {{.*}}%[[SBAR]], i8 0, i64 40, i1 false)
// LLVM: ret void
// OGCG: define{{.*}} void @_ZN3FooC2Ev(
diff --git a/clang/test/CIR/CodeGen/new.cpp b/clang/test/CIR/CodeGen/new.cpp
index 439e1d439c883..784fe18076c4c 100644
--- a/clang/test/CIR/CodeGen/new.cpp
+++ b/clang/test/CIR/CodeGen/new.cpp
@@ -864,16 +864,22 @@ void test_const_array_new_value_init() {
// CIR-BEFORE-LPP: cir.func{{.*}} @_Z31test_const_array_new_value_initv
// CIR-BEFORE-LPP: cir.array.ctor %{{.*}} : !cir.ptr<!cir.array<!rec_OuterZero x 3>> {
// CIR-BEFORE-LPP: ^bb0(%[[EL:.*]]: !cir.ptr<!rec_OuterZero>):
-// CIR-BEFORE-LPP: cir.const #cir.zero : !rec_OuterZero
-// CIR-BEFORE-LPP: cir.store{{.*}} %{{.*}}, %[[EL]] : !rec_OuterZero, !cir.ptr<!rec_OuterZero>
+// CIR-BEFORE-LPP: %[[EL_PTR_S8I:.*]] = cir.cast bitcast %[[EL]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!s8i>
+// CIR-BEFORE-LPP: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CIR-BEFORE-LPP: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
+// CIR-BEFORE-LPP: %[[EL_VOID_PTR:.*]] = cir.cast bitcast %[[EL_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR-BEFORE-LPP: cir.libc.memset %[[CONST_1]] bytes at %[[EL_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR-BEFORE-LPP: cir.call @_ZN9OuterZeroC1Ev(%[[EL]])
// CIR-BEFORE-LPP: }
// CHECK: cir.func{{.*}} @_Z31test_const_array_new_value_initv
// CHECK: cir.do {
// CHECK: %[[CUR:.*]] = cir.load{{.*}} : !cir.ptr<!cir.ptr<!rec_OuterZero>>, !cir.ptr<!rec_OuterZero>
-// CHECK: %[[ZERO:.*]] = cir.const #cir.zero : !rec_OuterZero
-// CHECK: cir.store{{.*}} %[[ZERO]], %[[CUR]] : !rec_OuterZero, !cir.ptr<!rec_OuterZero>
+// CHECK: %[[CUR_PTR_S8I:.*]] = cir.cast bitcast %[[CUR]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!s8i>
+// CHECK: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CHECK: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
+// CHECK: %[[CUR_VOID_PTR:.*]] = cir.cast bitcast %[[CUR_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CHECK: cir.libc.memset %[[CONST_1]] bytes at %[[CUR_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CHECK: cir.call @_ZN9OuterZeroC1Ev(%[[CUR]])
// CHECK: cir.ptr_stride
// CHECK: cir.store{{.*}} : !cir.ptr<!rec_OuterZero>, !cir.ptr<!cir.ptr<!rec_OuterZero>>
@@ -899,7 +905,7 @@ void test_const_array_new_value_init() {
// LLVM: br i1 %[[CMP]], label %[[BODY]], label %[[EXIT:.*]]
// LLVM: [[BODY]]:
// LLVM: %[[CUR:.*]] = load ptr, ptr %[[IDX]], align 8
-// LLVM: store %class.OuterZero zeroinitializer, ptr %[[CUR]], align 1
+// LLVM: call void @llvm.memset.p0.i64(ptr align 1 %[[CUR]], i8 0, i64 1, i1 false)
// LLVM: call void @_ZN9OuterZeroC1Ev(ptr {{.*}} %[[CUR]])
// LLVM: %[[NEXT:.*]] = getelementptr %class.OuterZero, ptr %[[CUR]], i64 1
// LLVM: store ptr %[[NEXT]], ptr %[[IDX]], align 8
@@ -944,16 +950,22 @@ void test_var_array_new_value_init(int n) {
// CIR-BEFORE-LPP-NEXT: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.array<!rec_OuterZero x 0>> -> !cir.ptr<!rec_OuterZero>
// CIR-BEFORE-LPP-NEXT: cir.array.ctor %{{.*}}, %[[N]] : !cir.ptr<!rec_OuterZero>, !u64i {
// CIR-BEFORE-LPP-NEXT: ^bb0(%[[EL:.*]]: !cir.ptr<!rec_OuterZero>):
-// CIR-BEFORE-LPP-NEXT: cir.const #cir.zero : !rec_OuterZero
-// CIR-BEFORE-LPP-NEXT: cir.store{{.*}} %{{.*}}, %[[EL]] : !rec_OuterZero, !cir.ptr<!rec_OuterZero>
+// CIR-BEFORE-LPP-NEXT: %[[EL_PTR_S8I:.*]] = cir.cast bitcast %[[EL]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!s8i>
+// CIR-BEFORE-LPP-NEXT: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CIR-BEFORE-LPP-NEXT: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
+// CIR-BEFORE-LPP-NEXT: %[[EL_VOID_PTR:.*]] = cir.cast bitcast %[[EL_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR-BEFORE-LPP-NEXT: cir.libc.memset %[[CONST_1]] bytes at %[[EL_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR-BEFORE-LPP-NEXT: cir.call @_ZN9OuterZeroC1Ev(%[[EL]]) : (!cir.ptr<!rec_OuterZero> {llvm.align = 1 : i64, llvm.dereferenceable = 1 : i64, llvm.nonnull, llvm.noundef}) -> ()
// CIR-BEFORE-LPP-NEXT: }
// CHECK-LABEL: cir.func{{.*}} @_Z29test_var_array_new_value_initi
// CHECK: cir.do {
// CHECK: cir.load{{.*}} : !cir.ptr<!cir.ptr<!rec_OuterZero>>, !cir.ptr<!rec_OuterZero>
-// CHECK: cir.const #cir.zero : !rec_OuterZero
-// CHECK: cir.store{{.*}} : !rec_OuterZero, !cir.ptr<!rec_OuterZero>
+// CHECK: %[[EL_PTR_S8I:.*]] = cir.cast bitcast {{.*}} : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!s8i>
+// CHECK: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CHECK: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
+// CHECK: %[[ARG_VOID_PTR:.*]] = cir.cast bitcast %{{.*}} : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CHECK: cir.libc.memset %[[CONST_1]] bytes at %[[ARG_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CHECK: cir.call @_ZN9OuterZeroC1Ev(
// CHECK: cir.ptr_stride
// CHECK: cir.store{{.*}} : !cir.ptr<!rec_OuterZero>, !cir.ptr<!cir.ptr<!rec_OuterZero>>
@@ -967,7 +979,7 @@ void test_var_array_new_value_init(int n) {
// LLVM-LABEL: define{{.*}} void @_Z29test_var_array_new_value_initi
// LLVM-NOT: call void @llvm.memset.p0.i64
-// LLVM: store %class.OuterZero zeroinitializer, ptr %[[CUR:.*]], align 1
+// LLVM: call void @llvm.memset.p0.i64(ptr align 1 %[[CUR:.*]], i8 0, i64 1, i1 false)
// LLVM-NEXT: call void @_ZN9OuterZeroC1Ev(ptr noundef nonnull align 1 dereferenceable(1) %[[CUR]])
// OGCG-LABEL: define{{.*}} void @_Z29test_var_array_new_value_initi
diff --git a/clang/test/CIR/CodeGen/paren-list-agg-init.cpp b/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
index 72bcf2c2e7ac1..cdb41ba307e06 100644
--- a/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
+++ b/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
@@ -355,8 +355,11 @@ D foo8() {
// CIR: %[[FP_2:.*]] = cir.const #cir.fp<2
// CIR: cir.store align(8) %[[FP_2]], %[[GET_J]] : !cir.double, !cir.ptr<!cir.double>
// CIR: %[[GET_C:.*]] = cir.get_member %[[D_ALLOCA]][3] {name = "c"} : !cir.ptr<![[STRUCT_D]]> -> !cir.ptr<![[STRUCT_A]]>
-// CIR: %[[ZERO:.*]] = cir.const #cir.zero : ![[STRUCT_A]]
-// CIR: cir.store align(8) %[[ZERO]], %[[GET_C]] : ![[STRUCT_A]], !cir.ptr<![[STRUCT_A]]>
+// CIR: %[[GET_C_PTR_S8I:.*]] = cir.cast bitcast %12 : !cir.ptr<![[STRUCT_A]]> -> !cir.ptr<!s8i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CIR: %[[CONST_16:.*]] = cir.const #cir.int<16> : !u64i
+// CIR: %[[GET_C_VOID_PTR:.*]] = cir.cast bitcast %[[GET_C_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR: cir.libc.memset %[[CONST_16]] bytes at %[[GET_C_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
void foo9() {
D d(A(1, 1));
}
>From 743b272363d023760c75329b50caeeb5cd9e8846 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Thu, 3 Sep 2026 22:21:17 +0200
Subject: [PATCH 2/3] Always cast to uint8
---
clang/lib/CIR/CodeGen/CIRGenFunction.cpp | 2 +-
clang/test/CIR/CodeGen/delegating-ctor.cpp | 10 +++++-----
.../CIR/CodeGen/implicit-value-init-expr.cpp | 12 ++++++------
clang/test/CIR/CodeGen/new.cpp | 16 ++++++++--------
clang/test/CIR/CodeGen/paren-list-agg-init.cpp | 4 ++--
5 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
index d576ee103c4d3..25ae08364713b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp
@@ -1377,7 +1377,7 @@ void CIRGenFunction::emitNullInitialization(mlir::Location loc, Address destPtr,
// Cast the dest ptr to the appropriate i8 pointer type.
if (!builder.isInt8Ty(destPtr.getElementType()))
- destPtr = destPtr.withElementType(builder, sInt8Ty);
+ destPtr = destPtr.withElementType(builder, uInt8Ty);
// Get size and alignment info for this aggregate.
mlir::IntegerAttr sizeVal;
diff --git a/clang/test/CIR/CodeGen/delegating-ctor.cpp b/clang/test/CIR/CodeGen/delegating-ctor.cpp
index 9422c586b1efa..1dbd44ee068c0 100644
--- a/clang/test/CIR/CodeGen/delegating-ctor.cpp
+++ b/clang/test/CIR/CodeGen/delegating-ctor.cpp
@@ -50,11 +50,11 @@ DelegatingWithZeroing::DelegatingWithZeroing(int) : DelegatingWithZeroing() {}
// CIR: cir.store{{.*}} %[[THIS_ARG]], %[[THIS_ADDR]]
// CIR: cir.store{{.*}} %[[I_ARG]], %[[I_ADDR]]
// CIR: %[[THIS:.*]] = cir.load %[[THIS_ADDR]]
-// CIR: %[[THIS_PTR_S8I:.*]] = cir.cast bitcast %[[THIS]] : !cir.ptr<!rec_DelegatingWithZeroing> -> !cir.ptr<!s8i>
-// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i loc(#loc47)
-// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !u64i loc(#loc47)
-// CIR: %[[THIS_VOID_PTR:.*]] = cir.cast bitcast %[[THIS_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void> loc(#loc15)
-// CIR: cir.libc.memset %[[CONST_4]] bytes at %[[THIS_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i loc(#loc47)
+// CIR: %[[THIS_PTR_i8:.*]] = cir.cast bitcast %[[THIS]] : !cir.ptr<!rec_DelegatingWithZeroing> -> !cir.ptr<!u8i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !u64i
+// CIR: %[[THIS_VOID_PTR:.*]] = cir.cast bitcast %[[THIS_PTR_i8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
+// CIR: cir.libc.memset %[[CONST_4]] bytes at %[[THIS_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// LLVM: define {{.*}} void @_ZN21DelegatingWithZeroingC2Ei(ptr {{.*}} %[[THIS_ARG:.*]], i32 {{.*}} %[[I_ARG:.*]])
// LLVM: %[[THIS_ADDR:.*]] = alloca ptr
diff --git a/clang/test/CIR/CodeGen/implicit-value-init-expr.cpp b/clang/test/CIR/CodeGen/implicit-value-init-expr.cpp
index ec55cb32eec78..399e72bcf202d 100644
--- a/clang/test/CIR/CodeGen/implicit-value-init-expr.cpp
+++ b/clang/test/CIR/CodeGen/implicit-value-init-expr.cpp
@@ -79,22 +79,22 @@ void test_aggregate() {
// CIR: %[[THIS:.*]] = cir.load %{{.*}}
// CIR: %[[BAR:.*]] = cir.get_member %[[THIS]][0] {name = "bar_"} : !cir.ptr<!rec_Foo> -> !cir.ptr<!cir.array<!s32i x 5>>
-// CIR: %[[BAR_PTR_S8I:.*]] = cir.cast bitcast %[[BAR]] : !cir.ptr<!cir.array<!s32i x 5>> -> !cir.ptr<!s8i>
+// CIR: %[[BAR_PTR_I8:.*]] = cir.cast bitcast %[[BAR]] : !cir.ptr<!cir.array<!s32i x 5>> -> !cir.ptr<!u8i>
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
// CIR: %[[CONST_20:.*]] = cir.const #cir.int<20> : !u64i
-// CIR: %[[BAR_VOID_PTR:.*]] = cir.cast bitcast %[[BAR_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR: %[[BAR_VOID_PTR:.*]] = cir.cast bitcast %[[BAR_PTR_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
// CIR: cir.libc.memset %[[CONST_20]] bytes at %[[BAR_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR: %[[DBAR:.*]] = cir.get_member %[[THIS]][1] {name = "dbar_"} : !cir.ptr<!rec_Foo> -> !cir.ptr<!cir.array<!cir.double x 5>>
-// CIR: %[[DBAR_PTR_S8I:.*]] = cir.cast bitcast %[[DBAR]] : !cir.ptr<!cir.array<!cir.double x 5>> -> !cir.ptr<!s8i>
+// CIR: %[[DBAR_PTR_I8:.*]] = cir.cast bitcast %[[DBAR]] : !cir.ptr<!cir.array<!cir.double x 5>> -> !cir.ptr<!u8i>
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
// CIR: %[[CONST_40:.*]] = cir.const #cir.int<40> : !u64i
-// CIR: %[[DBAR_VOID_PTR:.*]] = cir.cast bitcast %[[DBAR_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR: %[[DBAR_VOID_PTR:.*]] = cir.cast bitcast %[[DBAR_PTR_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
// CIR: cir.libc.memset %[[CONST_40]] bytes at %[[DBAR_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR: %[[SBAR:.*]] = cir.get_member %[[THIS]][2] {name = "sbar_"} : !cir.ptr<!rec_Foo> -> !cir.ptr<!cir.array<!rec_S x 5>>
-// CIR: %[[SBAR_PTR_S8I:.*]] = cir.cast bitcast %[[SBAR]] : !cir.ptr<!cir.array<!rec_S x 5>> -> !cir.ptr<!s8i>
+// CIR: %[[SBAR_PTR_I8:.*]] = cir.cast bitcast %[[SBAR]] : !cir.ptr<!cir.array<!rec_S x 5>> -> !cir.ptr<!u8i>
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
// CIR: %[[CONST_40:.*]] = cir.const #cir.int<40> : !u64i
-// CIR: %[[SBAR_VOID_PTR:.*]] = cir.cast bitcast %[[SBAR_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR: %[[SBAR_VOID_PTR:.*]] = cir.cast bitcast %[[SBAR_PTR_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
// CIR: cir.libc.memset %[[CONST_40]] bytes at %[[SBAR_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR: cir.return
diff --git a/clang/test/CIR/CodeGen/new.cpp b/clang/test/CIR/CodeGen/new.cpp
index 784fe18076c4c..539f40e24c98d 100644
--- a/clang/test/CIR/CodeGen/new.cpp
+++ b/clang/test/CIR/CodeGen/new.cpp
@@ -864,10 +864,10 @@ void test_const_array_new_value_init() {
// CIR-BEFORE-LPP: cir.func{{.*}} @_Z31test_const_array_new_value_initv
// CIR-BEFORE-LPP: cir.array.ctor %{{.*}} : !cir.ptr<!cir.array<!rec_OuterZero x 3>> {
// CIR-BEFORE-LPP: ^bb0(%[[EL:.*]]: !cir.ptr<!rec_OuterZero>):
-// CIR-BEFORE-LPP: %[[EL_PTR_S8I:.*]] = cir.cast bitcast %[[EL]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!s8i>
+// CIR-BEFORE-LPP: %[[EL_PTR_I8:.*]] = cir.cast bitcast %[[EL]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!u8i>
// CIR-BEFORE-LPP: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
// CIR-BEFORE-LPP: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
-// CIR-BEFORE-LPP: %[[EL_VOID_PTR:.*]] = cir.cast bitcast %[[EL_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR-BEFORE-LPP: %[[EL_VOID_PTR:.*]] = cir.cast bitcast %[[EL_PTR_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
// CIR-BEFORE-LPP: cir.libc.memset %[[CONST_1]] bytes at %[[EL_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR-BEFORE-LPP: cir.call @_ZN9OuterZeroC1Ev(%[[EL]])
// CIR-BEFORE-LPP: }
@@ -875,10 +875,10 @@ void test_const_array_new_value_init() {
// CHECK: cir.func{{.*}} @_Z31test_const_array_new_value_initv
// CHECK: cir.do {
// CHECK: %[[CUR:.*]] = cir.load{{.*}} : !cir.ptr<!cir.ptr<!rec_OuterZero>>, !cir.ptr<!rec_OuterZero>
-// CHECK: %[[CUR_PTR_S8I:.*]] = cir.cast bitcast %[[CUR]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!s8i>
+// CHECK: %[[CUR_PTR_I8:.*]] = cir.cast bitcast %[[CUR]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!u8i>
// CHECK: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
// CHECK: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
-// CHECK: %[[CUR_VOID_PTR:.*]] = cir.cast bitcast %[[CUR_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CHECK: %[[CUR_VOID_PTR:.*]] = cir.cast bitcast %[[CUR_PTR_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
// CHECK: cir.libc.memset %[[CONST_1]] bytes at %[[CUR_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CHECK: cir.call @_ZN9OuterZeroC1Ev(%[[CUR]])
// CHECK: cir.ptr_stride
@@ -950,10 +950,10 @@ void test_var_array_new_value_init(int n) {
// CIR-BEFORE-LPP-NEXT: cir.cast bitcast %{{.*}} : !cir.ptr<!cir.array<!rec_OuterZero x 0>> -> !cir.ptr<!rec_OuterZero>
// CIR-BEFORE-LPP-NEXT: cir.array.ctor %{{.*}}, %[[N]] : !cir.ptr<!rec_OuterZero>, !u64i {
// CIR-BEFORE-LPP-NEXT: ^bb0(%[[EL:.*]]: !cir.ptr<!rec_OuterZero>):
-// CIR-BEFORE-LPP-NEXT: %[[EL_PTR_S8I:.*]] = cir.cast bitcast %[[EL]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!s8i>
+// CIR-BEFORE-LPP-NEXT: %[[EL_PTR_I8:.*]] = cir.cast bitcast %[[EL]] : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!u8i>
// CIR-BEFORE-LPP-NEXT: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
// CIR-BEFORE-LPP-NEXT: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
-// CIR-BEFORE-LPP-NEXT: %[[EL_VOID_PTR:.*]] = cir.cast bitcast %[[EL_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR-BEFORE-LPP-NEXT: %[[EL_VOID_PTR:.*]] = cir.cast bitcast %[[EL_PTR_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
// CIR-BEFORE-LPP-NEXT: cir.libc.memset %[[CONST_1]] bytes at %[[EL_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR-BEFORE-LPP-NEXT: cir.call @_ZN9OuterZeroC1Ev(%[[EL]]) : (!cir.ptr<!rec_OuterZero> {llvm.align = 1 : i64, llvm.dereferenceable = 1 : i64, llvm.nonnull, llvm.noundef}) -> ()
// CIR-BEFORE-LPP-NEXT: }
@@ -961,10 +961,10 @@ void test_var_array_new_value_init(int n) {
// CHECK-LABEL: cir.func{{.*}} @_Z29test_var_array_new_value_initi
// CHECK: cir.do {
// CHECK: cir.load{{.*}} : !cir.ptr<!cir.ptr<!rec_OuterZero>>, !cir.ptr<!rec_OuterZero>
-// CHECK: %[[EL_PTR_S8I:.*]] = cir.cast bitcast {{.*}} : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!s8i>
+// CHECK: %[[EL_PTR_I8:.*]] = cir.cast bitcast {{.*}} : !cir.ptr<!rec_OuterZero> -> !cir.ptr<!u8i>
// CHECK: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
// CHECK: %[[CONST_1:.*]] = cir.const #cir.int<1> : !u64i
-// CHECK: %[[ARG_VOID_PTR:.*]] = cir.cast bitcast %{{.*}} : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CHECK: %[[ARG_VOID_PTR:.*]] = cir.cast bitcast %[[EL_PTR_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
// CHECK: cir.libc.memset %[[CONST_1]] bytes at %[[ARG_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CHECK: cir.call @_ZN9OuterZeroC1Ev(
// CHECK: cir.ptr_stride
diff --git a/clang/test/CIR/CodeGen/paren-list-agg-init.cpp b/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
index cdb41ba307e06..03ea451ac2387 100644
--- a/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
+++ b/clang/test/CIR/CodeGen/paren-list-agg-init.cpp
@@ -355,10 +355,10 @@ D foo8() {
// CIR: %[[FP_2:.*]] = cir.const #cir.fp<2
// CIR: cir.store align(8) %[[FP_2]], %[[GET_J]] : !cir.double, !cir.ptr<!cir.double>
// CIR: %[[GET_C:.*]] = cir.get_member %[[D_ALLOCA]][3] {name = "c"} : !cir.ptr<![[STRUCT_D]]> -> !cir.ptr<![[STRUCT_A]]>
-// CIR: %[[GET_C_PTR_S8I:.*]] = cir.cast bitcast %12 : !cir.ptr<![[STRUCT_A]]> -> !cir.ptr<!s8i>
+// CIR: %[[GET_C_PTR_I8:.*]] = cir.cast bitcast %12 : !cir.ptr<![[STRUCT_A]]> -> !cir.ptr<!u8i>
// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
// CIR: %[[CONST_16:.*]] = cir.const #cir.int<16> : !u64i
-// CIR: %[[GET_C_VOID_PTR:.*]] = cir.cast bitcast %[[GET_C_PTR_S8I]] : !cir.ptr<!s8i> -> !cir.ptr<!void>
+// CIR: %[[GET_C_VOID_PTR:.*]] = cir.cast bitcast %[[GET_C_PTR_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
// CIR: cir.libc.memset %[[CONST_16]] bytes at %[[GET_C_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
void foo9() {
D d(A(1, 1));
>From 4c253982761f37534a82834e8488030d933c2af3 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Fri, 4 Sep 2026 19:53:10 +0200
Subject: [PATCH 3/3] Update aggregate atomic cast test
---
clang/test/CIR/CodeGen/agg-atomic-cast.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/clang/test/CIR/CodeGen/agg-atomic-cast.c b/clang/test/CIR/CodeGen/agg-atomic-cast.c
index ac34d056dccd1..6cc429932db29 100644
--- a/clang/test/CIR/CodeGen/agg-atomic-cast.c
+++ b/clang/test/CIR/CodeGen/agg-atomic-cast.c
@@ -145,8 +145,11 @@ void load_struct_to_atomic_struct() {
// CIR: %[[A_ADDR:.*]] = cir.alloca "a" {{.*}} : !cir.ptr<!rec_T>
// CIR: %[[B_ADDR:.*]] = cir.alloca "b" {{.*}} : !cir.ptr<!rec_anon_struct>
// CIR: %[[AGG_TMP_ADDR:.*]] = cir.alloca "agg.tmp.ensured" {{.*}} : !cir.ptr<!rec_anon_struct>
-// CIR: %[[AGG_TMP_ZERO:.*]] = cir.get_global @__const.load_struct_to_atomic_struct.agg.tmp.ensured : !cir.ptr<!rec_anon_struct>
-// CIR: cir.copy %[[AGG_TMP_ZERO]] to %[[AGG_TMP_ADDR]] : !cir.ptr<!rec_anon_struct>
+// CIR: %[[AGG_TMP_I8:.*]] = cir.cast bitcast %[[AGG_TMP_ADDR]] : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u8i>
+// CIR: %[[CONST_0:.*]] = cir.const #cir.int<0> : !u8i
+// CIR: %[[CONST_4:.*]] = cir.const #cir.int<4> : !u64i
+// CIR: %[[AGG_TMP_VOID_PTR:.*]] = cir.cast bitcast %[[AGG_TMP_I8]] : !cir.ptr<!u8i> -> !cir.ptr<!void>
+// CIR: cir.libc.memset %[[CONST_4]] bytes at %[[AGG_TMP_VOID_PTR]] {{.*}} to %[[CONST_0]] : !cir.ptr<!void>, !u8i, !u64i
// CIR: %[[AGG_TMP_PTR:.*]] = cir.get_member %[[AGG_TMP_ADDR]][0] {name = "value_addr"} : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!rec_T>
// CIR: cir.copy %[[A_ADDR]] {{.*}} to %[[AGG_TMP_PTR]] {{.*}} : !cir.ptr<!rec_T>
// CIR: %[[AGG_TMP_ADDR_U32:.*]] = cir.cast bitcast %[[AGG_TMP_ADDR]] : !cir.ptr<!rec_anon_struct> -> !cir.ptr<!u32i>
@@ -157,7 +160,7 @@ void load_struct_to_atomic_struct() {
// LLVM: %[[A_ADDR:.*]] = alloca %struct.T, align 1
// LLVM: %[[B_ADDR:.*]] = alloca { %struct.T, [1 x i8] }, align 4
// LLVM: %[[AGG_TMP_ADDR:.*]] = alloca { %struct.T, [1 x i8] }, align 4
-// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %[[AGG_TMP_ADDR]], ptr align 1 @__const.load_struct_to_atomic_struct.agg.tmp.ensured, i64 4, i1 false)
+// LLVM: call void @llvm.memset.p0.i64(ptr align 4 %[[AGG_TMP_ADDR]], i8 0, i64 4, i1 false)
// LLVM: %[[AGG_TMP_PTR:.*]] = getelementptr inbounds nuw { %struct.T, [1 x i8] }, ptr %[[AGG_TMP_ADDR]], i32 0, i32 0
// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[AGG_TMP_PTR]], ptr align 1 %[[A_ADDR]], i64 3, i1 false)
// LLVM: %[[AGG_TMP:.*]] = load i32, ptr %[[AGG_TMP_ADDR]], align 4
More information about the cfe-commits
mailing list