
Summary: The documentation at https://llvm.org/docs/AMDGPUUsage.html#memory-scopes states that these 'one-as' modifiers are more specific versions of the scopes that only apply to a specific address space. This doesn't make sense for fences which have no associated address space to use, and it's a more restrictive version the normal scope. This should not tbe the default behavior, but it is currently emitted in all cases except for sequentially consistent.
260 lines
11 KiB
C
260 lines
11 KiB
C
// 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);
|
|
}
|