[clang] [CIR] Fix Cmp-Xchg generation when casting to int (PR #198924)
via cfe-commits
cfe-commits at lists.llvm.org
Wed May 20 15:49:47 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangir
Author: Erich Keane (erichkeane)
<details>
<summary>Changes</summary>
We have logic in CIRGenAtomic to handle 'cast float to an int', which works for most of our atomics. However, compare-exchange uses a second 'val' value, which was not getting cast, which caused a verification error.
This patch ensures that the correct cast is generated for 'val2' as well.
---
Full diff: https://github.com/llvm/llvm-project/pull/198924.diff
2 Files Affected:
- (modified) clang/lib/CIR/CodeGen/CIRGenAtomic.cpp (+2)
- (modified) clang/test/CIR/CodeGen/atomic.c (+29)
``````````diff
diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
index 7a81771de6e92..06616c432d9b1 100644
--- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp
@@ -1219,6 +1219,8 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) {
ptr = atomics.castToAtomicIntPointer(ptr);
if (val1.isValid())
val1 = atomics.convertToAtomicIntPointer(val1);
+ if (val2.isValid())
+ val2 = atomics.convertToAtomicIntPointer(val2);
}
if (dest.isValid()) {
if (shouldCastToIntPtrTy)
diff --git a/clang/test/CIR/CodeGen/atomic.c b/clang/test/CIR/CodeGen/atomic.c
index a6330173494a6..c3270e0632127 100644
--- a/clang/test/CIR/CodeGen/atomic.c
+++ b/clang/test/CIR/CodeGen/atomic.c
@@ -600,6 +600,35 @@ void atomic_cmpxchg(int *ptr, int *expected, int *desired, int failure) {
// OGCG: cmpxchg weak ptr %{{.+}}, i32 %{{.+}}, i32 %{{.+}} seq_cst seq_cst
}
+void atomic_cmpxchg_fp_to_int_cast(float *ptr, float *expected, float *desired) {
+ // CIR-LABEL: @atomic_cmpxchg_fp_to_int_cast
+ // LLVM-LABEL: @atomic_cmpxchg_fp_to_int_cast
+ // OGCG-LABEL: @atomic_cmpxchg_fp_to_int_cast
+
+ __atomic_compare_exchange(ptr, expected, desired, 0, __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+ // CIR: %[[PTR_CAST:.*]] = cir.cast bitcast %{{.*}} : !cir.ptr<!cir.float> -> !cir.ptr<!u32i>
+ // CIR: %[[EXP_CAST:.*]] = cir.cast bitcast %{{.*}} : !cir.ptr<!cir.float> -> !cir.ptr<!u32i>
+ // CIR: %[[DES_CAST:.*]] = cir.cast bitcast %{{.*}} : !cir.ptr<!cir.float> -> !cir.ptr<!u32i>
+ // CIR: %[[EXP_DEREF:.*]] = cir.load align(4) %[[EXP_CAST]] : !cir.ptr<!u32i>, !u32i
+ // CIR: %[[DES_DEREF:.*]] = cir.load align(4) %[[DES_CAST]] : !cir.ptr<!u32i>, !u32i
+ // CIR: cir.atomic.cmpxchg success(seq_cst) failure(seq_cst) syncscope(system) %[[PTR_CAST]], %[[EXP_DEREF]], %[[DES_DEREF]] align(4) : (!cir.ptr<!u32i>, !u32i, !u32i) -> (!u32i, !cir.bool)
+
+ // LLVM: %[[PTR_LOAD:.*]] = load ptr, ptr %{{.*}}
+ // LLVM: %[[EXP_LOAD:.*]] = load ptr, ptr %{{.*}}
+ // LLVM: %[[DES_LOAD:.*]] = load ptr, ptr %{{.*}}
+ // LLVM: %[[EXP_DEREF:.*]] = load i32, ptr %[[EXP_LOAD]]
+ // LLVM: %[[DES_DEREF:.*]] = load i32, ptr %[[DES_LOAD]]
+ // LLVM: cmpxchg ptr %[[PTR_LOAD]], i32 %[[EXP_DEREF]], i32 %[[DES_DEREF]] seq_cst seq_cst, align 4
+
+ // OGCG: %[[PTR_LOAD:.*]] = load ptr, ptr %{{.*}}
+ // OGCG: %[[EXP_LOAD:.*]] = load ptr, ptr %{{.*}}
+ // OGCG: %[[DES_LOAD:.*]] = load ptr, ptr %{{.*}}
+ // OGCG: %[[EXP_DEREF:.*]] = load i32, ptr %[[EXP_LOAD]]
+ // OGCG: %[[DES_DEREF:.*]] = load i32, ptr %[[DES_LOAD]]
+ // OGCG: cmpxchg ptr %[[PTR_LOAD]], i32 %[[EXP_DEREF]], i32 %[[DES_DEREF]] seq_cst seq_cst, align 4
+}
+
void atomic_cmpxchg_n(int *ptr, int *expected, int desired, int failure) {
// CIR-LABEL: @atomic_cmpxchg_n
// LLVM-LABEL: @atomic_cmpxchg_n
``````````
</details>
https://github.com/llvm/llvm-project/pull/198924
More information about the cfe-commits
mailing list