Skip to content

Commit 2a49c36

Browse files
committed
fix up function definition, add TiledResources shader flag
1 parent ec4e3a9 commit 2a49c36

File tree

5 files changed

+51
-32
lines changed

5 files changed

+51
-32
lines changed

clang/lib/CodeGen/CGHLSLBuiltins.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
357357
Value *HandleOp = EmitScalarExpr(E->getArg(0));
358358
Value *IndexOp = EmitScalarExpr(E->getArg(1));
359359

360-
// Get the *address* of the status argument (since it's a reference)
360+
// Get the *address* of the status argument to write to it by reference
361361
LValue StatusLVal = EmitLValue(E->getArg(2));
362362
Address StatusAddr = StatusLVal.getAddress();
363363

@@ -370,11 +370,9 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
370370
? llvm::Intrinsic::dx_resource_load_rawbuffer
371371
: llvm::Intrinsic::dx_resource_load_typedbuffer;
372372

373-
QualType BuiltinRetTy = E->getType();
374-
llvm::Type *DataTy = ConvertType(BuiltinRetTy->getPointeeType());
375-
376-
llvm::Type *IntrinsicRetTy = llvm::StructType::get(
377-
Builder.getContext(), {DataTy, Builder.getInt1Ty()});
373+
llvm::Type *DataTy = ConvertType(E->getType());
374+
llvm::Type *RetTy = llvm::StructType::get(Builder.getContext(),
375+
{DataTy, Builder.getInt1Ty()});
378376

379377
SmallVector<Value *, 3> Args;
380378
Args.push_back(HandleOp);
@@ -386,7 +384,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
386384

387385
// Call the intrinsic (returns a struct)
388386
Value *ResRet =
389-
Builder.CreateIntrinsic(IntrinsicRetTy, IntrID, Args, {}, "ld.struct");
387+
Builder.CreateIntrinsic(RetTy, IntrID, Args, {}, "ld.struct");
390388

391389
// Extract the loaded data (first element of the struct)
392390
Value *LoadedValue = Builder.CreateExtractValue(ResRet, {0}, "ld.value");

clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ struct BuiltinTypeMethodBuilder {
202202
BuiltinTypeMethodBuilder &declareLocalVar(LocalVar &Var);
203203
template <typename... Ts>
204204
BuiltinTypeMethodBuilder &callBuiltin(StringRef BuiltinName,
205-
QualType ReturnType, Ts... ArgSpecs);
205+
QualType ReturnType, Ts &&...ArgSpecs);
206206
template <typename TLHS, typename TRHS>
207207
BuiltinTypeMethodBuilder &assign(TLHS LHS, TRHS RHS);
208208
template <typename T> BuiltinTypeMethodBuilder &dereference(T Ptr);
@@ -572,7 +572,7 @@ BuiltinTypeMethodBuilder &BuiltinTypeMethodBuilder::returnThis() {
572572
template <typename... Ts>
573573
BuiltinTypeMethodBuilder &
574574
BuiltinTypeMethodBuilder::callBuiltin(StringRef BuiltinName,
575-
QualType ReturnType, Ts... ArgSpecs) {
575+
QualType ReturnType, Ts &&...ArgSpecs) {
576576
ensureCompleteDecl();
577577

578578
std::array<Expr *, sizeof...(ArgSpecs)> Args{
@@ -1240,23 +1240,20 @@ BuiltinTypeDeclBuilder::addLoadWithStatusFunction(DeclarationName &Name,
12401240
ASTContext &AST = SemaRef.getASTContext();
12411241
using PH = BuiltinTypeMethodBuilder::PlaceHolder;
12421242

1243-
QualType ElemTy = getHandleElementType();
1244-
QualType AddrSpaceElemTy =
1245-
AST.getAddrSpaceQualType(ElemTy, LangAS::hlsl_device);
1246-
QualType ElemPtrTy = AST.getPointerType(AddrSpaceElemTy);
1247-
QualType ReturnTy;
1248-
1249-
ReturnTy = ElemTy;
1250-
if (IsConst)
1251-
ReturnTy.addConst();
1243+
QualType ReturnTy = getHandleElementType();
1244+
BuiltinTypeMethodBuilder::LocalVar ResultVar("Result", ReturnTy);
1245+
BuiltinTypeMethodBuilder::LocalVar StatusVar("StatusBool", AST.BoolTy);
12521246

1253-
QualType StatusRefTy = AST.getLValueReferenceType(AST.UnsignedIntTy);
12541247
return BuiltinTypeMethodBuilder(*this, Name, ReturnTy, IsConst)
12551248
.addParam("Index", AST.UnsignedIntTy)
1256-
.addParam("Status", StatusRefTy)
1257-
.callBuiltin("__builtin_hlsl_resource_load_with_status", ElemPtrTy,
1258-
PH::Handle, PH::_0, PH::_1)
1259-
.dereference(PH::LastStmt)
1249+
.addParam("Status", AST.UnsignedIntTy, HLSLParamModifierAttr::Keyword_out)
1250+
.declareLocalVar(ResultVar)
1251+
.declareLocalVar(StatusVar)
1252+
.callBuiltin("__builtin_hlsl_resource_load_with_status", ReturnTy,
1253+
PH::Handle, PH::_0, StatusVar)
1254+
.assign(ResultVar, PH::LastStmt)
1255+
.assign(PH::_1, StatusVar)
1256+
.returnValue(ResultVar)
12601257
.finalize();
12611258
}
12621259

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3016,17 +3016,13 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
30163016
CheckArgTypeMatches(&SemaRef, TheCall->getArg(1),
30173017
SemaRef.getASTContext().UnsignedIntTy) ||
30183018
CheckArgTypeMatches(&SemaRef, TheCall->getArg(2),
3019-
SemaRef.getASTContext().UnsignedIntTy))
3019+
SemaRef.getASTContext().BoolTy))
30203020
return true;
30213021

