llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-codegen Author: Helena Kotas (hekota) <details> <summary>Changes</summary> Adds constructor for resources with implicit binding and applies it to all resources without binding at the global scope. Adds Clang builtin function `__builtin_hlsl_resource_handlefromimplicitbinding` that gets translated to `llvm.dx|spv.resource.handlefromimplicitbinding` intrinsic calls. Specific bindings are assigned in DXILResourceImplicitBinding pass. Design proposals: https://github.com/llvm/wg-hlsl/blob/main/proposals/0024-implicit-resource-binding.md https://github.com/llvm/wg-hlsl/blob/main/proposals/0025-resource-constructors.md One change from the proposals is that the `order_id` parameter is added onto the constructor. Originally it was supposed to be generated in codegen when the `llvm.dx|spv.resource.handlefromimplicitbinding` call is emitted, but that is not possible because the call is inside a constructor, and the constructor body is generated once per resource type and not resource instance. So the only way to inject instance-based data like `order_id` into the `llvm.dx|spv.resource.handlefromimplicitbinding` call is that it must come in via the constructor argument. Depends on #<!-- -->138043 Closes #<!-- -->136784 --- Patch is 34.47 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/138976.diff 18 Files Affected: - (modified) clang/include/clang/Basic/Builtins.td (+6) - (modified) clang/include/clang/Sema/SemaHLSL.h (+7) - (modified) clang/lib/CodeGen/CGHLSLBuiltins.cpp (+15) - (modified) clang/lib/CodeGen/CGHLSLRuntime.h (+2) - (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+20) - (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+2-1) - (modified) clang/lib/Sema/HLSLExternalSemaSource.cpp (+2-1) - (modified) clang/lib/Sema/SemaHLSL.cpp (+52-20) - (modified) clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl (+22) - (modified) clang/test/AST/HLSL/StructuredBuffers-AST.hlsl (+22) - (modified) clang/test/AST/HLSL/TypedBuffers-AST.hlsl (+22) - (modified) clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl (+1-1) - (modified) clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl (+51-4) - (modified) clang/test/CodeGenHLSL/builtins/RWBuffer-constructor.hlsl (+51-4) - (modified) clang/test/CodeGenHLSL/builtins/StructuredBuffers-constructors.hlsl (+51-3) - (modified) clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-ps.hlsl (+3-3) - (modified) clang/test/CodeGenHLSL/static-local-ctor.hlsl (+1-1) - (modified) llvm/include/llvm/IR/IntrinsicsSPIRV.td (+5) ``````````diff diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 11b1e247237a7..187d3b5ed24a7 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4819,6 +4819,12 @@ def HLSLResourceHandleFromBinding : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLResourceHandleFromImplicitBinding : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_resource_handlefromimplicitbinding"]; + let Attributes = [NoThrow]; + let Prototype = "void(...)"; +} + def HLSLAll : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_all"]; let Attributes = [NoThrow, Const]; diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index 5d260acf92abb..bedf541439dbf 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -174,6 +174,8 @@ class SemaHLSL : public SemaBase { // buffer which will be created at the end of the translation unit. llvm::SmallVector<Decl *> DefaultCBufferDecls; + uint32_t ImplicitBindingNextOrderID = 0; + private: void collectResourceBindingsOnVarDecl(VarDecl *D); void collectResourceBindingsOnUserRecordDecl(const VarDecl *VD, @@ -181,6 +183,11 @@ class SemaHLSL : public SemaBase { void processExplicitBindingsOnDecl(VarDecl *D); void diagnoseAvailabilityViolations(TranslationUnitDecl *TU); + + bool initGlobalResourceDecl(VarDecl *VD); + uint32_t getNextImplicitBindingOrderID() { + return ImplicitBindingNextOrderID++; + } }; } // namespace clang diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 5d93df34c66b2..d4a0714da07b3 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -303,6 +303,21 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, HandleTy, CGM.getHLSLRuntime().getCreateHandleFromBindingIntrinsic(), ArrayRef<Value *>{SpaceOp, RegisterOp, RangeOp, IndexOp, NonUniform}); } + case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: { + llvm::Type *HandleTy = CGM.getTypes().ConvertType(E->getType()); + Value *SpaceOp = EmitScalarExpr(E->getArg(1)); + Value *RangeOp = EmitScalarExpr(E->getArg(2)); + Value *IndexOp = EmitScalarExpr(E->getArg(3)); + Value *OrderID = EmitScalarExpr(E->getArg(4)); + // FIXME: NonUniformResourceIndex bit is not yet implemented + // (llvm/llvm-project#135452) + Value *NonUniform = + llvm::ConstantInt::get(llvm::Type::getInt1Ty(getLLVMContext()), false); + return Builder.CreateIntrinsic( + HandleTy, + CGM.getHLSLRuntime().getCreateHandleFromImplicitBindingIntrinsic(), + ArrayRef<Value *>{OrderID, SpaceOp, RangeOp, IndexOp, NonUniform}); + } case Builtin::BI__builtin_hlsl_all: { Value *Op0 = EmitScalarExpr(E->getArg(0)); return Builder.CreateIntrinsic( diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 4d6db3f5d9f3e..e40864d8ed854 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -119,6 +119,8 @@ class CGHLSLRuntime { resource_getpointer) GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, resource_handlefrombinding) + GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromImplicitBinding, + resource_handlefromimplicitbinding) GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, resource_updatecounter) GENERATE_HLSL_INTRINSIC_FUNCTION(GroupMemoryBarrierWithGroupSync, group_memory_barrier_with_group_sync) diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp index 35364a4d6f2ac..d5fbd5f6ecc9f 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp @@ -668,6 +668,26 @@ BuiltinTypeDeclBuilder::addHandleConstructorFromBinding() { .finalize(); } +BuiltinTypeDeclBuilder & +BuiltinTypeDeclBuilder::addHandleConstructorFromImplicitBinding() { + if (Record->isCompleteDefinition()) + return *this; + + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType HandleType = getResourceHandleField()->getType(); + + return BuiltinTypeMethodBuilder(*this, "", AST.VoidTy, false, true) + .addParam("spaceNo", AST.UnsignedIntTy) + .addParam("range", AST.IntTy) + .addParam("index", AST.UnsignedIntTy) + .addParam("order_id", AST.UnsignedIntTy) + .callBuiltin("__builtin_hlsl_resource_handlefromimplicitbinding", + HandleType, PH::Handle, PH::_0, PH::_1, PH::_2, PH::_3) + .assign(PH::Handle, PH::LastStmt) + .finalize(); +} + BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addArraySubscriptOperators() { ASTContext &AST = Record->getASTContext(); DeclarationName Subscript = diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h index db617dc53c899..a52e2938104c7 100644 --- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h +++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h @@ -76,9 +76,10 @@ class BuiltinTypeDeclBuilder { AccessSpecifier Access = AccessSpecifier::AS_private); BuiltinTypeDeclBuilder &addArraySubscriptOperators(); - // Builtin types methods + // Builtin types constructors BuiltinTypeDeclBuilder &addDefaultHandleConstructor(); BuiltinTypeDeclBuilder &addHandleConstructorFromBinding(); + BuiltinTypeDeclBuilder &addHandleConstructorFromImplicitBinding(); // Builtin types methods BuiltinTypeDeclBuilder &addLoadMethods(); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index f09232a9db4da..38bde7c28e946 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -132,7 +132,8 @@ static BuiltinTypeDeclBuilder setupBufferType(CXXRecordDecl *Decl, Sema &S, return BuiltinTypeDeclBuilder(S, Decl) .addHandleMember(RC, IsROV, RawBuffer) .addDefaultHandleConstructor() - .addHandleConstructorFromBinding(); + .addHandleConstructorFromBinding() + .addHandleConstructorFromImplicitBinding(); } // This function is responsible for constructing the constraint expression for diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 70aacaa2aadbe..c0669a8d60470 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -2427,6 +2427,20 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { TheCall->setType(ResourceTy); break; } + case Builtin::BI__builtin_hlsl_resource_handlefromimplicitbinding: { + ASTContext &AST = SemaRef.getASTContext(); + if (SemaRef.checkArgCount(TheCall, 5) || + CheckResourceHandle(&SemaRef, TheCall, 0) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(1), AST.UnsignedIntTy) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(2), AST.IntTy) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(3), AST.UnsignedIntTy) || + CheckArgTypeMatches(&SemaRef, TheCall->getArg(4), AST.UnsignedIntTy)) + return true; + // use the type of the handle (arg0) as a return type + QualType ResourceTy = TheCall->getArg(0)->getType(); + TheCall->setType(ResourceTy); + break; + } case Builtin::BI__builtin_hlsl_and: case Builtin::BI__builtin_hlsl_or: { if (SemaRef.checkArgCount(TheCall, 2)) @@ -3258,8 +3272,10 @@ static bool initVarDeclWithCtor(Sema &S, VarDecl *VD, VD->getLocation(), SourceLocation(), SourceLocation()); InitializationSequence InitSeq(S, Entity, Kind, Args); - ExprResult Init = InitSeq.Perform(S, Entity, Kind, Args); + if (InitSeq.Failed()) + return false; + ExprResult Init = InitSeq.Perform(S, Entity, Kind, Args); if (!Init.get()) return false; @@ -3269,27 +3285,42 @@ static bool initVarDeclWithCtor(Sema &S, VarDecl *VD, return true; } -static bool initGlobalResourceDecl(Sema &S, VarDecl *VD) { +bool SemaHLSL::initGlobalResourceDecl(VarDecl *VD) { + std::optional<uint32_t> RegisterSlot; + uint32_t SpaceNo = 0; HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>(); - if (!RBA || RBA->isImplicit()) - // FIXME: add support for implicit binding (llvm/llvm-project#110722) - return false; + if (RBA) { + if (!RBA->isImplicit()) + RegisterSlot = RBA->getSlotNumber(); + SpaceNo = RBA->getSpaceNumber(); + } - ASTContext &AST = S.getASTContext(); + ASTContext &AST = SemaRef.getASTContext(); uint64_t UIntTySize = AST.getTypeSize(AST.UnsignedIntTy); uint64_t IntTySize = AST.getTypeSize(AST.IntTy); - Expr *Args[] = { - IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, RBA->getSlotNumber()), - AST.UnsignedIntTy, SourceLocation()), - IntegerLiteral::Create(AST, - llvm::APInt(UIntTySize, RBA->getSpaceNumber()), - AST.UnsignedIntTy, SourceLocation()), - IntegerLiteral::Create(AST, llvm::APInt(IntTySize, 1), AST.IntTy, - SourceLocation()), - IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, 0), AST.UnsignedIntTy, - SourceLocation())}; - - return initVarDeclWithCtor(S, VD, Args); + IntegerLiteral *One = IntegerLiteral::Create(AST, llvm::APInt(IntTySize, 1), + AST.IntTy, SourceLocation()); + IntegerLiteral *Zero = IntegerLiteral::Create( + AST, llvm::APInt(UIntTySize, 0), AST.UnsignedIntTy, SourceLocation()); + IntegerLiteral *Space = + IntegerLiteral::Create(AST, llvm::APInt(UIntTySize, SpaceNo), + AST.UnsignedIntTy, SourceLocation()); + + // resource with explicit binding + if (RegisterSlot.has_value()) { + IntegerLiteral *RegSlot = IntegerLiteral::Create( + AST, llvm::APInt(UIntTySize, RegisterSlot.value()), AST.UnsignedIntTy, + SourceLocation()); + Expr *Args[] = {RegSlot, Space, One, Zero}; + return initVarDeclWithCtor(SemaRef, VD, Args); + } + + // resource with explicit binding + IntegerLiteral *OrderId = IntegerLiteral::Create( + AST, llvm::APInt(UIntTySize, getNextImplicitBindingOrderID()), + AST.UnsignedIntTy, SourceLocation()); + Expr *Args[] = {Space, One, Zero, OrderId}; + return initVarDeclWithCtor(SemaRef, VD, Args); } // Returns true if the initialization has been handled. @@ -3307,8 +3338,9 @@ bool SemaHLSL::ActOnUninitializedVarDecl(VarDecl *VD) { // FIXME: We currectly support only simple resources - no arrays of resources // or resources in user defined structs. // (llvm/llvm-project#133835, llvm/llvm-project#133837) - if (VD->getType()->isHLSLResourceRecord()) - return initGlobalResourceDecl(SemaRef, VD); + // Initialize resources at the global scope + if (VD->hasGlobalStorage() && VD->getType()->isHLSLResourceRecord()) + return initGlobalResourceDecl(VD); return false; } diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl index 5fba939d29cfe..99f26473dbb02 100644 --- a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl @@ -78,5 +78,27 @@ RESOURCE Buffer; // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr +// Constructor from implicit binding + +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]] 'void (unsigned int, int, unsigned int, unsigned int)' inline +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} order_id 'unsigned int' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t +// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'order_id' 'unsigned int' +// CHECK-NEXT: AlwaysInlineAttr + // CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'const element_type &(unsigned int) const' // CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'element_type &(unsigned int)' diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index 63265a0003582..03bfa6cb26003 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -125,6 +125,28 @@ RESOURCE<float> Buffer; // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr +// Constructor from implicit binding + +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int)' inline +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} order_id 'unsigned int' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t +// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'order_id' 'unsigned int' +// CHECK-NEXT: AlwaysInlineAttr + // Subscript operators // CHECK-SUBSCRIPT: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(unsigned int) const' diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index 6074c1e8bcdd2..f7b720090d436 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -92,6 +92,28 @@ RESOURCE<float> Buffer; // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr +// Constructor from implicit binding + +// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int)' inline +// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} range 'int' +// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int' +// CHECK-NEXT: ParmVarDecl {{.*}} order_id 'unsigned int' +// CHECK-NEXT: CompoundStmt {{.*}} +// CHECK-NEXT: BinaryOperator {{.*}} '=' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t +// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr> +// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding' +// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle +// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int' +// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'order_id' 'unsigned int' +// CHECK-NEXT: AlwaysInlineAttr + // Subsctript operators // CHECK: CXXMethodDecl {{.*}} operator[] 'const hlsl_device element_type &(unsigned int) const' diff --git a/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl b/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl index b798c2a6d6c4b..1d451acfc6214 100644 --- a/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl +++ b/clang/test/CodeGenHLSL/GlobalConstructorLib.hlsl @@ -33,7 +33,7 @@ void SecondEntry() {} // Verify the constructor is alwaysinline // NOINLINE: ; Function Attrs: {{.*}}alwaysinline -// NOINLINE-NEXT: define linkonce_odr void @_ZN4hlsl8RWBufferIfEC2Ev({{.*}} [[CtorAttr:\#[0-9]+]] +// NOINLINE-NEXT: define linkonce_odr void @_ZN4hlsl8RWBufferIfEC2Ejijj({{.*}} [[CtorAttr:\#[0-9]+]] // NOINLINE: ; Function Attrs: {{.*}}alwaysinline // NOINLINE-NEXT: define internal void @_GLOBAL__sub_I_GlobalConstructorLib.hlsl() [[InitAttr:\#[0-9]+]] diff --git a/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl index d7c4b03552cdc..7bc9b624ba9b9 100644 --- a/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl +++ b/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl @@ -55,11 +55,33 @@ export void foo() { // CHECK-SAME: i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3) // CHECK-NEXT: ret void -// Buf2 initialization part 1 - FIXME: constructor with implicit binding does not exist yet; -// the global init function currently calls the default RWByteAddressBuffer C1 constructor -// CHECK: define internal void @__cxx_global_var_init.1() +// Buf2 initialization part 1 - global init function that calls RWByteAddressBuffer C1 constructor with implicit binding +// CHECK: define internal void @__cxx_global_var_init.1() #0 { // CHECK-NEXT: entry: -// CHECK-NEXT: call void @_ZN4hlsl19RWByteAddressBufferC1Ev(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf2) +// CHECK-NEXT: call void @_ZN4hlsl19RWByteAddressBufferC1Ejijj(ptr noundef nonnull align 4 dereferenceable(4) @_ZL4Buf2, +// CHECK-SAME: i32 noundef 0, i32 noundef 1, i32 noundef 0, i32 noundef 0) + +// Buf2 initialization part 2 - body of RWByteAddressBuffer C1 constructor with implicit binding that calls the C2 constructor +// CHECK: define linkonce_odr void @_ZN4hlsl19RWByteAddressBufferC1Ejijj(ptr noundef nonnull align 4 dereferenceable(4) %this, +// CHECK-SAME: i32 noundef %spaceNo, i32 noundef %range, i32 noundef %index, i32 noundef %order_id) +// CHECK-NEXT: entry: +// CHECK-NEXT: %this.addr = alloca ptr, align 4 +// CHECK-NEXT: %spaceNo.addr = alloca i32, align 4 +// CHECK-NEXT: %range.addr = alloca i32, align 4 +// CHECK-NEXT: %index.addr = alloca i32, align 4 +// CHECK-NEXT: %order_id.addr = alloca i32, align 4 +// CHECK-NEXT: store ptr %this, ptr %this.addr, align 4 +// CHECK-NEXT: store i32 %spaceNo, ptr %spaceNo.addr, align 4 +// CHECK-NEXT: store i32 %range, ptr %range.addr, align 4 +// CHECK-NEXT: store i32 %index, ptr %index.addr, align 4 +// CHECK-NEXT: store i32 %order_id, ptr %order_id.addr, align 4 +// CHECK-NEXT: %this1 = load ptr, ptr %this.addr, align 4 +// CHECK-NEXT: %0 = load i32, ptr %spaceNo.addr, align 4 +// CHECK-NEXT: %1 = load i32, ptr %range.addr, align 4 +// CHECK-NEXT: %2 = load i32, ptr %index.addr, align 4 +// CHECK-NEXT: %3 = load i32, ptr %order_id.addr, align 4 +// CHECK-NEXT: call void @_ZN4hlsl19RWByteAddressBufferC2Ejijj(ptr noundef nonnull align 4 dereferenceable(4) %this1, i32 noundef %0, i32 noundef %1, i32 noundef %2, i32 noundef %3) #4 +// CHECK-NEXT: ret void // Buf3 initialization part 1 - local variable declared in function foo() is initial... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/138976 _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits