Skip to content

Commit 99c9788

Browse files
committed
as far as I can go without adding CAFM
1 parent a00bb9c commit 99c9788

File tree

11 files changed

+160
-0
lines changed

11 files changed

+160
-0
lines changed

clang/include/clang/Basic/Builtins.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4934,6 +4934,12 @@ def HLSLResourceGetPointer : LangBuiltin<"HLSL_LANG"> {
49344934
let Prototype = "void(...)";
49354935
}
49364936

4937+
def HLSLResourceGetPointerWithStatus : LangBuiltin<"HLSL_LANG"> {
4938+
let Spellings = ["__builtin_hlsl_resource_getpointer_with_status"];
4939+
let Attributes = [NoThrow];
4940+
let Prototype = "void(...)";
4941+
}
4942+
49374943
def HLSLResourceUninitializedHandle : LangBuiltin<"HLSL_LANG"> {
49384944
let Spellings = ["__builtin_hlsl_resource_uninitializedhandle"];
49394945
let Attributes = [NoThrow];

clang/lib/CodeGen/CGHLSLBuiltins.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,17 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
353353
RetTy, CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
354354
ArrayRef<Value *>{HandleOp, IndexOp});
355355
}
356+
case Builtin::BI__builtin_hlsl_resource_getpointer_with_status: {
357+
Value *HandleOp = EmitScalarExpr(E->getArg(0));
358+
Value *IndexOp = EmitScalarExpr(E->getArg(1));
359+
Value *StatusOp = EmitScalarExpr(E->getArg(2));
360+
361+
llvm::Type *RetTy = ConvertType(E->getType());
362+
return Builder.CreateIntrinsic(
363+
RetTy,
364+
CGM.getHLSLRuntime().getCreateResourceGetPointerWithStatusIntrinsic(),
365+
ArrayRef<Value *>{HandleOp, IndexOp, StatusOp});
366+
}
356367
case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
357368
llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType());
358369
return llvm::PoisonValue::get(HandleTy);

clang/lib/CodeGen/CGHLSLRuntime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ class CGHLSLRuntime {
126126

127127
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateResourceGetPointer,
128128
resource_getpointer)
129+
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateResourceGetPointerWithStatus,
130+
resource_getpointer_with_status)
129131
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding,
130132
resource_handlefrombinding)
131133
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromImplicitBinding,

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,7 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addLoadMethods() {
11401140
DeclarationName Load(&II);
11411141
// TODO: We also need versions with status for CheckAccessFullyMapped.
11421142
addHandleAccessFunction(Load, /*IsConst=*/false, /*IsRef=*/false);
1143+
addHandleAccessFunctionWithStatus(Load, /*IsConst=*/false, /*IsRef=*/false);
11431144

11441145
return *this;
11451146
}
@@ -1232,6 +1233,41 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addDecrementCounterMethod() {
12321233
.finalize();
12331234
}
12341235

