llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Amr Hesham (AmrDeveloper) <details> <summary>Changes</summary> Implement Atomic Complex to Complex types cast Issue https://github.com/llvm/llvm-project/issues/192331 --- Full diff: https://github.com/llvm/llvm-project/pull/199260.diff 3 Files Affected: - (modified) clang/lib/CIR/CodeGen/CIRGenAtomic.cpp (+44-2) - (modified) clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp (+2-6) - (modified) clang/test/CIR/CodeGen/complex-atomic-cast.c (+37) ``````````diff diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index 3df0cd23d570e..95280242618a2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -110,6 +110,10 @@ class AtomicInfo { /// copy the value across. Address convertToAtomicIntPointer(Address addr) const; + /// Turn an atomic-layout object into an r-value. + RValue convertAtomicTempToRValue(Address addr, SourceLocation loc, + bool asValue) const; + /// Converts a rvalue to integer value. mlir::Value convertRValueToInt(RValue rvalue, bool cmpxchg = false) const; @@ -202,6 +206,33 @@ Address AtomicInfo::convertToAtomicIntPointer(Address addr) const { return castToAtomicIntPointer(addr); } +RValue AtomicInfo::convertAtomicTempToRValue(Address addr, SourceLocation loc, + bool asValue) const { + if (lvalue.isSimple()) { + if (evaluationKind == TEK_Aggregate) { + cgf.cgm.errorNYI( + loc, + "AtomicInfo::convertAtomicTempToRValue: evaluationKind is aggregate"); + return RValue::get(nullptr); + } + + // Drill into the padding structure if we have one. + if (hasPadding()) { + cgf.cgm.errorNYI(loc, + "AtomicInfo::convertAtomicTempToRValue: hasPadding"); + return RValue::get(nullptr); + } + + // Otherwise, just convert the temporary to an r-value using the + // normal conversion routine. + return cgf.convertTempToRValue(addr, getValueType(), loc); + } + + cgf.cgm.errorNYI( + loc, "AtomicInfo::convertAtomicTempToRValue: lvalue is not simple"); + return RValue::get(nullptr); +} + RValue AtomicInfo::emitAtomicLoad(AggValueSlot resultSlot, SourceLocation loc, bool asValue, cir::MemOrder order, bool isVolatile) { @@ -334,8 +365,19 @@ RValue AtomicInfo::convertToValueOrAtomic(mlir::Value intVal, return RValue::get(nullptr); } - cgf.cgm.errorNYI("convertToValueOrAtomic: convert through temp"); - return RValue::get(nullptr); + // Create a temporary. This needs to be big enough to hold the + // atomic integer. + if (asValue && getEvaluationKind() == TEK_Aggregate) { + cgf.cgm.errorNYI("convertToValueOrAtomic: temporary aggregate"); + return RValue::get(nullptr); + } + + Address temp = createTempAlloca(); + + // Slam the integer into the temporary. + Address castTemp = castToAtomicIntPointer(temp); + cgf.getBuilder().createStore(cgf.getLoc(loc), intVal, castTemp); + return convertAtomicTempToRValue(temp, loc, asValue); } /// Copy an r-value into memory as part of storing to an atomic type. diff --git a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp index 5f7e616f2f28b..0e5c5fe8b622d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprComplex.cpp @@ -333,7 +333,7 @@ mlir::Value ComplexExprEmitter::emitLoadOfLValue(LValue lv, SourceLocation loc) { assert(lv.isSimple() && "non-simple complex l-value?"); if (lv.getType()->isAtomicType()) - cgf.cgm.errorNYI(loc, "emitLoadOfLValue with Atomic LV"); + return cgf.emitAtomicLoad(lv, loc).getComplexValue(); const Address srcAddr = lv.getAddress(); return builder.createLoad(cgf.getLoc(loc), srcAddr, lv.isVolatileQualified()); @@ -457,16 +457,12 @@ mlir::Value ComplexExprEmitter::emitCast(CastKind ck, Expr *op, // Atomic to non-atomic casts may be more than a no-op for some platforms // and for some types. case CK_NonAtomicToAtomic: + case CK_AtomicToNonAtomic: case CK_NoOp: case CK_LValueToRValue: case CK_UserDefinedConversion: return Visit(op); - case CK_AtomicToNonAtomic: { - cgf.cgm.errorNYI("ComplexExprEmitter::emitCast AtomicToNonAtomic"); - return {}; - } - case CK_LValueBitCast: { LValue origLV = cgf.emitLValue(op); Address addr = diff --git a/clang/test/CIR/CodeGen/complex-atomic-cast.c b/clang/test/CIR/CodeGen/complex-atomic-cast.c index 9500db594ea85..a15858fcf9711 100644 --- a/clang/test/CIR/CodeGen/complex-atomic-cast.c +++ b/clang/test/CIR/CodeGen/complex-atomic-cast.c @@ -30,3 +30,40 @@ void complex_to_atomic_complex() { // 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 + +void atomic_complex_to_complex() { + _Atomic _Complex int a; + _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: %[[ATOMIC_TMP_ADDR:.*]] = cir.alloca !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>>, ["atomic-temp"] +// CIR: %[[A_U64I:.*]] = cir.cast bitcast %[[A_ADDR]] : !cir.ptr<!cir.complex<!s32i>> -> !cir.ptr<!u64i> +// CIR: %[[TMP_A:.*]] = cir.load {{.*}} atomic(seq_cst) %[[A_U64I]] : !cir.ptr<!u64i>, !u64i +// CIR: %[[ATOMIC_TMP_U64I:.*]] = cir.cast bitcast %[[ATOMIC_TMP_ADDR]] : !cir.ptr<!cir.complex<!s32i>> -> !cir.ptr<!u64i> +// CIR: cir.store {{.*}} %[[TMP_A]], %[[ATOMIC_TMP_U64I]] : !u64i, !cir.ptr<!u64i> +// CIR: %[[TMP_ATOMIC:.*]] = cir.load {{.*}} %[[ATOMIC_TMP_ADDR]] : !cir.ptr<!cir.complex<!s32i>>, !cir.complex<!s32i> +// CIR: cir.store {{.*}} %[[TMP_ATOMIC]], %[[B_ADDR]] : !cir.complex<!s32i>, !cir.ptr<!cir.complex<!s32i>> + +// LLVM: %[[A_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 8 +// LLVM: %[[B_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 4 +// LLVM: %[[ATOMIC_TMP_ADDR:.*]] = alloca { i32, i32 }, i64 1, align 8 +// LLVM: %[[TMP_A:.*]] = load atomic i64, ptr %[[A_ADDR]] seq_cst, align 8 +// LLVM: store i64 %[[TMP_A]], ptr %[[ATOMIC_TMP_ADDR]], align 8 +// LLVM: %[[TMP_ATOMIC:.*]] = load { i32, i32 }, ptr %[[ATOMIC_TMP_ADDR]], align 8 +// LLVM: store { i32, i32 } %[[TMP_ATOMIC]], ptr %[[B_ADDR]], align 4 + +// OGCG: %[[A_ADDR:.*]] = alloca { i32, i32 }, align 8 +// OGCG: %[[B_ADDR:.*]] = alloca { i32, i32 }, align 4 +// OGCG: %[[ATOMIC_TMP_ADDR:.*]] = alloca { i32, i32 }, align 8 +// OGCG: %[[TMP_A:.*]] = load atomic i64, ptr %[[A_ADDR]] seq_cst, align 8 +// OGCG: store i64 %[[TMP_A]], ptr %[[ATOMIC_TMP_ADDR]], align 8 +// OGCG: %[[ATOMIC_TMP_REAL_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[ATOMIC_TMP_ADDR]], i32 0, i32 0 +// OGCG: %[[ATOMIC_TMP_REAL:.*]] = load i32, ptr %[[ATOMIC_TMP_REAL_PTR]], align 8 +// OGCG: %[[ATOMIC_TMP_IMAG_PTR:.*]] = getelementptr inbounds nuw { i32, i32 }, ptr %[[ATOMIC_TMP_ADDR]], i32 0, i32 1 +// OGCG: %[[ATOMIC_TMP_IMAG:.*]] = load i32, ptr %[[ATOMIC_TMP_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 %[[ATOMIC_TMP_REAL]], ptr %[[B_REAL_PTR]], align 4 +// OGCG: store i32 %[[ATOMIC_TMP_IMAG]], ptr %[[B_IMAG_PTR]], align 4 `````````` </details> https://github.com/llvm/llvm-project/pull/199260 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
