https://github.com/steffenlarsen updated https://github.com/llvm/llvm-project/pull/220856
>From dcae190072318ae83d7854dc83888f36893005c2 Mon Sep 17 00:00:00 2001 From: Steffen Holst Larsen <[email protected]> Date: Tue, 1 Sep 2026 09:02:12 -0500 Subject: [PATCH 1/5] [CIR][AMDGPU][OpenCL] Classify __hip_atomic_*/__opencl_atomic_* operations load, store, exchange, compare_exchange_strong/weak, and every fetch op were missing from the operand-classification switches, so they fell to the default and reported an unimplemented atomic. They take the same operands as their __c11_atomic_*/__atomic_* counterparts, so they belong with them. This is the ground work for implementing more AMDGPU atomics. --- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 94 ++++---- clang/test/CIR/CodeGenHIP/atomic-classify.hip | 207 ++++++++++++++++++ 2 files changed, 255 insertions(+), 46 deletions(-) create mode 100644 clang/test/CIR/CodeGenHIP/atomic-classify.hip diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index 4a028e0be34f7..6d2392c85eb1e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -670,11 +670,15 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, llvm_unreachable("already handled!"); case AtomicExpr::AO__c11_atomic_compare_exchange_strong: + case AtomicExpr::AO__hip_atomic_compare_exchange_strong: + case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: emitAtomicCmpXchgFailureSet(cgf, expr, /*isWeak=*/false, dest, ptr, val1, val2, failureOrderExpr, size, order, scope); return; case AtomicExpr::AO__c11_atomic_compare_exchange_weak: + case AtomicExpr::AO__hip_atomic_compare_exchange_weak: + case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: emitAtomicCmpXchgFailureSet(cgf, expr, /*isWeak=*/true, dest, ptr, val1, val2, failureOrderExpr, size, order, scope); return; @@ -700,6 +704,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__atomic_load: case AtomicExpr::AO__scoped_atomic_load_n: case AtomicExpr::AO__scoped_atomic_load: { + case AtomicExpr::AO__hip_atomic_load: + case AtomicExpr::AO__opencl_atomic_load: cir::LoadOp load = builder.createLoad(loc, ptr, /*isVolatile=*/expr->isVolatile()); @@ -715,6 +721,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__scoped_atomic_store: case AtomicExpr::AO__scoped_atomic_store_n: { + case AtomicExpr::AO__hip_atomic_store: + case AtomicExpr::AO__opencl_atomic_store: cir::LoadOp loadVal1 = builder.createLoad(loc, val1); assert(!cir::MissingFeatures::atomicSyncScopeID()); @@ -730,6 +738,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__atomic_exchange: case AtomicExpr::AO__scoped_atomic_exchange_n: case AtomicExpr::AO__scoped_atomic_exchange: + case AtomicExpr::AO__hip_atomic_exchange: + case AtomicExpr::AO__opencl_atomic_exchange: opName = cir::AtomicXchgOp::getOperationName(); break; @@ -740,6 +750,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__c11_atomic_fetch_add: case AtomicExpr::AO__atomic_fetch_add: case AtomicExpr::AO__scoped_atomic_fetch_add: + case AtomicExpr::AO__hip_atomic_fetch_add: + case AtomicExpr::AO__opencl_atomic_fetch_add: handleFetchOp(cir::AtomicFetchKind::Add); break; @@ -750,6 +762,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__c11_atomic_fetch_sub: case AtomicExpr::AO__atomic_fetch_sub: case AtomicExpr::AO__scoped_atomic_fetch_sub: + case AtomicExpr::AO__hip_atomic_fetch_sub: + case AtomicExpr::AO__opencl_atomic_fetch_sub: handleFetchOp(cir::AtomicFetchKind::Sub); break; @@ -760,6 +774,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__c11_atomic_fetch_min: case AtomicExpr::AO__atomic_fetch_min: case AtomicExpr::AO__scoped_atomic_fetch_min: + case AtomicExpr::AO__hip_atomic_fetch_min: + case AtomicExpr::AO__opencl_atomic_fetch_min: handleFetchOp(cir::AtomicFetchKind::Min); break; @@ -784,6 +800,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__c11_atomic_fetch_max: case AtomicExpr::AO__atomic_fetch_max: case AtomicExpr::AO__scoped_atomic_fetch_max: + case AtomicExpr::AO__hip_atomic_fetch_max: + case AtomicExpr::AO__opencl_atomic_fetch_max: handleFetchOp(cir::AtomicFetchKind::Max); break; @@ -808,6 +826,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__c11_atomic_fetch_and: case AtomicExpr::AO__atomic_fetch_and: case AtomicExpr::AO__scoped_atomic_fetch_and: + case AtomicExpr::AO__hip_atomic_fetch_and: + case AtomicExpr::AO__opencl_atomic_fetch_and: handleFetchOp(cir::AtomicFetchKind::And); break; @@ -818,6 +838,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__c11_atomic_fetch_or: case AtomicExpr::AO__atomic_fetch_or: case AtomicExpr::AO__scoped_atomic_fetch_or: + case AtomicExpr::AO__hip_atomic_fetch_or: + case AtomicExpr::AO__opencl_atomic_fetch_or: handleFetchOp(cir::AtomicFetchKind::Or); break; @@ -828,6 +850,8 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__c11_atomic_fetch_xor: case AtomicExpr::AO__atomic_fetch_xor: case AtomicExpr::AO__scoped_atomic_fetch_xor: + case AtomicExpr::AO__hip_atomic_fetch_xor: + case AtomicExpr::AO__opencl_atomic_fetch_xor: handleFetchOp(cir::AtomicFetchKind::Xor); break; @@ -870,41 +894,17 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__opencl_atomic_init: - case AtomicExpr::AO__hip_atomic_compare_exchange_strong: - case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: - case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: - case AtomicExpr::AO__hip_atomic_compare_exchange_weak: - case AtomicExpr::AO__opencl_atomic_load: - case AtomicExpr::AO__hip_atomic_load: - case AtomicExpr::AO__opencl_atomic_store: - case AtomicExpr::AO__hip_atomic_store: - case AtomicExpr::AO__hip_atomic_exchange: - case AtomicExpr::AO__opencl_atomic_exchange: - case AtomicExpr::AO__hip_atomic_fetch_add: - case AtomicExpr::AO__opencl_atomic_fetch_add: - case AtomicExpr::AO__hip_atomic_fetch_sub: - case AtomicExpr::AO__opencl_atomic_fetch_sub: - case AtomicExpr::AO__hip_atomic_fetch_min: - case AtomicExpr::AO__opencl_atomic_fetch_min: - case AtomicExpr::AO__hip_atomic_fetch_max: - case AtomicExpr::AO__opencl_atomic_fetch_max: - case AtomicExpr::AO__hip_atomic_fetch_and: - case AtomicExpr::AO__opencl_atomic_fetch_and: - case AtomicExpr::AO__hip_atomic_fetch_or: - case AtomicExpr::AO__opencl_atomic_fetch_or: - case AtomicExpr::AO__hip_atomic_fetch_xor: - case AtomicExpr::AO__opencl_atomic_fetch_xor: cgf.cgm.errorNYI(expr->getSourceRange(), "emitAtomicOp: expr op NYI"); return; @@ -1219,10 +1219,6 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, case AtomicExpr::AO__atomic_compare_exchange_n: case AtomicExpr::AO__c11_atomic_compare_exchange_weak: case AtomicExpr::AO__c11_atomic_compare_exchange_strong: - case AtomicExpr::AO__hip_atomic_compare_exchange_weak: - case AtomicExpr::AO__hip_atomic_compare_exchange_strong: - case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: - case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: case AtomicExpr::AO__scoped_atomic_compare_exchange: case AtomicExpr::AO__scoped_atomic_compare_exchange_n: cgf.cgm.errorNYI( @@ -1234,8 +1230,6 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, case AtomicExpr::AO__atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: case AtomicExpr::AO__c11_atomic_exchange: - case AtomicExpr::AO__hip_atomic_exchange: - case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__scoped_atomic_exchange: case AtomicExpr::AO__scoped_atomic_exchange_n: cgf.cgm.errorNYI(loc, "emitLibCallForAtomicExpr: atomic exchange NYI"); @@ -1256,8 +1250,6 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, break; } - case AtomicExpr::AO__hip_atomic_store: - case AtomicExpr::AO__opencl_atomic_store: cgf.cgm.errorNYI(loc, "emitLibCallForAtomicExpr: atomic store for hip/opencl"); return RValue::get(nullptr); @@ -1294,36 +1286,26 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, case AtomicExpr::AO__scoped_atomic_add_fetch: case AtomicExpr::AO__atomic_fetch_add: case AtomicExpr::AO__c11_atomic_fetch_add: - case AtomicExpr::AO__hip_atomic_fetch_add: - case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__scoped_atomic_fetch_add: case AtomicExpr::AO__atomic_and_fetch: case AtomicExpr::AO__scoped_atomic_and_fetch: case AtomicExpr::AO__atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_and: - case AtomicExpr::AO__hip_atomic_fetch_and: - case AtomicExpr::AO__opencl_atomic_fetch_and: case AtomicExpr::AO__scoped_atomic_fetch_and: case AtomicExpr::AO__atomic_or_fetch: case AtomicExpr::AO__scoped_atomic_or_fetch: case AtomicExpr::AO__atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_or: - case AtomicExpr::AO__hip_atomic_fetch_or: - case AtomicExpr::AO__opencl_atomic_fetch_or: case AtomicExpr::AO__scoped_atomic_fetch_or: case AtomicExpr::AO__atomic_sub_fetch: case AtomicExpr::AO__scoped_atomic_sub_fetch: case AtomicExpr::AO__atomic_fetch_sub: case AtomicExpr::AO__c11_atomic_fetch_sub: - case AtomicExpr::AO__hip_atomic_fetch_sub: - case AtomicExpr::AO__opencl_atomic_fetch_sub: case AtomicExpr::AO__scoped_atomic_fetch_sub: case AtomicExpr::AO__atomic_xor_fetch: case AtomicExpr::AO__scoped_atomic_xor_fetch: case AtomicExpr::AO__atomic_fetch_xor: case AtomicExpr::AO__c11_atomic_fetch_xor: - case AtomicExpr::AO__hip_atomic_fetch_xor: - case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__scoped_atomic_fetch_xor: case AtomicExpr::AO__atomic_nand_fetch: case AtomicExpr::AO__atomic_fetch_nand: @@ -1333,15 +1315,11 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, case AtomicExpr::AO__atomic_min_fetch: case AtomicExpr::AO__atomic_fetch_min: case AtomicExpr::AO__c11_atomic_fetch_min: - case AtomicExpr::AO__hip_atomic_fetch_min: - case AtomicExpr::AO__opencl_atomic_fetch_min: case AtomicExpr::AO__scoped_atomic_fetch_min: case AtomicExpr::AO__scoped_atomic_min_fetch: case AtomicExpr::AO__atomic_max_fetch: case AtomicExpr::AO__atomic_fetch_max: case AtomicExpr::AO__c11_atomic_fetch_max: - case AtomicExpr::AO__hip_atomic_fetch_max: - case AtomicExpr::AO__opencl_atomic_fetch_max: case AtomicExpr::AO__scoped_atomic_fetch_max: case AtomicExpr::AO__scoped_atomic_max_fetch: case AtomicExpr::AO__scoped_atomic_fetch_uinc: @@ -1433,6 +1411,8 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) { case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__scoped_atomic_load_n: case AtomicExpr::AO__c11_atomic_load: + case AtomicExpr::AO__opencl_atomic_load: + case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__atomic_test_and_set: case AtomicExpr::AO__atomic_clear: break; @@ -1459,6 +1439,10 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) { case AtomicExpr::AO__c11_atomic_compare_exchange_strong: case AtomicExpr::AO__scoped_atomic_compare_exchange: case AtomicExpr::AO__scoped_atomic_compare_exchange_n: + case AtomicExpr::AO__hip_atomic_compare_exchange_strong: + case AtomicExpr::AO__hip_atomic_compare_exchange_weak: + case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: + case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: val1 = emitPointerWithAlignment(e->getVal1()); if (e->getOp() == AtomicExpr::AO__atomic_compare_exchange || e->getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange) @@ -1560,6 +1544,24 @@ RValue CIRGenFunction::emitAtomicExpr(AtomicExpr *e) { case AtomicExpr::AO__atomic_fetch_fmaximum: case AtomicExpr::AO__atomic_fetch_fminimum_num: case AtomicExpr::AO__atomic_fetch_fmaximum_num: + case AtomicExpr::AO__hip_atomic_exchange: + case AtomicExpr::AO__hip_atomic_store: + case AtomicExpr::AO__hip_atomic_fetch_add: + case AtomicExpr::AO__hip_atomic_fetch_sub: + case AtomicExpr::AO__hip_atomic_fetch_min: + case AtomicExpr::AO__hip_atomic_fetch_max: + case AtomicExpr::AO__hip_atomic_fetch_and: + case AtomicExpr::AO__hip_atomic_fetch_or: + case AtomicExpr::AO__hip_atomic_fetch_xor: + case AtomicExpr::AO__opencl_atomic_exchange: + case AtomicExpr::AO__opencl_atomic_store: + case AtomicExpr::AO__opencl_atomic_fetch_add: + case AtomicExpr::AO__opencl_atomic_fetch_sub: + case AtomicExpr::AO__opencl_atomic_fetch_min: + case AtomicExpr::AO__opencl_atomic_fetch_max: + case AtomicExpr::AO__opencl_atomic_fetch_and: + case AtomicExpr::AO__opencl_atomic_fetch_or: + case AtomicExpr::AO__opencl_atomic_fetch_xor: val1 = emitValToTemp(*this, e->getVal1()); break; } diff --git a/clang/test/CIR/CodeGenHIP/atomic-classify.hip b/clang/test/CIR/CodeGenHIP/atomic-classify.hip new file mode 100644 index 0000000000000..3c19ba393d4c0 --- /dev/null +++ b/clang/test/CIR/CodeGenHIP/atomic-classify.hip @@ -0,0 +1,207 @@ +// REQUIRES: amdgpu-registered-target +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fclangir -fcuda-is-device \ +// RUN: -emit-cir %s -o - | FileCheck --check-prefix=CIR %s +// RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -fclangir -fcuda-is-device \ +// RUN: -emit-llvm %s -o - | FileCheck --check-prefix=LLVM %s + +#define __device__ __attribute__((device)) + +// CIR-LABEL: @_Z8hip_loadPi +// CIR: cir.load {{.*}} atomic(relaxed) +// LLVM-LABEL: @_Z8hip_loadPi +// LLVM: load atomic i32, ptr {{.*}} monotonic, align 4 +__device__ int hip_load(int *p) { + return __hip_atomic_load(p, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z11opencl_loadPVU7_Atomici +// CIR: cir.load volatile {{.*}} atomic(relaxed) +// LLVM-LABEL: @_Z11opencl_loadPVU7_Atomici +// LLVM: load atomic volatile i32, ptr {{.*}} monotonic, align 4 +__device__ int opencl_load(_Atomic(int) volatile *p) { + return __opencl_atomic_load(p, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z9hip_storePii +// CIR: cir.store {{.*}} atomic(relaxed) +// LLVM-LABEL: @_Z9hip_storePii +// LLVM: store atomic i32 {{.*}} monotonic, align 4 +__device__ void hip_store(int *p, int v) { + __hip_atomic_store(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z12opencl_storePVU7_Atomicii +// CIR: cir.store volatile {{.*}} atomic(relaxed) +// LLVM-LABEL: @_Z12opencl_storePVU7_Atomicii +// LLVM: store atomic volatile i32 {{.*}} monotonic, align 4 +__device__ void opencl_store(_Atomic(int) volatile *p, int v) { + __opencl_atomic_store(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z12hip_exchangePii +// CIR: cir.atomic.xchg relaxed +// LLVM-LABEL: @_Z12hip_exchangePii +// LLVM: atomicrmw xchg ptr {{.*}} monotonic +__device__ int hip_exchange(int *p, int v) { + return __hip_atomic_exchange(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z15opencl_exchangePVU7_Atomicii +// CIR: cir.atomic.xchg relaxed +// LLVM-LABEL: @_Z15opencl_exchangePVU7_Atomicii +// LLVM: atomicrmw xchg ptr {{.*}} monotonic +__device__ int opencl_exchange(_Atomic(int) volatile *p, int v) { + return __opencl_atomic_exchange(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z11hip_cmpxchgPiii +// CIR: cir.atomic.cmpxchg success(relaxed) failure(relaxed) +// LLVM-LABEL: @_Z11hip_cmpxchgPiii +// LLVM: cmpxchg ptr {{.*}} monotonic monotonic +__device__ bool hip_cmpxchg(int *p, int expected, int v) { + return __hip_atomic_compare_exchange_strong(p, &expected, v, __ATOMIC_RELAXED, + __ATOMIC_RELAXED, + __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z16hip_cmpxchg_weakPiii +// CIR: cir.atomic.cmpxchg weak success(relaxed) failure(relaxed) +// LLVM-LABEL: @_Z16hip_cmpxchg_weakPiii +// LLVM: cmpxchg weak ptr {{.*}} monotonic monotonic +__device__ bool hip_cmpxchg_weak(int *p, int expected, int v) { + return __hip_atomic_compare_exchange_weak(p, &expected, v, __ATOMIC_RELAXED, + __ATOMIC_RELAXED, + __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z14opencl_cmpxchgPVU7_AtomiciPii +// CIR: cir.atomic.cmpxchg success(relaxed) failure(relaxed) +// LLVM-LABEL: @_Z14opencl_cmpxchgPVU7_AtomiciPii +// LLVM: cmpxchg volatile ptr {{.*}} monotonic monotonic +__device__ bool opencl_cmpxchg(_Atomic(int) volatile *p, int *expected, int v) { + return __opencl_atomic_compare_exchange_strong(p, expected, v, __ATOMIC_RELAXED, + __ATOMIC_RELAXED, + __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z19opencl_cmpxchg_weakPVU7_AtomiciPii +// CIR: cir.atomic.cmpxchg weak success(relaxed) failure(relaxed) +// LLVM-LABEL: @_Z19opencl_cmpxchg_weakPVU7_AtomiciPii +// LLVM: cmpxchg weak volatile ptr {{.*}} monotonic monotonic +__device__ bool opencl_cmpxchg_weak(_Atomic(int) volatile *p, int *expected, int v) { + return __opencl_atomic_compare_exchange_weak(p, expected, v, __ATOMIC_RELAXED, + __ATOMIC_RELAXED, + __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z13hip_fetch_addPii +// CIR: cir.atomic.fetch add relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z13hip_fetch_addPii +// LLVM: atomicrmw add ptr {{.*}} monotonic +__device__ int hip_fetch_add(int *p, int v) { + return __hip_atomic_fetch_add(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z16opencl_fetch_addPVU7_Atomicii +// CIR: cir.atomic.fetch add relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z16opencl_fetch_addPVU7_Atomicii +// LLVM: atomicrmw add ptr {{.*}} monotonic +__device__ int opencl_fetch_add(_Atomic(int) volatile *p, int v) { + return __opencl_atomic_fetch_add(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z13hip_fetch_subPii +// CIR: cir.atomic.fetch sub relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z13hip_fetch_subPii +// LLVM: atomicrmw sub ptr {{.*}} monotonic +__device__ int hip_fetch_sub(int *p, int v) { + return __hip_atomic_fetch_sub(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z16opencl_fetch_subPVU7_Atomicii +// CIR: cir.atomic.fetch sub relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z16opencl_fetch_subPVU7_Atomicii +// LLVM: atomicrmw sub ptr {{.*}} monotonic +__device__ int opencl_fetch_sub(_Atomic(int) volatile *p, int v) { + return __opencl_atomic_fetch_sub(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z13hip_fetch_minPii +// CIR: cir.atomic.fetch min relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z13hip_fetch_minPii +// LLVM: atomicrmw min ptr {{.*}} monotonic +__device__ int hip_fetch_min(int *p, int v) { + return __hip_atomic_fetch_min(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z16opencl_fetch_minPVU7_Atomicii +// CIR: cir.atomic.fetch min relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z16opencl_fetch_minPVU7_Atomicii +// LLVM: atomicrmw min ptr {{.*}} monotonic +__device__ int opencl_fetch_min(_Atomic(int) volatile *p, int v) { + return __opencl_atomic_fetch_min(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z13hip_fetch_maxPii +// CIR: cir.atomic.fetch max relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z13hip_fetch_maxPii +// LLVM: atomicrmw max ptr {{.*}} monotonic +__device__ int hip_fetch_max(int *p, int v) { + return __hip_atomic_fetch_max(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z16opencl_fetch_maxPVU7_Atomicii +// CIR: cir.atomic.fetch max relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z16opencl_fetch_maxPVU7_Atomicii +// LLVM: atomicrmw max ptr {{.*}} monotonic +__device__ int opencl_fetch_max(_Atomic(int) volatile *p, int v) { + return __opencl_atomic_fetch_max(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z13hip_fetch_andPii +// CIR: cir.atomic.fetch and relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z13hip_fetch_andPii +// LLVM: atomicrmw and ptr {{.*}} monotonic +__device__ int hip_fetch_and(int *p, int v) { + return __hip_atomic_fetch_and(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z16opencl_fetch_andPVU7_Atomicii +// CIR: cir.atomic.fetch and relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z16opencl_fetch_andPVU7_Atomicii +// LLVM: atomicrmw and ptr {{.*}} monotonic +__device__ int opencl_fetch_and(_Atomic(int) volatile *p, int v) { + return __opencl_atomic_fetch_and(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z12hip_fetch_orPii +// CIR: cir.atomic.fetch or relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z12hip_fetch_orPii +// LLVM: atomicrmw or ptr {{.*}} monotonic +__device__ int hip_fetch_or(int *p, int v) { + return __hip_atomic_fetch_or(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z15opencl_fetch_orPVU7_Atomicii +// CIR: cir.atomic.fetch or relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z15opencl_fetch_orPVU7_Atomicii +// LLVM: atomicrmw or ptr {{.*}} monotonic +__device__ int opencl_fetch_or(_Atomic(int) volatile *p, int v) { + return __opencl_atomic_fetch_or(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} + +// CIR-LABEL: @_Z13hip_fetch_xorPii +// CIR: cir.atomic.fetch xor relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z13hip_fetch_xorPii +// LLVM: atomicrmw xor ptr {{.*}} monotonic +__device__ int hip_fetch_xor(int *p, int v) { + return __hip_atomic_fetch_xor(p, v, __ATOMIC_RELAXED, __HIP_MEMORY_SCOPE_AGENT); +} + +// CIR-LABEL: @_Z16opencl_fetch_xorPVU7_Atomicii +// CIR: cir.atomic.fetch xor relaxed {{.*}} fetch_first +// LLVM-LABEL: @_Z16opencl_fetch_xorPVU7_Atomicii +// LLVM: atomicrmw xor ptr {{.*}} monotonic +__device__ int opencl_fetch_xor(_Atomic(int) volatile *p, int v) { + return __opencl_atomic_fetch_xor(p, v, __ATOMIC_RELAXED, __OPENCL_MEMORY_SCOPE_DEVICE); +} >From d265334c38dc7c8add61c9a9daa3a14016ebbc8e Mon Sep 17 00:00:00 2001 From: Steffen Holst Larsen <[email protected]> Date: Thu, 3 Sep 2026 06:19:02 -0500 Subject: [PATCH 2/5] Fix formatting Signed-off-by: Steffen Holst Larsen <[email protected]> --- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index 6d2392c85eb1e..c70dcd6d32e4c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -893,19 +893,6 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, break; case AtomicExpr::AO__opencl_atomic_init: - - - - - - - - - - - - - cgf.cgm.errorNYI(expr->getSourceRange(), "emitAtomicOp: expr op NYI"); return; } >From b39e7571950fb16e2e16bece8ac9c389f77d1ebe Mon Sep 17 00:00:00 2001 From: Steffen Holst Larsen <[email protected]> Date: Thu, 3 Sep 2026 06:24:57 -0500 Subject: [PATCH 3/5] Add back switch cases Signed-off-by: Steffen Holst Larsen <[email protected]> --- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index c70dcd6d32e4c..9d28443d98238 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -1206,6 +1206,10 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, case AtomicExpr::AO__atomic_compare_exchange_n: case AtomicExpr::AO__c11_atomic_compare_exchange_weak: case AtomicExpr::AO__c11_atomic_compare_exchange_strong: + case AtomicExpr::AO__hip_atomic_compare_exchange_weak: + case AtomicExpr::AO__hip_atomic_compare_exchange_strong: + case AtomicExpr::AO__opencl_atomic_compare_exchange_weak: + case AtomicExpr::AO__opencl_atomic_compare_exchange_strong: case AtomicExpr::AO__scoped_atomic_compare_exchange: case AtomicExpr::AO__scoped_atomic_compare_exchange_n: cgf.cgm.errorNYI( @@ -1217,6 +1221,8 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, case AtomicExpr::AO__atomic_exchange: case AtomicExpr::AO__atomic_exchange_n: case AtomicExpr::AO__c11_atomic_exchange: + case AtomicExpr::AO__hip_atomic_exchange: + case AtomicExpr::AO__opencl_atomic_exchange: case AtomicExpr::AO__scoped_atomic_exchange: case AtomicExpr::AO__scoped_atomic_exchange_n: cgf.cgm.errorNYI(loc, "emitLibCallForAtomicExpr: atomic exchange NYI"); @@ -1236,7 +1242,8 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, cgf.getContext().VoidPtrTy); break; } - + case AtomicExpr::AO__hip_atomic_store: + case AtomicExpr::AO__opencl_atomic_store: cgf.cgm.errorNYI(loc, "emitLibCallForAtomicExpr: atomic store for hip/opencl"); return RValue::get(nullptr); @@ -1273,26 +1280,36 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, case AtomicExpr::AO__scoped_atomic_add_fetch: case AtomicExpr::AO__atomic_fetch_add: case AtomicExpr::AO__c11_atomic_fetch_add: + case AtomicExpr::AO__hip_atomic_fetch_add: + case AtomicExpr::AO__opencl_atomic_fetch_add: case AtomicExpr::AO__scoped_atomic_fetch_add: case AtomicExpr::AO__atomic_and_fetch: case AtomicExpr::AO__scoped_atomic_and_fetch: case AtomicExpr::AO__atomic_fetch_and: case AtomicExpr::AO__c11_atomic_fetch_and: + case AtomicExpr::AO__hip_atomic_fetch_and: + case AtomicExpr::AO__opencl_atomic_fetch_and: case AtomicExpr::AO__scoped_atomic_fetch_and: case AtomicExpr::AO__atomic_or_fetch: case AtomicExpr::AO__scoped_atomic_or_fetch: case AtomicExpr::AO__atomic_fetch_or: case AtomicExpr::AO__c11_atomic_fetch_or: + case AtomicExpr::AO__hip_atomic_fetch_or: + case AtomicExpr::AO__opencl_atomic_fetch_or: case AtomicExpr::AO__scoped_atomic_fetch_or: case AtomicExpr::AO__atomic_sub_fetch: case AtomicExpr::AO__scoped_atomic_sub_fetch: case AtomicExpr::AO__atomic_fetch_sub: case AtomicExpr::AO__c11_atomic_fetch_sub: + case AtomicExpr::AO__hip_atomic_fetch_sub: + case AtomicExpr::AO__opencl_atomic_fetch_sub: case AtomicExpr::AO__scoped_atomic_fetch_sub: case AtomicExpr::AO__atomic_xor_fetch: case AtomicExpr::AO__scoped_atomic_xor_fetch: case AtomicExpr::AO__atomic_fetch_xor: case AtomicExpr::AO__c11_atomic_fetch_xor: + case AtomicExpr::AO__hip_atomic_fetch_xor: + case AtomicExpr::AO__opencl_atomic_fetch_xor: case AtomicExpr::AO__scoped_atomic_fetch_xor: case AtomicExpr::AO__atomic_nand_fetch: case AtomicExpr::AO__atomic_fetch_nand: @@ -1302,11 +1319,15 @@ static RValue emitLibCallForAtomicExpr(CIRGenFunction &cgf, AtomicExpr *e, case AtomicExpr::AO__atomic_min_fetch: case AtomicExpr::AO__atomic_fetch_min: case AtomicExpr::AO__c11_atomic_fetch_min: + case AtomicExpr::AO__hip_atomic_fetch_min: + case AtomicExpr::AO__opencl_atomic_fetch_min: case AtomicExpr::AO__scoped_atomic_fetch_min: case AtomicExpr::AO__scoped_atomic_min_fetch: case AtomicExpr::AO__atomic_max_fetch: case AtomicExpr::AO__atomic_fetch_max: case AtomicExpr::AO__c11_atomic_fetch_max: + case AtomicExpr::AO__hip_atomic_fetch_max: + case AtomicExpr::AO__opencl_atomic_fetch_max: case AtomicExpr::AO__scoped_atomic_fetch_max: case AtomicExpr::AO__scoped_atomic_max_fetch: case AtomicExpr::AO__scoped_atomic_fetch_uinc: >From 67f096f55e4e00e2cef0815dee7a8a41fc8515ee Mon Sep 17 00:00:00 2001 From: Steffen Holst Larsen <[email protected]> Date: Thu, 3 Sep 2026 07:20:15 -0500 Subject: [PATCH 4/5] Move case body start down Signed-off-by: Steffen Holst Larsen <[email protected]> --- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index 9d28443d98238..bb5bc3f6cbc28 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -703,7 +703,7 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__atomic_load_n: case AtomicExpr::AO__atomic_load: case AtomicExpr::AO__scoped_atomic_load_n: - case AtomicExpr::AO__scoped_atomic_load: { + case AtomicExpr::AO__scoped_atomic_load: case AtomicExpr::AO__hip_atomic_load: case AtomicExpr::AO__opencl_atomic_load: cir::LoadOp load = >From 3a654b915b18a519c8b8779b4c8611661a3799ae Mon Sep 17 00:00:00 2001 From: Steffen Holst Larsen <[email protected]> Date: Thu, 3 Sep 2026 07:25:24 -0500 Subject: [PATCH 5/5] Fix bodies by actually saving the changes Signed-off-by: Steffen Holst Larsen <[email protected]> --- clang/lib/CIR/CodeGen/CIRGenAtomic.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp index bb5bc3f6cbc28..f8deef391e19d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenAtomic.cpp @@ -705,7 +705,7 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__scoped_atomic_load_n: case AtomicExpr::AO__scoped_atomic_load: case AtomicExpr::AO__hip_atomic_load: - case AtomicExpr::AO__opencl_atomic_load: + case AtomicExpr::AO__opencl_atomic_load: { cir::LoadOp load = builder.createLoad(loc, ptr, /*isVolatile=*/expr->isVolatile()); @@ -720,9 +720,9 @@ static void emitAtomicOp(CIRGenFunction &cgf, AtomicExpr *expr, Address dest, case AtomicExpr::AO__atomic_store_n: case AtomicExpr::AO__atomic_store: case AtomicExpr::AO__scoped_atomic_store: - case AtomicExpr::AO__scoped_atomic_store_n: { + case AtomicExpr::AO__scoped_atomic_store_n: case AtomicExpr::AO__hip_atomic_store: - case AtomicExpr::AO__opencl_atomic_store: + case AtomicExpr::AO__opencl_atomic_store: { cir::LoadOp loadVal1 = builder.createLoad(loc, val1); assert(!cir::MissingFeatures::atomicSyncScopeID()); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
