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
