| // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 |
| // RUN: %clang_cc1 %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa -ffreestanding \ |
| // RUN: -fvisibility=hidden | FileCheck --check-prefix=AMDGCN %s |
| // RUN: %clang_cc1 %s -emit-llvm -o - -triple=amdgcn-amd-amdhsa -ffreestanding \ |
| // RUN: -cl-std=CL2.0 -fvisibility=hidden | FileCheck --check-prefix=AMDGCN %s |
| // RUN: %clang_cc1 %s -emit-llvm -o - -triple=spirv64-unknown-unknown -ffreestanding \ |
| // RUN: -fvisibility=hidden | FileCheck --check-prefix=SPIRV %s |
| // RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-linux-gnu -ffreestanding \ |
| // RUN: -fvisibility=hidden | FileCheck --check-prefix=X86_64 %s |
| |
| // AMDGCN-LABEL: define hidden void @fe1a( |
| // AMDGCN-SAME: ) #[[ATTR0:[0-9]+]] { |
| // AMDGCN-NEXT: [[ENTRY:.*:]] |
| // AMDGCN-NEXT: fence syncscope("workgroup") release |
| // AMDGCN-NEXT: ret void |
| // |
| // SPIRV-LABEL: define hidden spir_func void @fe1a( |
| // SPIRV-SAME: ) #[[ATTR0:[0-9]+]] { |
| // SPIRV-NEXT: [[ENTRY:.*:]] |
| // SPIRV-NEXT: fence syncscope("workgroup") release |
| // SPIRV-NEXT: ret void |
| // |
| // X86_64-LABEL: define hidden void @fe1a( |
| // X86_64-SAME: ) #[[ATTR0:[0-9]+]] { |
| // X86_64-NEXT: [[ENTRY:.*:]] |
| // X86_64-NEXT: fence release |
| // X86_64-NEXT: ret void |
| // |
| void fe1a() { |
| __scoped_atomic_thread_fence(__ATOMIC_RELEASE, __MEMORY_SCOPE_WRKGRP); |
| } |
| |
| // AMDGCN-LABEL: define hidden void @fe1b( |
| // AMDGCN-SAME: i32 noundef [[ORD:%.*]]) #[[ATTR0]] { |
| // AMDGCN-NEXT: [[ENTRY:.*:]] |
| // AMDGCN-NEXT: [[ORD_ADDR:%.*]] = alloca i32, align 4, addrspace(5) |
| // AMDGCN-NEXT: [[ORD_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[ORD_ADDR]] to ptr |
| // AMDGCN-NEXT: store i32 [[ORD]], ptr [[ORD_ADDR_ASCAST]], align 4 |
| // AMDGCN-NEXT: [[TMP0:%.*]] = load i32, ptr [[ORD_ADDR_ASCAST]], align 4 |
| // AMDGCN-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [ |
| // AMDGCN-NEXT: i32 1, label %[[ACQUIRE:.*]] |
| // AMDGCN-NEXT: i32 2, label %[[ACQUIRE]] |
| // AMDGCN-NEXT: i32 3, label %[[RELEASE:.*]] |
| // AMDGCN-NEXT: i32 4, label %[[ACQREL:.*]] |
| // AMDGCN-NEXT: i32 5, label %[[SEQCST:.*]] |
| // AMDGCN-NEXT: ] |
| // AMDGCN: [[ATOMIC_SCOPE_CONTINUE]]: |
| // AMDGCN-NEXT: ret void |
| // AMDGCN: [[ACQUIRE]]: |
| // AMDGCN-NEXT: fence syncscope("workgroup") acquire |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // AMDGCN: [[RELEASE]]: |
| // AMDGCN-NEXT: fence syncscope("workgroup") release |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // AMDGCN: [[ACQREL]]: |
| // AMDGCN-NEXT: fence syncscope("workgroup") acq_rel |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // AMDGCN: [[SEQCST]]: |
| // AMDGCN-NEXT: fence syncscope("workgroup") seq_cst |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // |
| // SPIRV-LABEL: define hidden spir_func void @fe1b( |
| // SPIRV-SAME: i32 noundef [[ORD:%.*]]) #[[ATTR0]] { |
| // SPIRV-NEXT: [[ENTRY:.*:]] |
| // SPIRV-NEXT: [[ORD_ADDR:%.*]] = alloca i32, align 4 |
| // SPIRV-NEXT: store i32 [[ORD]], ptr [[ORD_ADDR]], align 4 |
| // SPIRV-NEXT: [[TMP0:%.*]] = load i32, ptr [[ORD_ADDR]], align 4 |
| // SPIRV-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [ |
| // SPIRV-NEXT: i32 1, label %[[ACQUIRE:.*]] |
| // SPIRV-NEXT: i32 2, label %[[ACQUIRE]] |
| // SPIRV-NEXT: i32 3, label %[[RELEASE:.*]] |
| // SPIRV-NEXT: i32 4, label %[[ACQREL:.*]] |
| // SPIRV-NEXT: i32 5, label %[[SEQCST:.*]] |
| // SPIRV-NEXT: ] |
| // SPIRV: [[ATOMIC_SCOPE_CONTINUE]]: |
| // SPIRV-NEXT: ret void |
| // SPIRV: [[ACQUIRE]]: |
| // SPIRV-NEXT: fence syncscope("workgroup") acquire |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // SPIRV: [[RELEASE]]: |
| // SPIRV-NEXT: fence syncscope("workgroup") release |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // SPIRV: [[ACQREL]]: |
| // SPIRV-NEXT: fence syncscope("workgroup") acq_rel |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // SPIRV: [[SEQCST]]: |
| // SPIRV-NEXT: fence syncscope("workgroup") seq_cst |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // |
| // X86_64-LABEL: define hidden void @fe1b( |
| // X86_64-SAME: i32 noundef [[ORD:%.*]]) #[[ATTR0]] { |
| // X86_64-NEXT: [[ENTRY:.*:]] |
| // X86_64-NEXT: [[ORD_ADDR:%.*]] = alloca i32, align 4 |
| // X86_64-NEXT: store i32 [[ORD]], ptr [[ORD_ADDR]], align 4 |
| // X86_64-NEXT: [[TMP0:%.*]] = load i32, ptr [[ORD_ADDR]], align 4 |
| // X86_64-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [ |
| // X86_64-NEXT: i32 1, label %[[ACQUIRE:.*]] |
| // X86_64-NEXT: i32 2, label %[[ACQUIRE]] |
| // X86_64-NEXT: i32 3, label %[[RELEASE:.*]] |
| // X86_64-NEXT: i32 4, label %[[ACQREL:.*]] |
| // X86_64-NEXT: i32 5, label %[[SEQCST:.*]] |
| // X86_64-NEXT: ] |
| // X86_64: [[ATOMIC_SCOPE_CONTINUE]]: |
| // X86_64-NEXT: ret void |
| // X86_64: [[ACQUIRE]]: |
| // X86_64-NEXT: fence acquire |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // X86_64: [[RELEASE]]: |
| // X86_64-NEXT: fence release |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // X86_64: [[ACQREL]]: |
| // X86_64-NEXT: fence acq_rel |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // X86_64: [[SEQCST]]: |
| // X86_64-NEXT: fence seq_cst |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // |
| void fe1b(int ord) { |
| __scoped_atomic_thread_fence(ord, __MEMORY_SCOPE_WRKGRP); |
| } |
| |
| // AMDGCN-LABEL: define hidden void @fe1c( |
| // AMDGCN-SAME: i32 noundef [[SCOPE:%.*]]) #[[ATTR0]] { |
| // AMDGCN-NEXT: [[ENTRY:.*:]] |
| // AMDGCN-NEXT: [[SCOPE_ADDR:%.*]] = alloca i32, align 4, addrspace(5) |
| // AMDGCN-NEXT: [[SCOPE_ADDR_ASCAST:%.*]] = addrspacecast ptr addrspace(5) [[SCOPE_ADDR]] to ptr |
| // AMDGCN-NEXT: store i32 [[SCOPE]], ptr [[SCOPE_ADDR_ASCAST]], align 4 |
| // AMDGCN-NEXT: [[TMP0:%.*]] = load i32, ptr [[SCOPE_ADDR_ASCAST]], align 4 |
| // AMDGCN-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [ |
| // AMDGCN-NEXT: i32 1, label %[[DEVICE_SCOPE:.*]] |
| // AMDGCN-NEXT: i32 0, label %[[SYSTEM_SCOPE:.*]] |
| // AMDGCN-NEXT: i32 2, label %[[WORKGROUP_SCOPE:.*]] |
| // AMDGCN-NEXT: i32 3, label %[[WAVEFRONT_SCOPE:.*]] |
| // AMDGCN-NEXT: i32 4, label %[[SINGLE_SCOPE:.*]] |
| // AMDGCN-NEXT: ] |
| // AMDGCN: [[ATOMIC_SCOPE_CONTINUE]]: |
| // AMDGCN-NEXT: ret void |
| // AMDGCN: [[DEVICE_SCOPE]]: |
| // AMDGCN-NEXT: fence syncscope("agent") release |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // AMDGCN: [[SYSTEM_SCOPE]]: |
| // AMDGCN-NEXT: fence release |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // AMDGCN: [[WORKGROUP_SCOPE]]: |
| // AMDGCN-NEXT: fence syncscope("workgroup") release |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // AMDGCN: [[WAVEFRONT_SCOPE]]: |
| // AMDGCN-NEXT: fence syncscope("wavefront") release |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // AMDGCN: [[SINGLE_SCOPE]]: |
| // AMDGCN-NEXT: fence syncscope("singlethread") release |
| // AMDGCN-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // |
| // SPIRV-LABEL: define hidden spir_func void @fe1c( |
| // SPIRV-SAME: i32 noundef [[SCOPE:%.*]]) #[[ATTR0]] { |
| // SPIRV-NEXT: [[ENTRY:.*:]] |
| // SPIRV-NEXT: [[SCOPE_ADDR:%.*]] = alloca i32, align 4 |
| // SPIRV-NEXT: store i32 [[SCOPE]], ptr [[SCOPE_ADDR]], align 4 |
| // SPIRV-NEXT: [[TMP0:%.*]] = load i32, ptr [[SCOPE_ADDR]], align 4 |
| // SPIRV-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [ |
| // SPIRV-NEXT: i32 1, label %[[DEVICE_SCOPE:.*]] |
| // SPIRV-NEXT: i32 0, label %[[SYSTEM_SCOPE:.*]] |
| // SPIRV-NEXT: i32 2, label %[[WORKGROUP_SCOPE:.*]] |
| // SPIRV-NEXT: i32 3, label %[[WAVEFRONT_SCOPE:.*]] |
| // SPIRV-NEXT: i32 4, label %[[SINGLE_SCOPE:.*]] |
| // SPIRV-NEXT: ] |
| // SPIRV: [[ATOMIC_SCOPE_CONTINUE]]: |
| // SPIRV-NEXT: ret void |
| // SPIRV: [[DEVICE_SCOPE]]: |
| // SPIRV-NEXT: fence syncscope("device") release |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // SPIRV: [[SYSTEM_SCOPE]]: |
| // SPIRV-NEXT: fence release |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // SPIRV: [[WORKGROUP_SCOPE]]: |
| // SPIRV-NEXT: fence syncscope("workgroup") release |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // SPIRV: [[WAVEFRONT_SCOPE]]: |
| // SPIRV-NEXT: fence syncscope("subgroup") release |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // SPIRV: [[SINGLE_SCOPE]]: |
| // SPIRV-NEXT: fence syncscope("singlethread") release |
| // SPIRV-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // |
| // X86_64-LABEL: define hidden void @fe1c( |
| // X86_64-SAME: i32 noundef [[SCOPE:%.*]]) #[[ATTR0]] { |
| // X86_64-NEXT: [[ENTRY:.*:]] |
| // X86_64-NEXT: [[SCOPE_ADDR:%.*]] = alloca i32, align 4 |
| // X86_64-NEXT: store i32 [[SCOPE]], ptr [[SCOPE_ADDR]], align 4 |
| // X86_64-NEXT: [[TMP0:%.*]] = load i32, ptr [[SCOPE_ADDR]], align 4 |
| // X86_64-NEXT: switch i32 [[TMP0]], label %[[ATOMIC_SCOPE_CONTINUE:.*]] [ |
| // X86_64-NEXT: i32 1, label %[[DEVICE_SCOPE:.*]] |
| // X86_64-NEXT: i32 0, label %[[SYSTEM_SCOPE:.*]] |
| // X86_64-NEXT: i32 2, label %[[WORKGROUP_SCOPE:.*]] |
| // X86_64-NEXT: i32 3, label %[[WAVEFRONT_SCOPE:.*]] |
| // X86_64-NEXT: i32 4, label %[[SINGLE_SCOPE:.*]] |
| // X86_64-NEXT: ] |
| // X86_64: [[ATOMIC_SCOPE_CONTINUE]]: |
| // X86_64-NEXT: ret void |
| // X86_64: [[DEVICE_SCOPE]]: |
| // X86_64-NEXT: fence release |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // X86_64: [[SYSTEM_SCOPE]]: |
| // X86_64-NEXT: fence release |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // X86_64: [[WORKGROUP_SCOPE]]: |
| // X86_64-NEXT: fence release |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // X86_64: [[WAVEFRONT_SCOPE]]: |
| // X86_64-NEXT: fence release |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // X86_64: [[SINGLE_SCOPE]]: |
| // X86_64-NEXT: fence release |
| // X86_64-NEXT: br label %[[ATOMIC_SCOPE_CONTINUE]] |
| // |
| void fe1c(int scope) { |
| __scoped_atomic_thread_fence(__ATOMIC_RELEASE, scope); |
| } |
| |
| // AMDGCN-LABEL: define hidden void @fe2a( |
| // AMDGCN-SAME: ) #[[ATTR0]] { |
| // AMDGCN-NEXT: [[ENTRY:.*:]] |
| // AMDGCN-NEXT: ret void |
| // |
| // SPIRV-LABEL: define hidden spir_func void @fe2a( |
| // SPIRV-SAME: ) #[[ATTR0]] { |
| // SPIRV-NEXT: [[ENTRY:.*:]] |
| // SPIRV-NEXT: ret void |
| // |
| // X86_64-LABEL: define hidden void @fe2a( |
| // X86_64-SAME: ) #[[ATTR0]] { |
| // X86_64-NEXT: [[ENTRY:.*:]] |
| // X86_64-NEXT: ret void |
| // |
| void fe2a() { |
| __scoped_atomic_thread_fence(999, __MEMORY_SCOPE_SYSTEM); |
| } |
| |
| // AMDGCN-LABEL: define hidden void @fe2b( |
| // AMDGCN-SAME: ) #[[ATTR0]] { |
| // AMDGCN-NEXT: [[ENTRY:.*:]] |
| // AMDGCN-NEXT: fence release |
| // AMDGCN-NEXT: ret void |
| // |
| // SPIRV-LABEL: define hidden spir_func void @fe2b( |
| // SPIRV-SAME: ) #[[ATTR0]] { |
| // SPIRV-NEXT: [[ENTRY:.*:]] |
| // SPIRV-NEXT: fence release |
| // SPIRV-NEXT: ret void |
| // |
| // X86_64-LABEL: define hidden void @fe2b( |
| // X86_64-SAME: ) #[[ATTR0]] { |
| // X86_64-NEXT: [[ENTRY:.*:]] |
| // X86_64-NEXT: fence release |
| // X86_64-NEXT: ret void |
| // |
| void fe2b() { |
| __scoped_atomic_thread_fence(__ATOMIC_RELEASE, 999); |
| } |