|
| 1 | +; RUN: llvm-as %s -o %t.bc |
| 2 | +; RUN: llvm-spirv %t.bc --spirv-ext=+SPV_EXT_shader_atomic_float_add -o %t.spv |
| 3 | +; RUN: spirv-val %t.spv |
| 4 | +; RUN: llvm-spirv %t.spv -to-text -o %t.spt |
| 5 | +; RUN: FileCheck < %t.spt %s -check-prefix=CHECK-SPIRV |
| 6 | +; RUN: llvm-spirv %t.spv -r --spirv-target-env=CL2.0 -o - | llvm-dis -o %t.rev.ll |
| 7 | +; RUN: FileCheck < %t.rev.ll %s -check-prefix=CHECK-LLVM |
| 8 | + |
| 9 | +target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024" |
| 10 | +target triple = "spir64" |
| 11 | + |
| 12 | +@j = local_unnamed_addr addrspace(1) global i32 0, align 4 |
| 13 | + |
| 14 | +; SPIRV scopes |
| 15 | +; 0 - ScopeCrossDevice (all svm devices) |
| 16 | +; 1 - ScopeDevice |
| 17 | +; 2 - ScopeWorkGroup |
| 18 | +; 3 - ScopeSubgroup |
| 19 | +; 4 - ScopeInvocation (mapped from work item) |
| 20 | + |
| 21 | +; OCL scopes |
| 22 | +; 0 - work_item |
| 23 | +; 1 - work_group |
| 24 | +; 2 - device |
| 25 | +; 3 - all_svm_devices |
| 26 | +; 4 - sub_group |
| 27 | + |
| 28 | +; CHECK-SPIRV-DAG: Constant [[#]] [[#ConstInt0:]] 0 |
| 29 | +; CHECK-SPIRV-DAG: Constant [[#]] [[#SequentiallyConsistent:]] 16 |
| 30 | +; CHECK-SPIRV-DAG: Constant [[#]] [[#ConstInt1:]] 1 |
| 31 | +; CHECK-SPIRV-DAG: Constant [[#]] [[#ConstInt2:]] 2 |
| 32 | +; CHECK-SPIRV-DAG: Constant [[#]] [[#ConstInt3:]] 3 |
| 33 | +; CHECK-SPIRV-DAG: Constant [[#]] [[#ConstInt4:]] 4 |
| 34 | +; CHECK-SPIRV-DAG: Constant [[#]] [[#Const2Power30:]] 1073741824 |
| 35 | +; CHECK-SPIRV-DAG: Constant [[#]] [[#ConstInt42:]] 42 |
| 36 | + |
| 37 | +; AtomicLoad ResTypeId ResId PtrId MemScopeId MemSemanticsId |
| 38 | +; CHECK-SPIRV: AtomicLoad [[#]] [[#]] [[#]] [[#ConstInt2]] [[#SequentiallyConsistent]] |
| 39 | +; CHECK-SPIRV: AtomicLoad [[#]] [[#]] [[#]] [[#ConstInt1]] [[#SequentiallyConsistent]] |
| 40 | +; CHECK-SPIRV: AtomicLoad [[#]] [[#]] [[#]] [[#ConstInt1]] [[#SequentiallyConsistent]] |
| 41 | +; CHECK-SPIRV: AtomicLoad [[#]] [[#]] [[#]] [[#ConstInt3]] [[#SequentiallyConsistent]] |
| 42 | + |
| 43 | +; CHECK-LLVM: call spir_func i32 @_Z20atomic_load_explicitPU3AS4VU7_Atomici12memory_order12memory_scope(ptr{{.*}}, i32 5, i32 1) |
| 44 | +; CHECK-LLVM: call spir_func i32 @_Z20atomic_load_explicitPU3AS4VU7_Atomici12memory_order12memory_scope(ptr{{.*}}, i32 5, i32 2) |
| 45 | +; CHECK-LLVM: call spir_func i32 @_Z20atomic_load_explicitPU3AS4VU7_Atomici12memory_order12memory_scope(ptr{{.*}}, i32 5, i32 2) |
| 46 | +; CHECK-LLVM: call spir_func i32 @_Z20atomic_load_explicitPU3AS4VU7_Atomici12memory_order12memory_scope(ptr{{.*}}, i32 5, i32 4) |
| 47 | + |
| 48 | +define dso_local void @fi1(ptr addrspace(4) nocapture noundef readonly %i) local_unnamed_addr #0 { |
| 49 | +entry: |
| 50 | + %0 = load atomic i32, ptr addrspace(4) %i syncscope("workgroup") seq_cst, align 4 |
| 51 | + %1 = load atomic i32, ptr addrspace(4) %i syncscope("device") seq_cst, align 4 |
| 52 | + %2 = load atomic i32, ptr addrspace(4) %i seq_cst, align 4 |
| 53 | + %3 = load atomic i32, ptr addrspace(4) %i syncscope("subgroup") seq_cst, align 4 |
| 54 | + ret void |
| 55 | +} |
| 56 | + |
| 57 | +; AtomicStore PtrId MemScopeId MemSemanticsId ValueId |
| 58 | +; CHECK-SPIRV: AtomicStore [[#]] [[#ConstInt3]] [[#SequentiallyConsistent]] [[#ConstInt1]] |
| 59 | +; CHECK-SPIRV: AtomicStore [[#]] [[#ConstInt2]] [[#SequentiallyConsistent]] [[#ConstInt1]] |
| 60 | +; CHECK-LLVM: call spir_func void @_Z21atomic_store_explicitPU3AS4VU7_Atomicii12memory_order12memory_scope(ptr{{.*}}, i32 5, i32 4) |
| 61 | +; CHECK-LLVM: call spir_func void @_Z21atomic_store_explicitPU3AS4VU7_Atomicii12memory_order12memory_scope(ptr{{.*}}, i32 5, i32 1) |
| 62 | + |
| 63 | +define dso_local void @test_addr(ptr addrspace(1) nocapture noundef writeonly %ig, ptr addrspace(3) nocapture noundef writeonly %il) local_unnamed_addr #0 { |
| 64 | +entry: |
| 65 | + store atomic i32 1, ptr addrspace(1) %ig syncscope("subgroup") seq_cst, align 4 |
| 66 | + store atomic i32 1, ptr addrspace(3) %il syncscope("workgroup") seq_cst, align 4 |
| 67 | + ret void |
| 68 | +} |
| 69 | + |
| 70 | +; Atomic* ResTypeId ResId PtrId MemScopeId MemSemanticsId ValueId |
| 71 | +; CHECK-SPIRV: AtomicAnd [[#]] [[#]] [[#]] [[#ConstInt4]] [[#SequentiallyConsistent]] [[#ConstInt1]] |
| 72 | +; CHECK-SPIRV: AtomicSMin [[#]] [[#]] [[#]] [[#ConstInt0]] [[#SequentiallyConsistent]] [[#ConstInt1]] |
| 73 | +; CHECK-SPIRV: AtomicSMax [[#]] [[#]] [[#]] [[#ConstInt1]] [[#SequentiallyConsistent]] [[#ConstInt1]] |
| 74 | +; CHECK-SPIRV: AtomicUMin [[#]] [[#]] [[#]] [[#ConstInt2]] [[#SequentiallyConsistent]] [[#ConstInt1]] |
| 75 | +; CHECK-SPIRV: AtomicUMax [[#]] [[#]] [[#]] [[#ConstInt2]] [[#SequentiallyConsistent]] [[#ConstInt1]] |
| 76 | + |
| 77 | +; CHECK-LLVM: call spir_func i32 @_Z25atomic_fetch_and_explicitPU3AS4VU7_Atomicii12memory_order12memory_scope(ptr{{.*}}, i32 1, i32 5, i32 0) |
| 78 | +; CHECK-LLVM: call spir_func i32 @_Z25atomic_fetch_min_explicitPU3AS4VU7_Atomicii12memory_order12memory_scope(ptr{{.*}}, i32 1, i32 5, i32 3) |
| 79 | +; CHECK-LLVM: call spir_func i32 @_Z25atomic_fetch_max_explicitPU3AS4VU7_Atomicii12memory_order12memory_scope(ptr{{.*}}, i32 1, i32 5, i32 2) |
| 80 | +; CHECK-LLVM: call spir_func i32 @_Z25atomic_fetch_min_explicitPU3AS4VU7_Atomicjj12memory_order12memory_scope(ptr{{.*}}, i32 1, i32 5, i32 1) |
| 81 | +; CHECK-LLVM: call spir_func i32 @_Z25atomic_fetch_max_explicitPU3AS4VU7_Atomicjj12memory_order12memory_scope(ptr{{.*}}, i32 1, i32 5, i32 1) |
| 82 | + |
| 83 | +define dso_local void @fi3(ptr nocapture noundef %i, ptr nocapture noundef %ui) local_unnamed_addr #0 { |
| 84 | +entry: |
| 85 | + %0 = atomicrmw and ptr %i, i32 1 syncscope("work_item") seq_cst, align 4 |
| 86 | + %1 = atomicrmw min ptr %i, i32 1 syncscope("all_svm_devices") seq_cst, align 4 |
| 87 | + %2 = atomicrmw max ptr %i, i32 1 syncscope("wrong_scope") seq_cst, align 4 |
| 88 | + %3 = atomicrmw umin ptr %ui, i32 1 syncscope("workgroup") seq_cst, align 4 |
| 89 | + %4 = atomicrmw umax ptr %ui, i32 1 syncscope("workgroup") seq_cst, align 4 |
| 90 | + ret void |
| 91 | +} |
| 92 | + |
| 93 | +; AtomicCompareExchange ResTypeId ResId PtrId MemScopeId MemSemEqualId MemSemUnequalId ValueId ComparatorId |
| 94 | +; CHECK-SPIRV: AtomicCompareExchange [[#]] [[#]] [[#]] [[#ConstInt2]] [[#ConstInt2]] [[#ConstInt2]] [[#ConstInt1]] [[#ConstInt0]] |
| 95 | +; CHECK-LLVM: call spir_func i1 @_Z39atomic_compare_exchange_strong_explicitPU3AS4VU7_AtomiciPU3AS4ii12memory_orderS4_12memory_scope(ptr{{.*}}, ptr{{.*}}, i32 1, i32 2, i32 2, i32 1) |
| 96 | + |
| 97 | +define dso_local zeroext i1 @fi4(ptr nocapture noundef %i) local_unnamed_addr #0 { |
| 98 | +entry: |
| 99 | + %0 = cmpxchg ptr %i, i32 0, i32 1 syncscope("workgroup") acquire acquire, align 4 |
| 100 | + %1 = extractvalue { i32, i1 } %0, 1 |
| 101 | + ret i1 %1 |
| 102 | +} |
| 103 | + |
| 104 | +; AtomicExchange ResTypeId ResId PtrId MemScopeId MemSemanticsId ValueId |
| 105 | +; CHECK-SPIRV: AtomicExchange [[#]] [[#]] [[#]] [[#ConstInt2]] [[#SequentiallyConsistent]] [[#Const2Power30]] |
| 106 | +; CHECK-LLVM: call spir_func i32 @_Z24atomic_exchange_explicitPU3AS4VU7_Atomicii12memory_order12memory_scope(ptr{{.*}}, i32 1073741824, i32 5, i32 1) |
| 107 | + |
| 108 | +define dso_local float @ff3(ptr nocapture noundef %d) local_unnamed_addr #0 { |
| 109 | +entry: |
| 110 | + %0 = atomicrmw xchg ptr %d, i32 1073741824 syncscope("workgroup") seq_cst, align 4 |
| 111 | + %1 = bitcast i32 %0 to float |
| 112 | + ret float %1 |
| 113 | +} |
| 114 | + |
| 115 | +; AtomicFAddEXT ResTypeId ResId PtrId MemScopeId MemSemanticsId ValueId |
| 116 | +; CHECK-SPIRV: AtomicFAddEXT [[#]] [[#]] [[#]] [[#ConstInt2]] [[#ConstInt0]] [[#]] |
| 117 | +; CHECK-LLVM: call spir_func float @_Z25atomic_fetch_add_explicitPU3AS4VU7_Atomicff12memory_order12memory_scope(ptr{{.*}}, i32 0, i32 1) |
| 118 | + |
| 119 | +define dso_local float @ff4(ptr addrspace(1) nocapture noundef %d, float noundef %a) local_unnamed_addr #0 { |
| 120 | +entry: |
| 121 | + %0 = atomicrmw fadd ptr addrspace(1) %d, float %a syncscope("workgroup") monotonic, align 4 |
| 122 | + ret float %0 |
| 123 | +} |
| 124 | + |
| 125 | +; ; Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) |
| 126 | +; define dso_local void @atomic_init_foo() local_unnamed_addr #1 { |
| 127 | +; entry: |
| 128 | +; store i32 42, ptr addrspace(1) @j, align 4 |
| 129 | +; ret void |
| 130 | +; } |
| 131 | + |
| 132 | +; Store PtrId ObjId MemOps+ |
| 133 | +; CHECK-SPIRV: Store [[#]] [[#ConstInt42]] |
| 134 | +; CHECK-LLVM: store i32 42, ptr addrspace(1) @j |
| 135 | + |
| 136 | +define dso_local void @atomic_init_foo() local_unnamed_addr #1 { |
| 137 | +entry: |
| 138 | + tail call spir_func void @_Z11atomic_initPU3AS4VU7_Atomicff(ptr addrspace(1) @j, i32 42) |
| 139 | + ret void |
| 140 | +} |
| 141 | + |
| 142 | +; Function Attrs: convergent |
| 143 | +declare spir_func void @_Z11atomic_initPU3AS4VU7_Atomicff(ptr addrspace(1), i32) local_unnamed_addr |
| 144 | + |
| 145 | +attributes #0 = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite) "no-trapping-math"="true" "stack-protector-buffer-size"="8" } |
| 146 | +attributes #1 = { mustprogress nofree norecurse nosync nounwind willreturn memory(write, argmem: none, inaccessiblemem: none) "no-trapping-math"="true" "stack-protector-buffer-size"="8" } |
| 147 | +attributes #2 = { mustprogress nofree norecurse nounwind willreturn memory(argmem: readwrite, inaccessiblemem: readwrite) "no-trapping-math"="true" "stack-protector-buffer-size"="8" } |
| 148 | + |
| 149 | +!llvm.module.flags = !{!1} |
| 150 | +!opencl.ocl.version = !{!2} |
| 151 | +!llvm.ident = !{!3} |
| 152 | + |
| 153 | +!1 = !{i32 1, !"wchar_size", i32 4} |
| 154 | +!2 = !{i32 2, i32 0} |
| 155 | +!3 = !{!"clang version 18.0.0 (https://github.com/llvm/llvm-project.git 7ce613fc77af092dd6e9db71ce3747b75bc5616e)"} |
| 156 | +!4 = !{!5, !5, i64 0} |
| 157 | +!5 = !{!"omnipotent char", !6, i64 0} |
| 158 | +!6 = !{!"Simple C/C++ TBAA"} |
0 commit comments