diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index d8981c8c7ca56..3b78e6e22d2a7 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -159,9 +159,9 @@ bool AtomicInfo::requiresMemSetZero(mlir::Type ty) const { case cir::TEK_Scalar: return !isFullSizeType(cgf.cgm, ty, atomicSizeInBits); case cir::TEK_Complex: - cgf.cgm.errorNYI(loc, "AtomicInfo::requiresMemSetZero: complex type"); - return false; - + return !isFullSizeType(cgf.cgm, + mlir::cast(ty).getElementType(), + atomicSizeInBits / 2); // Padding in structs has an undefined bit pattern. User beware. case cir::TEK_Aggregate: return false; @@ -556,9 +556,11 @@ void CIRGenFunction::emitAtomicInit(Expr *init, LValue dest) { return; } - case cir::TEK_Complex: - cgm.errorNYI(init->getSourceRange(), "emitAtomicInit: complex type"); + case cir::TEK_Complex: { + mlir::Value value = emitComplexExpr(init); + atomics.emitCopyIntoMemory(RValue::get(value)); return; + } case cir::TEK_Aggregate: cgm.errorNYI(init->getSourceRange(), "emitAtomicInit: aggregate type"); diff --git a/clang/test/CIR/CodeGen/complex.cpp b/clang/test/CIR/CodeGen/complex.cpp index db837e568e0be..2e1198b09f010 100644 --- a/clang/test/CIR/CodeGen/complex.cpp +++ b/clang/test/CIR/CodeGen/complex.cpp @@ -909,3 +909,21 @@ void foo33(__builtin_va_list a) { // OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1 // OGCG: store float %[[RESULT_REAL]], ptr %[[B_REAL_PTR]], align 4 // OGCG: store float %[[RESULT_IMAG]], ptr %[[B_IMAG_PTR]], align 4 + +void foo34() { + _Atomic(float _Complex) a; + __c11_atomic_init(&a, {1.0f, 2.0f}); +} + +// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex, !cir.ptr>, ["a"] +// CIR: %[[CONST_COMPLEX:.*]] = cir.const #cir.const_complex<#cir.fp<1.000000e+00> : !cir.float, #cir.fp<2.000000e+00> : !cir.float> : !cir.complex +// CIR: cir.store{{.*}} %[[CONST_COMPLEX]], %[[A_ADDR]] : !cir.complex, !cir.ptr> + +// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 8 +// LLVM: store { float, float } { float 1.000000e+00, float 2.000000e+00 }, ptr %[[A_ADDR]], align 8 + +// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 8 +// OGCG: %[[A_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 0 +// OGCG: %[[A_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[A_ADDR]], i32 0, i32 1 +// OGCG: store float 1.000000e+00, ptr %[[A_REAL_PTR]], align 8 +// OGCG: store float 2.000000e+00, ptr %[[A_IMAG_PTR]], align 4