https://github.com/AmrDeveloper created https://github.com/llvm/llvm-project/pull/206322
Implement support for the Aggregate atomic to non-atomic cast >From 41289ffba3513cbb1a85aea394a9ae51f354ea27 Mon Sep 17 00:00:00 2001 From: Amr Hesham <[email protected]> Date: Sun, 28 Jun 2026 12:03:10 +0200 Subject: [PATCH] [CIR] Implement Aggregate atomic to non-atomic cast --- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 27 +++++----- clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp | 10 ++-- clang/test/CIR/CodeGen/agg-atomic-cast.c | 50 +++++++++++++++++++ clang/test/CIR/CodeGen/agg-atomic-cast.cpp | 27 ---------- 4 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 clang/test/CIR/CodeGen/agg-atomic-cast.c delete mode 100644 clang/test/CIR/CodeGen/agg-atomic-cast.cpp diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index 4d774761b975a..42e027887b9c4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -112,8 +112,8 @@ class AtomicInfo { Address convertToAtomicIntPointer(Address addr) const; /// Turn an atomic-layout object into an r-value. - RValue convertAtomicTempToRValue(Address addr, SourceLocation loc, - bool asValue) const; + RValue convertAtomicTempToRValue(Address addr, AggValueSlot resultSlot, + SourceLocation loc, bool asValue) const; /// Converts a rvalue to integer value. mlir::Value convertRValueToInt(RValue rvalue, mlir::Location loc, @@ -211,15 +211,13 @@ Address AtomicInfo::convertToAtomicIntPointer(Address addr) const { return castToAtomicIntPointer(addr); } -RValue AtomicInfo::convertAtomicTempToRValue(Address addr, SourceLocation loc, +RValue AtomicInfo::convertAtomicTempToRValue(Address addr, + AggValueSlot resultSlot, + 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); - } + if (evaluationKind == TEK_Aggregate) + return resultSlot.asRValue(); // Drill into the padding structure if we have one. if (hasPadding()) { @@ -384,17 +382,20 @@ RValue AtomicInfo::convertToValueOrAtomic(mlir::Value intVal, // Create a temporary. This needs to be big enough to hold the // atomic integer. Address temp = Address::invalid(); + bool tempIsVolatile = false; if (asValue && getEvaluationKind() == TEK_Aggregate) { - cgf.cgm.errorNYI("convertToValueOrAtomic: temporary aggregate"); - return RValue::get(nullptr); + assert(!resultSlot.isIgnored()); + temp = resultSlot.getAddress(); + tempIsVolatile = resultSlot.isVolatile(); } else { 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); + cgf.getBuilder().createStore(cgf.getLoc(loc), intVal, castTemp, + tempIsVolatile); + return convertAtomicTempToRValue(temp, resultSlot, loc, asValue); } /// Copy an r-value into memory as part of storing to an atomic type. diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index 4d54519e4d25f..75435696ef915 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -262,11 +262,6 @@ class AggExprEmitter : public StmtVisitor<AggExprEmitter> { case CK_NonAtomicToAtomic: case CK_AtomicToNonAtomic: { bool isToAtomic = (e->getCastKind() == CK_NonAtomicToAtomic); - if (!isToAtomic) { - cgf.cgm.errorNYI(e->getSourceRange(), - "AggExprEmitter: CK_AtomicToNonAtomic"); - return; - } // Determine the atomic and value types. QualType atomicType = e->getSubExpr()->getType(); @@ -691,7 +686,10 @@ void AggExprEmitter::emitAggLoadOfLValue(const Expr *e) { LValue lv = cgf.emitLValue(e); // If the type of the l-value is atomic, then do an atomic load. - assert(!cir::MissingFeatures::opLoadStoreAtomic()); + if (lv.getType()->isAtomicType() || cgf.isLValueSuitableForInlineAtomic(lv)) { + cgf.emitAtomicLoad(lv, e->getExprLoc(), dest); + return; + } emitFinalDestCopy(e->getType(), lv); } diff --git a/clang/test/CIR/CodeGen/agg-atomic-cast.c b/clang/test/CIR/CodeGen/agg-atomic-cast.c new file mode 100644 index 0000000000000..f9af8ae317e03 --- /dev/null +++ b/clang/test/CIR/CodeGen/agg-atomic-cast.c @@ -0,0 +1,50 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -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 -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 + +typedef struct S { + int x; +} S; + +void non_atomic_to_atomic_cast() { + S s; + _Atomic(S) as = s; +} + +// CIR: %[[S_ADDR:.*]] = cir.alloca "s" {{.*}} : !cir.ptr<!rec_S> +// CIR: %[[SA_ADDR:.*]] = cir.alloca "as" {{.*}} init : !cir.ptr<!rec_S> +// CIR: cir.copy %[[S_ADDR]] to %[[SA_ADDR]] : !cir.ptr<!rec_S> + +// LLVM: %[[S_ADDR:.*]] = alloca %struct.S, i64 1, align 4 +// LLVM: %[[SA_ADDR:.*]] = alloca %struct.S, i64 1, align 4 +// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[SA_ADDR]], ptr %[[S_ADDR]], i64 4, i1 false) + +// OGCG: %[[S_ADDR:.*]] = alloca %struct.S, align 4 +// OGCG: %[[SA_ADDR:.*]] = alloca %struct.S, align 4 +// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %[[SA_ADDR]], ptr align 4 %[[S_ADDR]], i64 4, i1 false) + +void atomic_to_non_atomic_cast() { + _Atomic S as; + S s; + s = as; +} + +// CIR: %[[AS_ADDR:.*]] = cir.alloca "as" {{.*}} : !cir.ptr<!rec_S> +// CIR: %[[S_ADDR:.*]] = cir.alloca "s" {{.*}} : !cir.ptr<!rec_S> +// CIR: %[[SA_PTR:.*]] = cir.cast bitcast %[[AS_ADDR]] : !cir.ptr<!rec_S> -> !cir.ptr<!u32i> +// CIR: %[[ATOMIC_LOAD:.*]] = cir.load {{.*}} atomic(seq_cst) %[[SA_PTR]] : !cir.ptr<!u32i>, !u32i +// CIR: %[[S_PTR:.*]] = cir.cast bitcast %[[S_ADDR]] : !cir.ptr<!rec_S> -> !cir.ptr<!u32i> +// CIR: cir.store {{.*}} %[[ATOMIC_LOAD]], %[[S_PTR]] : !u32i, !cir.ptr<!u32i> + +// LLVM: %[[AS_ADDR:.*]] = alloca %struct.S, i64 1, align 4 +// LLVM: %[[S_ADDR:.*]] = alloca %struct.S, i64 1, align 4 +// LLVM: %[[ATOMIC_LOAD:.*]] = load atomic i32, ptr %[[AS_ADDR]] seq_cst, align 4 +// LLVM: store i32 %[[ATOMIC_LOAD]], ptr %[[S_ADDR]], align 4 + +// OGCG: %[[AS_ADDR:.*]] = alloca %struct.S, align 4 +// OGCG: %[[S_ADDR:.*]] = alloca %struct.S, align 4 +// OGCG: %[[ATOMIC_LOAD:.*]] = load atomic i32, ptr %[[AS_ADDR]] seq_cst, align 4 +// OGCG: store i32 %[[ATOMIC_LOAD]], ptr %[[S_ADDR]], align 4 diff --git a/clang/test/CIR/CodeGen/agg-atomic-cast.cpp b/clang/test/CIR/CodeGen/agg-atomic-cast.cpp deleted file mode 100644 index 12ed04f14edf2..0000000000000 --- a/clang/test/CIR/CodeGen/agg-atomic-cast.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir -// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR -// RUN: %clang_cc1 -std=c++20 -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=c++20 -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 - -struct S { - int data[4]; -}; - -void non_atomic_to_atomic_cast() { - S s; - _Atomic(S) as = s; -} - -// CIR: %[[S_ADDR:.*]] = cir.alloca "s" {{.*}} : !cir.ptr<!rec_S> -// CIR: %[[SA_ADDR:.*]] = cir.alloca "as" {{.*}} init : !cir.ptr<!rec_S> -// CIR: cir.copy %[[S_ADDR]] to %[[SA_ADDR]] : !cir.ptr<!rec_S> - -// LLVM: %[[S_ADDR:.*]] = alloca %struct.S, i64 1, align 4 -// LLVM: %[[SA_ADDR:.*]] = alloca %struct.S, i64 1, align 16 -// LLVM: call void @llvm.memcpy.p0.p0.i64(ptr %[[SA_ADDR]], ptr %[[S_ADDR]], i64 16, i1 false) - -// OGCG: %[[S_ADDR:.*]] = alloca %struct.S, align 4 -// OGCG: %[[SA_ADDR:.*]] = alloca %struct.S, align 16 -// OGCG: call void @llvm.memcpy.p0.p0.i64(ptr align 16 %[[SA_ADDR]], ptr align 4 %[[S_ADDR]], i64 16, i1 false) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
