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@+1 {{too few arguments to function call, expected 2, have 1}} + // expected-error@+1 {{used type 'unsigned int' where __hlsl_resource_t is required}} __builtin_hlsl_resource_getpointer(x); - // expected-error@+1 {{too many arguments to function call, expected 2, have 3}} + // expected-error@+1 {{too many arguments to function call, expected at most 2, have 3}} __builtin_hlsl_resource_getpointer(x, x, x); - // expected-error@+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@+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]>; _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
