https://github.com/AmrDeveloper updated https://github.com/llvm/llvm-project/pull/173775
>From c25e12c605021e4bf8f6fc8b2f1bbf0add83baab Mon Sep 17 00:00:00 2001 From: Amr Hesham <[email protected]> Date: Sat, 27 Dec 2025 22:15:28 +0100 Subject: [PATCH 1/2] [CIR] Implement AtomicExpr for Aggregate expr --- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 3 +-- clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 11 +++++++- clang/lib/CIR/CodeGen/CIRGenValue.h | 4 +++ clang/test/CIR/CodeGen/atomic.c | 27 +++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 1d386f43fc8f4..cd13498e3702f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -2145,8 +2145,7 @@ RValue CIRGenFunction::convertTempToRValue(Address addr, clang::QualType type, case cir::TEK_Complex: return RValue::getComplex(emitLoadOfComplex(lvalue, loc)); case cir::TEK_Aggregate: - cgm.errorNYI(loc, "convertTempToRValue: aggregate type"); - return RValue::get(nullptr); + return lvalue.asAggregateRValue(); case cir::TEK_Scalar: return RValue::get(emitLoadOfScalar(lvalue, loc)); } diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index 3eef284405ad0..b6b369cfcb7ea 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -130,6 +130,7 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> { Expr *exprToVisit, ArrayRef<Expr *> args, Expr *arrayFiller); + void emitFinalDestCopy(QualType type, RValue src); /// Perform the final copy to DestPtr, if desired. void emitFinalDestCopy(QualType type, const LValue &src); @@ -397,7 +398,8 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> { cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitCXXThrowExpr"); } void VisitAtomicExpr(AtomicExpr *e) { - cgf.cgm.errorNYI(e->getSourceRange(), "AggExprEmitter: VisitAtomicExpr"); + RValue result = cgf.emitAtomicExpr(e); + emitFinalDestCopy(e->getType(), result); } }; @@ -587,6 +589,13 @@ void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, } } +/// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired. +void AggExprEmitter::emitFinalDestCopy(QualType type, RValue src) { + assert(src.isAggregate() && "value must be aggregate value!"); + LValue srcLV = cgf.makeAddrLValue(src.getAggregateAddress(), type); + emitFinalDestCopy(type, srcLV); +} + /// Perform the final copy to destPtr, if desired. void AggExprEmitter::emitFinalDestCopy(QualType type, const LValue &src) { // If dest is ignored, then we're evaluating an aggregate expression diff --git a/clang/lib/CIR/CodeGen/CIRGenValue.h b/clang/lib/CIR/CodeGen/CIRGenValue.h index 2002bd7e7c488..e5b925f82a635 100644 --- a/clang/lib/CIR/CodeGen/CIRGenValue.h +++ b/clang/lib/CIR/CodeGen/CIRGenValue.h @@ -328,6 +328,10 @@ class LValue { r.initialize(type, type.getQualifiers(), addr.getAlignment(), baseInfo); return r; } + + RValue asAggregateRValue() const { + return RValue::getAggregate(getAddress(), isVolatileQualified()); + } }; /// An aggregate value slot. diff --git a/clang/test/CIR/CodeGen/atomic.c b/clang/test/CIR/CodeGen/atomic.c index 4baac3bab7bce..483dc6d26dccd 100644 --- a/clang/test/CIR/CodeGen/atomic.c +++ b/clang/test/CIR/CodeGen/atomic.c @@ -158,6 +158,33 @@ void c11_load(_Atomic(int) *ptr) { // OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} seq_cst, align 4 // OGCG: } +struct Pair { + int x; + int y; +}; + +void c11_load_aggregate() { + _Atomic(struct Pair) a; + __c11_atomic_load(&a, __ATOMIC_RELAXED); + __c11_atomic_load(&a, __ATOMIC_ACQUIRE); + __c11_atomic_load(&a, __ATOMIC_SEQ_CST); +} + +// CIR-LABEL: @c11_load_aggregate +// CIR: %{{.*}} = cir.load {{.*}} syncscope(system) atomic(relaxed) %{{.*}} : !cir.ptr<!u64i>, !u64i +// CIR: %{{.*}} = cir.load {{.*}} syncscope(system) atomic(acquire) %{{.*}} : !cir.ptr<!u64i>, !u64i +// CIR: %{{.*}} = cir.load {{.*}} syncscope(system) atomic(seq_cst) %{{.*}} : !cir.ptr<!u64i>, !u64i + +// LLVM-LABEL: @c11_load_aggregate +// LLVM: %{{.*}} = load atomic i64, ptr %{{.*}} monotonic, align 8 +// LLVM: %{{.*}} = load atomic i64, ptr %{{.*}} acquire, align 8 +// LLVM: %{{.*}} = load atomic i64, ptr %{{.*}} seq_cst, align 8 + +// OGCG-LABEL: @c11_load_aggregate +// OGCG: %{{.*}} = load atomic i64, ptr %{{.*}} monotonic, align 8 +// OGCG: %{{.*}} = load atomic i64, ptr %{{.*}} acquire, align 8 +// OGCG: %{{.*}} = load atomic i64, ptr %{{.*}} seq_cst, align 8 + void store(int *ptr, int x) { __atomic_store(ptr, &x, __ATOMIC_RELAXED); __atomic_store(ptr, &x, __ATOMIC_RELEASE); >From 12f140bdb6330e484d459a07bf02e7c3f37cee52 Mon Sep 17 00:00:00 2001 From: Amr Hesham <[email protected]> Date: Wed, 7 Jan 2026 19:48:38 +0100 Subject: [PATCH 2/2] Add NYI for ExprValueKind in emitFinalDestCopy --- clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 21 ++++++++++++++++--- clang/lib/CIR/CodeGen/CIRGenFunction.h | 2 ++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index b6b369cfcb7ea..8fcff6d0f9b84 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -131,8 +131,11 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> { Expr *arrayFiller); void emitFinalDestCopy(QualType type, RValue src); + /// Perform the final copy to DestPtr, if desired. - void emitFinalDestCopy(QualType type, const LValue &src); + void emitFinalDestCopy(QualType type, const LValue &src, + CIRGenFunction::ExprValueKind srcValueKind = + CIRGenFunction::EVK_NonRValue); void emitCopy(QualType type, const AggValueSlot &dest, const AggValueSlot &src); @@ -593,11 +596,13 @@ void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, void AggExprEmitter::emitFinalDestCopy(QualType type, RValue src) { assert(src.isAggregate() && "value must be aggregate value!"); LValue srcLV = cgf.makeAddrLValue(src.getAggregateAddress(), type); - emitFinalDestCopy(type, srcLV); + emitFinalDestCopy(type, srcLV, CIRGenFunction::EVK_RValue); } /// Perform the final copy to destPtr, if desired. -void AggExprEmitter::emitFinalDestCopy(QualType type, const LValue &src) { +void AggExprEmitter::emitFinalDestCopy( + QualType type, const LValue &src, + CIRGenFunction::ExprValueKind srcValueKind) { // If dest is ignored, then we're evaluating an aggregate expression // in a context that doesn't care about the result. Note that loads // from volatile l-values force the existence of a non-ignored @@ -605,6 +610,16 @@ void AggExprEmitter::emitFinalDestCopy(QualType type, const LValue &src) { if (dest.isIgnored()) return; + if (srcValueKind == CIRGenFunction::EVK_RValue) { + if (type.isNonTrivialToPrimitiveDestructiveMove() == QualType::PCK_Struct) { + cgf.cgm.errorNYI("emitFinalDestCopy: EVK_RValue & PCK_Struct"); + } + } else { + if (type.isNonTrivialToPrimitiveCopy() == QualType::PCK_Struct) { + cgf.cgm.errorNYI("emitFinalDestCopy: !EVK_RValue & PCK_Struct"); + } + } + assert(!cir::MissingFeatures::aggValueSlotVolatile()); assert(!cir::MissingFeatures::aggEmitFinalDestCopyRValue()); assert(!cir::MissingFeatures::aggValueSlotGC()); diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 49ebccc221950..3101fc6cd228c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1309,6 +1309,8 @@ class CIRGenFunction : public CIRGenTypeCache { void emitAggExpr(const clang::Expr *e, AggValueSlot slot); + enum ExprValueKind { EVK_RValue, EVK_NonRValue }; + LValue emitAggExprToLValue(const Expr *e); /// Emit an aggregate copy. _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
