[clang] [CIR] Implement Aggregate non-atomic to atomic cast (PR #204653)
Amr Hesham via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 19 10:35:18 PDT 2026
https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/204653
>From 1a55a287ab78c1c4687eb2c06562669474be5a5b Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Thu, 18 Jun 2026 19:37:23 +0200
Subject: [PATCH 1/2] [CIR] Implement Aggregate non-atomic to atomic cast
---
clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 31 +++++++++++++++++++
clang/lib/CIR/CodeGen/CIRGenModule.h | 3 ++
clang/lib/CIR/CodeGen/CIRGenTypes.cpp | 9 ++++++
clang/test/CIR/CodeGen/agg-atomic-cast.cpp | 27 ++++++++++++++++
4 files changed, 70 insertions(+)
create mode 100644 clang/test/CIR/CodeGen/agg-atomic-cast.cpp
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 44f481508cd7e..23f62f4688f02 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -258,6 +258,37 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
break;
}
+
+ case CK_NonAtomicToAtomic:
+ case CK_AtomicToNonAtomic: {
+ bool isToAtomic = (e->getCastKind() == CK_NonAtomicToAtomic);
+ if (!isToAtomic) {
+ cgf.cgm.errorNYI(e->getSourceRange(),
+ "AggExprEmitter: CK_AtomicToNonAtomic");
+ return;
+ }
+
+ // Determine the atomic and value types.
+ QualType atomicType = e->getSubExpr()->getType();
+ QualType valueType = e->getType();
+ if (isToAtomic)
+ std::swap(atomicType, valueType);
+
+ assert(atomicType->isAtomicType());
+ assert(cgf.getContext().hasSameUnqualifiedType(
+ valueType, atomicType->castAs<AtomicType>()->getValueType()));
+
+ // Just recurse normally if we're ignoring the result or the
+ // atomic type doesn't change representation.
+ if (dest.isIgnored() || !cgf.cgm.isPaddedAtomicType(atomicType)) {
+ return Visit(e->getSubExpr());
+ }
+
+ cgf.cgm.errorNYI(
+ e->getSourceRange(),
+ "AggExprEmitter: AtomicCast not ignored or has padded atomic type");
+ return;
+ }
case CK_LValueToRValue:
// If we're loading from a volatile type, force the destination
// into existence.
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h
index fa166c1f39b69..0883a6b891c61 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -823,6 +823,9 @@ class CIRGenModule : public CIRGenTypeCache {
return *openMPRuntime;
}
+ bool isPaddedAtomicType(QualType type);
+ bool isPaddedAtomicType(const AtomicType *type);
+
mlir::IntegerAttr getSize(CharUnits size) {
return builder.getSizeFromCharUnits(size);
}
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index ea37d82c82d79..3170666304a06 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -226,6 +226,15 @@ static bool isSafeToConvert(const RecordDecl *rd, CIRGenTypes &cgt) {
return isSafeToConvert(rd, cgt, alreadyChecked);
}
+bool CIRGenModule::isPaddedAtomicType(QualType type) {
+ return isPaddedAtomicType(type->castAs<AtomicType>());
+}
+
+bool CIRGenModule::isPaddedAtomicType(const AtomicType *type) {
+ return astContext.getTypeSize(type) !=
+ astContext.getTypeSize(type->getValueType());
+}
+
/// Lay out a tagged decl type like struct or union.
mlir::Type CIRGenTypes::convertRecordDeclType(const clang::RecordDecl *rd) {
// TagDecl's are not necessarily unique, instead use the (clang) type
diff --git a/clang/test/CIR/CodeGen/agg-atomic-cast.cpp b/clang/test/CIR/CodeGen/agg-atomic-cast.cpp
new file mode 100644
index 0000000000000..12ed04f14edf2
--- /dev/null
+++ b/clang/test/CIR/CodeGen/agg-atomic-cast.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll
+// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll
+// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG
+
+struct S {
+ int data[4];
+};
+
+void non_atomic_to_atomic_cast() {
+ S s;
+ _Atomic(S) as = s;
+}
+
+// CIR: %[[S_ADDR:.*]] = cir.alloca "s" {{.*}} : !cir.ptr<!rec_S>
+// CIR: %[[SA_ADDR:.*]] = cir.alloca "as" {{.*}} init : !cir.ptr<!rec_S>
+// CIR: cir.copy %[[S_ADDR]] to %[[SA_ADDR]] : !cir.ptr<!rec_S>
+
+// LLVM: %[[S_ADDR:.*]] = alloca %struct.S, i64 1, align 4
+// LLVM: %[[SA_ADDR:.*]] = alloca %struct.S, i64 1, align 16
+// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[SA_ADDR]], ptr %[[S_ADDR]], i64 16, i1 false)
+
+// OGCG: %[[S_ADDR:.*]] = alloca %struct.S, align 4
+// OGCG: %[[SA_ADDR:.*]] = alloca %struct.S, align 16
+// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[SA_ADDR]], ptr align 4 %[[S_ADDR]], i64 16, i1 false)
>From 8c0a24c678f7fc4d1a9034c06569a4745bf37919 Mon Sep 17 00:00:00 2001
From: Amr Hesham <amr96 at programmer.net>
Date: Fri, 19 Jun 2026 18:23:08 +0200
Subject: [PATCH 2/2] Address code review comments
---
clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
index 23f62f4688f02..c53453bd3e88b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -280,13 +280,12 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
// Just recurse normally if we're ignoring the result or the
// atomic type doesn't change representation.
- if (dest.isIgnored() || !cgf.cgm.isPaddedAtomicType(atomicType)) {
+ if (dest.isIgnored() || !cgf.cgm.isPaddedAtomicType(atomicType))
return Visit(e->getSubExpr());
- }
cgf.cgm.errorNYI(
e->getSourceRange(),
- "AggExprEmitter: AtomicCast not ignored or has padded atomic type");
+ "AggExprEmitter: AtomicCast not ignored and has padded atomic type");
return;
}
case CK_LValueToRValue:
More information about the cfe-commits
mailing list