1236+
BuiltinTypeDeclBuilder &
1237+
BuiltinTypeDeclBuilder::addHandleAccessFunctionWithStatus(DeclarationName &Name,
1238+
bool IsConst,
1239+
bool IsRef) {
1240+
assert(!Record->isCompleteDefinition() && "record is already complete");
1241+
ASTContext &AST = SemaRef.getASTContext();
1242+
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
1243+
1244+
QualType ElemTy = getHandleElementType();
1245+
QualType AddrSpaceElemTy =
1246+
AST.getAddrSpaceQualType(ElemTy, LangAS::hlsl_device);
1247+
QualType ElemPtrTy = AST.getPointerType(AddrSpaceElemTy);
1248+
QualType ReturnTy;
1249+
1250+
if (IsRef) {
1251+
ReturnTy = AddrSpaceElemTy;
1252+
if (IsConst)
1253+
ReturnTy.addConst();
1254+
ReturnTy = AST.getLValueReferenceType(ReturnTy);
1255+
} else {
1256+
ReturnTy = ElemTy;
1257+
if (IsConst)
1258+
ReturnTy.addConst();
1259+
}
1260+
1261+
QualType StatusRefTy = AST.getLValueReferenceType(AST.UnsignedIntTy);
1262+
return BuiltinTypeMethodBuilder(*this, Name, ReturnTy, IsConst)
1263+
.addParam("Index", AST.UnsignedIntTy)
1264+
.addParam("Status", StatusRefTy)
1265+
.callBuiltin("__builtin_hlsl_resource_getpointer_with_status", ElemPtrTy,
1266+
PH::Handle, PH::_0, PH::_1)
1267+
.dereference(PH::LastStmt)
1268+
.finalize();
1269+
}
1270+
12351271
BuiltinTypeDeclBuilder &
12361272
BuiltinTypeDeclBuilder::addHandleAccessFunction(DeclarationName &Name,
12371273
bool IsConst, bool IsRef) {

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class BuiltinTypeDeclBuilder {
9191
BuiltinTypeDeclBuilder &addDecrementCounterMethod();
9292
BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name,
9393
bool IsConst, bool IsRef);
94+
BuiltinTypeDeclBuilder &
95+
addHandleAccessFunctionWithStatus(DeclarationName &Name, bool IsConst,
96+
bool IsRef);
9497
BuiltinTypeDeclBuilder &addAppendMethod();
9598
BuiltinTypeDeclBuilder &addConsumeMethod();
9699

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3010,6 +3010,27 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
30103010

30113011
break;
30123012
}
3013+
case Builtin::BI__builtin_hlsl_resource_getpointer_with_status: {
3014+
if (SemaRef.checkArgCount(TheCall, 3) ||
3015+
CheckResourceHandle(&SemaRef, TheCall, 0) ||
3016+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1),
3017+
SemaRef.getASTContext().UnsignedIntTy) ||
3018+
CheckArgTypeMatches(&SemaRef, TheCall->getArg(2),
3019+
SemaRef.getASTContext().UnsignedIntTy))
3020+
return true;
3021+
3022+
auto *ResourceTy =
3023+
TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
3024+
QualType ContainedTy = ResourceTy->getContainedType();
3025+
auto ReturnType =
3026+
SemaRef.Context.getAddrSpaceQualType(ContainedTy, LangAS::hlsl_device);
3027+
ReturnType = SemaRef.Context.getPointerType(ReturnType);
3028+
TheCall->setType(ReturnType);
3029+
TheCall->setValueKind(VK_LValue);
3030+
3031+
break;
3032+
}
3033+
30133034
case Builtin::BI__builtin_hlsl_resource_uninitializedhandle: {
30143035
if (SemaRef.checkArgCount(TheCall, 1) ||
30153036
CheckResourceHandle(&SemaRef, TheCall, 0))

clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-lib.hlsl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,36 @@ export float TestLoad() {
104104
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[PTR]]
105105
// CHECK-NEXT: ret float %[[VAL]]
106106

107+
export float TestLoadWithStatus() {
108+
uint s1;
109+
uint s2;
110+
float ret = RWSB1.Load(1, s) + SB1.Load(2, s2);
111+
ret += float(s1 + s2);
112+
return ret;
113+
}
114+
115+
// CHECK: define noundef nofpclass(nan inf) float @TestLoad()()
116+
// CHECK: call {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} @RWSB1, i32 noundef 1)
117+
// CHECK: call {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} @SB1, i32 noundef 2)
118+
// CHECK: add
119+
// CHECK: ret float
120+
121+
// CHECK: define {{.*}} float @hlsl::RWStructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
122+
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RWStructuredBuffer", ptr %{{.*}}, i32 0, i32 0
123+
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 0), ptr %__handle
124+
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
125+
// DXIL-NEXT: %[[PTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %[[HANDLE]], i32 %[[INDEX]])
126+
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[PTR]]
127+
// CHECK-NEXT: ret float %[[VAL]]
128+
129+
// CHECK: define {{.*}} float @hlsl::StructuredBuffer<float>::Load(unsigned int)(ptr {{.*}} %this, i32 noundef %Index)
130+
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::StructuredBuffer", ptr %{{.*}}, i32 0, i32 0
131+
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 0, 0), ptr %__handle
132+
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
133+
// DXIL-NEXT: %[[PTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0) %[[HANDLE]], i32 %[[INDEX]])
134+
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[PTR]]
135+
// CHECK-NEXT: ret float %[[VAL]]
136+
107137
export uint TestGetDimensions() {
108138
uint dim1, dim2, dim3, stride1, stride2, stride3;
109139
SB1.GetDimensions(dim1, stride1);

clang/test/CodeGenHLSL/resources/StructuredBuffers-methods-ps.hlsl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,39 @@ export float TestLoad() {
6565
// CHECK-NEXT: %[[VAL:.*]] = load <2 x i32>, ptr %[[BUFPTR]]
6666
// CHECK-NEXT: ret <2 x i32> %[[VAL]]
6767

68+
export float TestLoadWithStatus() {
69+
uint status;
70+
uint status2;
71+
float val = ROSB1.Load(10, status).x + ROSB2.Load(20, status2).x;
72+
return val + float(status + status2);
73+
}
74+
75+
// CHECK: define {{.*}} float @TestLoadWithStatus()()
76+
// CHECK: call {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @ROSB1, i32 noundef 10, ptr noundef nonnull align 4 dereferenceable(4) %status)
77+
// CHECK: call {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int, unsigned int&)(ptr {{.*}} @ROSB2, i32 noundef 20, ptr noundef nonnull align 4 dereferenceable(4) %status2)
78+
// CHECK: ret
79+
80+
// CHECK: define {{.*}} float @hlsl::RasterizerOrderedStructuredBuffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %Index, ptr noundef nonnull align 4 dereferenceable(4) %Status)
81+
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer", ptr {{.*}}, i32 0, i32 0
82+
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", float, 1, 1), ptr %__handle
83+
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
84+
// CHECK-NEXT: %[[STATUS_HANDLE:.*]] = load ptr, ptr %Status.addr, align 4, !nonnull !3, !align !4
85+
// CHECK-NEXT: %[[STATUS:.*]] = load i32, ptr %[[STATUS_HANDLE]], align 4
86+
// DXIL-NEXT: %[[BUFPTR:.*]] = call ptr @llvm.dx.resource.getpointer.with.status.p0.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1) %[[HANDLE]], i32 %[[INDEX]], i32 %[[STATUS]])
87+
// CHECK-NEXT: %[[VAL:.*]] = load float, ptr %[[BUFPTR]]
88+
// CHECK-NEXT: ret float %[[VAL]]
89+
90+
// CHECK: define {{.*}} <2 x i32> @hlsl::RasterizerOrderedStructuredBuffer<int vector[2]>::Load(unsigned int, unsigned int&)(ptr {{.*}} %Index, ptr noundef nonnull align 4 dereferenceable(4) %Status)
91+
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::RasterizerOrderedStructuredBuffer.0", ptr {{.*}}, i32 0, i32 0
92+
// CHECK-NEXT: %[[HANDLE:.*]] = load target("dx.RawBuffer", <2 x i32>, 1, 1), ptr %__handle
93+
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr
94+
// CHECK-NEXT: %[[STATUS_HANDLE:.*]] = load ptr, ptr %Status.addr, align 4, !nonnull !3, !align !4
95+
// CHECK-NEXT: %[[STATUS:.*]] = load i32, ptr %[[STATUS_HANDLE]], align 4
96+
// DXIL-NEXT: %[[BUFPTR:.*]] = call ptr @llvm.dx.resource.getpointer.with.status.p0.tdx.RawBuffer_v2i32_1_1t(target("dx.RawBuffer", <2 x i32>, 1, 1) %[[HANDLE]], i32 %[[INDEX]], i32 %[[STATUS]])
97+
// CHECK-NEXT: %[[VAL:.*]] = load <2 x i32>, ptr %[[BUFPTR]]
98+
// CHECK-NEXT: ret <2 x i32> %[[VAL]]
99+
100+
68101
export uint TestGetDimensions() {
69102
uint dim1, dim2, stride1, stride2;
70103
ROSB1.GetDimensions(dim1, stride1);

llvm/include/llvm/IR/IntrinsicsDirectX.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ def int_dx_resource_getpointer
4040
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty, llvm_i32_ty],
4141
[IntrNoMem]>;
4242

43+
def int_dx_resource_getpointer_with_status
44+
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty, llvm_i32_ty, llvm_i32_ty],
45+
[IntrNoMem]>;
46+
4347
def int_dx_resource_nonuniformindex
4448
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
4549

llvm/include/llvm/IR/IntrinsicsSPIRV.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,9 @@ def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]
175175
def int_spv_resource_getpointer
176176
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty, llvm_i32_ty],
177177
[IntrNoMem]>;
178+
def int_spv_resource_getpointer_with_status
179+
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty, llvm_i32_ty, llvm_i32_ty],
180+
[IntrNoMem]>;
178181

179182
def int_spv_resource_nonuniformindex
180183
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;

0 commit comments

Comments
 (0)