Author: Amr Hesham
Date: 2026-01-08T18:55:31+01:00
New Revision: 4bd84a9f335e2847a96d5ed4eac04576e811a963

URL: 
https://github.com/llvm/llvm-project/commit/4bd84a9f335e2847a96d5ed4eac04576e811a963
DIFF: 
https://github.com/llvm/llvm-project/commit/4bd84a9f335e2847a96d5ed4eac04576e811a963.diff

LOG: [CIR] Implement AtomicExpr for Aggregate expr (#173775)

Implement support for AtomicExpr for Aggregate expr

Added: 
    

Modified: 
    clang/lib/CIR/CodeGen/CIRGenExpr.cpp
    clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
    clang/lib/CIR/CodeGen/CIRGenFunction.h
    clang/lib/CIR/CodeGen/CIRGenValue.h
    clang/test/CIR/CodeGen/atomic.c

Removed: 
    


################################################################################
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..8fcff6d0f9b84 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp
@@ -130,8 +130,12 @@ 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);
+  void emitFinalDestCopy(QualType type, const LValue &src,
+                         CIRGenFunction::ExprValueKind srcValueKind =
+                             CIRGenFunction::EVK_NonRValue);
 
   void emitCopy(QualType type, const AggValueSlot &dest,
                 const AggValueSlot &src);
@@ -397,7 +401,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,8 +592,17 @@ 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, 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
@@ -596,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.

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);


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

Reply via email to