[CIR] Synchronize CIR with recent changes to atomic ops (#184416)

This synchronizes the CIR atomic expression handling with changes that
were made in https://github.com/llvm/llvm-project/pull/183853
This commit is contained in:
Andy Kaylor 2026-03-03 11:27:54 -08:00 committed by GitHub
parent a5ca0ec16b
commit c7c16573b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 23 deletions

View File

@ -895,8 +895,6 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
e->getScopeModel() && e->getScope()->EvaluateAsInt(eval, getContext()))
scopeConst.emplace(std::move(eval));
bool shouldCastToIntPtrTy = true;
switch (e->getOp()) {
default:
cgm.errorNYI(e->getSourceRange(), "atomic op NYI");
@ -974,7 +972,6 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
case AtomicExpr::AO__scoped_atomic_max_fetch:
case AtomicExpr::AO__scoped_atomic_min_fetch:
case AtomicExpr::AO__scoped_atomic_sub_fetch:
shouldCastToIntPtrTy = !memTy->isFloatingType();
[[fallthrough]];
case AtomicExpr::AO__atomic_fetch_and:
@ -1009,6 +1006,9 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
QualType resultTy = e->getType().getUnqualifiedType();
bool shouldCastToIntPtrTy =
shouldCastToInt(convertTypeForMem(memTy), e->isCmpXChg());
// The inlined atomics only function on iN types, where N is a power of 2. We
// need to make sure (via temporaries if necessary) that all incoming values
// are compatible.

View File

@ -109,12 +109,9 @@ void loadWithThreadFence(DataPtr d) {
// CIR: cir.atomic.fence syncscope(system) seq_cst
// CIR: %[[LOAD_DATA:.*]] = cir.load{{.*}} %[[DATA]] : !cir.ptr<!cir.ptr<!rec_Data>>, !cir.ptr<!rec_Data>
// CIR: %[[DATA_VALUE:.*]] = cir.get_member %[[LOAD_DATA]][1] {name = "ptr"} : !cir.ptr<!rec_Data> -> !cir.ptr<!cir.ptr<!void>>
// CIR: %[[CASTED_DATA_VALUE:.*]] = cir.cast bitcast %[[DATA_VALUE]] : !cir.ptr<!cir.ptr<!void>> -> !cir.ptr<!u64i>
// CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast bitcast %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>> -> !cir.ptr<!u64i>
// CIR: %[[ATOMIC_LOAD:.*]] = cir.load{{.*}} atomic(seq_cst) %[[CASTED_DATA_VALUE]] : !cir.ptr<!u64i>, !u64i
// CIR: cir.store{{.*}} %[[ATOMIC_LOAD]], %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr<!u64i>
// CIR: %[[DOUBLE_CASTED_ATOMIC_TEMP:.*]] = cir.cast bitcast %[[CASTED_ATOMIC_TEMP]] : !cir.ptr<!u64i> -> !cir.ptr<!cir.ptr<!void>>
// CIR: %[[ATOMIC_LOAD_PTR:.*]] = cir.load{{.*}} %[[DOUBLE_CASTED_ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: %[[ATOMIC_LOAD:.*]] = cir.load{{.*}} atomic(seq_cst) %[[DATA_VALUE]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: cir.store{{.*}} %[[ATOMIC_LOAD]], %[[ATOMIC_TEMP]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CIR: %[[ATOMIC_LOAD_PTR:.*]] = cir.load{{.*}} %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: cir.return
// LLVM-LABEL: @loadWithThreadFence
@ -123,8 +120,8 @@ void loadWithThreadFence(DataPtr d) {
// LLVM: fence seq_cst
// LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
// LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
// LLVM: %[[ATOMIC_LOAD:.*]] = load atomic i64, ptr %[[DATA_VALUE]] seq_cst, align 8
// LLVM: store i64 %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// LLVM: %[[ATOMIC_LOAD:.*]] = load atomic ptr, ptr %[[DATA_VALUE]] seq_cst, align 8
// LLVM: store ptr %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// LLVM: %[[DATA_TEMP_LOAD:.*]] = load ptr, ptr %[[DATA_TEMP]], align 8
// LLVM: ret void
@ -134,8 +131,8 @@ void loadWithThreadFence(DataPtr d) {
// OGCG: fence seq_cst
// OGCG: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
// OGCG: %[[DATA_VALUE:.*]] = getelementptr inbounds nuw %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
// OGCG: %[[ATOMIC_LOAD:.*]] = load atomic i64, ptr %[[DATA_VALUE]] seq_cst, align 8
// OGCG: store i64 %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// OGCG: %[[ATOMIC_LOAD:.*]] = load atomic ptr, ptr %[[DATA_VALUE]] seq_cst, align 8
// OGCG: store ptr %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// OGCG: %[[DATA_TEMP_LOAD:.*]] = load ptr, ptr %[[DATA_TEMP]], align 8
// OGCG: ret void
}
@ -149,12 +146,9 @@ void loadWithSignalFence(DataPtr d) {
// CIR: cir.atomic.fence syncscope(single_thread) seq_cst
// CIR: %[[LOAD_DATA:.*]] = cir.load{{.*}} %[[DATA]] : !cir.ptr<!cir.ptr<!rec_Data>>, !cir.ptr<!rec_Data>
// CIR: %[[DATA_PTR:.*]] = cir.get_member %[[LOAD_DATA]][1] {name = "ptr"} : !cir.ptr<!rec_Data> -> !cir.ptr<!cir.ptr<!void>>
// CIR: %[[CASTED_DATA_PTR:.*]] = cir.cast bitcast %[[DATA_PTR]] : !cir.ptr<!cir.ptr<!void>> -> !cir.ptr<!u64i>
// CIR: %[[CASTED_ATOMIC_TEMP:.*]] = cir.cast bitcast %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>> -> !cir.ptr<!u64i>
// CIR: %[[ATOMIC_LOAD:.*]] = cir.load{{.*}} atomic(seq_cst) %[[CASTED_DATA_PTR]] : !cir.ptr<!u64i>, !u64i
// CIR: cir.store{{.*}} %[[ATOMIC_LOAD]], %[[CASTED_ATOMIC_TEMP]] : !u64i, !cir.ptr<!u64i>
// CIR: %[[DOUBLE_CASTED_ATOMIC_TEMP:.*]] = cir.cast bitcast %[[CASTED_ATOMIC_TEMP]] : !cir.ptr<!u64i> -> !cir.ptr<!cir.ptr<!void>>
// CIR: %[[LOAD_ATOMIC_TEMP:.*]] = cir.load{{.*}} %[[DOUBLE_CASTED_ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: %[[ATOMIC_LOAD:.*]] = cir.load{{.*}} atomic(seq_cst) %[[DATA_PTR]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: cir.store{{.*}} %[[ATOMIC_LOAD]], %[[ATOMIC_TEMP]] : !cir.ptr<!void>, !cir.ptr<!cir.ptr<!void>>
// CIR: %[[LOAD_ATOMIC_TEMP:.*]] = cir.load{{.*}} %[[ATOMIC_TEMP]] : !cir.ptr<!cir.ptr<!void>>, !cir.ptr<!void>
// CIR: cir.return
// LLVM-LABEL: @loadWithSignalFence
@ -163,8 +157,8 @@ void loadWithSignalFence(DataPtr d) {
// LLVM: fence syncscope("singlethread") seq_cst
// LLVM: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
// LLVM: %[[DATA_VALUE:.*]] = getelementptr %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
// LLVM: %[[ATOMIC_LOAD:.*]] = load atomic i64, ptr %[[DATA_VALUE]] seq_cst, align 8
// LLVM: store i64 %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// LLVM: %[[ATOMIC_LOAD:.*]] = load atomic ptr, ptr %[[DATA_VALUE]] seq_cst, align 8
// LLVM: store ptr %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// LLVM: %[[DATA_TEMP_LOAD]] = load ptr, ptr %[[DATA_TEMP]], align 8
// LLVM: ret void
@ -174,8 +168,8 @@ void loadWithSignalFence(DataPtr d) {
// OGCG: fence syncscope("singlethread") seq_cst
// OGCG: %[[DATA_PTR:.*]] = load ptr, ptr %[[DATA]], align 8
// OGCG: %[[DATA_VALUE:.*]] = getelementptr inbounds nuw %struct.Data, ptr %[[DATA_PTR]], i32 0, i32 1
// OGCG: %[[ATOMIC_LOAD:.*]] = load atomic i64, ptr %[[DATA_VALUE]] seq_cst, align 8
// OGCG: store i64 %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// OGCG: %[[ATOMIC_LOAD:.*]] = load atomic ptr, ptr %[[DATA_VALUE]] seq_cst, align 8
// OGCG: store ptr %[[ATOMIC_LOAD]], ptr %[[DATA_TEMP]], align 8
// OGCG: %[[DATA_TEMP_LOAD]] = load ptr, ptr %[[DATA_TEMP]], align 8
// OGCG: ret void
}