Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/HLSL/HLLegalizeParameter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ bool HLLegalizeParameter::runOnModule(Module &M) {
continue;

for (Argument &Arg : F.args()) {
if (!Arg.getType()->isPointerTy())
Type *PtrTy = dyn_cast<PointerType>(Arg.getType());
if (!PtrTy || 0 != PtrTy->getPointerAddressSpace())
continue;
Type *EltTy = dxilutil::GetArrayEltTy(Arg.getType());
if (dxilutil::IsHLSLObjectType(EltTy) ||
Expand Down
2 changes: 2 additions & 0 deletions tools/clang/include/clang/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1458,6 +1458,8 @@ class ParmVarDecl : public VarDecl {
void setModifierOut(bool value) { ParmVarDeclBits.IsModifierOut = value; }
/// Synthesize a ParameterModifier value for this parameter.
hlsl::ParameterModifier getParamModifiers() const {
if (!isModifierIn() && !isModifierOut())
return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::Ref);
if (isModifierIn() && !isModifierOut())
return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::In);
if (isModifierIn() && isModifierOut())
Expand Down
7 changes: 7 additions & 0 deletions tools/clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1597,6 +1597,13 @@ def warn_hlsl_sometimes_uninit_out_param : Warning<
"its declaration is reached|"
"%3 is called}2">,
InGroup<HLSLParameterUsage>;
def warn_hlsl_groupshared_202x: Warning<
"Support for groupshared parameter annotation not added until HLSL 202x">,
InGroup<HLSLParameterUsage>;
def warn_hlsl_groupshared_inout: Warning<
"Passing groupshared variable to a parameter annotated with inout. See"
"'groupshared' parameter annotation added in 202x.">,
InGroup<HLSLParameterUsage>;
// HLSL Change End - Add warning for uninitialized out param
def warn_maybe_uninit_var : Warning<
"variable %0 may be uninitialized when "
Expand Down
18 changes: 18 additions & 0 deletions tools/clang/lib/AST/HlslTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,9 @@ bool HasHLSLReorderCoherent(clang::QualType type) {
return false;
}

/// Checks whether the pAttributes indicate a parameter is groupshared
bool IsParamAttributedAsGroupShared(clang::AttributeList *pAttributes);

/// Checks whether the pAttributes indicate a parameter is inout or out; if
/// inout, pIsIn will be set to true.
bool IsParamAttributedAsOut(clang::AttributeList *pAttributes, bool *pIsIn);
Expand Down Expand Up @@ -934,6 +937,19 @@ unsigned GetHLSLOutputPatchCount(QualType type) {
return argList[1].getAsIntegral().getLimitedValue();
}

bool IsParamAttributedAsGroupShared(clang::AttributeList *pAttributes) {
while (pAttributes != nullptr) {
switch (pAttributes->getKind()) {
case AttributeList::AT_HLSLGroupShared:
return true;
default:
break;
}
pAttributes = pAttributes->getNext();
}
return false;
}

bool IsParamAttributedAsOut(clang::AttributeList *pAttributes, bool *pIsIn) {
bool anyFound = false;
bool inFound = false;
Expand Down Expand Up @@ -967,6 +983,8 @@ bool IsParamAttributedAsOut(clang::AttributeList *pAttributes, bool *pIsIn) {

hlsl::ParameterModifier
ParamModFromAttributeList(clang::AttributeList *pAttributes) {
if (IsParamAttributedAsGroupShared(pAttributes))
return ParameterModifier(hlsl::ParameterModifier::Kind::Ref);
bool isIn, isOut;
isOut = IsParamAttributedAsOut(pAttributes, &isIn);
return ParameterModifier::FromInOut(isIn, isOut);
Expand Down
2 changes: 2 additions & 0 deletions tools/clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2033,6 +2033,8 @@ void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T,
Qualifiers Quals, SourceRange Range) {
QualType PointeeType = T->getPointeeType();
Out << (Quals.hasVolatile() ? 'B' : 'A');
if (PointeeType.getQualifiers().getAddressSpace() == 3)
Out << 'G';
manglePointerExtQualifiers(Quals, PointeeType);
mangleType(PointeeType, Range);
}
Expand Down
11 changes: 10 additions & 1 deletion tools/clang/lib/CodeGen/CGHLSLMS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1309,6 +1309,14 @@ unsigned CGMSHLSLRuntime::AddTypeAnnotation(QualType Ty,
const IncompleteArrayType *arrayTy =
CGM.getContext().getAsIncompleteArrayType(Ty);
arrayElementTy = arrayTy->getElementType();
} else if (paramTy->isConstantArrayType()) {
// hacky because unclear proper usage of paramTy vs Ty...
const ConstantArrayType *arrayTy =
CGM.getContext().getAsConstantArrayType(paramTy);
DXASSERT(arrayTy != nullptr, "Must be array type here");

arraySize = arrayTy->getSize().getLimitedValue();
arrayElementTy = arrayTy->getElementType();
} else {
DXASSERT(0, "Must array type here");
}
Expand Down Expand Up @@ -6232,7 +6240,8 @@ void CGMSHLSLRuntime::EmitHLSLOutParamConversionInit(
}
} else if (isAggregateType) {
// aggregate in-only - emit RValue, unless LValueToRValue cast
EmitRValueAgg = true;
if (Param->isModifierIn())
EmitRValueAgg = true;
if (const ImplicitCastExpr *cast = dyn_cast<ImplicitCastExpr>(Arg)) {
if (cast->getCastKind() == CastKind::CK_LValueToRValue) {
EmitRValueAgg = false;
Expand Down
6 changes: 6 additions & 0 deletions tools/clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4945,6 +4945,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
handleSimpleAttribute<NoDuplicateAttr>(S, D, Attr);
break;
case AttributeList::AT_NoInline:
if (S.LangOpts.HLSL) {
bool Handled = false;
hlsl::HandleDeclAttributeForHLSL(S, D, Attr, Handled);
if (Handled)
break;
}
handleSimpleAttribute<NoInlineAttr>(S, D, Attr);
break;
case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg.
Expand Down
37 changes: 36 additions & 1 deletion tools/clang/lib/Sema/SemaHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14474,6 +14474,27 @@ void Sema::DiagnoseHLSLDeclAttr(const Decl *D, const Attr *A) {
HLSLExternalSource *ExtSource = HLSLExternalSource::FromSema(this);
const bool IsGCAttr = isa<HLSLGloballyCoherentAttr>(A);
const bool IsRCAttr = isa<HLSLReorderCoherentAttr>(A);
const bool IsExportAttr = isa<HLSLExportAttr>(A);
const bool IsNoInlineAttr = isa<NoInlineAttr>(A);
if (IsExportAttr || IsNoInlineAttr) {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
for (ParmVarDecl *PVD : FD->parameters()) {
if (!PVD->hasAttrs())
continue;
for (Attr *A : PVD->getAttrs()) {
switch (A->getKind()) {
case clang::attr::HLSLGroupShared: { // todo improve this error msg
Diag(A->getLocation(), diag::err_hlsl_varmodifiersna)
<< "groupshared" << "export/noinline" << "parameter";
return;
break;
}
}
}
}
return;
}
}
if (IsGCAttr || IsRCAttr) {
const ValueDecl *TD = cast<ValueDecl>(D);
if (TD->getType()->isDependentType())
Expand Down Expand Up @@ -14655,6 +14676,8 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A,
VD->setType(
S.Context.getAddrSpaceQualType(VD->getType(), DXIL::kTGSMAddrSpace));
}
if (ParmVarDecl *VD = dyn_cast<ParmVarDecl>(D))
VD->setType(S.Context.getLValueReferenceType(VD->getType()));
break;
case AttributeList::AT_HLSLUniform:
declAttr = ::new (S.Context) HLSLUniformAttr(
Expand Down Expand Up @@ -14996,6 +15019,7 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A,
}

if (declAttr != nullptr) {
S.DiagnoseHLSLDeclAttr(D, declAttr);
DXASSERT_NOMSG(Handled);
D->addAttr(declAttr);

Expand Down Expand Up @@ -15749,7 +15773,14 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth,
break;
case AttributeList::AT_HLSLGroupShared:
isGroupShared = true;
if (!isGlobal) {
if (isParameter && getLangOpts().HLSLVersion < hlsl::LangStd::v202x)
Diag(pAttr->getLoc(), diag::warn_hlsl_groupshared_202x);
if (isParameter && (usageIn || usageOut)) {
Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
<< pAttr->getName() << "in/out/inout modifiers" << declarationType;
result = false;
}
if (!(isGlobal || isParameter)) {
Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna)
<< pAttr->getName() << declarationType << pAttr->getRange();
result = false;
Expand Down Expand Up @@ -15786,6 +15817,10 @@ bool Sema::DiagnoseHLSLDecl(Declarator &D, DeclContext *DC, Expr *BitWidth,
Diag(pAttr->getLoc(), diag::err_hlsl_usage_not_on_parameter)
<< pAttr->getName() << pAttr->getRange();
result = false;
} else if (isGroupShared) {
Diag(pAttr->getLoc(), diag::err_hlsl_varmodifiersna)
<< pAttr->getName() << "groupshared" << declarationType;
result = false;
}
if (!IsUsageAttributeCompatible(pAttr->getKind(), usageIn, usageOut)) {
Diag(pAttr->getLoc(), diag::err_hlsl_duplicate_parameter_usages)
Expand Down
20 changes: 20 additions & 0 deletions tools/clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4953,6 +4953,26 @@ InitCallParamConversions(Sema &S, const FunctionProtoType *Proto,
ImplicitConversionSequence &OutConversion) {
hlsl::ParameterModifier paramMods = Proto->getParamMods()[ArgIdx];
QualType ParamType = Proto->getParamType(ArgIdx);

// must be a Ref; don't allow any conversions
if (!(paramMods.isAnyIn() || paramMods.isAnyOut())) {
if (!S.getASTContext().hasSameUnqualifiedType(
ParamType.getNonReferenceType(), Arg->getType()) ||
Arg->getType().getQualifiers().getAddressSpace() !=
hlsl::DXIL::kTGSMAddrSpace) {
InConversion.setBad(BadConversionSequence::no_conversion, Arg->getType(),
ParamType);
InConversion.Bad.FromExpr = Arg; // hack for now
return;
}
}

if (S.getLangOpts().HLSLVersion >= hlsl::LangStd::v202x &&
paramMods.isAnyIn() && paramMods.isAnyOut() &&
Arg->getType().getQualifiers().getAddressSpace() ==
hlsl::DXIL::kTGSMAddrSpace)
S.Diag(Arg->getLocStart(), diag::warn_hlsl_groupshared_inout);

if (paramMods.isAnyIn()) {
InConversion =
TryCopyInitialization(S, Arg, ParamType, SuppressUserConversions,
Expand Down
16 changes: 16 additions & 0 deletions tools/clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: %dxc -E main -T cs_6_0 -HV 202x -fcgl %s | FileCheck %s

groupshared float4 SharedArr[64];

// CHECK-LABEL: define internal void @"\01?fn@@YAXAGAY0EA@$$CAV?$vector@M$03@@M@Z"([64 x <4 x float>] addrspace(3)* dereferenceable(1024) %Arr, float %F)
// CHECK: [[ArrIdx:%.*]] = getelementptr inbounds [64 x <4 x float>], [64 x <4 x float>] addrspace(3)* %Arr, i32 0, i32 5
// CHECK-NEXT: store <4 x float> {{.*}}, <4 x float> addrspace(3)* [[ArrIdx]], align 4
void fn(groupshared float4 Arr[64], float F) {
float4 tmp = F.xxxx;
Arr[5] = tmp;
}

[numthreads(4,1,1)]
void main() {
fn(SharedArr, 6.0);
}
37 changes: 37 additions & 0 deletions tools/clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// RUN: %dxc -E main -T cs_6_0 -HV 202x -fcgl %s | FileCheck %s

// Verify we are calling the correct overloads
void fn(groupshared float4 Arr[2]);
void fn(inout float4 Arr[2]);

void fn2(groupshared int4 Shared);
void fn2(int4 Local);

// CHECK-LABEL: define void @main()
[numthreads(4,1,1)]
void main() {
float4 Local[2] = {1.0.xxxx, 2.0.xxxx};
// CHECK-DAG: call void @"\01?fn@@YAXY01$$CAV?$vector@M$03@@@Z"([2 x <4 x float>]* %Local)
fn(Local);

// CHECK-DAG: call void @"\01?fn2@@YAXV?$vector@H$03@@@Z"(<4 x i32>
fn2(11.xxxx);
}

void fn(groupshared float4 Arr[2]) {
Arr[1] = 7.0.xxxx;
}

// CHECK-LABEL: define internal void @"\01?fn@@YAXY01$$CAV?$vector@M$03@@@Z"([2 x <4 x float>]* noalias %Arr)
void fn(inout float4 Arr[2]) {
Arr[1] = 5.0.xxxx;
}

void fn2(groupshared int4 Shared) {
Shared.x = 10;
}

// CHECK-DAG: define internal void @"\01?fn2@@YAXV?$vector@H$03@@@Z"(<4 x i32> %Local)
void fn2(int4 Local) {
int X = Local.y;
}
15 changes: 15 additions & 0 deletions tools/clang/test/CodeGenHLSL/groupsharedArgs/ScalarTest.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// RUN: %dxc -E main -T cs_6_2 -enable-16bit-types -HV 202x -fcgl %s | FileCheck %s

groupshared uint16_t SharedData;

// mangling changes added the first G
// CHECK-LABEL: @"\01?fn1@@YAXAGAG@Z"
// CHECK: store i16 5, i16 addrspace(3)* %Sh, align 4
void fn1(groupshared uint16_t Sh) {
Sh = 5;
}

[numthreads(4, 1, 1)]
void main(uint3 TID : SV_GroupThreadID) {
fn1(SharedData);
}
32 changes: 32 additions & 0 deletions tools/clang/test/CodeGenHLSL/groupsharedArgs/StructTest.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %dxc -E main -T cs_6_3 -HV 202x -fcgl %s | FileCheck %s

struct Shared {
int A;
float F;
double Arr[4];
};

groupshared Shared SharedData;

// CHECK-LABEL: @"\01?fn1@@YAXAGAUShared@@@Z"
// CHECK: [[D:%.*]] = alloca double, align 8
// CHECK: [[A:%.*]] = getelementptr inbounds %struct.Shared, %struct.Shared addrspace(3)* %Sh, i32 0, i32 0
// CHECK: store i32 10, i32 addrspace(3)* [[A]], align 4
// CHECK: [[F:%.*]] = getelementptr inbounds %struct.Shared, %struct.Shared addrspace(3)* %Sh, i32 0, i32 1
// CHECK: store float 0x40263851E0000000, float addrspace(3)* %F, align 4
// CHECK: store double 1.000000e+01, double* [[D]], align 8
// CHECK: [[Z:%.*]] = load double, double* [[D]], align 8
// CHECK: [[Arr:%.*]] = getelementptr inbounds %struct.Shared, %struct.Shared addrspace(3)* %Sh, i32 0, i32 2
// CHECK: [[ArrIdx:%.*]] = getelementptr inbounds [4 x double], [4 x double] addrspace(3)* [[Arr]], i32 0, i32 1
// CHECK: store double [[Z]], double addrspace(3)* [[ArrIdx]], align 4
void fn1(groupshared Shared Sh) {
Sh.A = 10;
Sh.F = 11.11;
double D = 10.0;
Sh.Arr[1] = D;
}

[numthreads(4, 1, 1)]
void main(uint3 TID : SV_GroupThreadID) {
fn1(SharedData);
}
32 changes: 32 additions & 0 deletions tools/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// RUN: %dxc -E main -T cs_6_3 -HV 202x -fcgl %s | FileCheck %s

template<typename T> struct Shared {
T A;
float F;
double Arr[4];
};

groupshared Shared<int> SharedData;

// CHECK-LABEL: @"\01?fn1@@YAXAGAU?$Shared@H@@@Z"
// CHECK: [[D:%.*]] = alloca double, align 8
// CHECK: [[A:%.*]] = getelementptr inbounds %"struct.Shared<int>", %"struct.Shared<int>" addrspace(3)* %Sh, i32 0, i32 0
// CHECK: store i32 10, i32 addrspace(3)* [[A]], align 4
// CHECK: [[F:%.*]] = getelementptr inbounds %"struct.Shared<int>", %"struct.Shared<int>" addrspace(3)* %Sh, i32 0, i32 1
// CHECK: store float 0x40263851E0000000, float addrspace(3)* %F, align 4
// CHECK: store double 1.000000e+01, double* [[D]], align 8
// CHECK: [[Z:%.*]] = load double, double* [[D]], align 8
// CHECK: [[Arr:%.*]] = getelementptr inbounds %"struct.Shared<int>", %"struct.Shared<int>" addrspace(3)* %Sh, i32 0, i32 2
// CHECK: [[ArrIdx:%.*]] = getelementptr inbounds [4 x double], [4 x double] addrspace(3)* [[Arr]], i32 0, i32 1
// CHECK: store double [[Z]], double addrspace(3)* [[ArrIdx]], align 4
void fn1(groupshared Shared<int> Sh) {
Sh.A = 10;
Sh.F = 11.11;
double D = 10.0;
Sh.Arr[1] = D;
}

[numthreads(4, 1, 1)]
void main(uint3 TID : SV_GroupThreadID) {
fn1(SharedData);
}
18 changes: 18 additions & 0 deletions tools/clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %dxc -E main -T cs_6_3 -HV 202x -fcgl %s | FileCheck %s

groupshared float4 SharedData;

// CHECK-LABEL: @"\01?fn1@@YAXAGAV?$vector@M$03@@@Z"
// CHECK: [[Tmp:%.*]] = alloca <1 x float>, align 4
// CHECK: store <1 x float> <float 5.000000e+00>, <1 x float>* [[Tmp]]
// CHECK: [[Z:%.*]] = load <1 x float>, <1 x float>* [[Tmp]]
// CHECK: [[Y:%.*]] = shufflevector <1 x float> [[Z]], <1 x float> undef, <4 x i32> zeroinitializer
// CHECK: store <4 x float> [[Y]], <4 x float> addrspace(3)* %Sh, align 4
void fn1(groupshared float4 Sh) {
Sh = 5.0.xxxx;
}

[numthreads(4, 1, 1)]
void main(uint3 TID : SV_GroupThreadID) {
fn1(SharedData);
}
13 changes: 13 additions & 0 deletions tools/clang/test/SemaHLSL/v202x/groupshared/ExplicitCast.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %dxc -T lib_6_3 -enable-16bit-types -HV 202x -verify %s

groupshared uint16_t SharedData;

void fn1(groupshared half Sh) {
// expected-note@-1{{candidate function not viable: 1st argument ('half') is in address space 0, but parameter must be in address space 3}}
Sh = 5;
}

void fn2() {
fn1((half)SharedData);
// expected-error@-1{{no matching function for call to 'fn1'}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// RUN: %dxc -T lib_6_3 -HV 202x -verify %s

export void fn1(groupshared uint Sh) {
// expected-error@-1{{groupshared and export/noinline cannot be used together for a parameter}}
Sh = 5;
}

[noinline] void fn2(groupshared uint Sh) {
// expected-error@-1{{groupshared and export/noinline cannot be used together for a parameter}}
Sh = 6;
}
Loading
Loading