30223022
auto *ResourceTy =
30233023
TheCall->getArg(0)->getType()->castAs<HLSLAttributedResourceType>();
3024-
QualType ContainedTy = ResourceTy->getContainedType();
3025-
auto ReturnType =
3026-
SemaRef.Context.getAddrSpaceQualType(ContainedTy, LangAS::hlsl_device);
3027-
ReturnType = SemaRef.Context.getPointerType(ReturnType);
3024+
QualType ReturnType = ResourceTy->getContainedType();
30283025
TheCall->setType(ReturnType);
3029-
TheCall->setValueKind(VK_LValue);
30303026

30313027
break;
30323028
}

clang/test/CodeGenHLSL/resources/TypedBuffers-methods.hlsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ export float TestLoadWithStatus() {
4747
}
4848

4949
// CHECK: define noundef nofpclass(nan inf) float @TestLoadWithStatus()()
50-
// CHECK: call {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @Buf, i32 noundef 1, ptr noundef nonnull align 4 dereferenceable(4) %s1)
51-
// CHECK: call {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int, unsigned int&)(ptr {{.*}} @RWBuf, i32 noundef 2, ptr noundef nonnull align 4 dereferenceable(4) %s2)
50+
// CHECK: call {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} @Buf, i32 noundef 1, ptr noalias noundef nonnull align 4 dereferenceable(4) %tmp)
51+
// CHECK: call {{.*}} <4 x i32> @hlsl::RWBuffer<unsigned int vector[4]>::Load(unsigned int, unsigned int&)(ptr {{.*}} @RWBuf, i32 noundef 2, ptr noalias noundef nonnull align 4 dereferenceable(4) %tmp1)
5252
// CHECK: add
5353
// CHECK: ret float
5454

55-
// CHECK: define {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr noundef nonnull align 4 dereferenceable(4) %Status)
55+
// CHECK: define {{.*}} float @hlsl::Buffer<float>::Load(unsigned int, unsigned int&)(ptr {{.*}} %this, i32 noundef %Index, ptr noalias noundef nonnull align 4 dereferenceable(4) %Status)
5656
// CHECK: %__handle = getelementptr inbounds nuw %"class.hlsl::Buffer", ptr %{{.*}}, i32 0, i32 0
5757
// DXIL-NEXT: %[[HANDLE:.*]] = load target("dx.TypedBuffer", float, 0, 0, 0), ptr %__handle
5858
// CHECK-NEXT: %[[INDEX:.*]] = load i32, ptr %Index.addr

llvm/lib/Target/DirectX/DXILShaderFlags.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,27 @@ static bool checkWaveOps(Intrinsic::ID IID) {
100100
}
101101
}
102102

103+
// Checks to see if the status bit from a load with status
104+
// instruction is ever extracted.
105+
// This is our proof that the module requires TiledResources
106+
// to be set, as if check access fully mapped was used.
107+
bool checkIfStatusIsExtracted(const Instruction &I) {
108+
// Iterate over all uses of the instruction
109+
for (const Use &U : I.uses()) {
110+
const User *UserInst = U.getUser();
111+
112+
// Check if the user is an ExtractValue instruction
113+
if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(UserInst)) {
114+
// ExtractValueInst has a list of indices; check if it extracts index 1
115+
if (EVI->getNumIndices() == 1 && EVI->getIndices()[0] == 1) {
116+
return true;
117+
}
118+
}
119+
}
120+
121+
return false;
122+
}
123+
103124
/// Update the shader flags mask based on the given instruction.
104125
/// \param CSF Shader flags mask to update.
105126
/// \param I Instruction to check.
@@ -192,6 +213,13 @@ void ModuleShaderFlags::updateFunctionFlags(ComputedShaderFlags &CSF,
192213
DRTM[cast<TargetExtType>(II->getArgOperand(0)->getType())];
193214
if (RTI.isTyped())
194215
CSF.TypedUAVLoadAdditionalFormats |= RTI.getTyped().ElementCount > 1;
216+
if (!CSF.TiledResources && checkIfStatusIsExtracted(I))
217+
CSF.TiledResources = true;
218+
break;
219+
}
220+
case Intrinsic::dx_resource_load_rawbuffer: {
221+
if (!CSF.TiledResources && checkIfStatusIsExtracted(I))
222+
CSF.TiledResources = true;
195223
break;
196224
}
197225
}

0 commit comments

Comments
 (0)