blob: 9df45d8b98c581a5b39d0ed45bf69a24aa28d17f [file]
; RUN: opt -S -dxil-resource-access -dxil-op-lower %s | FileCheck %s --check-prefixes=CHECK,I32 --implicit-check-not=insertvalue --implicit-check-not=icmp
; RUN: opt -S -dxil-resource-access -dxil-op-lower -mtriple=dxil-pc-shadermodel6.6-compute %s | FileCheck %s --check-prefixes=CHECK,I32,I64 --implicit-check-not=insertvalue --implicit-check-not=icmp
; Verify cmpxchg through a dx.resource.getpointer is lowered to
; dx.op.atomicCompareExchange for UAV resources. The DXIL op returns only the
; original value, so the users of the { value, success } pair read that value
; directly and the pair is never rebuilt.
target triple = "dxil-pc-shadermodel6.6-compute"
; CHECK-LABEL: define i32 @cmpxchg_i32(
define i32 @cmpxchg_i32(i32 %index, i32 %cmp, i32 %value) {
%buffer = call target("dx.RawBuffer", i32, 1, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, ptr null)
%ptr = call ptr @llvm.dx.resource.getpointer(
target("dx.RawBuffer", i32, 1, 0, 0) %buffer, i32 %index)
; I32: [[ORIG:%.*]] = call i32 @dx.op.atomicCompareExchange.i32(i32 79, %dx.types.Handle %{{.*}}, i32 %index, i32 0, i32 poison, i32 %cmp, i32 %value)
; I32: ret i32 [[ORIG]]
%pair = cmpxchg ptr %ptr, i32 %cmp, i32 %value monotonic monotonic
%old = extractvalue { i32, i1 } %pair, 0
ret i32 %old
}
; A ByteAddressBuffer is not a struct, so the byte offset is folded into the
; index and coord1 is poison.
; CHECK-LABEL: define i32 @cmpxchg_i32_byteaddress(
define i32 @cmpxchg_i32_byteaddress(i32 %offset, i32 %cmp, i32 %value) {
%buffer = call target("dx.RawBuffer", i8, 1, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 1, i32 1, i32 0, ptr null)
%ptr = call ptr @llvm.dx.resource.getpointer(
target("dx.RawBuffer", i8, 1, 0, 0) %buffer, i32 %offset)
; I32: [[ORIG:%.*]] = call i32 @dx.op.atomicCompareExchange.i32(i32 79, %dx.types.Handle %{{.*}}, i32 %offset, i32 poison, i32 poison, i32 %cmp, i32 %value)
; I32: 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 i64 @cmpxchg_i64(
define i64 @cmpxchg_i64(i32 %index, i64 %cmp, i64 %value) {
%buffer = call target("dx.RawBuffer", i64, 1, 0, 0)
@llvm.dx.resource.handlefrombinding(i32 0, i32 2, i32 1, i32 0, ptr null)
%ptr = call ptr @llvm.dx.resource.getpointer(
target("dx.RawBuffer", i64, 1, 0, 0) %buffer, i32 %index)
; I64: [[ORIG:%.*]] = call i64 @dx.op.atomicCompareExchange.i64(i32 79, %dx.types.Handle %{{.*}}, i32 %index, i32 0, i32 poison, i64 %cmp, i64 %value)
; I64: ret i64 [[ORIG]]
%pair = cmpxchg ptr %ptr, i64 %cmp, i64 %value monotonic monotonic
%old = extractvalue { i64, i1 } %pair, 0
ret i64 %old
}