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

Reply via email to