brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.2 KiB · 214b3a4 Raw
362 lines · plain
1// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -O0 -o - -triple=amdgcn-amd-amdhsa \2// RUN:   | FileCheck %s3 4// Also test serialization of atomic operations here, to avoid duplicating the test.5// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-pch -O0 -o %t -triple=amdgcn-amd-amdhsa6// RUN: %clang_cc1 %s -cl-std=CL2.0 -include-pch %t -O0 -triple=amdgcn-amd-amdhsa \7// RUN:   -emit-llvm -o - | FileCheck %s8 9#ifndef ALREADY_INCLUDED10#define ALREADY_INCLUDED11 12#pragma OPENCL EXTENSION cl_khr_int64_base_atomics : enable13#pragma OPENCL EXTENSION cl_khr_int64_extended_atomics : enable14 15typedef __INTPTR_TYPE__ intptr_t;16typedef int int8 __attribute__((ext_vector_type(8)));17 18typedef enum memory_order {19  memory_order_relaxed = __ATOMIC_RELAXED,20  memory_order_acquire = __ATOMIC_ACQUIRE,21  memory_order_release = __ATOMIC_RELEASE,22  memory_order_acq_rel = __ATOMIC_ACQ_REL,23  memory_order_seq_cst = __ATOMIC_SEQ_CST24} memory_order;25 26typedef enum memory_scope {27  memory_scope_work_item = __OPENCL_MEMORY_SCOPE_WORK_ITEM,28  memory_scope_work_group = __OPENCL_MEMORY_SCOPE_WORK_GROUP,29  memory_scope_device = __OPENCL_MEMORY_SCOPE_DEVICE,30  memory_scope_all_svm_devices = __OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES,31#if defined(cl_intel_subgroups) || defined(cl_khr_subgroups)32  memory_scope_sub_group = __OPENCL_MEMORY_SCOPE_SUB_GROUP33#endif34} memory_scope;35 36atomic_int j;37 38void fi1(atomic_int *i) {39  // CHECK-LABEL: @fi140  // CHECK: load atomic i32, ptr %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4{{$}}41  int x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);42 43  // CHECK: load atomic i32, ptr %{{[.0-9A-Z_a-z]+}} syncscope("agent") seq_cst, align 4{{$}}44  x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_device);45 46  // CHECK: load atomic i32, ptr %{{[.0-9A-Z_a-z]+}} seq_cst, align 4{{$}}47  x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_all_svm_devices);48 49  // CHECK: load atomic i32, ptr %{{[.0-9A-Z_a-z]+}} syncscope("wavefront") seq_cst, align 4{{$}}50  x = __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_sub_group);51}52 53void fi2(atomic_int *i) {54  // CHECK-LABEL: @fi255  // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, ptr %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4{{$}}56  __opencl_atomic_store(i, 1, memory_order_seq_cst, memory_scope_work_group);57}58 59void test_addr(global atomic_int *ig, private atomic_int *ip, local atomic_int *il) {60  // CHECK-LABEL: @test_addr61  // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, ptr addrspace(1) %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4{{$}}62  __opencl_atomic_store(ig, 1, memory_order_seq_cst, memory_scope_work_group);63 64  // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, ptr addrspace(5) %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4{{$}}65  __opencl_atomic_store(ip, 1, memory_order_seq_cst, memory_scope_work_group);66 67  // CHECK: store atomic i32 %{{[.0-9A-Z_a-z]+}}, ptr addrspace(3) %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4{{$}}68  __opencl_atomic_store(il, 1, memory_order_seq_cst, memory_scope_work_group);69}70 71void fi3(atomic_int *i, atomic_uint *ui) {72  // CHECK-LABEL: @fi373  // CHECK: atomicrmw and ptr %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE:![0-9]+]], [[$DEFMD:!amdgpu.no.fine.grained.memory ![0-9]+, !amdgpu.no.remote.memory ![0-9]+$]]74  int x = __opencl_atomic_fetch_and(i, 1, memory_order_seq_cst, memory_scope_work_group);75 76  // CHECK: atomicrmw min ptr %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]], [[$DEFMD]]77  x = __opencl_atomic_fetch_min(i, 1, memory_order_seq_cst, memory_scope_work_group);78 79  // CHECK: atomicrmw max ptr %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]], [[$DEFMD]]80  x = __opencl_atomic_fetch_max(i, 1, memory_order_seq_cst, memory_scope_work_group);81 82  // CHECK: atomicrmw umin ptr %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]], [[$DEFMD]]83  x = __opencl_atomic_fetch_min(ui, 1, memory_order_seq_cst, memory_scope_work_group);84 85  // CHECK: atomicrmw umax ptr %{{[.0-9A-Z_a-z]+}}, i32 %{{[.0-9A-Z_a-z]+}} syncscope("workgroup") seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]], [[$DEFMD]]86  x = __opencl_atomic_fetch_max(ui, 1, memory_order_seq_cst, memory_scope_work_group);87}88 89bool fi4(atomic_int *i) {90  // CHECK-LABEL: @fi4(91  // CHECK: [[PAIR:%[.0-9A-Z_a-z]+]] = cmpxchg ptr [[PTR:%[.0-9A-Z_a-z]+]], i32 [[EXPECTED:%[.0-9A-Z_a-z]+]], i32 [[DESIRED:%[.0-9A-Z_a-z]+]] syncscope("workgroup-one-as") acquire acquire, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}92  // CHECK: [[OLD:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 093  // CHECK: [[CMP:%[.0-9A-Z_a-z]+]] = extractvalue { i32, i1 } [[PAIR]], 194  // CHECK: br i1 [[CMP]], label %[[STORE_EXPECTED:[.0-9A-Z_a-z]+]], label %[[CONTINUE:[.0-9A-Z_a-z]+]]95  // CHECK: store i32 [[OLD]]96  int cmp = 0;97  return __opencl_atomic_compare_exchange_strong(i, &cmp, 1, memory_order_acquire, memory_order_acquire, memory_scope_work_group);98}99 100void fi5(atomic_int *i, int scope) {101  // CHECK-LABEL: @fi5102  // CHECK: switch i32 %{{.*}}, label %[[opencl_allsvmdevices:.*]] [103  // CHECK-NEXT: i32 1, label %[[opencl_workgroup:.*]]104  // CHECK-NEXT: i32 2, label %[[opencl_device:.*]]105  // CHECK-NEXT: i32 4, label %[[opencl_subgroup:.*]]106  // CHECK-NEXT: ]107  // CHECK: [[opencl_workgroup]]:108  // CHECK: load atomic i32, ptr %{{.*}} syncscope("workgroup") seq_cst, align 4{{$}}109  // CHECK: br label %[[continue:.*]]110  // CHECK: [[opencl_device]]:111  // CHECK: load atomic i32, ptr %{{.*}} syncscope("agent") seq_cst, align 4{{$}}112  // CHECK: br label %[[continue]]113  // CHECK: [[opencl_allsvmdevices]]:114  // CHECK: load atomic i32, ptr %{{.*}} seq_cst, align 4115  // CHECK: br label %[[continue]]116  // CHECK: [[opencl_subgroup]]:117  // CHECK: load atomic i32, ptr %{{.*}} syncscope("wavefront") seq_cst, align 4{{$}}118  // CHECK: br label %[[continue]]119  // CHECK: [[continue]]:120  int x = __opencl_atomic_load(i, memory_order_seq_cst, scope);121}122 123void fi6(atomic_int *i, int order, int scope) {124  // CHECK-LABEL: @fi6125  // CHECK: switch i32 %{{.*}}, label %[[monotonic:.*]] [126  // CHECK-NEXT: i32 1, label %[[acquire:.*]]127  // CHECK-NEXT: i32 2, label %[[acquire:.*]]128  // CHECK-NEXT: i32 5, label %[[seqcst:.*]]129  // CHECK-NEXT: ]130  // CHECK: [[monotonic]]:131  // CHECK: switch i32 %{{.*}}, label %[[MON_ALL:.*]] [132  // CHECK-NEXT: i32 1, label %[[MON_WG:.*]]133  // CHECK-NEXT: i32 2, label %[[MON_DEV:.*]]134  // CHECK-NEXT: i32 4, label %[[MON_SUB:.*]]135  // CHECK-NEXT: ]136  // CHECK: [[acquire]]:137  // CHECK: switch i32 %{{.*}}, label %[[ACQ_ALL:.*]] [138  // CHECK-NEXT: i32 1, label %[[ACQ_WG:.*]]139  // CHECK-NEXT: i32 2, label %[[ACQ_DEV:.*]]140  // CHECK-NEXT: i32 4, label %[[ACQ_SUB:.*]]141  // CHECK-NEXT: ]142  // CHECK: [[seqcst]]:143  // CHECK: switch i32 %{{.*}}, label %[[SEQ_ALL:.*]] [144  // CHECK-NEXT: i32 1, label %[[SEQ_WG:.*]]145  // CHECK-NEXT: i32 2, label %[[SEQ_DEV:.*]]146  // CHECK-NEXT: i32 4, label %[[SEQ_SUB:.*]]147  // CHECK-NEXT: ]148  // CHECK: [[MON_WG]]:149  // CHECK: load atomic i32, ptr %{{.*}} syncscope("workgroup-one-as") monotonic, align 4{{$}}150  // CHECK: [[MON_DEV]]:151  // CHECK: load atomic i32, ptr %{{.*}} syncscope("agent-one-as") monotonic, align 4{{$}}152  // CHECK: [[MON_ALL]]:153  // CHECK: load atomic i32, ptr %{{.*}} monotonic, align 4{{$}}154  // CHECK: [[MON_SUB]]:155  // CHECK: load atomic i32, ptr %{{.*}} syncscope("wavefront-one-as") monotonic, align 4{{$}}156  // CHECK: [[ACQ_WG]]:157  // CHECK: load atomic i32, ptr %{{.*}} syncscope("workgroup-one-as") acquire, align 4{{$}}158  // CHECK: [[ACQ_DEV]]:159  // CHECK: load atomic i32, ptr %{{.*}} syncscope("agent-one-as") acquire, align 4{{$}}160  // CHECK: [[ACQ_ALL]]:161  // CHECK: load atomic i32, ptr %{{.*}} acquire, align 4{{$}}162  // CHECK: [[ACQ_SUB]]:163  // CHECK: load atomic i32, ptr %{{.*}} syncscope("wavefront-one-as") acquire, align 4{{$}}164  // CHECK: [[SEQ_WG]]:165  // CHECK: load atomic i32, ptr %{{.*}} syncscope("workgroup") seq_cst, align 4{{$}}166  // CHECK: [[SEQ_DEV]]:167  // CHECK: load atomic i32, ptr %{{.*}} syncscope("agent") seq_cst, align 4{{$}}168  // CHECK: [[SEQ_ALL]]:169  // CHECK: load atomic i32, ptr %{{.*}} seq_cst, align 4{{$}}170  // CHECK: [[SEQ_SUB]]:171  // CHECK: load atomic i32, ptr %{{.*}} syncscope("wavefront") seq_cst, align 4{{$}}172  int x = __opencl_atomic_load(i, order, scope);173}174 175float ff1(global atomic_float *d) {176  // CHECK-LABEL: @ff1177  // CHECK: load atomic i32, ptr addrspace(1) {{.*}} syncscope("workgroup-one-as") monotonic, align 4{{$}}178  return __opencl_atomic_load(d, memory_order_relaxed, memory_scope_work_group);179}180 181void ff2(atomic_float *d) {182  // CHECK-LABEL: @ff2183  // CHECK: store atomic i32 {{.*}} syncscope("workgroup-one-as") release, align 4184  __opencl_atomic_store(d, 1, memory_order_release, memory_scope_work_group);185}186 187float ff3(atomic_float *d) {188  // CHECK-LABEL: @ff3189  // CHECK: atomicrmw xchg ptr {{.*}} syncscope("workgroup") seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]], [[$DEFMD]]190  return __opencl_atomic_exchange(d, 2, memory_order_seq_cst, memory_scope_work_group);191}192 193float ff4(global atomic_float *d, float a) {194  // CHECK-LABEL: @ff4195  // CHECK: atomicrmw fadd ptr addrspace(1) {{.*}} syncscope("workgroup-one-as") monotonic, align 4, [[$DEFMD]]196  return __opencl_atomic_fetch_add(d, a, memory_order_relaxed, memory_scope_work_group);197}198 199float ff5(global atomic_double *d, double a) {200  // CHECK-LABEL: @ff5201  // CHECK: atomicrmw fadd ptr addrspace(1) {{.*}} syncscope("workgroup-one-as") monotonic, align 8, [[$DEFMD]]202  return __opencl_atomic_fetch_add(d, a, memory_order_relaxed, memory_scope_work_group);203}204 205float ff4_generic(atomic_float *d, float a) {206  // CHECK-LABEL: @ff4_generic207  // CHECK: atomicrmw fadd ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 4, !noalias.addrspace [[$NOPRIVATE]], [[$DEFMD]]208  return __opencl_atomic_fetch_add(d, a, memory_order_relaxed, memory_scope_work_group);209}210 211float ff5_generic(atomic_double *d, double a) {212  // CHECK-LABEL: @ff5_generic213  // CHECK: atomicrmw fadd ptr {{.*}} syncscope("workgroup-one-as") monotonic, align 8, !noalias.addrspace [[$NOPRIVATE]], [[$DEFMD]]214  return __opencl_atomic_fetch_add(d, a, memory_order_relaxed, memory_scope_work_group);215}216 217// CHECK-LABEL: @atomic_init_foo218void atomic_init_foo()219{220  // CHECK-NOT: atomic221  // CHECK: store222  __opencl_atomic_init(&j, 42);223 224  // CHECK-NOT: atomic225  // CHECK: }226}227 228// CHECK-LABEL: @failureOrder229void failureOrder(atomic_int *ptr, int *ptr2) {230  // CHECK: cmpxchg ptr {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup-one-as") acquire monotonic, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}231  __opencl_atomic_compare_exchange_strong(ptr, ptr2, 43, memory_order_acquire, memory_order_relaxed, memory_scope_work_group);232 233  // CHECK: cmpxchg weak ptr {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z._]+}}, i32 {{%[0-9A-Za-z_.]+}} syncscope("workgroup") seq_cst acquire, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}234  __opencl_atomic_compare_exchange_weak(ptr, ptr2, 43, memory_order_seq_cst, memory_order_acquire, memory_scope_work_group);235}236 237// CHECK-LABEL: @generalFailureOrder238void generalFailureOrder(atomic_int *ptr, int *ptr2, int success, int fail) {239  __opencl_atomic_compare_exchange_strong(ptr, ptr2, 42, success, fail, memory_scope_work_group);240// CHECK: switch i32 {{.*}}, label %[[MONOTONIC:[0-9a-zA-Z._]+]] [241  // CHECK-NEXT: i32 1, label %[[ACQUIRE:[0-9a-zA-Z._]+]]242  // CHECK-NEXT: i32 2, label %[[ACQUIRE]]243  // CHECK-NEXT: i32 3, label %[[RELEASE:[0-9a-zA-Z._]+]]244  // CHECK-NEXT: i32 4, label %[[ACQREL:[0-9a-zA-Z._]+]]245  // CHECK-NEXT: i32 5, label %[[SEQCST:[0-9a-zA-Z._]+]]246 247  // CHECK: [[MONOTONIC]]248  // CHECK: switch {{.*}}, label %[[MONOTONIC_MONOTONIC:[0-9a-zA-Z._]+]] [249  // CHECK-NEXT: i32 1, label %[[MONOTONIC_ACQUIRE:[0-9a-zA-Z._]+]]250  // CHECK-NEXT: i32 2, label %[[MONOTONIC_ACQUIRE:[0-9a-zA-Z._]+]]251  // CHECK-NEXT: i32 5, label %[[MONOTONIC_SEQCST:[0-9a-zA-Z._]+]]252  // CHECK-NEXT: ]253 254  // CHECK: [[ACQUIRE]]255  // CHECK: switch {{.*}}, label %[[ACQUIRE_MONOTONIC:[0-9a-zA-Z._]+]] [256  // CHECK-NEXT: i32 1, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]257  // CHECK-NEXT: i32 2, label %[[ACQUIRE_ACQUIRE:[0-9a-zA-Z._]+]]258  // CHECK-NEXT: i32 5, label %[[ACQUIRE_SEQCST:[0-9a-zA-Z._]+]]259  // CHECK-NEXT: ]260 261  // CHECK: [[RELEASE]]262  // CHECK: switch {{.*}}, label %[[RELEASE_MONOTONIC:[0-9a-zA-Z._]+]] [263  // CHECK-NEXT: i32 1, label %[[RELEASE_ACQUIRE:[0-9a-zA-Z._]+]]264  // CHECK-NEXT: i32 2, label %[[RELEASE_ACQUIRE:[0-9a-zA-Z._]+]]265  // CHECK-NEXT: i32 5, label %[[RELEASE_SEQCST:[0-9a-zA-Z._]+]]266  // CHECK-NEXT: ]267 268  // CHECK: [[ACQREL]]269  // CHECK: switch {{.*}}, label %[[ACQREL_MONOTONIC:[0-9a-zA-Z._]+]] [270  // CHECK-NEXT: i32 1, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]271  // CHECK-NEXT: i32 2, label %[[ACQREL_ACQUIRE:[0-9a-zA-Z._]+]]272  // CHECK-NEXT: i32 5, label %[[ACQREL_SEQCST:[0-9a-zA-Z._]+]]273  // CHECK-NEXT: ]274 275  // CHECK: [[SEQCST]]276  // CHECK: switch {{.*}}, label %[[SEQCST_MONOTONIC:[0-9a-zA-Z._]+]] [277  // CHECK-NEXT: i32 1, label %[[SEQCST_ACQUIRE:[0-9a-zA-Z._]+]]278  // CHECK-NEXT: i32 2, label %[[SEQCST_ACQUIRE]]279  // CHECK-NEXT: i32 5, label %[[SEQCST_SEQCST:[0-9a-zA-Z._]+]]280  // CHECK-NEXT: ]281 282  // CHECK: [[MONOTONIC_MONOTONIC]]283  // CHECK: cmpxchg {{.*}} monotonic monotonic, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}284  // CHECK: br285 286  // CHECK: [[MONOTONIC_ACQUIRE]]287  // CHECK: cmpxchg {{.*}} monotonic acquire, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}288  // CHECK: br289 290  // CHECK: [[MONOTONIC_SEQCST]]291  // CHECK: cmpxchg {{.*}} monotonic seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}292  // CHECK: br293 294  // CHECK: [[ACQUIRE_MONOTONIC]]295  // CHECK: cmpxchg {{.*}} acquire monotonic, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}296  // CHECK: br297 298  // CHECK: [[ACQUIRE_ACQUIRE]]299  // CHECK: cmpxchg {{.*}} acquire acquire, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}300  // CHECK: br301 302  // CHECK: [[ACQUIRE_SEQCST]]303  // CHECK: cmpxchg {{.*}} acquire seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}304  // CHECK: br305 306  // CHECK: [[RELEASE_MONOTONIC]]307  // CHECK: cmpxchg {{.*}} release monotonic, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}308  // CHECK: br309 310  // CHECK: [[RELEASE_ACQUIRE]]311  // CHECK: cmpxchg {{.*}} release acquire, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}312  // CHECK: br313 314  // CHECK: [[RELEASE_SEQCST]]315  // CHECK: cmpxchg {{.*}} release seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}316  // CHECK: br317 318  // CHECK: [[ACQREL_MONOTONIC]]319  // CHECK: cmpxchg {{.*}} acq_rel monotonic, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}320  // CHECK: br321 322  // CHECK: [[ACQREL_ACQUIRE]]323  // CHECK: cmpxchg {{.*}} acq_rel acquire, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}324  // CHECK: br325 326  // CHECK: [[ACQREL_SEQCST]]327  // CHECK: cmpxchg {{.*}} acq_rel seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}328  // CHECK: br329 330  // CHECK: [[SEQCST_MONOTONIC]]331  // CHECK: cmpxchg {{.*}} seq_cst monotonic, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}332  // CHECK: br333 334  // CHECK: [[SEQCST_ACQUIRE]]335  // CHECK: cmpxchg {{.*}} seq_cst acquire, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}336  // CHECK: br337 338  // CHECK: [[SEQCST_SEQCST]]339  // CHECK: cmpxchg {{.*}} seq_cst seq_cst, align 4, !noalias.addrspace [[$NOPRIVATE]]{{$}}340  // CHECK: br341}342 343int test_volatile(volatile atomic_int *i) {344  // CHECK-LABEL: @test_volatile345  // CHECK:      %[[i_addr:.*]] = alloca ptr346  // CHECK-NEXT: %[[atomicdst:.*]] = alloca i32347  // CHECK-NEXT: %[[retval_ascast:.*]] = addrspacecast ptr addrspace(5) {{.*}} to ptr348  // CHECK-NEXT: %[[i_addr_ascast:.*]] = addrspacecast ptr addrspace(5) %[[i_addr]] to ptr349  // CHECK-NEXT: %[[atomicdst_ascast:.*]] = addrspacecast ptr addrspace(5) %[[atomicdst]] to ptr350  // CHECK-NEXT: store ptr %i, ptr %[[i_addr_ascast]]351  // CHECK-NEXT: %[[addr:.*]] = load ptr, ptr %[[i_addr_ascast]]352  // CHECK-NEXT: %[[res:.*]] = load atomic volatile i32, ptr %[[addr]] syncscope("workgroup") seq_cst, align 4{{$}}353  // CHECK-NEXT: store i32 %[[res]], ptr %[[atomicdst_ascast]]354  // CHECK-NEXT: %[[retval:.*]] = load i32, ptr %[[atomicdst_ascast]]355  // CHECK-NEXT: ret i32 %[[retval]]356  return __opencl_atomic_load(i, memory_order_seq_cst, memory_scope_work_group);357}358 359#endif360 361// CHECK: [[$NOPRIVATE]] = !{i32 5, i32 6}362