Skip to content

Commit 35c14c4

Browse files
authored
[CIR] Implement AtomicExpr for ComplexType (#160563)
This change implements AtomicExpr for ComplexType Issue: #141365
1 parent 62450ba commit 35c14c4

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,8 +1915,7 @@ RValue CIRGenFunction::convertTempToRValue(Address addr, clang::QualType type,
19151915
LValue lvalue = makeAddrLValue(addr, type, AlignmentSource::Decl);
19161916
switch (getEvaluationKind(type)) {
19171917
case cir::TEK_Complex:
1918-
cgm.errorNYI(loc, "convertTempToRValue: complex type");
1919-
return RValue::get(nullptr);
1918+
return RValue::getComplex(emitLoadOfComplex(lvalue, loc));
19201919
case cir::TEK_Aggregate:
19211920
cgm.errorNYI(loc, "convertTempToRValue: aggregate type");
19221921
return RValue::get(nullptr);

clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,7 @@ class ComplexExprEmitter : public StmtVisitor<ComplexExprEmitter, mlir::Value> {
316316
mlir::Value VisitVAArgExpr(VAArgExpr *e);
317317

318318
mlir::Value VisitAtomicExpr(AtomicExpr *e) {
319-
cgf.cgm.errorNYI(e->getExprLoc(), "ComplexExprEmitter VisitAtomicExpr");
320-
return {};
319+
return cgf.emitAtomicExpr(e).getComplexValue();
321320
}
322321

323322
mlir::Value VisitPackIndexingExpr(PackIndexingExpr *e) {

clang/test/CIR/CodeGen/complex.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,44 @@ void imag_on_non_glvalue() {
10941094
// OGCG: %[[A_IMAG:.*]] = load float, ptr %[[A_IMAG_PTR]], align 4
10951095
// OGCG: store float %[[A_IMAG]], ptr %[[B_ADDR]], align 4
10961096

1097+
void atomic_complex_type() {
1098+
_Atomic(float _Complex) a;
1099+
float _Complex b = __c11_atomic_load(&a, __ATOMIC_RELAXED);
1100+
}
1101+
1102+
// CIR: %[[A_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["a"]
1103+
// CIR: %[[B_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["b", init]
1104+
// CIR: %[[ATOMIC_TMP_ADDR:.*]] = cir.alloca !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>, ["atomic-temp"]
1105+
// CIR: %[[A_PTR:.*]] = cir.cast(bitcast, %[[A_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>), !cir.ptr<!u64i>
1106+
// CIR: %[[ATOMIC_TMP_PTR:.*]] = cir.cast(bitcast, %[[ATOMIC_TMP_ADDR]] : !cir.ptr<!cir.complex<!cir.float>>), !cir.ptr<!u64i>
1107+
// CIR: %[[TMP_A_ATOMIC:.*]] = cir.load{{.*}} atomic(relaxed) %[[A_PTR]] : !cir.ptr<!u64i>, !u64i
1108+
// CIR: cir.store{{.*}} %[[TMP_A_ATOMIC]], %[[ATOMIC_TMP_PTR]] : !u64i, !cir.ptr<!u64i>
1109+
// CIR: %[[TMP_ATOMIC_PTR:.*]] = cir.cast(bitcast, %[[ATOMIC_TMP_PTR]] : !cir.ptr<!u64i>), !cir.ptr<!cir.complex<!cir.float>>
1110+
// CIR: %[[TMP_ATOMIC:.*]] = cir.load{{.*}} %[[TMP_ATOMIC_PTR]] : !cir.ptr<!cir.complex<!cir.float>>, !cir.complex<!cir.float>
1111+
// CIR: cir.store{{.*}} %[[TMP_ATOMIC]], %[[B_ADDR]] : !cir.complex<!cir.float>, !cir.ptr<!cir.complex<!cir.float>>
1112+
1113+
// LLVM: %[[A_ADDR:.*]] = alloca { float, float }, i64 1, align 8
1114+
// LLVM: %[[B_ADDR:.*]] = alloca { float, float }, i64 1, align 4
1115+
// LLVM: %[[ATOMIC_TMP_ADDR:.*]] = alloca { float, float }, i64 1, align 8
1116+
// LLVM: %[[TMP_A_ATOMIC:.*]] = load atomic i64, ptr %[[A_ADDR]] monotonic, align 8
1117+
// LLVM: store i64 %[[TMP_A_ATOMIC]], ptr %[[ATOMIC_TMP_ADDR]], align 8
1118+
// LLVM: %[[TMP_ATOMIC:.*]] = load { float, float }, ptr %[[ATOMIC_TMP_ADDR]], align 8
1119+
// LLVM: store { float, float } %[[TMP_ATOMIC]], ptr %[[B_ADDR]], align 4
1120+
1121+
// OGCG: %[[A_ADDR:.*]] = alloca { float, float }, align 8
1122+
// OGCG: %[[B_ADDR:.*]] = alloca { float, float }, align 4
1123+
// OGCG: %[[ATOMIC_TMP_ADDR:.*]] = alloca { float, float }, align 8
1124+
// OGCG: %[[TMP_A_ATOMIC:.*]] = load atomic i64, ptr %[[A_ADDR]] monotonic, align 8
1125+
// OGCG: store i64 %[[TMP_A_ATOMIC]], ptr %[[ATOMIC_TMP_ADDR]], align 8
1126+
// OGCG: %[[ATOMIC_TMP_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[ATOMIC_TMP_ADDR]], i32 0, i32 0
1127+
// OGCG: %[[ATOMIC_TMP_REAL:.*]] = load float, ptr %[[ATOMIC_TMP_REAL_PTR]], align 8
1128+
// OGCG: %[[ATOMIC_TMP_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[ATOMIC_TMP_ADDR]], i32 0, i32 1
1129+
// OGCG: %[[ATOMIC_TMP_IMAG:.*]] = load float, ptr %[[ATOMIC_TMP_IMAG_PTR]], align 4
1130+
// OGCG: %[[B_REAL_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 0
1131+
// OGCG: %[[B_IMAG_PTR:.*]] = getelementptr inbounds nuw { float, float }, ptr %[[B_ADDR]], i32 0, i32 1
1132+
// OGCG: store float %[[ATOMIC_TMP_REAL]], ptr %[[B_REAL_PTR]], align 4
1133+
// OGCG: store float %[[ATOMIC_TMP_IMAG]], ptr %[[B_IMAG_PTR]], align 4
1134+
10971135
void real_on_scalar_glvalue() {
10981136
float a;
10991137
float b = __real__ a;

0 commit comments

Comments
 (0)