| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 |
| // REQUIRES: amdgpu-registered-target |
| // RUN: %clang_cc1 %s -emit-llvm -O0 -o - \ |
| // RUN: -triple=amdgcn-amd-amdhsa -std=c23 | FileCheck %s |
| |
| // Test that [[clang::amdgpu_av("none")]] works with _Atomic type |
| // qualifier operations, which go through CGExprScalar and CGAtomic |
| // codegen paths. |
| |
| // CHECK-LABEL: define dso_local void @test_atomic_rmw_add( |
| // CHECK-SAME: ptr noundef [[P:%.*]]) #[[ATTR0:[0-9]+]] { |
| // CHECK-NEXT: [[ENTRY:.*:]] |
| // CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) |
| // CHECK-NEXT: [[P_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[P_ADDR]] to ptr |
| // CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR_ASCAST]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR_ASCAST]], align 8 |
| // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[TMP0]], i32 1 seq_cst, align 4, !mmra [[META2:![0-9]+]], !amdgpu.no.fine.grained.memory [[META3:![0-9]+]], !amdgpu.no.remote.memory [[META3]] |
| // CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 |
| // CHECK-NEXT: ret void |
| // |
| void test_atomic_rmw_add(_Atomic int *p) { |
| [[clang::amdgpu_av("none")]] *p += 1; |
| } |
| |
| // CHECK-LABEL: define dso_local void @test_atomic_store( |
| // CHECK-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: [[ENTRY:.*:]] |
| // CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) |
| // CHECK-NEXT: [[P_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[P_ADDR]] to ptr |
| // CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR_ASCAST]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR_ASCAST]], align 8 |
| // CHECK-NEXT: store atomic i32 42, ptr [[TMP0]] seq_cst, align 4, !mmra [[META2]] |
| // CHECK-NEXT: ret void |
| // |
| void test_atomic_store(_Atomic int *p) { |
| [[clang::amdgpu_av("none")]] *p = 42; |
| } |
| |
| // CHECK-LABEL: define dso_local void @test_atomic_load( |
| // CHECK-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: [[ENTRY:.*:]] |
| // CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) |
| // CHECK-NEXT: [[P_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[P_ADDR]] to ptr |
| // CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR_ASCAST]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR_ASCAST]], align 8 |
| // CHECK-NEXT: [[ATOMIC_LOAD:%.*]] = load atomic i32, ptr [[TMP0]] seq_cst, align 4, !mmra [[META2]] |
| // CHECK-NEXT: ret void |
| // |
| void test_atomic_load(_Atomic int *p) { |
| [[clang::amdgpu_av("none")]] (void)*p; |
| } |
| |
| // --- Negative control: no attribute --- |
| |
| // CHECK-LABEL: define dso_local void @test_no_attr( |
| // CHECK-SAME: ptr noundef [[P:%.*]]) #[[ATTR0]] { |
| // CHECK-NEXT: [[ENTRY:.*:]] |
| // CHECK-NEXT: [[P_ADDR:%.*]] = alloca ptr, align 8, addrspace(5) |
| // CHECK-NEXT: [[P_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[P_ADDR]] to ptr |
| // CHECK-NEXT: store ptr [[P]], ptr [[P_ADDR_ASCAST]], align 8 |
| // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[P_ADDR_ASCAST]], align 8 |
| // CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add ptr [[TMP0]], i32 1 seq_cst, align 4, !amdgpu.no.fine.grained.memory [[META3]], !amdgpu.no.remote.memory [[META3]] |
| // CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1 |
| // CHECK-NEXT: ret void |
| // |
| void test_no_attr(_Atomic int *p) { |
| *p += 1; |
| } |
| //. |
| // CHECK: [[META2]] = !{!"amdgcn-av", !"none"} |
| // CHECK: [[META3]] = !{} |
| //. |