Skip to content

Commit d67da8a

Browse files
hekotasivan-shani
authored andcommitted
[DirectX] Add resource name argument to llvm.dx.handlefrom[implicit]binding intrinsics (llvm#139991)
Adds resource name argument to `llvm.dx.handlefrombinding` and `llvm.dx.handlefromimplicitbinding` intrinsics. SPIR-V currently does not seem to need the resource names so this change only affects DirectX binding intrinsics. Part 2/4 of llvm#105059
1 parent 68746b8 commit d67da8a

File tree

69 files changed

+396
-311
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+396
-311
lines changed

clang/lib/CodeGen/CGHLSLBuiltins.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
299299
// (llvm/llvm-project#135452)
300300
Value *NonUniform =
301301
llvm::ConstantInt::get(llvm::Type::getInt1Ty(getLLVMContext()), false);
302-
return Builder.CreateIntrinsic(
303-
HandleTy, CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic(),
304-
ArrayRef<Value *>{SpaceOp, RegisterOp, RangeOp, IndexOp, NonUniform});
302+
303+
auto [IntrinsicID, HasNameArg] =
304+
CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
305+
SmallVector<Value *> Args{SpaceOp, RegisterOp, RangeOp, IndexOp,
306+
NonUniform};
307+
if (HasNameArg)
308+
Args.push_back(EmitScalarExpr(E->getArg(5)));
309+
return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
305310
}
306311
case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: {
307312
llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType());
@@ -313,10 +318,13 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
313318
// (llvm/llvm-project#135452)
314319
Value *NonUniform =
315320
llvm::ConstantInt::get(llvm::Type::getInt1Ty(getLLVMContext()), false);
316-
return Builder.CreateIntrinsic(
317-
HandleTy,
318-
CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic(),
319-
ArrayRef<Value *>{OrderID, SpaceOp, RangeOp, IndexOp, NonUniform});
321+
322+
auto [IntrinsicID, HasNameArg] =
323+
CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
324+
SmallVector<Value *> Args{OrderID, SpaceOp, RangeOp, IndexOp, NonUniform};
325+
if (HasNameArg)
326+
Args.push_back(EmitScalarExpr(E->getArg(5)));
327+
return Builder.CreateIntrinsic(HandleTy, IntrinsicID, Args);
320328
}
321329
case Builtin::BI__builtin_hlsl_all: {
322330
Value *Op0 = EmitScalarExpr(E->getArg(0));

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "llvm/Support/Alignment.h"
3535
#include "llvm/Support/ErrorHandling.h"
3636
#include "llvm/Support/FormatVariadic.h"
37+
#include <utility>
3738

3839
using namespace clang;
3940
using namespace CodeGen;
@@ -42,10 +43,6 @@ using namespace llvm;
4243

4344
using llvm::hlsl::CBufferRowSizeInBytes;
4445

45-
static void initializeBufferFromBinding(CodeGenModule &CGM,
46-
llvm::GlobalVariable *GV,
47-
HLSLResourceBindingAttr *RBA);
48-
4946
namespace {
5047

5148
void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) {
@@ -239,6 +236,35 @@ static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl,
239236
}
240237
}
241238

239+
std::pair<llvm::Intrinsic::ID, bool>
240+
CGHLSLRuntime::getCreateHandleFromBindingIntrinsic() {
241+
switch (getArch()) {
242+
case llvm::Triple::dxil:
243+
return std::pair(llvm::Intrinsic::dx_resource_handlefrombinding, true);
244+
case llvm::Triple::spirv:
245+
return std::pair(llvm::Intrinsic::spv_resource_handlefrombinding, false);
246+
default:
247+
llvm_unreachable("Intrinsic resource_handlefrombinding not supported by "
248+
"target architecture");
249+
}
250+
}
251+
252+
std::pair<llvm::Intrinsic::ID, bool>
253+
CGHLSLRuntime::getCreateHandleFromImplicitBindingIntrinsic() {
254+
switch (getArch()) {
255+
case llvm::Triple::dxil:
256+
return std::pair(llvm::Intrinsic::dx_resource_handlefromimplicitbinding,
257+
true);
258+
case llvm::Triple::spirv:
259+
return std::pair(llvm::Intrinsic::spv_resource_handlefromimplicitbinding,
260+
false);
261+
default:
262+
llvm_unreachable(
263+
"Intrinsic resource_handlefromimplicitbinding not supported by "
264+
"target architecture");
265+
}
266+
}
267+
242268
// Codegen for HLSLBufferDecl
243269
void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) {
244270

@@ -275,7 +301,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) {
275301
HLSLResourceBindingAttr *RBA = BufDecl->getAttr<HLSLResourceBindingAttr>();
276302
assert(RBA &&
277303
"cbuffer/tbuffer should always have resource binding attribute");
278-
initializeBufferFromBinding(CGM, BufGV, RBA);
304+
initializeBufferFromBinding(BufDecl, BufGV, RBA);
279305
}
280306

