Skip to content

Commit 6fb658a

Browse files
committed
[HLSL] Allow register annotations to specify only space
Specifying only `space` in a `register` annotation means the compiler should implicitly assign a register slot to the resource from the provided virtual register space.
1 parent 4b25a5f commit 6fb658a

File tree

6 files changed

+64
-38
lines changed

6 files changed

+64
-38
lines changed

clang/include/clang/Basic/Attr.td

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4751,20 +4751,25 @@ def HLSLResourceBinding: InheritableAttr {
47514751

47524752
private:
47534753
RegisterType RegType;
4754-
unsigned SlotNumber;
4754+
int SlotNumber; // -1 if the register slot was not specified
47554755
unsigned SpaceNumber;
47564756

47574757
public:
4758-
void setBinding(RegisterType RT, unsigned SlotNum, unsigned SpaceNum) {
4758+
void setBinding(RegisterType RT, int SlotNum, unsigned SpaceNum) {
47594759
RegType = RT;
47604760
SlotNumber = SlotNum;
47614761
SpaceNumber = SpaceNum;
47624762
}
4763+
bool isImplicit() const {
4764+
return SlotNumber < 0;
4765+
}
47634766
RegisterType getRegisterType() const {
4767+
assert(!isImplicit() && "binding does not have register slot");
47644768
return RegType;
47654769
}
47664770
unsigned getSlotNumber() const {
4767-
return SlotNumber;
4771+
assert(!isImplicit() && "binding does not have register slot");
4772+
return (unsigned)SlotNumber;
47684773
}
47694774
unsigned getSpaceNumber() const {
47704775
return SpaceNumber;

clang/lib/CodeGen/CGHLSLRuntime.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) {
261261
BufDecl->getAttr<HLSLResourceBindingAttr>();
262262
// FIXME: handle implicit binding if no binding attribute is found
263263
// (llvm/llvm-project#110722)
264-
if (RBA)
264+
if (RBA && !RBA->isImplicit())
265265
initializeBufferFromBinding(CGM, BufGV, RBA->getSlotNumber(),
266266
RBA->getSpaceNumber());
267267
}

clang/lib/Sema/SemaHLSL.cpp

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1529,72 +1529,82 @@ void SemaHLSL::handleResourceBindingAttr(Decl *TheDecl, const ParsedAttr &AL) {
15291529
diag::err_incomplete_type))
15301530
return;
15311531
}
1532-
StringRef Space = "space0";
1532+
15331533
StringRef Slot = "";
1534+
StringRef Space = "";
1535+
SourceLocation SlotLoc, SpaceLoc;
15341536

15351537
if (!AL.isArgIdent(0)) {
15361538
Diag(AL.getLoc(), diag::err_attribute_argument_type)
15371539
<< AL << AANT_ArgumentIdentifier;
15381540
return;
15391541
}
1540-
15411542
IdentifierLoc *Loc = AL.getArgAsIdent(0);
1542-
StringRef Str = Loc->Ident->getName();
1543-
SourceLocation ArgLoc = Loc->Loc;
15441543

1545-
SourceLocation SpaceArgLoc;
1546-
bool SpecifiedSpace = false;
15471544
if (AL.getNumArgs() == 2) {
1548-
SpecifiedSpace = true;
1549-
Slot = Str;
1545+
Slot = Loc->Ident->getName();
1546+
SlotLoc = Loc->Loc;
1547+
15501548
if (!AL.isArgIdent(1)) {
15511549
Diag(AL.getLoc(), diag::err_attribute_argument_type)
15521550
<< AL << AANT_ArgumentIdentifier;
15531551
return;
15541552
}
15551553

1556-
IdentifierLoc *Loc = AL.getArgAsIdent(1);
1554+
Loc = AL.getArgAsIdent(1);
15571555
Space = Loc->Ident->getName();
1558-
SpaceArgLoc = Loc->Loc;
1556+
SpaceLoc = Loc->Loc;
15591557
} else {
1560-
Slot = Str;
1558+
StringRef Str = Loc->Ident->getName();
1559+
if (Str.starts_with("space")) {
1560+
Space = Str;
1561+
SpaceLoc = Loc->Loc;
1562+
} else {
1563+
Slot = Str;
1564+
SlotLoc = Loc->Loc;
1565+
Space = "space0";
1566+
}
15611567
}
15621568

1563-
RegisterType RegType;
1564-
unsigned SlotNum = 0;
1569+
RegisterType RegType = RegisterType::SRV;
1570+
int SlotNum = -1;
15651571
unsigned SpaceNum = 0;
15661572

1567-
// Validate.
1573+
// Validate slot
15681574
if (!Slot.empty()) {
15691575
if (!convertToRegisterType(Slot, &RegType)) {
1570-
Diag(ArgLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1);
1576+
Diag(SlotLoc, diag::err_hlsl_binding_type_invalid) << Slot.substr(0, 1);
15711577
return;
15721578
}
15731579
if (RegType == RegisterType::I) {
1574-
Diag(ArgLoc, diag::warn_hlsl_deprecated_register_type_i);
1580+
Diag(SlotLoc, diag::warn_hlsl_deprecated_register_type_i);
15751581
return;
15761582
}
1577-
15781583
StringRef SlotNumStr = Slot.substr(1);
15791584
if (SlotNumStr.getAsInteger(10, SlotNum)) {
1580-
Diag(ArgLoc, diag::err_hlsl_unsupported_register_number);
1585+
Diag(SlotLoc, diag::err_hlsl_unsupported_register_number);
15811586
return;
15821587
}
15831588
}
15841589

