|  | // 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); | 
|  | } |