// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 // REQUIRES: amdgpu-registered-target // RUN: %clang_cc1 -triple amdgcn-amd-amdhsa -target-cpu gfx942 -emit-llvm -fcuda-is-device %s -o - | FileCheck %s // RUN: %clang_cc1 -triple spirv64-amd-amdhsa -emit-llvm -fcuda-is-device %s -o - | FileCheck --check-prefix=SPIRV %s #define __device__ __attribute__((device)) #define __shared__ __attribute__((shared)) #define __constant__ __attribute__((constant)) __constant__ float const_float; __constant__ double const_double; __device__ float global_float; __device__ double global_double; // CHECK-LABEL: define dso_local void @_Z30test_flat_atomic_fadd_f32_flatPff( // CHECK-SAME: ptr noundef [[PTR:%.*]], float noundef [[VAL:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4, addrspace(5) // CHECK-NEXT: [[RESULT:%.*]] = alloca float, align 4, addrspace(5) // CHECK-NEXT: [[PTR_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[PTR_ADDR]] to ptr // CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[VAL_ADDR]] to ptr // CHECK-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RESULT]] to ptr // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR_ASCAST]], align 8 // CHECK-NEXT: store float [[VAL]], ptr [[VAL_ADDR_ASCAST]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[VAL_ADDR_ASCAST]], align 4 // CHECK-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr [[TMP0]], float [[TMP1]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory [[META3:![0-9]+]], !amdgpu.ignore.denormal.mode [[META3]] // CHECK-NEXT: store float [[TMP2]], ptr [[RESULT_ASCAST]], align 4 // CHECK-NEXT: ret void // // SPIRV-LABEL: define spir_func void @_Z30test_flat_atomic_fadd_f32_flatPff( // SPIRV-SAME: ptr addrspace(4) noundef [[PTR:%.*]], float noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0:[0-9]+]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[PTR_ADDR:%.*]] = alloca ptr addrspace(4), align 8 // SPIRV-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 // SPIRV-NEXT: [[RESULT:%.*]] = alloca float, align 4 // SPIRV-NEXT: [[PTR_ADDR_ASCAST:%.*]] = addrspacecast ptr [[PTR_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr [[RESULT]] to ptr addrspace(4) // SPIRV-NEXT: store ptr addrspace(4) [[PTR]], ptr addrspace(4) [[PTR_ADDR_ASCAST]], align 8 // SPIRV-NEXT: store float [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 // SPIRV-NEXT: [[TMP0:%.*]] = call addrspace(4) i1 @llvm.spv.named.boolean.spec.constant(i32 -1, i1 false, metadata [[META4:![0-9]+]]) // SPIRV-NEXT: br i1 [[TMP0]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] // SPIRV: [[IF_THEN]]: // SPIRV-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[PTR_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr // SPIRV-NEXT: [[TMP3:%.*]] = load float, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 // SPIRV-NEXT: [[TMP4:%.*]] = atomicrmw fadd ptr [[TMP2]], float [[TMP3]] syncscope("device") monotonic, align 4, !amdgpu.no.fine.grained.memory [[META5:![0-9]+]], !amdgpu.ignore.denormal.mode [[META5]] // SPIRV-NEXT: store float [[TMP4]], ptr addrspace(4) [[RESULT_ASCAST]], align 4 // SPIRV-NEXT: br label %[[IF_END]] // SPIRV: [[IF_END]]: // SPIRV-NEXT: ret void // __device__ void test_flat_atomic_fadd_f32_flat(float *ptr, float val) { if (__builtin_amdgcn_is_invocable(__builtin_amdgcn_flat_atomic_fadd_f32)) float result = __builtin_amdgcn_flat_atomic_fadd_f32(ptr, val); } // CHECK-LABEL: define dso_local void @_Z30test_flat_atomic_fadd_f64_flatPdd( // CHECK-SAME: ptr noundef [[PTR:%.*]], double noundef [[VAL:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8, addrspace(5) // CHECK-NEXT: [[RESULT:%.*]] = alloca double, align 8, addrspace(5) // CHECK-NEXT: [[PTR_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[PTR_ADDR]] to ptr // CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[VAL_ADDR]] to ptr // CHECK-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RESULT]] to ptr // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR_ASCAST]], align 8 // CHECK-NEXT: store double [[VAL]], ptr [[VAL_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[VAL_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr [[TMP0]], double [[TMP1]] syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory [[META3]] // CHECK-NEXT: store double [[TMP2]], ptr [[RESULT_ASCAST]], align 8 // CHECK-NEXT: ret void // // SPIRV-LABEL: define spir_func void @_Z30test_flat_atomic_fadd_f64_flatPdd( // SPIRV-SAME: ptr addrspace(4) noundef [[PTR:%.*]], double noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[PTR_ADDR:%.*]] = alloca ptr addrspace(4), align 8 // SPIRV-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8 // SPIRV-NEXT: [[RESULT:%.*]] = alloca double, align 8 // SPIRV-NEXT: [[PTR_ADDR_ASCAST:%.*]] = addrspacecast ptr [[PTR_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr [[RESULT]] to ptr addrspace(4) // SPIRV-NEXT: store ptr addrspace(4) [[PTR]], ptr addrspace(4) [[PTR_ADDR_ASCAST]], align 8 // SPIRV-NEXT: store double [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP0:%.*]] = call addrspace(4) i1 @llvm.spv.named.boolean.spec.constant(i32 -1, i1 false, metadata [[META6:![0-9]+]]) // SPIRV-NEXT: br i1 [[TMP0]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] // SPIRV: [[IF_THEN]]: // SPIRV-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[PTR_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr // SPIRV-NEXT: [[TMP3:%.*]] = load double, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP4:%.*]] = atomicrmw fadd ptr [[TMP2]], double [[TMP3]] syncscope("device") monotonic, align 8, !amdgpu.no.fine.grained.memory [[META5]] // SPIRV-NEXT: store double [[TMP4]], ptr addrspace(4) [[RESULT_ASCAST]], align 8 // SPIRV-NEXT: br label %[[IF_END]] // SPIRV: [[IF_END]]: // SPIRV-NEXT: ret void // __device__ void test_flat_atomic_fadd_f64_flat(double *ptr, double val) { if (__builtin_amdgcn_is_invocable(__builtin_amdgcn_flat_atomic_fadd_f64)) double result = __builtin_amdgcn_flat_atomic_fadd_f64(ptr, val); } // CHECK-LABEL: define dso_local void @_Z32test_flat_atomic_fadd_f32_sharedPff( // CHECK-SAME: ptr noundef [[PTR:%.*]], float noundef [[VAL:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4, addrspace(5) // CHECK-NEXT: [[RESULT:%.*]] = alloca float, align 4, addrspace(5) // CHECK-NEXT: [[PTR_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[PTR_ADDR]] to ptr // CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[VAL_ADDR]] to ptr // CHECK-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RESULT]] to ptr // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR_ASCAST]], align 8 // CHECK-NEXT: store float [[VAL]], ptr [[VAL_ADDR_ASCAST]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[VAL_ADDR_ASCAST]], align 4 // CHECK-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr [[TMP0]], float [[TMP1]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] // CHECK-NEXT: store float [[TMP2]], ptr [[RESULT_ASCAST]], align 4 // CHECK-NEXT: ret void // // SPIRV-LABEL: define spir_func void @_Z32test_flat_atomic_fadd_f32_sharedPff( // SPIRV-SAME: ptr addrspace(4) noundef [[PTR:%.*]], float noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[PTR_ADDR:%.*]] = alloca ptr addrspace(4), align 8 // SPIRV-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 // SPIRV-NEXT: [[RESULT:%.*]] = alloca float, align 4 // SPIRV-NEXT: [[PTR_ADDR_ASCAST:%.*]] = addrspacecast ptr [[PTR_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr [[RESULT]] to ptr addrspace(4) // SPIRV-NEXT: store ptr addrspace(4) [[PTR]], ptr addrspace(4) [[PTR_ADDR_ASCAST]], align 8 // SPIRV-NEXT: store float [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 // SPIRV-NEXT: [[TMP0:%.*]] = call addrspace(4) i1 @llvm.spv.named.boolean.spec.constant(i32 -1, i1 false, metadata [[META4]]) // SPIRV-NEXT: br i1 [[TMP0]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] // SPIRV: [[IF_THEN]]: // SPIRV-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[PTR_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr // SPIRV-NEXT: [[TMP3:%.*]] = load float, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 // SPIRV-NEXT: [[TMP4:%.*]] = atomicrmw fadd ptr [[TMP2]], float [[TMP3]] syncscope("device") monotonic, align 4, !amdgpu.no.fine.grained.memory [[META5]], !amdgpu.ignore.denormal.mode [[META5]] // SPIRV-NEXT: store float [[TMP4]], ptr addrspace(4) [[RESULT_ASCAST]], align 4 // SPIRV-NEXT: br label %[[IF_END]] // SPIRV: [[IF_END]]: // SPIRV-NEXT: ret void // __device__ void test_flat_atomic_fadd_f32_shared(__shared__ float *ptr, float val) { if (__builtin_amdgcn_is_invocable(__builtin_amdgcn_flat_atomic_fadd_f32)) float result = __builtin_amdgcn_flat_atomic_fadd_f32(ptr, val); } // CHECK-LABEL: define dso_local void @_Z32test_flat_atomic_fadd_f64_sharedPdd( // CHECK-SAME: ptr noundef [[PTR:%.*]], double noundef [[VAL:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[PTR_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8, addrspace(5) // CHECK-NEXT: [[RESULT:%.*]] = alloca double, align 8, addrspace(5) // CHECK-NEXT: [[PTR_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[PTR_ADDR]] to ptr // CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[VAL_ADDR]] to ptr // CHECK-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RESULT]] to ptr // CHECK-NEXT: store ptr [[PTR]], ptr [[PTR_ADDR_ASCAST]], align 8 // CHECK-NEXT: store double [[VAL]], ptr [[VAL_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = load double, ptr [[VAL_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr [[TMP0]], double [[TMP1]] syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory [[META3]] // CHECK-NEXT: store double [[TMP2]], ptr [[RESULT_ASCAST]], align 8 // CHECK-NEXT: ret void // // SPIRV-LABEL: define spir_func void @_Z32test_flat_atomic_fadd_f64_sharedPdd( // SPIRV-SAME: ptr addrspace(4) noundef [[PTR:%.*]], double noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[PTR_ADDR:%.*]] = alloca ptr addrspace(4), align 8 // SPIRV-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8 // SPIRV-NEXT: [[RESULT:%.*]] = alloca double, align 8 // SPIRV-NEXT: [[PTR_ADDR_ASCAST:%.*]] = addrspacecast ptr [[PTR_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr [[RESULT]] to ptr addrspace(4) // SPIRV-NEXT: store ptr addrspace(4) [[PTR]], ptr addrspace(4) [[PTR_ADDR_ASCAST]], align 8 // SPIRV-NEXT: store double [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP0:%.*]] = call addrspace(4) i1 @llvm.spv.named.boolean.spec.constant(i32 -1, i1 false, metadata [[META6]]) // SPIRV-NEXT: br i1 [[TMP0]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] // SPIRV: [[IF_THEN]]: // SPIRV-NEXT: [[TMP1:%.*]] = load ptr addrspace(4), ptr addrspace(4) [[PTR_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP2:%.*]] = addrspacecast ptr addrspace(4) [[TMP1]] to ptr // SPIRV-NEXT: [[TMP3:%.*]] = load double, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP4:%.*]] = atomicrmw fadd ptr [[TMP2]], double [[TMP3]] syncscope("device") monotonic, align 8, !amdgpu.no.fine.grained.memory [[META5]] // SPIRV-NEXT: store double [[TMP4]], ptr addrspace(4) [[RESULT_ASCAST]], align 8 // SPIRV-NEXT: br label %[[IF_END]] // SPIRV: [[IF_END]]: // SPIRV-NEXT: ret void // __device__ void test_flat_atomic_fadd_f64_shared(__shared__ double *ptr, double val) { if (__builtin_amdgcn_is_invocable(__builtin_amdgcn_flat_atomic_fadd_f64)) double result = __builtin_amdgcn_flat_atomic_fadd_f64(ptr, val); } // CHECK-LABEL: define dso_local void @_Z34test_flat_atomic_fadd_f32_constantf( // CHECK-SAME: float noundef [[VAL:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4, addrspace(5) // CHECK-NEXT: [[RESULT:%.*]] = alloca float, align 4, addrspace(5) // CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[VAL_ADDR]] to ptr // CHECK-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RESULT]] to ptr // CHECK-NEXT: store float [[VAL]], ptr [[VAL_ADDR_ASCAST]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[VAL_ADDR_ASCAST]], align 4 // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(4) @const_float to ptr), float [[TMP0]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] // CHECK-NEXT: store float [[TMP1]], ptr [[RESULT_ASCAST]], align 4 // CHECK-NEXT: ret void // // SPIRV-LABEL: define spir_func void @_Z34test_flat_atomic_fadd_f32_constantf( // SPIRV-SAME: float noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 // SPIRV-NEXT: [[RESULT:%.*]] = alloca float, align 4 // SPIRV-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr [[RESULT]] to ptr addrspace(4) // SPIRV-NEXT: store float [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 // SPIRV-NEXT: [[TMP0:%.*]] = call addrspace(4) i1 @llvm.spv.named.boolean.spec.constant(i32 -1, i1 false, metadata [[META4]]) // SPIRV-NEXT: br i1 [[TMP0]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] // SPIRV: [[IF_THEN]]: // SPIRV-NEXT: [[TMP1:%.*]] = load float, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 // SPIRV-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @const_float to ptr), float [[TMP1]] syncscope("device") monotonic, align 4, !amdgpu.no.fine.grained.memory [[META5]], !amdgpu.ignore.denormal.mode [[META5]] // SPIRV-NEXT: store float [[TMP2]], ptr addrspace(4) [[RESULT_ASCAST]], align 4 // SPIRV-NEXT: br label %[[IF_END]] // SPIRV: [[IF_END]]: // SPIRV-NEXT: ret void // __device__ void test_flat_atomic_fadd_f32_constant(float val) { if (__builtin_amdgcn_is_invocable(__builtin_amdgcn_flat_atomic_fadd_f32)) float result = __builtin_amdgcn_flat_atomic_fadd_f32(&const_float, val); } // CHECK-LABEL: define dso_local void @_Z34test_flat_atomic_fadd_f64_constantd( // CHECK-SAME: double noundef [[VAL:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8, addrspace(5) // CHECK-NEXT: [[RESULT:%.*]] = alloca double, align 8, addrspace(5) // CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[VAL_ADDR]] to ptr // CHECK-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RESULT]] to ptr // CHECK-NEXT: store double [[VAL]], ptr [[VAL_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[VAL_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(4) @const_double to ptr), double [[TMP0]] syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory [[META3]] // CHECK-NEXT: store double [[TMP1]], ptr [[RESULT_ASCAST]], align 8 // CHECK-NEXT: ret void // // SPIRV-LABEL: define spir_func void @_Z34test_flat_atomic_fadd_f64_constantd( // SPIRV-SAME: double noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8 // SPIRV-NEXT: [[RESULT:%.*]] = alloca double, align 8 // SPIRV-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr [[RESULT]] to ptr addrspace(4) // SPIRV-NEXT: store double [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP0:%.*]] = call addrspace(4) i1 @llvm.spv.named.boolean.spec.constant(i32 -1, i1 false, metadata [[META6]]) // SPIRV-NEXT: br i1 [[TMP0]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] // SPIRV: [[IF_THEN]]: // SPIRV-NEXT: [[TMP1:%.*]] = load double, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @const_double to ptr), double [[TMP1]] syncscope("device") monotonic, align 8, !amdgpu.no.fine.grained.memory [[META5]] // SPIRV-NEXT: store double [[TMP2]], ptr addrspace(4) [[RESULT_ASCAST]], align 8 // SPIRV-NEXT: br label %[[IF_END]] // SPIRV: [[IF_END]]: // SPIRV-NEXT: ret void // __device__ void test_flat_atomic_fadd_f64_constant(double val) { if (__builtin_amdgcn_is_invocable(__builtin_amdgcn_flat_atomic_fadd_f64)) double result = __builtin_amdgcn_flat_atomic_fadd_f64(&const_double, val); } // CHECK-LABEL: define dso_local void @_Z32test_flat_atomic_fadd_f32_globalf( // CHECK-SAME: float noundef [[VAL:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4, addrspace(5) // CHECK-NEXT: [[RESULT:%.*]] = alloca float, align 4, addrspace(5) // CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[VAL_ADDR]] to ptr // CHECK-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RESULT]] to ptr // CHECK-NEXT: store float [[VAL]], ptr [[VAL_ADDR_ASCAST]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[VAL_ADDR_ASCAST]], align 4 // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @global_float to ptr), float [[TMP0]] syncscope("agent") monotonic, align 4, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.ignore.denormal.mode [[META3]] // CHECK-NEXT: store float [[TMP1]], ptr [[RESULT_ASCAST]], align 4 // CHECK-NEXT: ret void // // SPIRV-LABEL: define spir_func void @_Z32test_flat_atomic_fadd_f32_globalf( // SPIRV-SAME: float noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[VAL_ADDR:%.*]] = alloca float, align 4 // SPIRV-NEXT: [[RESULT:%.*]] = alloca float, align 4 // SPIRV-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr [[RESULT]] to ptr addrspace(4) // SPIRV-NEXT: store float [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 // SPIRV-NEXT: [[TMP0:%.*]] = call addrspace(4) i1 @llvm.spv.named.boolean.spec.constant(i32 -1, i1 false, metadata [[META4]]) // SPIRV-NEXT: br i1 [[TMP0]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] // SPIRV: [[IF_THEN]]: // SPIRV-NEXT: [[TMP1:%.*]] = load float, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 4 // SPIRV-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @global_float to ptr), float [[TMP1]] syncscope("device") monotonic, align 4, !amdgpu.no.fine.grained.memory [[META5]], !amdgpu.ignore.denormal.mode [[META5]] // SPIRV-NEXT: store float [[TMP2]], ptr addrspace(4) [[RESULT_ASCAST]], align 4 // SPIRV-NEXT: br label %[[IF_END]] // SPIRV: [[IF_END]]: // SPIRV-NEXT: ret void // __device__ void test_flat_atomic_fadd_f32_global(float val) { if (__builtin_amdgcn_is_invocable(__builtin_amdgcn_flat_atomic_fadd_f32)) float result = __builtin_amdgcn_flat_atomic_fadd_f32(&global_float, val); } // CHECK-LABEL: define dso_local void @_Z32test_flat_atomic_fadd_f64_globald( // CHECK-SAME: double noundef [[VAL:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8, addrspace(5) // CHECK-NEXT: [[RESULT:%.*]] = alloca double, align 8, addrspace(5) // CHECK-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[VAL_ADDR]] to ptr // CHECK-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[RESULT]] to ptr // CHECK-NEXT: store double [[VAL]], ptr [[VAL_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[VAL_ADDR_ASCAST]], align 8 // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @global_double to ptr), double [[TMP0]] syncscope("agent") monotonic, align 8, !amdgpu.no.fine.grained.memory [[META3]] // CHECK-NEXT: store double [[TMP1]], ptr [[RESULT_ASCAST]], align 8 // CHECK-NEXT: ret void // // SPIRV-LABEL: define spir_func void @_Z32test_flat_atomic_fadd_f64_globald( // SPIRV-SAME: double noundef [[VAL:%.*]]) addrspace(4) #[[ATTR0]] { // SPIRV-NEXT: [[ENTRY:.*:]] // SPIRV-NEXT: [[VAL_ADDR:%.*]] = alloca double, align 8 // SPIRV-NEXT: [[RESULT:%.*]] = alloca double, align 8 // SPIRV-NEXT: [[VAL_ADDR_ASCAST:%.*]] = addrspacecast ptr [[VAL_ADDR]] to ptr addrspace(4) // SPIRV-NEXT: [[RESULT_ASCAST:%.*]] = addrspacecast ptr [[RESULT]] to ptr addrspace(4) // SPIRV-NEXT: store double [[VAL]], ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP0:%.*]] = call addrspace(4) i1 @llvm.spv.named.boolean.spec.constant(i32 -1, i1 false, metadata [[META6]]) // SPIRV-NEXT: br i1 [[TMP0]], label %[[IF_THEN:.*]], label %[[IF_END:.*]] // SPIRV: [[IF_THEN]]: // SPIRV-NEXT: [[TMP1:%.*]] = load double, ptr addrspace(4) [[VAL_ADDR_ASCAST]], align 8 // SPIRV-NEXT: [[TMP2:%.*]] = atomicrmw fadd ptr addrspacecast (ptr addrspace(1) @global_double to ptr), double [[TMP1]] syncscope("device") monotonic, align 8, !amdgpu.no.fine.grained.memory [[META5]] // SPIRV-NEXT: store double [[TMP2]], ptr addrspace(4) [[RESULT_ASCAST]], align 8 // SPIRV-NEXT: br label %[[IF_END]] // SPIRV: [[IF_END]]: // SPIRV-NEXT: ret void // __device__ void test_flat_atomic_fadd_f64_global(double val) { if (__builtin_amdgcn_is_invocable(__builtin_amdgcn_flat_atomic_fadd_f64)) double result = __builtin_amdgcn_flat_atomic_fadd_f64(&global_double, val); } //. // CHECK: [[META3]] = !{} //. // SPIRV: [[META4]] = !{!"has.gfx940-insts"} // SPIRV: [[META5]] = !{} // SPIRV: [[META6]] = !{!"has.gfx90a-insts"} //.