https://github.com/AmrDeveloper created 
https://github.com/llvm/llvm-project/pull/198117

Implement Complex to Atomic Complex types cast

Issue #192331

>From b80416672cc5f94b6865936f90ee6a3cd1f61f77 Mon Sep 17 00:00:00 2001
From: Amr Hesham <[email protected]>
Date: Sat, 16 May 2026 21:02:28 +0200
Subject: [PATCH] [CIR] Implement Complex to Atomic Complex cast

---
 clang/lib/CIR/CodeGen/CIRGenAtomic.cpp       |  3 +-
 clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp  | 11 ++++---
 clang/test/CIR/CodeGen/complex-atomic-cast.c | 32 ++++++++++++++++++++
 3 files changed, 40 insertions(+), 6 deletions(-)
 create mode 100644 clang/test/CIR/CodeGen/complex-atomic-cast.c

diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp 
b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 3a02fa0888f82..df4a09abdb21d 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -363,7 +363,8 @@ void AtomicInfo::emitCopyIntoMemory(RValue rvalue) const {
   if (rvalue.isScalar()) {
     cgf.emitStoreOfScalar(rvalue.getValue(), tempLValue, /*isInit=*/true);
   } else {
-    cgf.cgm.errorNYI("copying complex into atomic lvalue");
+    cgf.emitStoreOfComplex(loc, rvalue.getComplexValue(), tempLValue,
+                           /*isInit=*/true);
   }
 }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
index 08a7def1022d3..5f7e616f2f28b 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp
@@ -345,8 +345,7 @@ void ComplexExprEmitter::emitStoreOfComplex(mlir::Location 
loc, mlir::Value val,
                                             LValue lv, bool isInit) {
   if (lv.getType()->isAtomicType() ||
       (!isInit && cgf.isLValueSuitableForInlineAtomic(lv))) {
-    cgf.cgm.errorNYI(loc, "StoreOfComplex with Atomic LV");
-    return;
+    return cgf.emitAtomicStore(RValue::getComplex(val), lv, isInit);
   }
 
   const Address destAddr = lv.getAddress();
@@ -455,14 +454,16 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, 
Expr *op,
   case CK_Dependent:
     llvm_unreachable("dependent type must be resolved before the CIR codegen");
 
+  // Atomic to non-atomic casts may be more than a no-op for some platforms
+  // and for some types.
+  case CK_NonAtomicToAtomic:
   case CK_NoOp:
   case CK_LValueToRValue:
   case CK_UserDefinedConversion:
     return Visit(op);
 
-  case CK_AtomicToNonAtomic:
-  case CK_NonAtomicToAtomic: {
-    cgf.cgm.errorNYI("ComplexExprEmitter::emitCast Atmoic");
+  case CK_AtomicToNonAtomic: {
+    cgf.cgm.errorNYI("ComplexExprEmitter::emitCast AtomicToNonAtomic");
     return {};
   }
 
diff --git a/clang/test/CIR/CodeGen/complex-atomic-cast.c 
b/clang/test/CIR/CodeGen/complex-atomic-cast.c
new file mode 100644
index 0000000000000..9500db594ea85
--- /dev/null
+++ b/clang/test/CIR/CodeGen/complex-atomic-cast.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -fclangir 
-emit-cir %s -o %t.cir
+// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR
+// RUN: %clang_cc1 -std=c23 -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=c23 -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
+
+void complex_to_atomic_complex() {
+  _Complex int a;
+  _Atomic _Complex int b = a;
+}
+
+// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, 
!cir.ptr<!cir.complex<!s32i>>, ["a"]
+// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, 
!cir.ptr<!cir.complex<!s32i>>, ["b", init]
+// CIR: %[[TMP_A:.*]] = cir.load {{.*}} %[[A_ADDR]] : 
!cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i>
+// CIR: cir.store {{.*}} %[[TMP_A]], %[[B_ADDR]] : !cir.complex<!s32i>, 
!cir.ptr<!cir.complex<!s32i>>
+
+// LLVM: %[[A_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4
+// LLVM: %[[B_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 8
+// LLVM: %[[TMP_A:.*]] = load { i32, i32 }, ptr %[[A_ADDR]], align 4
+// LLVM: store { i32, i32 } %[[TMP_A]], ptr %[[B_ADDR]], align 8
+
+// OGCG: %[[A_ADDR:.*]] = alloca { i32, i32 }, align 4
+// OGCG: %[[B_ADDR:.*]] = alloca { i32, i32 }, align 8
+// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr 
%[[A_ADDR]], i32 0, i32 0
+// OGCG: %[[A_REAL:.*]] = load i32, ptr %[[A_REAL_PTR]], align 4
+// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr 
%[[A_ADDR]], i32 0, i32 1
+// OGCG: %[[A_IMAG:.*]] = load i32, ptr %[[A_IMAG_PTR]], align 4
+// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr 
%[[B_ADDR]], i32 0, i32 0
+// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr 
%[[B_ADDR]], i32 0, i32 1
+// OGCG: store i32 %[[A_REAL]], ptr %[[B_REAL_PTR]], align 8
+// OGCG: store i32 %[[A_IMAG]], ptr %[[B_IMAG_PTR]], align 4

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

Reply via email to