https://github.com/s-perron updated https://github.com/llvm/llvm-project/pull/127675
>From 78348586c0b237db689b669fcf4352e6b42898a1 Mon Sep 17 00:00:00 2001 From: Steven Perron <stevenper...@google.com> Date: Wed, 12 Feb 2025 15:45:32 -0500 Subject: [PATCH] [HLSL] Use hlsl_device address space for getpointer. We add the hlsl_device address space to represent the device memory space as defined in section 1.7.1.3 of the [HLSL spec](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf). Fixes https://github.com/llvm/llvm-project/issues/127075 --- clang/include/clang/Basic/AddressSpaces.h | 1 + clang/lib/AST/Type.cpp | 5 ++ clang/lib/AST/TypePrinter.cpp | 2 + clang/lib/Basic/Targets/AArch64.h | 1 + clang/lib/Basic/Targets/AMDGPU.cpp | 2 + clang/lib/Basic/Targets/DirectX.h | 1 + clang/lib/Basic/Targets/NVPTX.h | 1 + clang/lib/Basic/Targets/SPIR.h | 46 ++++++++++--------- clang/lib/Basic/Targets/SystemZ.h | 1 + clang/lib/Basic/Targets/TCE.h | 1 + clang/lib/Basic/Targets/WebAssembly.h | 1 + clang/lib/Basic/Targets/X86.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 4 +- clang/lib/Sema/HLSLExternalSemaSource.cpp | 21 ++++++--- clang/lib/Sema/SemaHLSL.cpp | 6 ++- clang/test/AST/HLSL/OutArgExpr.hlsl | 14 +++--- .../test/AST/HLSL/StructuredBuffers-AST.hlsl | 30 ++++++------ clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 22 ++++----- .../builtins/RWBuffer-subscript.hlsl | 24 +++++----- .../StructuredBuffers-methods-lib.hlsl | 20 ++++---- .../StructuredBuffers-methods-ps.hlsl | 6 +-- .../StructuredBuffers-subscripts.hlsl | 31 +++++++++---- .../SemaTemplate/address_space-dependent.cpp | 4 +- .../lib/Target/DirectX/DXILResourceAccess.cpp | 4 ++ .../DirectX/ResourceAccess/store_rawbuffer.ll | 21 +++++++++ 25 files changed, 168 insertions(+), 102 deletions(-) diff --git a/clang/include/clang/Basic/AddressSpaces.h b/clang/include/clang/Basic/AddressSpaces.h index d18bfe54931f9..c095ecf64272e 100644 --- a/clang/include/clang/Basic/AddressSpaces.h +++ b/clang/include/clang/Basic/AddressSpaces.h @@ -59,6 +59,7 @@ enum class LangAS : unsigned { // HLSL specific address spaces. hlsl_groupshared, hlsl_constant, + hlsl_device, // Wasm specific address spaces. wasm_funcref, diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 72161c06a88d4..0afc49287107a 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -94,6 +94,11 @@ bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B, (A == LangAS::Default && (B == LangAS::cuda_constant || B == LangAS::cuda_device || B == LangAS::cuda_shared)) || + // In HLSL, the this pointer for member functions is in the default + // address space. This causes problem if the structure is in + // hlsl_device. We want to allow casting from hlsl_device to default + // until a proper solution for that issue is found. + (A == LangAS::Default && B == LangAS::hlsl_device) || // Conversions from target specific address spaces may be legal // depending on the target information. Ctx.getTargetInfo().isAddressSpaceSupersetOf(A, B); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index dfd1959bbdcb0..9db12a698867d 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -2579,6 +2579,8 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) { return "groupshared"; case LangAS::hlsl_constant: return "hlsl_constant"; + case LangAS::hlsl_device: + return "hlsl_device"; case LangAS::wasm_funcref: return "__funcref"; default: diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index 9b6451bd06316..ea4db8eac8060 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -45,6 +45,7 @@ static const unsigned ARM64AddrSpaceMap[] = { static_cast<unsigned>(AArch64AddrSpace::ptr64), 0, // hlsl_groupshared 0, // hlsl_constant + 0, // hlsl_device // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp index a42b4589fb5ac..30bfa8c5b6259 100644 --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -60,6 +60,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared llvm::AMDGPUAS::CONSTANT_ADDRESS, // hlsl_constant + llvm::AMDGPUAS::GLOBAL_ADDRESS, // hlsl_device }; const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { @@ -85,6 +86,7 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = { llvm::AMDGPUAS::FLAT_ADDRESS, // ptr64 llvm::AMDGPUAS::FLAT_ADDRESS, // hlsl_groupshared llvm::AMDGPUAS::CONSTANT_ADDRESS, // hlsl_constant + llvm::AMDGPUAS::GLOBAL_ADDRESS, // hlsl_device }; } // namespace targets } // namespace clang diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index 6e3ddad626341..8f9243654a587 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -43,6 +43,7 @@ static const unsigned DirectXAddrSpaceMap[] = { 0, // ptr64 3, // hlsl_groupshared 2, // hlsl_constant + 1, // hlsl_device // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h index 6a868c42e1265..81c3222f4c1fc 100644 --- a/clang/lib/Basic/Targets/NVPTX.h +++ b/clang/lib/Basic/Targets/NVPTX.h @@ -47,6 +47,7 @@ static const unsigned NVPTXAddrSpaceMap[] = { 0, // ptr64 0, // hlsl_groupshared 0, // hlsl_constant + 0, // hlsl_device // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h index 78505d66d6f2f..f84606742d439 100644 --- a/clang/lib/Basic/Targets/SPIR.h +++ b/clang/lib/Basic/Targets/SPIR.h @@ -38,16 +38,17 @@ static const unsigned SPIRDefIsPrivMap[] = { 0, // cuda_constant 0, // cuda_shared // SYCL address space values for this map are dummy - 0, // sycl_global - 0, // sycl_global_device - 0, // sycl_global_host - 0, // sycl_local - 0, // sycl_private - 0, // ptr32_sptr - 0, // ptr32_uptr - 0, // ptr64 - 0, // hlsl_groupshared - 2, // hlsl_constant + 0, // sycl_global + 0, // sycl_global_device + 0, // sycl_global_host + 0, // sycl_local + 0, // sycl_private + 0, // ptr32_sptr + 0, // ptr32_uptr + 0, // ptr64 + 0, // hlsl_groupshared + 2, // hlsl_constant + 11, // hlsl_device // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref @@ -70,18 +71,19 @@ static const unsigned SPIRDefIsGenMap[] = { // cuda_constant pointer can be casted to default/"flat" pointer, but in // SPIR-V casts between constant and generic pointers are not allowed. For // this reason cuda_constant is mapped to SPIR-V CrossWorkgroup. - 1, // cuda_constant - 3, // cuda_shared - 1, // sycl_global - 5, // sycl_global_device - 6, // sycl_global_host - 3, // sycl_local - 0, // sycl_private - 0, // ptr32_sptr - 0, // ptr32_uptr - 0, // ptr64 - 0, // hlsl_groupshared - 0, // hlsl_constant + 1, // cuda_constant + 3, // cuda_shared + 1, // sycl_global + 5, // sycl_global_device + 6, // sycl_global_host + 3, // sycl_local + 0, // sycl_private + 0, // ptr32_sptr + 0, // ptr32_uptr + 0, // ptr64 + 0, // hlsl_groupshared + 2, // hlsl_constant + 11, // hlsl_device // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index 4ca3f53f83cba..7da4d73523f30 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -43,6 +43,7 @@ static const unsigned ZOSAddressMap[] = { 0, // ptr64 0, // hlsl_groupshared 0, // hlsl_constant + 0, // hlsl_device 0 // wasm_funcref }; diff --git a/clang/lib/Basic/Targets/TCE.h b/clang/lib/Basic/Targets/TCE.h index 46c70de8f9ec1..d13055be66805 100644 --- a/clang/lib/Basic/Targets/TCE.h +++ b/clang/lib/Basic/Targets/TCE.h @@ -52,6 +52,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = { 0, // ptr64 0, // hlsl_groupshared 0, // hlsl_constant + 0, // hlsl_device // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index fb48c786a7edb..4e546b2b91c7a 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -43,6 +43,7 @@ static const unsigned WebAssemblyAddrSpaceMap[] = { 0, // ptr64 0, // hlsl_groupshared 0, // hlsl_constant + 0, // hlsl_device 20, // wasm_funcref }; diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h index 205edcab9ccb3..d40708fc04b67 100644 --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -47,6 +47,7 @@ static const unsigned X86AddrSpaceMap[] = { 272, // ptr64 0, // hlsl_groupshared 0, // hlsl_constant + 0, // hlsl_device // Wasm address space values for this target are dummy values, // as it is only enabled for Wasm targets. 20, // wasm_funcref diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index c126f88b9e3a5..f41285e289b3a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -19573,9 +19573,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *HandleOp = EmitScalarExpr(E->getArg(0)); Value *IndexOp = EmitScalarExpr(E->getArg(1)); - // TODO: Map to an hlsl_device address space. - llvm::Type *RetTy = llvm::PointerType::getUnqual(getLLVMContext()); - + llvm::Type *RetTy = ConvertType(E->getType()); return Builder.CreateIntrinsic( RetTy, CGM.getHLSLRuntime().getCreateResourceGetPointerIntrinsic(), ArrayRef<Value *>{HandleOp, IndexOp}); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index cfa49029a2fb1..d028fa914e462 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -711,13 +711,14 @@ BuiltinTypeDeclBuilder::addHandleAccessFunction(DeclarationName &Name, using PH = BuiltinTypeMethodBuilder::PlaceHolder; QualType ElemTy = getHandleElementType(); - // TODO: Map to an hlsl_device address space. - QualType ElemPtrTy = AST.getPointerType(ElemTy); - QualType ReturnTy = ElemTy; + QualType AddrSpaceElemTy = + AST.getAddrSpaceQualType(ElemTy, LangAS::hlsl_device); + QualType ElemPtrTy = AST.getPointerType(AddrSpaceElemTy); + // QualType ReturnTy = (IsRef ? AST.getLValueReferenceType(ElemTy) : ElemTy); + QualType ReturnTy = + (IsRef ? AST.getLValueReferenceType(AddrSpaceElemTy) : ElemTy); if (IsConst) ReturnTy.addConst(); - if (IsRef) - ReturnTy = AST.getLValueReferenceType(ReturnTy); return BuiltinTypeMethodBuilder(*this, Name, ReturnTy, IsConst) .addParam("Index", AST.UnsignedIntTy) @@ -731,12 +732,15 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addAppendMethod() { using PH = BuiltinTypeMethodBuilder::PlaceHolder; ASTContext &AST = SemaRef.getASTContext(); QualType ElemTy = getHandleElementType(); + QualType AddrSpaceElemTy = + AST.getAddrSpaceQualType(ElemTy, LangAS::hlsl_device); return BuiltinTypeMethodBuilder(*this, "Append", AST.VoidTy) .addParam("value", ElemTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy, PH::Handle, getConstantIntExpr(1)) .callBuiltin("__builtin_hlsl_resource_getpointer", - AST.getPointerType(ElemTy), PH::Handle, PH::LastStmt) + AST.getPointerType(AddrSpaceElemTy), PH::Handle, + PH::LastStmt) .dereference(PH::LastStmt) .assign(PH::LastStmt, PH::_0) .finalizeMethod(); @@ -746,11 +750,14 @@ BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() { using PH = BuiltinTypeMethodBuilder::PlaceHolder; ASTContext &AST = SemaRef.getASTContext(); QualType ElemTy = getHandleElementType(); + QualType AddrSpaceElemTy = + AST.getAddrSpaceQualType(ElemTy, LangAS::hlsl_device); return BuiltinTypeMethodBuilder(*this, "Consume", ElemTy) .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy, PH::Handle, getConstantIntExpr(-1)) .callBuiltin("__builtin_hlsl_resource_getpointer", - AST.getPointerType(ElemTy), PH::Handle, PH::LastStmt) + AST.getPointerType(AddrSpaceElemTy), PH::Handle, + PH::LastStmt) .dereference(PH::LastStmt) .finalizeMethod(); } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 07d03e2c58b9a..975275e0377c9 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -2378,8 +2378,10 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { auto *ResourceTy = TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>(); QualType ContainedTy = ResourceTy->getContainedType(); - // TODO: Map to an hlsl_device address space. - TheCall->setType(getASTContext().getPointerType(ContainedTy)); + auto returnType = + SemaRef.Context.getAddrSpaceQualType(ContainedTy, LangAS::hlsl_device); + returnType = SemaRef.Context.getPointerType(returnType); + TheCall->setType(returnType); TheCall->setValueKind(VK_LValue); break; diff --git a/clang/test/AST/HLSL/OutArgExpr.hlsl b/clang/test/AST/HLSL/OutArgExpr.hlsl index b07c2efadbf4a..04ce635e721bf 100644 --- a/clang/test/AST/HLSL/OutArgExpr.hlsl +++ b/clang/test/AST/HLSL/OutArgExpr.hlsl @@ -30,10 +30,10 @@ void zero(out int Z) { Z = 0; } // AST-NEXT: ImplicitCastExpr {{.*}} 'void (*)(inout int)' <FunctionToPointerDecay> // AST-NEXT: DeclRefExpr {{.*}} 'void (inout int)' lvalue Function // AST-NEXT: HLSLOutArgExpr {{.*}} 'int' lvalue inout -// AST-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'float' lvalue -// AST-NEXT: CXXOperatorCallExpr {{.*}} 'float' lvalue '[]' -// AST-NEXT: ImplicitCastExpr {{.*}} 'float &(*)(unsigned int)' <FunctionToPointerDecay> -// AST-NEXT: DeclRefExpr {{.*}} 'float &(unsigned int)' lvalue CXXMethod {{.*}} 'operator[]' 'float &(unsigned int)' +// AST-NEXT: OpaqueValueExpr [[LVOpV:0x[0-9a-fA-F]+]] {{.*}} 'hlsl_device float' lvalue +// AST-NEXT: CXXOperatorCallExpr {{.*}} 'hlsl_device float' lvalue '[]' +// AST-NEXT: ImplicitCastExpr {{.*}} 'hlsl_device float &(*)(unsigned int)' <FunctionToPointerDecay> +// AST-NEXT: DeclRefExpr {{.*}} 'hlsl_device float &(unsigned int)' lvalue CXXMethod {{.*}} 'operator[]' 'hlsl_device float &(unsigned int)' // AST-NEXT: DeclRefExpr {{.*}} 'RWBuffer<float>':'hlsl::RWBuffer<float>' lvalue Var {{.*}} 'Buf' 'RWBuffer<float>':'hlsl::RWBuffer<float>' // AST-NEXT: ImplicitCastExpr {{.*}} 'uint':'unsigned int' <LValueToRValue> // AST-NEXT: DeclRefExpr {{.*}} 'uint':'unsigned int' lvalue ParmVar {{.*}} 'GI' 'uint':'unsigned int' @@ -41,10 +41,10 @@ void zero(out int Z) { Z = 0; } // AST-NEXT: OpaqueValueExpr [[TmpOpV:0x[0-9a-fA-F]+]] {{.*}} 'int' lvalue // AST-NEXT: ImplicitCastExpr {{.*}} 'int' <FloatingToIntegral> // AST-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue> -// AST-NEXT: OpaqueValueExpr [[LVOpV]] <col:15, col:21> 'float' lvalue +// AST-NEXT: OpaqueValueExpr [[LVOpV]] <col:15, col:21> 'hlsl_device float' lvalue -// AST: BinaryOperator {{.*}} 'float' lvalue '=' -// AST-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'float' lvalue +// AST: BinaryOperator {{.*}} 'hlsl_device float' lvalue '=' +// AST-NEXT: OpaqueValueExpr [[LVOpV]] {{.*}} 'hlsl_device float' lvalue // AST: ImplicitCastExpr {{.*}} 'float' <IntegralToFloating> // AST-NEXT: ImplicitCastExpr {{.*}} 'int' <LValueToRValue> // AST-NEXT: OpaqueValueExpr [[TmpOpV]] {{.*}} 'int' lvalue diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index dcead068f481e..75dd4fe23121b 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -89,12 +89,12 @@ RESOURCE<float> Buffer; // CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]] // CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-SUBSCRIPT: CXXMethodDecl {{.*}} operator[] 'const element_type &(unsigned int) const' +// CHECK-SUBSCRIPT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &const (unsigned int) const' // CHECK-SUBSCRIPT-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' // CHECK-SUBSCRIPT-NEXT: CompoundStmt // CHECK-SUBSCRIPT-NEXT: ReturnStmt -// CHECK-SUBSCRIPT-NEXT: UnaryOperator {{.*}} 'element_type' prefix '*' cannot overflow -// CHECK-SUBSCRIPT-NEXT: CallExpr {{.*}} 'element_type *' +// CHECK-SUBSCRIPT-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow +// CHECK-SUBSCRIPT-NEXT: CallExpr {{.*}} 'hlsl_device element_type *' // CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' // CHECK-SUBSCRIPT-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::resource_class( @@ -105,12 +105,12 @@ RESOURCE<float> Buffer; // CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' // CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline -// CHECK-SUBSCRIPT-NEXT: CXXMethodDecl {{.*}} operator[] 'element_type &(unsigned int)' +// CHECK-SUBSCRIPT-NEXT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)' // CHECK-SUBSCRIPT-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' // CHECK-SUBSCRIPT-NEXT: CompoundStmt // CHECK-SUBSCRIPT-NEXT: ReturnStmt -// CHECK-SUBSCRIPT-NEXT: UnaryOperator {{.*}} 'element_type' prefix '*' cannot overflow -// CHECK-SUBSCRIPT-NEXT: CallExpr {{.*}} 'element_type *' +// CHECK-SUBSCRIPT-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow +// CHECK-SUBSCRIPT-NEXT: CallExpr {{.*}} 'hlsl_device element_type *' // CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' // CHECK-SUBSCRIPT-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::resource_class( @@ -121,15 +121,15 @@ RESOURCE<float> Buffer; // CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' // CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline -// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'const element_type &(unsigned int) const' -// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'element_type &(unsigned int)' +// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &const (unsigned int) const' +// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)' // CHECK-LOAD: CXXMethodDecl {{.*}} Load 'element_type (unsigned int)' // CHECK-LOAD-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' // CHECK-LOAD-NEXT: CompoundStmt // CHECK-LOAD-NEXT: ReturnStmt -// CHECK-LOAD-NEXT: UnaryOperator {{.*}} 'element_type' prefix '*' cannot overflow -// CHECK-LOAD-NEXT: CallExpr {{.*}} 'element_type *' +// CHECK-LOAD-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow +// CHECK-LOAD-NEXT: CallExpr {{.*}} 'hlsl_device element_type *' // CHECK-LOAD-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' // CHECK-LOAD-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-LOAD-SAME{LITERAL}: [[hlsl::resource_class( @@ -168,9 +168,9 @@ RESOURCE<float> Buffer; // CHECK-APPEND: CXXMethodDecl {{.*}} Append 'void (element_type)' // CHECK-APPEND-NEXT: ParmVarDecl {{.*}} value 'element_type' // CHECK-APPEND-NEXT: CompoundStmt -// CHECK-APPEND-NEXT: BinaryOperator {{.*}} 'element_type' '=' -// CHECK-APPEND-NEXT: UnaryOperator {{.*}} 'element_type' prefix '*' cannot overflow -// CHECK-APPEND-NEXT: CallExpr {{.*}} 'element_type *' +// CHECK-APPEND-NEXT: BinaryOperator {{.*}} 'hlsl_device element_type' '=' +// CHECK-APPEND-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow +// CHECK-APPEND-NEXT: CallExpr {{.*}} 'hlsl_device element_type *' // CHECK-APPEND-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' // CHECK-APPEND-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] @@ -190,8 +190,8 @@ RESOURCE<float> Buffer; // CHECK-CONSUME: CXXMethodDecl {{.*}} Consume 'element_type ()' // CHECK-CONSUME-NEXT: CompoundStmt // CHECK-CONSUME-NEXT: ReturnStmt -// CHECK-CONSUME-NEXT: UnaryOperator {{.*}} 'element_type' prefix '*' cannot overflow -// CHECK-CONSUME-NEXT: CallExpr {{.*}} 'element_type *' +// CHECK-CONSUME-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow +// CHECK-CONSUME-NEXT: CallExpr {{.*}} 'hlsl_device element_type *' // CHECK-CONSUME-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' // CHECK-CONSUME-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index f665b06d691e8..1da474469c0c0 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -56,32 +56,32 @@ RESOURCE<float> Buffer; // CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] // CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK: CXXMethodDecl {{.*}} operator[] 'const element_type &(unsigned int) const' +// CHECK: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &const (unsigned int) const' // CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: ReturnStmt -// CHECK-NEXT: UnaryOperator {{.*}} 'element_type' prefix '*' cannot overflow -// CHECK-NEXT: CallExpr {{.*}} 'element_type *' +// CHECK-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow +// CHECK-NEXT: CallExpr {{.*}} 'hlsl_device element_type *' // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] // CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-SAME: ' lvalue .__handle {{.*}} +// CHECK-SAME: ' lvalue .__handle {{.*}} // CHECK-NEXT: CXXThisExpr {{.*}} 'const [[RESOURCE]]<element_type>' lvalue implicit this // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline -// CHECK-NEXT: CXXMethodDecl {{.*}} operator[] 'element_type &(unsigned int)' +// CHECK-NEXT: CXXMethodDecl {{.*}} operator[] 'hlsl_device element_type &(unsigned int)' // CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: ReturnStmt -// CHECK-NEXT: UnaryOperator {{.*}} 'element_type' prefix '*' cannot overflow -// CHECK-NEXT: CallExpr {{.*}} 'element_type *' +// CHECK-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow +// CHECK-NEXT: CallExpr {{.*}} 'hlsl_device element_type *' // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] // CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-SAME: ' lvalue .__handle {{.*}} +// CHECK-SAME: ' lvalue .__handle {{.*}} // CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline @@ -90,13 +90,13 @@ RESOURCE<float> Buffer; // CHECK-NEXT: ParmVarDecl {{.*}} Index 'unsigned int' // CHECK-NEXT: CompoundStmt // CHECK-NEXT: ReturnStmt -// CHECK-NEXT: UnaryOperator {{.*}} 'element_type' prefix '*' cannot overflow -// CHECK-NEXT: CallExpr {{.*}} 'element_type *' +// CHECK-NEXT: UnaryOperator {{.*}} 'hlsl_device element_type' prefix '*' cannot overflow +// CHECK-NEXT: CallExpr {{.*}} 'hlsl_device element_type *' // CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' // CHECK-NEXT: MemberExpr {{.*}} '__hlsl_resource_t // CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] // CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] -// CHECK-SAME: ' lvalue .__handle {{.*}} +// CHECK-SAME: ' lvalue .__handle {{.*}} // CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this // CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl index 2ad5b82a02912..39f77eac0528d 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl @@ -8,19 +8,19 @@ RWBuffer<int> Out; void main(unsigned GI : SV_GroupIndex) { // CHECK: define void @main() - // DXC: %[[INPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) - // SPIRV: %[[INPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_0t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) %{{.*}}, i32 %{{.*}}) - // CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]] - // DXC: %[[OUTPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) - // SPIRV: %[[OUTPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_0t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) %{{.*}}, i32 %{{.*}}) - // CHECK: store i32 %[[LOAD]], ptr %[[OUTPTR]] + // DXC: %[[INPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) + // SPIRV: %[[INPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_0t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: %[[LOAD:.*]] = load i32, ptr addrspace({{[0-9]+}}) %[[INPTR]] + // DXC: %[[OUTPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) + // SPIRV: %[[OUTPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_0t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: store i32 %[[LOAD]], ptr addrspace({{[0-9]+}}) %[[OUTPTR]] Out[GI] = In[GI]; - // DXC: %[[INPTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) - // SPIRV: %[[INPTR:.*]] = call ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_0t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) %{{.*}}, i32 %{{.*}}) - // CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]] - // DXC: %[[OUTPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) - // SPIRV: %[[OUTPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.spv.resource.getpointer.p0.tspirv.Image_i32_5_2_0_0_2_0t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) %{{.*}}, i32 %{{.*}}) - // CHECK: store i32 %[[LOAD]], ptr %[[OUTPTR]] + // DXC: %[[INPTR:.*]] = call ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) + // SPIRV: %[[INPTR:.*]] = call ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_0t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: %[[LOAD:.*]] = load i32, ptr addrspace({{[0-9]+}}) %[[INPTR]] + // DXC: %[[OUTPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) + // SPIRV: %[[OUTPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(11) @llvm.spv.resource.getpointer.p11.tspirv.Image_i32_5_2_0_0_2_0t(target("spirv.Image", i32, 5, 2, 0, 0, 2, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: store i32 %[[LOAD]], ptr addrspace({{[0-9]+}}) %[[OUTPTR]] Out[GI] = In.Load(GI); } diff --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl index 93aa218f63ecf..489c5a50511be 100644 --- a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl +++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl @@ -36,8 +36,8 @@ export void TestAppend(float value) { // CHECK: define void @_Z10TestAppendf(float noundef nofpclass(nan inf) %value) // CHECK-DXIL: %[[VALUE:.*]] = load float, ptr %value.addr, align 4 // CHECK-DXIL: %[[INDEX:.*]] = call i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i8 1) -// CHECK-DXIL: %[[RESPTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i32 %[[INDEX]]) -// CHECK-DXIL: store float %[[VALUE]], ptr %[[RESPTR]], align 4 +// CHECK-DXIL: %[[RESPTR:.*]] = call ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i32 %[[INDEX]]) +// CHECK-DXIL: store float %[[VALUE]], ptr addrspace(1) %[[RESPTR]], align 4 export float TestConsume() { return CSB.Consume(); @@ -45,8 +45,8 @@ export float TestConsume() { // CHECK: define noundef nofpclass(nan inf) float @_Z11TestConsumev() // CHECK-DXIL: %[[INDEX:.*]] = call i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %1, i8 -1) -// CHECK-DXIL: %[[RESPTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %0, i32 %[[INDEX]]) -// CHECK-DXIL: %[[VALUE:.*]] = load float, ptr %[[RESPTR]], align 4 +// CHECK-DXIL: %[[RESPTR:.*]] = call ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %0, i32 %[[INDEX]]) +// CHECK-DXIL: %[[VALUE:.*]] = load float, ptr addrspace(1) %[[RESPTR]], align 4 // CHECK-DXIL: ret float %[[VALUE]] export float TestLoad() { @@ -54,11 +54,11 @@ export float TestLoad() { } // CHECK: define noundef nofpclass(nan inf) float @_Z8TestLoadv() -// CHECK: %[[PTR1:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i32 %{{[0-9]+}}) -// CHECK: %[[VALUE1:.*]] = load float, ptr %[[PTR1]] -// CHECK: %[[PTR2:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0) %{{[0-9]+}}, i32 %{{[0-9]+}}) -// CHECK: %[[VALUE2:.*]] = load float, ptr %[[PTR2]] +// CHECK: %[[PTR1:.*]] = call ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i32 %{{[0-9]+}}) +// CHECK: %[[VALUE1:.*]] = load float, ptr addrspace(1) %[[PTR1]] +// CHECK: %[[PTR2:.*]] = call ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0) %{{[0-9]+}}, i32 %{{[0-9]+}}) +// CHECK: %[[VALUE2:.*]] = load float, ptr addrspace(1) %[[PTR2]] // CHECK: declare i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i8) -// CHECK: declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32) -// CHECK: declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0), i32) +// CHECK: declare ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32) +// CHECK: declare ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_f32_0_0t(target("dx.RawBuffer", float, 0, 0), i32) diff --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-ps.hlsl b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-ps.hlsl index 5b1d8e3052eae..a4e9fe8e35442 100644 --- a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-ps.hlsl +++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-ps.hlsl @@ -29,9 +29,9 @@ export float TestLoad() { } // CHECK: define noundef nofpclass(nan inf) float @_Z8TestLoadv() -// CHECK: %[[PTR1:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1) %{{[0-9]+}}, i32 %{{[0-9]+}}) -// CHECK: %[[VALUE1:.*]] = load float, ptr %[[PTR1]] +// CHECK: %[[PTR1:.*]] = call ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1) %{{[0-9]+}}, i32 %{{[0-9]+}}) +// CHECK: %[[VALUE1:.*]] = load float, ptr addrspace(1) %[[PTR1]] // CHECK: declare i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i8) #3 // CHECK: declare i32 @llvm.dx.resource.updatecounter.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1), i8) #3 -// CHECK: declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1), i32) #4 +// CHECK: declare ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_f32_1_1t(target("dx.RawBuffer", float, 1, 1), i32) #4 diff --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-subscripts.hlsl b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-subscripts.hlsl index 2af7c3ed3219f..3810e3b472dc7 100644 --- a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-subscripts.hlsl +++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-subscripts.hlsl @@ -1,22 +1,37 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -emit-llvm -o - -O0 %s | FileCheck %s +struct S { + float f; +}; + StructuredBuffer<int> In; RWStructuredBuffer<int> Out1; +RWStructuredBuffer<S> RWSB3; RasterizerOrderedStructuredBuffer<int> Out2; [numthreads(1,1,1)] void main(unsigned GI : SV_GroupIndex) { // CHECK: define void @main() - // CHECK: %[[INPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %{{.*}}, i32 %{{.*}}) - // CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]] - // CHECK: %[[OUT1PTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0) %{{.*}}, i32 %{{.*}}) - // CHECK: store i32 %[[LOAD]], ptr %[[OUT1PTR]] + // CHECK: %[[INPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: %[[LOAD:.*]] = load i32, ptr addrspace(1) %[[INPTR]] + // CHECK: %[[OUT1PTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_i32_1_0t(target("dx.RawBuffer", i32, 1, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: store i32 %[[LOAD]], ptr addrspace(1) %[[OUT1PTR]] Out1[GI] = In[GI]; - // CHECK: %[[INPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %{{.*}}, i32 %{{.*}}) - // CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]] - // CHECK: %[[OUT2PTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_i32_1_1t(target("dx.RawBuffer", i32, 1, 1) %{{.*}}, i32 %{{.*}}) - // CHECK: store i32 %[[LOAD]], ptr %[[OUT2PTR]] + // CHECK: %[[INPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_i32_0_0t(target("dx.RawBuffer", i32, 0, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: %[[LOAD:.*]] = load i32, ptr addrspace(1) %[[INPTR]] + // CHECK: %[[OUT2PTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_i32_1_1t(target("dx.RawBuffer", i32, 1, 1) %{{.*}}, i32 %{{.*}}) + // CHECK: store i32 %[[LOAD]], ptr addrspace(1) %[[OUT2PTR]] Out2[GI] = In[GI]; + + // The addrspacecast comes from `S::operator=` member function, which expects + // parameters in address space 0. This is why hlsl_device is a sub address + // space of the default address space. + // CHECK: %[[INPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_s_struct.Ss_1_0t(target("dx.RawBuffer", %struct.S, 1, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: %[[INCAST:.*]] = addrspacecast ptr addrspace(1) %[[INPTR]] to ptr + // CHECK: %[[OUTPTR:.*]] = call noundef align 4 dereferenceable(4) ptr addrspace(1) @llvm.dx.resource.getpointer.p1.tdx.RawBuffer_s_struct.Ss_1_0t(target("dx.RawBuffer", %struct.S, 1, 0) %{{.*}}, i32 %{{.*}}) + // CHECK: %[[OUTCAST:.*]] = addrspacecast ptr addrspace(1) %[[OUTPTR]] to ptr + // CHECK: call void @llvm.memcpy.p0.p0.i32(ptr align 4 %[[OUTCAST]], ptr align 4 %[[INCAST]], i32 4, i1 false) + RWSB3[0] = RWSB3[1]; } diff --git a/clang/test/SemaTemplate/address_space-dependent.cpp b/clang/test/SemaTemplate/address_space-dependent.cpp index eb8dbc69a945e..3e73e909746a5 100644 --- a/clang/test/SemaTemplate/address_space-dependent.cpp +++ b/clang/test/SemaTemplate/address_space-dependent.cpp @@ -43,7 +43,7 @@ void neg() { template <long int I> void tooBig() { - __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388585)}} + __attribute__((address_space(I))) int *bounds; // expected-error {{address space is larger than the maximum supported (8388584)}} } template <long int I> @@ -101,7 +101,7 @@ int main() { car<1, 2, 3>(); // expected-note {{in instantiation of function template specialization 'car<1, 2, 3>' requested here}} HasASTemplateFields<1> HASTF; neg<-1>(); // expected-note {{in instantiation of function template specialization 'neg<-1>' requested here}} - correct<0x7FFFE9>(); + correct<0x7FFFE8>(); tooBig<8388650>(); // expected-note {{in instantiation of function template specialization 'tooBig<8388650L>' requested here}} __attribute__((address_space(1))) char *x; diff --git a/llvm/lib/Target/DirectX/DXILResourceAccess.cpp b/llvm/lib/Target/DirectX/DXILResourceAccess.cpp index 3b8f7140d3122..ba91809d1feb9 100644 --- a/llvm/lib/Target/DirectX/DXILResourceAccess.cpp +++ b/llvm/lib/Target/DirectX/DXILResourceAccess.cpp @@ -224,6 +224,10 @@ static void replaceAccess(IntrinsicInst *II, dxil::ResourceTypeInfo &RTI) { createLoadIntrinsic(II, LI, Current.Offset, RTI); DeadInsts.push_back(LI); + } else if (auto ASC = dyn_cast<AddrSpaceCastInst>(Current.Access)) { + for (User *U : ASC->users()) + Worklist.push_back({U, Current.Offset}); + DeadInsts.push_back(ASC); } else llvm_unreachable("Unhandled instruction - pointer escaped?"); } diff --git a/llvm/test/CodeGen/DirectX/ResourceAccess/store_rawbuffer.ll b/llvm/test/CodeGen/DirectX/ResourceAccess/store_rawbuffer.ll index b19f9d04a2dff..62395c2cac714 100644 --- a/llvm/test/CodeGen/DirectX/ResourceAccess/store_rawbuffer.ll +++ b/llvm/test/CodeGen/DirectX/ResourceAccess/store_rawbuffer.ll @@ -122,3 +122,24 @@ define void @storev4f64_byte(i32 %offset, <4 x double> %data) { ret void } + +%struct.S = type { i32 } +; CHECK-LABEL: define void @copyStructWithAddrspaceCast +define void @copyStructWithAddrspaceCast() { +entry: + %buffer = tail call target("dx.RawBuffer", %struct.S, 1, 0) + @llvm.dx.resource.handlefrombinding(i32 0, i32 0, i32 1, i32 0, i1 false) + %ptr0 = call ptr addrspace(1) @llvm.dx.resource.getpointer( + target("dx.RawBuffer", %struct.S, 1, 0) %buffer, i32 1) + %cast0 = addrspacecast ptr addrspace(1) %ptr0 to ptr + %ptr1 = call ptr addrspace(1) @llvm.dx.resource.getpointer( + target("dx.RawBuffer", %struct.S, 1, 0) %buffer, i32 0) + %cast1 = addrspacecast ptr addrspace(1) %ptr1 to ptr + + ; CHECK: %[[L:.*]] = call { i32, i1 } @llvm.dx.resource.load.rawbuffer.i32.tdx.RawBuffer_s_struct.Ss_1_0t(target("dx.RawBuffer", %struct.S, 1, 0) %buffer, i32 1, i32 0) + ; CHECK: %[[V:.*]] = extractvalue { i32, i1 } %[[L]], 0 + ; CHECK: call void @llvm.dx.resource.store.rawbuffer.tdx.RawBuffer_s_struct.Ss_1_0t.i32(target("dx.RawBuffer", %struct.S, 1, 0) %{{.*}}, i32 0, i32 0, i32 %[[V]]) + %2 = load i32, ptr %cast0, align 4 + store i32 %2, ptr %cast1, align 4 + ret void +} \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits