| ; RUN: opt -S -dxil-resource-access -dxil-op-lower %s | FileCheck %s --implicit-check-not=insertvalue --implicit-check-not=icmp | |
| ; Verify cmpxchg through a dx.resource.getpointer of a texture is lowered to | |
| ; dx.op.atomicCompareExchange, with one coordinate operand per texture | |
| ; dimension. Unused coordinates are poison. | |
| target triple = "dxil-pc-shadermodel6.6-compute" | |
| ; CHECK-LABEL: define i32 @cmpxchg_texture1d( | |
| define i32 @cmpxchg_texture1d(i32 %coord, i32 %cmp, i32 %value) { | |
| %texture = call target("dx.Texture", i32, 1, 0, 0, 1) | |
| @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr null) | |
| %ptr = call ptr @llvm.dx.resource.getpointer( | |
| target("dx.Texture", i32, 1, 0, 0, 1) %texture, i32 %coord) | |
| ; CHECK: [[ORIG:%.*]] = call i32 @dx.op.atomicCompareExchange.i32(i32 79, %dx.types.Handle %{{.*}}, i32 %coord, i32 poison, i32 poison, i32 %cmp, i32 %value) | |
| ; CHECK: ret i32 [[ORIG]] | |
| %pair = cmpxchg ptr %ptr, i32 %cmp, i32 %value monotonic monotonic | |
| %old = extractvalue { i32, i1 } %pair, 0 | |
| ret i32 %old | |
| } | |
| ; CHECK-LABEL: define i32 @cmpxchg_texture2d( | |
| define i32 @cmpxchg_texture2d(<2 x i32> %coords, i32 %cmp, i32 %value) { | |
| %texture = call target("dx.Texture", i32, 1, 0, 0, 2) | |
| @llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, ptr null) | |
| %ptr = call ptr @llvm.dx.resource.getpointer( | |
| target("dx.Texture", i32, 1, 0, 0, 2) %texture, <2 x i32> %coords) | |
| ; CHECK: %[[X:.*]] = extractelement <2 x i32> %coords, i64 0 | |
| ; CHECK: %[[Y:.*]] = extractelement <2 x i32> %coords, i64 1 | |
| ; CHECK: call i32 @dx.op.atomicCompareExchange.i32(i32 79, %dx.types.Handle %{{.*}}, i32 %[[X]], i32 %[[Y]], i32 poison, i32 %cmp, i32 %value) | |
| %pair = cmpxchg ptr %ptr, i32 %cmp, i32 %value monotonic monotonic | |
| %old = extractvalue { i32, i1 } %pair, 0 | |
| ret i32 %old | |
| } | |
| ; CHECK-LABEL: define i32 @cmpxchg_texture2darray( | |
| define i32 @cmpxchg_texture2darray(<3 x i32> %coords, i32 %cmp, i32 %value) { | |
| %texture = call target("dx.Texture", i32, 1, 0, 0, 7) | |
| @llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, ptr null) | |
| %ptr = call ptr @llvm.dx.resource.getpointer( | |
| target("dx.Texture", i32, 1, 0, 0, 7) %texture, <3 x i32> %coords) | |
| ; CHECK: %[[X:.*]] = extractelement <3 x i32> %coords, i64 0 | |
| ; CHECK: %[[Y:.*]] = extractelement <3 x i32> %coords, i64 1 | |
| ; CHECK: %[[Z:.*]] = extractelement <3 x i32> %coords, i64 2 | |
| ; CHECK: call i32 @dx.op.atomicCompareExchange.i32(i32 79, %dx.types.Handle %{{.*}}, i32 %[[X]], i32 %[[Y]], i32 %[[Z]], i32 %cmp, i32 %value) | |
| %pair = cmpxchg ptr %ptr, i32 %cmp, i32 %value monotonic monotonic | |
| %old = extractvalue { i32, i1 } %pair, 0 | |
| ret i32 %old | |
| } | |
| ; A float texture still lowers, because the cmpxchg operands are integers. This | |
| ; is what InterlockedCompareStoreFloatBitwise lowers to. | |
| ; CHECK-LABEL: define i32 @cmpxchg_texture2d_float( | |
| define i32 @cmpxchg_texture2d_float(<2 x i32> %coords, i32 %cmp, i32 %value) { | |
| %texture = call target("dx.Texture", float, 1, 0, 0, 2) | |
| @llvm.dx.resource.handlefrombinding(i32 0, i32 3, i32 1, i32 0, ptr null) | |
| %ptr = call ptr @llvm.dx.resource.getpointer( | |
| target("dx.Texture", float, 1, 0, 0, 2) %texture, <2 x i32> %coords) | |
| ; CHECK: %[[X:.*]] = extractelement <2 x i32> %coords, i64 0 | |
| ; CHECK: %[[Y:.*]] = extractelement <2 x i32> %coords, i64 1 | |
| ; CHECK: call i32 @dx.op.atomicCompareExchange.i32(i32 79, %dx.types.Handle %{{.*}}, i32 %[[X]], i32 %[[Y]], i32 poison, i32 %cmp, i32 %value) | |
| %pair = cmpxchg ptr %ptr, i32 %cmp, i32 %value monotonic monotonic | |
| %old = extractvalue { i32, i1 } %pair, 0 | |
| ret i32 %old | |
| } | |
| ; CHECK-LABEL: define i64 @cmpxchg_texture3d_i64( | |
| define i64 @cmpxchg_texture3d_i64(<3 x i32> %coords, i64 %cmp, i64 %value) { | |
| %texture = call target("dx.Texture", i64, 1, 0, 0, 4) | |
| @llvm.dx.resource.handlefrombinding(i32 0, i32 4, i32 1, i32 0, ptr null) | |
| %ptr = call ptr @llvm.dx.resource.getpointer( | |
| target("dx.Texture", i64, 1, 0, 0, 4) %texture, <3 x i32> %coords) | |
| ; CHECK: call i64 @dx.op.atomicCompareExchange.i64(i32 79, %dx.types.Handle %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i64 %cmp, i64 %value) | |
| %pair = cmpxchg ptr %ptr, i64 %cmp, i64 %value monotonic monotonic | |
| %old = extractvalue { i64, i1 } %pair, 0 | |
| ret i64 %old | |
| } |