281307
llvm::TargetExtType *
@@ -557,29 +583,43 @@ static void initializeBuffer(CodeGenModule &CGM, llvm::GlobalVariable *GV,
557583
CGM.AddCXXGlobalInit(InitResFunc);
558584
}
559585

560-
static void initializeBufferFromBinding(CodeGenModule &CGM,
561-
llvm::GlobalVariable *GV,
562-
HLSLResourceBindingAttr *RBA) {
586+
void CGHLSLRuntime::initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
587+
llvm::GlobalVariable *GV,
588+
HLSLResourceBindingAttr *RBA) {
563589
llvm::Type *Int1Ty = llvm::Type::getInt1Ty(CGM.getLLVMContext());
564590
auto *NonUniform = llvm::ConstantInt::get(Int1Ty, false);
565591
auto *Index = llvm::ConstantInt::get(CGM.IntTy, 0);
566592
auto *RangeSize = llvm::ConstantInt::get(CGM.IntTy, 1);
567593
auto *Space =
568594
llvm::ConstantInt::get(CGM.IntTy, RBA ? RBA->getSpaceNumber() : 0);
595+
Value *Name = nullptr;
596+
597+
auto [IntrinsicID, HasNameArg] =
598+
RBA->hasRegisterSlot()
599+
? CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic()
600+
: CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
601+
602+
if (HasNameArg) {
603+
std::string Str(BufDecl->getName());
604+
std::string GlobalName(Str + ".str");
605+
Name = CGM.GetAddrOfConstantCString(Str, GlobalName.c_str()).getPointer();
606+
}
569607

608+
// buffer with explicit binding
570609
if (RBA->hasRegisterSlot()) {
571610
auto *RegSlot = llvm::ConstantInt::get(CGM.IntTy, RBA->getSlotNumber());
572-
Intrinsic::ID Intr =
573-
CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic();
574-
initializeBuffer(CGM, GV, Intr,
575-
{Space, RegSlot, RangeSize, Index, NonUniform});
611+
SmallVector<Value *> Args{Space, RegSlot, RangeSize, Index, NonUniform};
612+
if (Name)
613+
Args.push_back(Name);
614+
initializeBuffer(CGM, GV, IntrinsicID, Args);
576615
} else {
616+
// buffer with implicit binding
577617
auto *OrderID =
578618
llvm::ConstantInt::get(CGM.IntTy, RBA->getImplicitBindingOrderID());
579-
Intrinsic::ID Intr =
580-
CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic();
581-
initializeBuffer(CGM, GV, Intr,
582-
{OrderID, Space, RangeSize, Index, NonUniform});
619+
SmallVector<Value *> Args{OrderID, Space, RangeSize, Index, NonUniform};
620+
if (Name)
621+
Args.push_back(Name);
622+
initializeBuffer(CGM, GV, IntrinsicID, Args);
583623
}
584624
}
585625

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,6 @@ class CGHLSLRuntime {
117117

118118
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateResourceGetPointer,
119119
resource_getpointer)
120-
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding,
121-
resource_handlefrombinding)
122-
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromImplicitBinding,
123-
resource_handlefromimplicitbinding)
124120
GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, resource_updatecounter)
125121
GENERATE_HLSL_INTRINSIC_FUNCTION(GroupMemoryBarrierWithGroupSync,
126122
group_memory_barrier_with_group_sync)
@@ -129,6 +125,15 @@ class CGHLSLRuntime {
129125
// End of reserved area for HLSL intrinsic getters.
130126
//===----------------------------------------------------------------------===//
131127

128+
// Returns ID of the intrinsic that initializes resource handle from binding
129+
// and a bool value indicating whether the last argument of the intrinsic is
130+
// the resource name (not all targets need that).
131+
std::pair<llvm::Intrinsic::ID, bool> getCreateHandleFromBindingIntrinsic();
132+
133+
// Same as above but for implicit binding.
134+
std::pair<llvm::Intrinsic::ID, bool>
135+
getCreateHandleFromImplicitBindingIntrinsic();
136+
132137
protected:
133138
CodeGenModule &CGM;
134139

@@ -164,6 +169,9 @@ class CGHLSLRuntime {
164169
private:
165170
void emitBufferGlobalsAndMetadata(const HLSLBufferDecl *BufDecl,
166171
llvm::GlobalVariable *BufGV);
172+
void initializeBufferFromBinding(const HLSLBufferDecl *BufDecl,
173+
llvm::GlobalVariable *GV,
174+
HLSLResourceBindingAttr *RBA);
167175
llvm::Triple::ArchType getArch();
168176

169177
llvm::DenseMap<const clang::RecordType *, llvm::TargetExtType *> LayoutTypes;

clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export void foo() {
7070
// CHECK: define linkonce_odr void @_ZN4hlsl17ByteAddressBufferC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
7171
// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
7272
// CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.RawBuffer", i8, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_i8_0_0t(
73-
// CHECK-DXIL-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false)
73+
// CHECK-DXIL-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
7474
// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::ByteAddressBuffer", ptr %{{.*}}, i32 0, i32 0
7575
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 0, 0) %[[HANDLE]], ptr %__handle, align 4
7676

@@ -79,7 +79,7 @@ export void foo() {
7979
// CHECK: define linkonce_odr void @_ZN4hlsl19RWByteAddressBufferC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
8080
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
8181
// CHECK: %[[HANDLE:.*]] = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_i8_1_0t
82-
// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false)
82+
// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
8383
// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::RWByteAddressBuffer", ptr %this1, i32 0, i32 0
8484
// CHECK-NEXT: store target("dx.RawBuffer", i8, 1, 0) %[[HANDLE]], ptr %__handle, align 4
8585

clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export void foo() {
6767
// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
6868
// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
6969
// CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.TypedBuffer", float, 1, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.TypedBuffer_f32_1_0_0t(
70-
// CHECK-DXIL-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false)
70+
// CHECK-DXIL-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
7171
// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer", ptr %{{.*}}, i32 0, i32 0
7272
// CHECK-DXIL-NEXT: store target("dx.TypedBuffer", float, 1, 0, 0) %[[HANDLE]], ptr %__handle, align 4
7373

@@ -76,7 +76,7 @@ export void foo() {
7676
// CHECK: define linkonce_odr void @_ZN4hlsl8RWBufferIdEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
7777
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
7878
// CHECK: %[[HANDLE:.*]] = call target("dx.TypedBuffer", double, 1, 0, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.TypedBuffer_f64_1_0_0t
79-
// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false)
79+
// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
8080
// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::RWBuffer.0", ptr %{{.*}}, i32 0, i32 0
8181
// CHECK-NEXT: store target("dx.TypedBuffer", double, 1, 0, 0) %[[HANDLE]], ptr %__handle, align 4
8282

clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ export void foo() {
7171
// CHECK: define linkonce_odr void @_ZN4hlsl16StructuredBufferIfEC2EjjijPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
7272
// CHECK-SAME: i32 noundef %registerNo, i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, ptr noundef %name)
7373
// CHECK-DXIL: %[[HANDLE:.*]] = call target("dx.RawBuffer", float, 0, 0) @llvm.dx.resource.handlefrombinding.tdx.RawBuffer_f32_0_0t(
74-
// CHECK-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false)
74+
// CHECK-SAME: i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
7575
// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0
7676
// CHECK-DXIL-NEXT: store target("dx.RawBuffer", float, 0, 0) %[[HANDLE]], ptr %__handle, align 4
7777

@@ -80,7 +80,7 @@ export void foo() {
8080
// CHECK: define linkonce_odr void @_ZN4hlsl18RWStructuredBufferIfEC2EjijjPKc(ptr noundef nonnull align 4 dereferenceable(4) %this,
8181
// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %orderId, ptr noundef %name)
8282
// CHECK: %[[HANDLE:.*]] = call target("dx.RawBuffer", float, 1, 0) @llvm.dx.resource.handlefromimplicitbinding.tdx.RawBuffer_f32_1_0t
83-
// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false)
83+
// CHECK-SAME: (i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i32 %{{.*}}, i1 false, ptr %{{.*}})
8484
// CHECK-NEXT: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
8585
// CHECK-NEXT: store target("dx.RawBuffer", float, 1, 0) %[[HANDLE]], ptr %__handle, align 4
8686

0 commit comments

Comments
 (0)