1// RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s 2 3//===----------------------------------------------------------------------===// 4// spirv.AtomicAnd 5//===----------------------------------------------------------------------===// 6 7func.func @atomic_and(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 8 // CHECK: spirv.AtomicAnd <Device> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 9 %0 = spirv.AtomicAnd <Device> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 10 return %0 : i32 11} 12 13// ----- 14 15func.func @atomic_and(%ptr : !spirv.ptr<f32, StorageBuffer>, %value : i32) -> i32 { 16 // expected-error @+1 {{'spirv.AtomicAnd' op failed to verify that `value` type matches pointee type of `pointer`}} 17 %0 = "spirv.AtomicAnd"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<f32, StorageBuffer>, i32) -> (i32) 18 return %0 : i32 19} 20 21 22// ----- 23 24func.func @atomic_and(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i64) -> i64 { 25 // expected-error @+1 {{'spirv.AtomicAnd' op failed to verify that `value` type matches pointee type of `pointer`}} 26 %0 = "spirv.AtomicAnd"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, StorageBuffer>, i64) -> (i64) 27 return %0 : i64 28} 29 30// ----- 31 32func.func @atomic_and(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 33 // expected-error @+1 {{expected at most one of these four memory constraints to be set: `Acquire`, `Release`,`AcquireRelease` or `SequentiallyConsistent`}} 34 %0 = spirv.AtomicAnd <Device> <Acquire|Release> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 35 return %0 : i32 36} 37 38// ----- 39 40//===----------------------------------------------------------------------===// 41// spirv.AtomicCompareExchange 42//===----------------------------------------------------------------------===// 43 44func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 { 45 // CHECK: spirv.AtomicCompareExchange <Workgroup> <Release> <Acquire> %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup> 46 %0 = spirv.AtomicCompareExchange <Workgroup> <Release> <Acquire> %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup> 47 return %0: i32 48} 49 50// ----- 51 52func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i64, %comparator: i32) -> i32 { 53 // expected-error @+1 {{'spirv.AtomicCompareExchange' op failed to verify that `value` type matches pointee type of `pointer`}} 54 %0 = "spirv.AtomicCompareExchange"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i64, i32) -> (i32) 55 return %0: i32 56} 57 58// ----- 59 60func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i16) -> i32 { 61 // expected-error @+1 {{'spirv.AtomicCompareExchange' op failed to verify that `comparator` type matches pointee type of `pointer`}} 62 %0 = "spirv.AtomicCompareExchange"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i32, i16) -> (i32) 63 return %0: i32 64} 65 66// ----- 67 68func.func @atomic_compare_exchange(%ptr: !spirv.ptr<i64, Workgroup>, %value: i32, %comparator: i32) -> i32 { 69 // expected-error @+1 {{spirv.AtomicCompareExchange' op failed to verify that `result` type matches pointee type of `pointer`}} 70 %0 = "spirv.AtomicCompareExchange"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i64, Workgroup>, i32, i32) -> (i32) 71 return %0: i32 72} 73 74// ----- 75 76//===----------------------------------------------------------------------===// 77// spirv.AtomicCompareExchangeWeak 78//===----------------------------------------------------------------------===// 79 80func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i32) -> i32 { 81 // CHECK: spirv.AtomicCompareExchangeWeak <Workgroup> <Release> <Acquire> %{{.*}}, %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup> 82 %0 = spirv.AtomicCompareExchangeWeak <Workgroup> <Release> <Acquire> %ptr, %value, %comparator: !spirv.ptr<i32, Workgroup> 83 return %0: i32 84} 85 86// ----- 87 88func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value: i64, %comparator: i32) -> i32 { 89 // expected-error @+1 {{'spirv.AtomicCompareExchangeWeak' op failed to verify that `value` type matches pointee type of `pointer`}} 90 %0 = "spirv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i64, i32) -> (i32) 91 return %0: i32 92} 93 94// ----- 95 96func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32, %comparator: i16) -> i32 { 97 // expected-error @+1 {{'spirv.AtomicCompareExchangeWeak' op failed to verify that `comparator` type matches pointee type of `pointer`}} 98 %0 = "spirv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i32, i16) -> (i32) 99 return %0: i32 100} 101 102// ----- 103 104func.func @atomic_compare_exchange_weak(%ptr: !spirv.ptr<i64, Workgroup>, %value: i32, %comparator: i32) -> i32 { 105 // expected-error @+1 {{'spirv.AtomicCompareExchangeWeak' op failed to verify that `result` type matches pointee type of `pointer`}} 106 %0 = "spirv.AtomicCompareExchangeWeak"(%ptr, %value, %comparator) {memory_scope = #spirv.scope<Workgroup>, equal_semantics = #spirv.memory_semantics<AcquireRelease>, unequal_semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i64, Workgroup>, i32, i32) -> (i32) 107 return %0: i32 108} 109 110// ----- 111 112//===----------------------------------------------------------------------===// 113// spirv.AtomicExchange 114//===----------------------------------------------------------------------===// 115 116func.func @atomic_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i32) -> i32 { 117 // CHECK: spirv.AtomicExchange <Workgroup> <Release> %{{.*}}, %{{.*}} : !spirv.ptr<i32, Workgroup> 118 %0 = spirv.AtomicExchange <Workgroup> <Release> %ptr, %value: !spirv.ptr<i32, Workgroup> 119 return %0: i32 120} 121 122// ----- 123 124func.func @atomic_exchange(%ptr: !spirv.ptr<i32, Workgroup>, %value: i64) -> i32 { 125 // expected-error @+1 {{'spirv.AtomicExchange' op failed to verify that `value` type matches pointee type of `pointer`}} 126 %0 = "spirv.AtomicExchange"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, Workgroup>, i64) -> (i32) 127 return %0: i32 128} 129 130// ----- 131 132func.func @atomic_exchange(%ptr: !spirv.ptr<i64, Workgroup>, %value: i32) -> i32 { 133 // expected-error @+1 {{'spirv.AtomicExchange' op failed to verify that `value` type matches pointee type of `pointer`}} 134 %0 = "spirv.AtomicExchange"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i64, Workgroup>, i32) -> (i32) 135 return %0: i32 136} 137 138// ----- 139 140//===----------------------------------------------------------------------===// 141// spirv.AtomicIAdd 142//===----------------------------------------------------------------------===// 143 144func.func @atomic_iadd(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 145 // CHECK: spirv.AtomicIAdd <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 146 %0 = spirv.AtomicIAdd <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 147 return %0 : i32 148} 149 150//===----------------------------------------------------------------------===// 151// spirv.AtomicIDecrement 152//===----------------------------------------------------------------------===// 153 154func.func @atomic_idecrement(%ptr : !spirv.ptr<i32, StorageBuffer>) -> i32 { 155 // CHECK: spirv.AtomicIDecrement <Workgroup> <None> %{{.*}} : !spirv.ptr<i32, StorageBuffer> 156 %0 = spirv.AtomicIDecrement <Workgroup> <None> %ptr : !spirv.ptr<i32, StorageBuffer> 157 return %0 : i32 158} 159 160//===----------------------------------------------------------------------===// 161// spirv.AtomicIIncrement 162//===----------------------------------------------------------------------===// 163 164func.func @atomic_iincrement(%ptr : !spirv.ptr<i32, StorageBuffer>) -> i32 { 165 // CHECK: spirv.AtomicIIncrement <Workgroup> <None> %{{.*}} : !spirv.ptr<i32, StorageBuffer> 166 %0 = spirv.AtomicIIncrement <Workgroup> <None> %ptr : !spirv.ptr<i32, StorageBuffer> 167 return %0 : i32 168} 169 170//===----------------------------------------------------------------------===// 171// spirv.AtomicISub 172//===----------------------------------------------------------------------===// 173 174func.func @atomic_isub(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 175 // CHECK: spirv.AtomicISub <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 176 %0 = spirv.AtomicISub <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 177 return %0 : i32 178} 179 180//===----------------------------------------------------------------------===// 181// spirv.AtomicOr 182//===----------------------------------------------------------------------===// 183 184func.func @atomic_or(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 185 // CHECK: spirv.AtomicOr <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 186 %0 = spirv.AtomicOr <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 187 return %0 : i32 188} 189 190//===----------------------------------------------------------------------===// 191// spirv.AtomicSMax 192//===----------------------------------------------------------------------===// 193 194func.func @atomic_smax(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 195 // CHECK: spirv.AtomicSMax <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 196 %0 = spirv.AtomicSMax <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 197 return %0 : i32 198} 199 200//===----------------------------------------------------------------------===// 201// spirv.AtomicSMin 202//===----------------------------------------------------------------------===// 203 204func.func @atomic_smin(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 205 // CHECK: spirv.AtomicSMin <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 206 %0 = spirv.AtomicSMin <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 207 return %0 : i32 208} 209 210//===----------------------------------------------------------------------===// 211// spirv.AtomicUMax 212//===----------------------------------------------------------------------===// 213 214func.func @atomic_umax(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 215 // CHECK: spirv.AtomicUMax <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 216 %0 = spirv.AtomicUMax <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 217 return %0 : i32 218} 219 220//===----------------------------------------------------------------------===// 221// spirv.AtomicUMin 222//===----------------------------------------------------------------------===// 223 224func.func @atomic_umin(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 225 // CHECK: spirv.AtomicUMin <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 226 %0 = spirv.AtomicUMin <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 227 return %0 : i32 228} 229 230//===----------------------------------------------------------------------===// 231// spirv.AtomicXor 232//===----------------------------------------------------------------------===// 233 234func.func @atomic_xor(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : i32) -> i32 { 235 // CHECK: spirv.AtomicXor <Workgroup> <None> %{{.*}}, %{{.*}} : !spirv.ptr<i32, StorageBuffer> 236 %0 = spirv.AtomicXor <Workgroup> <None> %ptr, %value : !spirv.ptr<i32, StorageBuffer> 237 return %0 : i32 238} 239 240// ----- 241 242//===----------------------------------------------------------------------===// 243// spirv.EXT.AtomicFAdd 244//===----------------------------------------------------------------------===// 245 246func.func @atomic_fadd(%ptr : !spirv.ptr<f32, StorageBuffer>, %value : f32) -> f32 { 247 // CHECK: spirv.EXT.AtomicFAdd <Device> <None> %{{.*}}, %{{.*}} : !spirv.ptr<f32, StorageBuffer> 248 %0 = spirv.EXT.AtomicFAdd <Device> <None> %ptr, %value : !spirv.ptr<f32, StorageBuffer> 249 return %0 : f32 250} 251 252// ----- 253 254func.func @atomic_fadd(%ptr : !spirv.ptr<i32, StorageBuffer>, %value : f32) -> f32 { 255 // expected-error @+1 {{'spirv.EXT.AtomicFAdd' op failed to verify that `result` type matches pointee type of `pointer`}} 256 %0 = "spirv.EXT.AtomicFAdd"(%ptr, %value) {memory_scope = #spirv.scope<Workgroup>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<i32, StorageBuffer>, f32) -> (f32) 257 return %0 : f32 258} 259 260// ----- 261 262func.func @atomic_fadd(%ptr : !spirv.ptr<f32, StorageBuffer>, %value : f64) -> f64 { 263 // expected-error @+1 {{'spirv.EXT.AtomicFAdd' op failed to verify that `result` type matches pointee type of `pointer`}} 264 %0 = "spirv.EXT.AtomicFAdd"(%ptr, %value) {memory_scope = #spirv.scope<Device>, semantics = #spirv.memory_semantics<AcquireRelease>} : (!spirv.ptr<f32, StorageBuffer>, f64) -> (f64) 265 return %0 : f64 266} 267 268// ----- 269 270func.func @atomic_fadd(%ptr : !spirv.ptr<f32, StorageBuffer>, %value : f32) -> f32 { 271 // expected-error @+1 {{expected at most one of these four memory constraints to be set: `Acquire`, `Release`,`AcquireRelease` or `SequentiallyConsistent`}} 272 %0 = spirv.EXT.AtomicFAdd <Device> <Acquire|Release> %ptr, %value : !spirv.ptr<f32, StorageBuffer> 273 return %0 : f32 274} 275