1585-
if (!Space.starts_with("space")) {
1586-
Diag(SpaceArgLoc, diag::err_hlsl_expected_space) << Space;
1587-
return;
1588-
}
1589-
StringRef SpaceNumStr = Space.substr(5);
1590-
if (SpaceNumStr.getAsInteger(10, SpaceNum)) {
1591-
Diag(SpaceArgLoc, diag::err_hlsl_expected_space) << Space;
1592-
return;
1590+
// Validate space
1591+
if (!Space.empty()) {
1592+
if (!Space.starts_with("space")) {
1593+
Diag(SpaceLoc, diag::err_hlsl_expected_space) << Space;
1594+
return;
1595+
}
1596+
StringRef SpaceNumStr = Space.substr(5);
1597+
if (SpaceNumStr.getAsInteger(10, SpaceNum)) {
1598+
Diag(SpaceLoc, diag::err_hlsl_expected_space) << Space;
1599+
return;
1600+
}
15931601
}
15941602

1595-
if (!DiagnoseHLSLRegisterAttribute(SemaRef, ArgLoc, TheDecl, RegType,
1596-
SpecifiedSpace))
1597-
return;
1603+
// If we have slot, diagnose it is the right register type for the decl
1604+
if (SlotNum >= 0)
1605+
if (!DiagnoseHLSLRegisterAttribute(SemaRef, SlotLoc, TheDecl, RegType,
1606+
!SpaceLoc.isInvalid()))
1607+
return;
15981608

15991609
HLSLResourceBindingAttr *NewAttr =
16001610
HLSLResourceBindingAttr::Create(getASTContext(), Slot, Space, AL);
@@ -1967,7 +1977,7 @@ void SemaHLSL::ActOnEndOfTranslationUnit(TranslationUnitDecl *TU) {
19671977
for (const Decl *VD : DefaultCBufferDecls) {
19681978
const HLSLResourceBindingAttr *RBA =
19691979
VD->getAttr<HLSLResourceBindingAttr>();
1970-
if (RBA &&
1980+
if (RBA && !RBA->isImplicit() &&
19711981
RBA->getRegisterType() == HLSLResourceBindingAttr::RegisterType::C) {
19721982
DefaultCBuffer->setHasValidPackoffset(true);
19731983
break;
@@ -3227,7 +3237,7 @@ static bool initVarDeclWithCtor(Sema &S, VarDecl *VD,
32273237

32283238
static bool initGlobalResourceDecl(Sema &S, VarDecl *VD) {
32293239
HLSLResourceBindingAttr *RBA = VD->getAttr<HLSLResourceBindingAttr>();
3230-
if (!RBA)
3240+
if (!RBA || RBA->isImplicit())
32313241
// FIXME: add support for implicit binding (llvm/llvm-project#110722)
32323242
return false;
32333243

@@ -3310,7 +3320,7 @@ void SemaHLSL::processExplicitBindingsOnDecl(VarDecl *VD) {
33103320

33113321
for (Attr *A : VD->attrs()) {
33123322
HLSLResourceBindingAttr *RBA = dyn_cast<HLSLResourceBindingAttr>(A);
3313-
if (!RBA)
3323+
if (!RBA || RBA->isImplicit())
33143324
continue;
33153325

33163326
RegisterType RT = RBA->getRegisterType();

clang/test/AST/HLSL/resource_binding_attr.hlsl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ RWBuffer<float> UAV : register(u3);
3030
// CHECK: HLSLResourceBindingAttr {{.*}} "u4" "space0"
3131
RWBuffer<float> UAV1 : register(u2), UAV2 : register(u4);
3232

33+
// CHECK: VarDecl {{.*}} UAV3 'RWBuffer<float>':'hlsl::RWBuffer<float>'
34+
// CHECK: HLSLResourceBindingAttr {{.*}} "" "space5"
35+
RWBuffer<float> UAV3 : register(space5);
36+
3337
//
3438
// Default constants ($Globals) layout annotations
3539

clang/test/SemaHLSL/resource_binding_attr_error.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ cbuffer c : register(bf, s2) {
2222
// expected-error@+1 {{expected identifier}}
2323
cbuffer A : register() {}
2424

25-
// expected-error@+1 {{register number should be an integer}}
26-
cbuffer B : register(space1) {}
25+
// expected-error@+1 {{invalid space specifier 'space' used; expected 'space' followed by an integer, like space1}}
26+
cbuffer B : register(space) {}
2727

2828
// expected-error@+1 {{wrong argument format for hlsl attribute, use b2 instead}}
2929
cbuffer C : register(b 2) {}

test.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ByteAddressBuffer Buffer0: register(t0);
2+
RWBuffer<float> Buf : register(u0);
3+
4+
[numthreads(4,1,1)]
5+
void main() {
6+
Buf[0] = 10;
7+
}

0 commit comments

Comments
 (0)