Skip to content

Commit 1f25099

Browse files
[DirectX] introducing lowering for bufferUpdateCounter (#115041)
- Adding custom lowering for `bufferUpdateCounter` - introduces llvm intrinsic `int_dx_updateCounter` - adds tests Closes #92147 --------- Co-authored-by: Joao Saffran <[email protected]>
1 parent dd1c99b commit 1f25099

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

llvm/include/llvm/IR/IntrinsicsDirectX.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ def int_dx_typedBufferLoad_checkbit
3535
def int_dx_typedBufferStore
3636
: DefaultAttrsIntrinsic<[], [llvm_any_ty, llvm_i32_ty, llvm_anyvector_ty]>;
3737

38+
def int_dx_updateCounter
39+
: DefaultAttrsIntrinsic<[], [llvm_any_ty, llvm_i8_ty]>;
40+
3841
// Cast between target extension handle types and dxil-style opaque handles
3942
def int_dx_cast_handle : Intrinsic<[llvm_any_ty], [llvm_any_ty]>;
4043

llvm/lib/Target/DirectX/DXIL.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,13 @@ def BufferStore : DXILOp<69, bufferStore> {
754754
let stages = [Stages<DXIL1_0, [all_stages]>];
755755
}
756756

757+
def UpdateCounter : DXILOp<70, bufferUpdateCounter> {
758+
let Doc = "increments/decrements a buffer counter";
759+
let arguments = [HandleTy, Int8Ty];
760+
let result = VoidTy;
761+
let stages = [Stages<DXIL1_0, [all_stages]>];
762+
}
763+
757764
def CheckAccessFullyMapped : DXILOp<71, checkAccessFullyMapped> {
758765
let Doc = "checks whether a Sample, Gather, or Load operation "
759766
"accessed mapped tiles in a tiled resource";

llvm/lib/Target/DirectX/DXILOpLowering.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,28 @@ class OpLowerer {
463463
});
464464
}
465465

466+
[[nodiscard]] bool lowerUpdateCounter(Function &F) {
467+
IRBuilder<> &IRB = OpBuilder.getIRB();
468+
469+
return replaceFunction(F, [&](CallInst *CI) -> Error {
470+
IRB.SetInsertPoint(CI);
471+
Value *Handle =
472+
createTmpHandleCast(CI->getArgOperand(0), OpBuilder.getHandleType());
473+
Value *Op1 = CI->getArgOperand(1);
474+
475+
std::array<Value *, 2> Args{Handle, Op1};
476+
477+
Expected<CallInst *> OpCall =
478+
OpBuilder.tryCreateOp(OpCode::UpdateCounter, Args, CI->getName());
479+
480+
if (Error E = OpCall.takeError())
481+
return E;
482+
483+
CI->eraseFromParent();
484+
return Error::success();
485+
});
486+
}
487+
466488
[[nodiscard]] bool lowerTypedBufferStore(Function &F) {
467489
IRBuilder<> &IRB = OpBuilder.getIRB();
468490
Type *Int8Ty = IRB.getInt8Ty();
@@ -600,6 +622,9 @@ class OpLowerer {
600622
case Intrinsic::dx_typedBufferStore:
601623
HasErrors |= lowerTypedBufferStore(F);
602624
break;
625+
case Intrinsic::dx_updateCounter:
626+
HasErrors |= lowerUpdateCounter(F);
627+
break;
603628
// TODO: this can be removed when
604629
// https://github.com/llvm/llvm-project/issues/113192 is fixed
605630
case Intrinsic::dx_splitdouble:
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; RUN: opt -S -dxil-op-lower %s | FileCheck %s
2+
3+
4+
target triple = "dxil-pc-shadermodel6.6-compute"
5+
6+
; CHECK-LABEL: define void @update_counter_decrement_vector() {
7+
define void @update_counter_decrement_vector() {
8+
; CHECK: [[BIND:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217,
9+
%buffer = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0)
10+
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_v4f32_0_0_0(
11+
i32 0, i32 0, i32 1, i32 0, i1 false)
12+
13+
; CHECK-NEXT: [[BUFFANOT:%.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[BIND]]
14+
; CHECK-NEXT: call void @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle [[BUFFANOT]], i8 -1)
15+
call void @llvm.dx.updateCounter(target("dx.TypedBuffer", <4 x float>, 0, 0, 0) %buffer, i8 -1)
16+
ret void
17+
}
18+
19+
; CHECK-LABEL: define void @update_counter_increment_vector() {
20+
define void @update_counter_increment_vector() {
21+
; CHECK: [[BIND:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217,
22+
%buffer = call target("dx.TypedBuffer", <4 x float>, 0, 0, 0)
23+
@llvm.dx.handle.fromBinding.tdx.TypedBuffer_v4f32_0_0_0(
24+
i32 0, i32 0, i32 1, i32 0, i1 false)
25+
; CHECK-NEXT: [[BUFFANOT:%.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[BIND]]
26+
; CHECK-NEXT: call void @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle [[BUFFANOT]], i8 1)
27+
call void @llvm.dx.updateCounter(target("dx.TypedBuffer", <4 x float>, 0, 0, 0) %buffer, i8 1)
28+
ret void
29+
}
30+
31+
; CHECK-LABEL: define void @update_counter_decrement_scalar() {
32+
define void @update_counter_decrement_scalar() {
33+
; CHECK: [[BIND:%.*]] = call %dx.types.Handle @dx.op.createHandleFromBinding(i32 217,
34+
%buffer = call target("dx.RawBuffer", i8, 0, 0)
35+
@llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t(
36+
i32 1, i32 8, i32 1, i32 0, i1 false)
37+
; CHECK-NEXT: [[BUFFANOT:%.*]] = call %dx.types.Handle @dx.op.annotateHandle(i32 216, %dx.types.Handle [[BIND]]
38+
; CHECK-NEXT: call void @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle [[BUFFANOT]], i8 -1)
39+
call void @llvm.dx.updateCounter(target("dx.RawBuffer", i8, 0, 0) %buffer, i8 -1)
40+
ret void
41+
}

0 commit comments

Comments
 (0)