From a828bf2b06dcebb92b58ab2803e66d8910edc293 Mon Sep 17 00:00:00 2001 From: AmrDeveloper Date: Sun, 5 Oct 2025 20:33:18 +0200 Subject: [PATCH] [CIR] Backport AtomicExpr for ComplexType --- clang/lib/CIR/CodeGen/CIRGenExpr.cpp | 4 +-- clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp | 4 ++- clang/test/CIR/CodeGen/complex.cpp | 38 +++++++++++++++++++++ 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index 353ec61ed15c..62cd9d48d399 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -2717,13 +2717,13 @@ RValue CIRGenFunction::convertTempToRValue(Address addr, clang::QualType type, LValue lvalue = makeAddrLValue(addr, type, AlignmentSource::Decl); switch (getEvaluationKind(type)) { case cir::TEK_Complex: - llvm_unreachable("NYI"); + return RValue::getComplex(emitLoadOfComplex(lvalue, loc)); case cir::TEK_Aggregate: return lvalue.asAggregateRValue(); case cir::TEK_Scalar: return RValue::get(emitLoadOfScalar(lvalue, loc)); } - llvm_unreachable("NYI"); + llvm_unreachable("bad evaluation kind"); } /// An LValue is a candidate for having its loads and stores be made atomic if diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 7020381a4324..a538993e3773 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -374,7 +374,9 @@ class ComplexExprEmitter : public StmtVisitor { mlir::Value VisitVAArgExpr(VAArgExpr *E) { llvm_unreachable("NYI"); } - mlir::Value VisitAtomicExpr(AtomicExpr *E) { llvm_unreachable("NYI"); } + mlir::Value VisitAtomicExpr(AtomicExpr *E) { + return CGF.emitAtomicExpr(E).getComplexVal(); + } mlir::Value VisitPackIndexingExpr(PackIndexingExpr *E) { llvm_unreachable("NYI"); diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index c0b19845197e..4af8dfcdd94d 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -246,3 +246,41 @@ void complex_opaque_value_expr() { // OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 4 // OGCG: %[[B_ADDR:.*]] = alloca float, align 4 // OGCG: store float 1.000000e+00, ptr %[[B_ADDR]], align 4 + +void atomic_complex_type() { + _Atomic(float _Complex) a; + float _Complex b = __c11_atomic_load(&a, __ATOMIC_RELAXED); +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["a"] +// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["b", init] +// CIR: %[[ATOMIC_TMP_ADDR:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["atomic-temp"] +// CIR: %[[A_PTR:.*]] = cir.cast bitcast %[[A_ADDR]] : !cir.ptr> -> !cir.ptr +// CIR: %[[ATOMIC_TMP_PTR:.*]] = cir.cast bitcast %[[ATOMIC_TMP_ADDR]] : !cir.ptr> -> !cir.ptr +// CIR: %[[TMP_A_ATOMIC:.*]] = cir.load{{.*}} atomic(relaxed) %[[A_PTR]] : !cir.ptr, !u64i +// CIR: cir.store{{.*}} %[[TMP_A_ATOMIC]], %[[ATOMIC_TMP_PTR]] : !u64i, !cir.ptr +// CIR: %[[TMP_ATOMIC_PTR:.*]] = cir.cast bitcast %[[ATOMIC_TMP_PTR]] : !cir.ptr -> !cir.ptr> +// CIR: %[[TMP_ATOMIC:.*]] = cir.load{{.*}} %[[TMP_ATOMIC_PTR]] : !cir.ptr>, !cir.complex +// CIR: cir.store{{.*}} %[[TMP_ATOMIC]], %[[B_ADDR]] : !cir.complex, !cir.ptr> + +// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 8 +// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 4 +// LLVM: %[[ATOMIC_TMP_ADDR:.*]] = alloca { float, float }, i64 1, align 8 +// LLVM: %[[TMP_A_ATOMIC:.*]] = load atomic i64, ptr %[[A_ADDR]] monotonic, align 8 +// LLVM: store i64 %[[TMP_A_ATOMIC]], ptr %[[ATOMIC_TMP_ADDR]], align 8 +// LLVM: %[[TMP_ATOMIC:.*]] = load { float, float }, ptr %[[ATOMIC_TMP_ADDR]], align 8 +// LLVM: store { float, float } %[[TMP_ATOMIC]], ptr %[[B_ADDR]], align 4 + +// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 8 +// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4 +// OGCG: %[[ATOMIC_TMP_ADDR:.*]] = alloca { float, float }, align 8 +// OGCG: %[[TMP_A_ATOMIC:.*]] = load atomic i64, ptr %[[A_ADDR]] monotonic, align 8 +// OGCG: store i64 %[[TMP_A_ATOMIC]], ptr %[[ATOMIC_TMP_ADDR]], align 8 +// OGCG: %[[ATOMIC_TMP_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[ATOMIC_TMP_ADDR]], i32 0, i32 0 +// OGCG: %[[ATOMIC_TMP_REAL:.*]] = load float, ptr %[[ATOMIC_TMP_REAL_PTR]], align 8 +// OGCG: %[[ATOMIC_TMP_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[ATOMIC_TMP_ADDR]], i32 0, i32 1 +// OGCG: %[[ATOMIC_TMP_IMAG:.*]] = load float, ptr %[[ATOMIC_TMP_IMAG_PTR]], align 4 +// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 0 +// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1 +// OGCG: store float %[[ATOMIC_TMP_REAL]], ptr %[[B_REAL_PTR]], align 4 +// OGCG: store float %[[ATOMIC_TMP_IMAG]], ptr %[[B_IMAG_PTR]], align 4