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 <[email protected]> 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 <[email protected]> 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: _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
