[llvm] f08b4ff - [HLSL] Allow __builtin_hlsl_resource_getpointer to take no indices (#195151)
via llvm-commits
llvm-commits at lists.llvm.org
Wed May 6 06:16:41 PDT 2026
Author: Steven Perron
Date: 2026-05-06T09:16:35-04:00
New Revision: f08b4fff52cdd3fc8fdd962080da089497c00fcc
URL: https://github.com/llvm/llvm-project/commit/f08b4fff52cdd3fc8fdd962080da089497c00fcc
DIFF: https://github.com/llvm/llvm-project/commit/f08b4fff52cdd3fc8fdd962080da089497c00fcc.diff
LOG: [HLSL] Allow __builtin_hlsl_resource_getpointer to take no indices (#195151)
In preperation for adding ConstnatBuffer<T>, we will need to be able to
access the base pointer for the data constat buffer resource handle is
pointingto
to. This is done by:
1. Making the index operand in __builtin_hlsl_resource_getpointer
optional.
2. Modifing the codegen for __builtin_hlsl_resource_getpointer to emit a
call to resource.getbasepointer when no index is provided.
3. Add the resource.getbasepointer for the dx and spv targets.
Another issue is that the address space for the pointer returned by
__builtin_hlsl_resource_getpointer is not always hlsl_device any more.
Changes are made to get the correct address space based on the resource
class of the handle.
Note that we cannot implement codegen for
__builtin_hlsl_resource_getpointer directly. The tests for the codegen
changes will be in a follow up PR that add ConstnatBuffer<T>.
Assisted-by: Gemini
<!-- branch-stack-start -->
-------------------------
- main
- https://github.com/llvm/llvm-project/pull/195151 :point_left:
- https://github.com/llvm/llvm-project/pull/195152
- https://github.com/llvm/llvm-project/pull/195153
- https://github.com/llvm/llvm-project/pull/195154
<sup>[Stack](https://www.git-town.com/how-to/proposal-breadcrumb.html)
generated by [Git Town](https://github.com/git-town/git-town)</sup>
<!-- branch-stack-end -->
Added:
Modified:
clang/lib/CodeGen/CGHLSLBuiltins.cpp
clang/lib/CodeGen/CGHLSLRuntime.h
clang/lib/Sema/SemaHLSL.cpp
clang/test/SemaHLSL/BuiltIns/resource_getpointer-errors.hlsl
llvm/include/llvm/IR/IntrinsicsDirectX.td
llvm/include/llvm/IR/IntrinsicsSPIRV.td
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
index b82a237ecefca..82b03d7d5f069 100644
--- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp
+++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp
@@ -571,12 +571,20 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
case Builtin::BI__builtin_hlsl_resource_getpointer:
case Builtin::BI__builtin_hlsl_resource_getpointer_typed: {
Value *HandleOp = EmitScalarExpr(E->getArg(0));
- Value *IndexOp = EmitScalarExpr(E->getArg(1));
+ bool IsIndexed =
+ BuiltinID == Builtin::BI__builtin_hlsl_resource_getpointer_typed ||
+ E->getNumArgs() > 1;
llvm::Type *RetTy = ConvertType(E->getType());
+ if (IsIndexed) {
+ Value *IndexOp = EmitScalarExpr(E->getArg(1));
+ return Builder.CreateIntrinsic(
+ RetTy, CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
+ ArrayRef<Value *>{HandleOp, IndexOp});
+ }
return Builder.CreateIntrinsic(
- RetTy, CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(),
- ArrayRef<Value *>{HandleOp, IndexOp});
+ RetTy, CGM.getHLSLRuntime().getCreateResourceGetBasePointerIntrinsic(),
+ ArrayRef<Value *>{HandleOp});
}
case Builtin::BI__builtin_hlsl_resource_sample: {
Value *HandleOp = EmitScalarExpr(E->getArg(0));
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h
index b54cbab906056..d7ac2346f2428 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.h
+++ b/clang/lib/CodeGen/CGHLSLRuntime.h
@@ -167,6 +167,8 @@ class CGHLSLRuntime {
GENERATE_HLSL_INTRINSIC_FUNCTION(SClamp, sclamp)
GENERATE_HLSL_INTRINSIC_FUNCTION(UClamp, uclamp)
+ GENERATE_HLSL_INTRINSIC_FUNCTION(CreateResourceGetBasePointer,
+ resource_getbasepointer)
GENERATE_HLSL_INTRINSIC_FUNCTION(CreateResourceGetPointer,
resource_getpointer)
GENERATE_HLSL_INTRINSIC_FUNCTION(Sample, resource_sample)
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index aba1c5072a5fc..7788d777edf1c 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -77,6 +77,19 @@ static RegisterType getRegisterType(const HLSLAttributedResourceType *ResTy) {
return getRegisterType(ResTy->getAttrs().ResourceClass);
}
+static LangAS getLangASFromResourceClass(ResourceClass RC) {
+ switch (RC) {
+ case ResourceClass::SRV:
+ case ResourceClass::UAV:
+ return LangAS::hlsl_device;
+ case ResourceClass::CBuffer:
+ return LangAS::hlsl_constant;
+ case ResourceClass::Sampler:
+ return LangAS::hlsl_device;
+ }
+ llvm_unreachable("unexpected ResourceClass value");
+}
+
// Converts the first letter of string Slot to RegisterType.
// Returns false if the letter does not correspond to a valid register type.
static bool convertToRegisterType(StringRef Slot, RegisterType *RT) {
@@ -3891,19 +3904,19 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
break;
}
case Builtin::BI__builtin_hlsl_resource_getpointer: {
- if (SemaRef.checkArgCount(TheCall, 2) ||
+ if (SemaRef.checkArgCountRange(TheCall, 1, 2) ||
CheckResourceHandle(&SemaRef, TheCall, 0) ||
- CheckIndexType(&SemaRef, TheCall, 1))
+ (TheCall->getNumArgs() == 2 && CheckIndexType(&SemaRef, TheCall, 1)))
return true;
auto *ResourceTy =
TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
QualType ContainedTy = ResourceTy->getContainedType();
- auto ReturnType =
- SemaRef.Context.getAddrSpaceQualType(ContainedTy, LangAS::hlsl_device);
+ auto ReturnType = SemaRef.Context.getAddrSpaceQualType(
+ ContainedTy,
+ getLangASFromResourceClass(ResourceTy->getAttrs().ResourceClass));
ReturnType = SemaRef.Context.getPointerType(ReturnType);
TheCall->setType(ReturnType);
- TheCall->setValueKind(VK_LValue);
break;
}
@@ -3924,8 +3937,11 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
cast<FunctionDecl>(SemaRef.CurContext)->getPointOfInstantiation(),
diag::err_invalid_use_of_array_type);
- auto ReturnType =
- SemaRef.Context.getAddrSpaceQualType(ElementTy, LangAS::hlsl_device);
+ auto *ResourceTy =
+ TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
+ auto ReturnType = SemaRef.Context.getAddrSpaceQualType(
+ ElementTy,
+ getLangASFromResourceClass(ResourceTy->getAttrs().ResourceClass));
ReturnType = SemaRef.Context.getPointerType(ReturnType);
TheCall->setType(ReturnType);
diff --git a/clang/test/SemaHLSL/BuiltIns/resource_getpointer-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/resource_getpointer-errors.hlsl
index 20de0773a1742..7dde4dcf6c149 100644
--- a/clang/test/SemaHLSL/BuiltIns/resource_getpointer-errors.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/resource_getpointer-errors.hlsl
@@ -5,17 +5,17 @@ using handle_t = __hlsl_resource_t
[[hlsl::resource_class(UAV)]] [[hlsl::contained_type(int)]];
void test_args(unsigned int x) {
- // expected-error at +1 {{too few arguments to function call, expected 2, have 1}}
+ // expected-error at +1 {{used type 'unsigned int' where __hlsl_resource_t is required}}
__builtin_hlsl_resource_getpointer(x);
- // expected-error at +1 {{too many arguments to function call, expected 2, have 3}}
+ // expected-error at +1 {{too many arguments to function call, expected at most 2, have 3}}
__builtin_hlsl_resource_getpointer(x, x, x);
- // expected-error at +1 {{used type 'unsigned int' where __hlsl_resource_t is required}}
- __builtin_hlsl_resource_getpointer(x, x);
-
handle_t res;
+ // no error
+ __builtin_hlsl_resource_getpointer(res);
+
// expected-error at +1 {{used type 'const char *' where integer is required}}
__builtin_hlsl_resource_getpointer(res, "1");
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index f37180ce9084a..f55996234aea5 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -40,6 +40,10 @@ def int_dx_resource_getpointer
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty, llvm_any_ty],
[IntrReadMem, IntrInaccessibleMemOnly]>;
+def int_dx_resource_getbasepointer
+ : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty],
+ [IntrReadMem, IntrInaccessibleMemOnly]>;
+
def int_dx_resource_nonuniformindex
: DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty], [IntrNoMem]>;
diff --git a/llvm/include/llvm/IR/IntrinsicsSPIRV.td b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
index 5fef26d859d03..3f1c67a8ad5f5 100644
--- a/llvm/include/llvm/IR/IntrinsicsSPIRV.td
+++ b/llvm/include/llvm/IR/IntrinsicsSPIRV.td
@@ -319,6 +319,10 @@ def int_spv_rsqrt : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty]
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty, llvm_any_ty],
[IntrNoMem]>;
+ def int_spv_resource_getbasepointer
+ : DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty],
+ [IntrNoMem]>;
+
def int_spv_pushconstant_getpointer
: DefaultAttrsIntrinsic<[llvm_anyptr_ty], [llvm_any_ty], [IntrNoMem]>;
More information about the llvm-commits
mailing list