diff --git a/docs/ReleaseNotes.md b/docs/ReleaseNotes.md index 4fdb82f2ca..2352a31106 100644 --- a/docs/ReleaseNotes.md +++ b/docs/ReleaseNotes.md @@ -23,6 +23,7 @@ The included licenses apply to the following files: - Fixed regression: [#7508](https://github.com/microsoft/DirectXShaderCompiler/issues/7508) crash when calling `Load` with `status`. - Header file `dxcpix.h` was added to the release package. - Moved Linear Algebra (Cooperative Vector) DXIL Opcodes to experimental Shader Model 6.10 +- Added support for the groupshared attribute for parameters to Shader Model 6.10 ### Version 1.8.2505 diff --git a/lib/HLSL/HLLegalizeParameter.cpp b/lib/HLSL/HLLegalizeParameter.cpp index 141f163e15..51653070ea 100644 --- a/lib/HLSL/HLLegalizeParameter.cpp +++ b/lib/HLSL/HLLegalizeParameter.cpp @@ -256,7 +256,8 @@ bool HLLegalizeParameter::runOnModule(Module &M) { continue; for (Argument &Arg : F.args()) { - if (!Arg.getType()->isPointerTy()) + Type *PtrTy = dyn_cast(Arg.getType()); + if (!PtrTy || DXIL::kTGSMAddrSpace == PtrTy->getPointerAddressSpace()) continue; Type *EltTy = dxilutil::GetArrayEltTy(Arg.getType()); if (dxilutil::IsHLSLObjectType(EltTy) || diff --git a/tools/clang/include/clang/AST/Decl.h b/tools/clang/include/clang/AST/Decl.h index 985ad895ab..0d7ffe3808 100644 --- a/tools/clang/include/clang/AST/Decl.h +++ b/tools/clang/include/clang/AST/Decl.h @@ -813,6 +813,9 @@ class VarDecl : public DeclaratorDecl, public Redeclarable { /// Whether the parameter is copied out. unsigned IsModifierOut : 1; + /// Whether the parameter should be treated as a reference. + unsigned IsModifierRef : 1; + /// The number of parameters preceding this parameter in the /// function parameter scope in which it was declared. unsigned ParameterIndex : NumParameterIndexBits; @@ -1377,6 +1380,7 @@ class ParmVarDecl : public VarDecl { assert(ParmVarDeclBits.IsObjCMethodParam == false); setDefaultArg(DefArg); // HLSL Change Start + setModifierRef(ParamMod.isRef()); setModifierIn(ParamMod.isAnyIn()); setModifierOut(ParamMod.isAnyOut()); // change to reference type for out param @@ -1456,8 +1460,12 @@ class ParmVarDecl : public VarDecl { void setModifierIn(bool value) { ParmVarDeclBits.IsKNRPromoted = !value; } bool isModifierOut() const { return ParmVarDeclBits.IsModifierOut; } void setModifierOut(bool value) { ParmVarDeclBits.IsModifierOut = value; } + bool isModifierRef() const { return ParmVarDeclBits.IsModifierRef; } + void setModifierRef(bool value) { ParmVarDeclBits.IsModifierRef = value; } /// Synthesize a ParameterModifier value for this parameter. hlsl::ParameterModifier getParamModifiers() const { + if (isModifierRef()) + return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::Ref); if (isModifierIn() && !isModifierOut()) return hlsl::ParameterModifier(hlsl::ParameterModifier::Kind::In); if (isModifierIn() && isModifierOut()) diff --git a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index 34a2195cbc..47c545c32b 100644 --- a/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -1597,6 +1597,13 @@ def warn_hlsl_sometimes_uninit_out_param : Warning< "its declaration is reached|" "%3 is called}2">, InGroup; +def warn_hlsl_groupshared_202x: Warning< + "Support for groupshared parameter annotation not added until HLSL 202x">, + InGroup; +def warn_hlsl_groupshared_inout: Warning< + "Passing groupshared variable to a parameter annotated with inout. See " + "'groupshared' parameter annotation added in 202x.">, + InGroup; // HLSL Change End - Add warning for uninitialized out param def warn_maybe_uninit_var : Warning< "variable %0 may be uninitialized when " diff --git a/tools/clang/include/clang/Basic/Specifiers.h b/tools/clang/include/clang/Basic/Specifiers.h index 1e5a214ee9..dda6d49caf 100644 --- a/tools/clang/include/clang/Basic/Specifiers.h +++ b/tools/clang/include/clang/Basic/Specifiers.h @@ -295,6 +295,7 @@ namespace hlsl { unsigned getAsUnsigned() const { return (unsigned)m_Kind; } + bool isRef() const { return m_Kind == Kind::Ref; } bool isIn() const { return m_Kind == Kind::In; } bool isOut() const { return m_Kind == Kind::Out; } bool isInOut() const { return m_Kind == Kind::InOut; } diff --git a/tools/clang/lib/AST/HlslTypes.cpp b/tools/clang/lib/AST/HlslTypes.cpp index 00c18a81a9..43aa379512 100644 --- a/tools/clang/lib/AST/HlslTypes.cpp +++ b/tools/clang/lib/AST/HlslTypes.cpp @@ -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); @@ -934,6 +937,15 @@ unsigned GetHLSLOutputPatchCount(QualType type) { return argList[1].getAsIntegral().getLimitedValue(); } +bool IsParamAttributedAsGroupShared(clang::AttributeList *pAttributes) { + while (pAttributes != nullptr) { + if (pAttributes->getKind() == AttributeList::AT_HLSLGroupShared) + return true; + pAttributes = pAttributes->getNext(); + } + return false; +} + bool IsParamAttributedAsOut(clang::AttributeList *pAttributes, bool *pIsIn) { bool anyFound = false; bool inFound = false; @@ -967,6 +979,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); diff --git a/tools/clang/lib/AST/MicrosoftMangle.cpp b/tools/clang/lib/AST/MicrosoftMangle.cpp index ae9f1cd7f8..35cbb7cd46 100644 --- a/tools/clang/lib/AST/MicrosoftMangle.cpp +++ b/tools/clang/lib/AST/MicrosoftMangle.cpp @@ -11,6 +11,8 @@ // //===----------------------------------------------------------------------===// +#include "dxc/DXIL/DxilConstants.h" + #include "clang/AST/Mangle.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" @@ -2033,6 +2035,9 @@ void MicrosoftCXXNameMangler::mangleType(const LValueReferenceType *T, Qualifiers Quals, SourceRange Range) { QualType PointeeType = T->getPointeeType(); Out << (Quals.hasVolatile() ? 'B' : 'A'); + if (PointeeType.getQualifiers().getAddressSpace() == + hlsl::DXIL::kTGSMAddrSpace) + Out << 'G'; manglePointerExtQualifiers(Quals, PointeeType); mangleType(PointeeType, Range); } diff --git a/tools/clang/lib/CodeGen/CGHLSLMS.cpp b/tools/clang/lib/CodeGen/CGHLSLMS.cpp index 6c68381a20..200f62f68d 100644 --- a/tools/clang/lib/CodeGen/CGHLSLMS.cpp +++ b/tools/clang/lib/CodeGen/CGHLSLMS.cpp @@ -1245,6 +1245,9 @@ unsigned CGMSHLSLRuntime::AddTypeAnnotation(QualType Ty, if (const ReferenceType *RefType = dyn_cast(paramTy)) paramTy = RefType->getPointeeType(); + if (const ReferenceType *RefType = dyn_cast(Ty)) + Ty = RefType->getPointeeType(); + // Get size. llvm::Type *Type = CGM.getTypes().ConvertType(paramTy); unsigned size = dataLayout.getTypeAllocSize(Type); @@ -6232,7 +6235,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(Arg)) { if (cast->getCastKind() == CastKind::CK_LValueToRValue) { EmitRValueAgg = false; diff --git a/tools/clang/lib/Sema/SemaDeclAttr.cpp b/tools/clang/lib/Sema/SemaDeclAttr.cpp index 085874a0ed..8a45e56c2b 100644 --- a/tools/clang/lib/Sema/SemaDeclAttr.cpp +++ b/tools/clang/lib/Sema/SemaDeclAttr.cpp @@ -4945,6 +4945,12 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, handleSimpleAttribute(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(S, D, Attr); break; case AttributeList::AT_NoInstrumentFunction: // Interacts with -pg. diff --git a/tools/clang/lib/Sema/SemaHLSL.cpp b/tools/clang/lib/Sema/SemaHLSL.cpp index e9c8c90a2d..46ab3a5178 100644 --- a/tools/clang/lib/Sema/SemaHLSL.cpp +++ b/tools/clang/lib/Sema/SemaHLSL.cpp @@ -14474,6 +14474,21 @@ void Sema::DiagnoseHLSLDeclAttr(const Decl *D, const Attr *A) { HLSLExternalSource *ExtSource = HLSLExternalSource::FromSema(this); const bool IsGCAttr = isa(A); const bool IsRCAttr = isa(A); + const bool IsExportAttr = isa(A); + const bool IsNoInlineAttr = isa(A); + if (IsExportAttr || IsNoInlineAttr) { + if (const FunctionDecl *FD = dyn_cast(D)) { + for (ParmVarDecl *PVD : FD->parameters()) { + if (PVD->hasAttr()) { + Diag(A->getLocation(), diag::err_hlsl_varmodifiersna) + << "groupshared" + << "export/noinline" + << "parameter"; + return; + } + } + } + } if (IsGCAttr || IsRCAttr) { const ValueDecl *TD = cast(D); if (TD->getType()->isDependentType()) @@ -14655,6 +14670,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(D)) + VD->setType(S.Context.getLValueReferenceType(VD->getType())); break; case AttributeList::AT_HLSLUniform: declAttr = ::new (S.Context) HLSLUniformAttr( @@ -14996,6 +15013,7 @@ void hlsl::HandleDeclAttributeForHLSL(Sema &S, Decl *D, const AttributeList &A, } if (declAttr != nullptr) { + S.DiagnoseHLSLDeclAttr(D, declAttr); DXASSERT_NOMSG(Handled); D->addAttr(declAttr); @@ -15749,7 +15767,17 @@ 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) + << (usageIn && usageOut ? "'inout'" + : usageIn ? "'in'" + : "'out'") + << pAttr->getName() << declarationType; + result = false; + } + if (!(isGlobal || isParameter)) { Diag(pAttr->getLoc(), diag::err_hlsl_varmodifierna) << pAttr->getName() << declarationType << pAttr->getRange(); result = false; @@ -15786,6 +15814,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) diff --git a/tools/clang/lib/Sema/SemaOverload.cpp b/tools/clang/lib/Sema/SemaOverload.cpp index 274b66646b..6198282ff0 100644 --- a/tools/clang/lib/Sema/SemaOverload.cpp +++ b/tools/clang/lib/Sema/SemaOverload.cpp @@ -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.getNonReferenceType()); + InConversion.Bad.FromExpr = Arg; + 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, diff --git a/tools/clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl b/tools/clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl new file mode 100644 index 0000000000..f4bfd02570 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/groupsharedArgs/ArrTest.hlsl @@ -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); +} diff --git a/tools/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl b/tools/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl new file mode 100644 index 0000000000..913a364d63 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/groupsharedArgs/MatrixTest.hlsl @@ -0,0 +1,18 @@ +// RUN: %dxc -E main -T cs_6_3 -HV 202x -fcgl %s | FileCheck %s + +groupshared float4x4 SharedData; + +// CHECK-LABEL: @"\01?fn1@@YAXAGAV?$matrix@M$03$03@@@Z" +// CHECK: [[M1:%.*]] = addrspacecast %class.matrix.float.4.4 addrspace(3)* %Sh to %class.matrix.float.4.4* +// CHECK: [[A:%.*]] = call <4 x float>* @"dx.hl.subscript.colMajor[].rn.<4 x float>* (i32, %class.matrix.float.4.4*, i32, i32, i32, i32)"(i32 1, %class.matrix.float.4.4* [[M1]], i32 0, i32 4, i32 8, i32 12) +// CHECK: [[B:%.*]] = getelementptr <4 x float>, <4 x float>* [[A]], i32 0, i32 1 +// CHECK: store float 5.000000e+00, float* [[B]] +// CHECK: ret void +void fn1(groupshared float4x4 Sh) { + Sh[0][1] = 5.0; +} + +[numthreads(4,1,1)] +void main(uint3 TID : SV_GroupThreadID) { + fn1(SharedData); +} diff --git a/tools/clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl b/tools/clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl new file mode 100644 index 0000000000..61a04770c6 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/groupsharedArgs/Overloads.hlsl @@ -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: call void @"\01?fn@@YAXY01$$CAV?$vector@M$03@@@Z"([2 x <4 x float>]* %Local) + fn(Local); + +// CHECK: 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-LABEL: define internal void @"\01?fn2@@YAXV?$vector@H$03@@@Z"(<4 x i32> %Local) +void fn2(int4 Local) { + int X = Local.y; +} diff --git a/tools/clang/test/CodeGenHLSL/groupsharedArgs/ScalarTest.hlsl b/tools/clang/test/CodeGenHLSL/groupsharedArgs/ScalarTest.hlsl new file mode 100644 index 0000000000..74181653ff --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/groupsharedArgs/ScalarTest.hlsl @@ -0,0 +1,16 @@ +// RUN: %dxc -E main -T cs_6_2 -enable-16bit-types -HV 202x -fcgl %s | FileCheck %s + +groupshared uint16_t SharedData; + +// Make sure the mangling changes for groupshared parameter annotation is reflected in the function signature (the first G) +// The mangled function signature for void fn(uint16_t Sh) should be @"\01?fn1@@YAXAAG@Z" (without the extra 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); +} diff --git a/tools/clang/test/CodeGenHLSL/groupsharedArgs/StructTest.hlsl b/tools/clang/test/CodeGenHLSL/groupsharedArgs/StructTest.hlsl new file mode 100644 index 0000000000..d5ec94bed6 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/groupsharedArgs/StructTest.hlsl @@ -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); +} diff --git a/tools/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl b/tools/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl new file mode 100644 index 0000000000..48a615a196 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/groupsharedArgs/TemplateTest.hlsl @@ -0,0 +1,32 @@ +// RUN: %dxc -E main -T cs_6_3 -HV 202x -fcgl %s | FileCheck %s + +template struct Shared { + T A; + float F; + double Arr[4]; +}; + +groupshared Shared SharedData; + +// CHECK-LABEL: @"\01?fn1@@YAXAGAU?$Shared@H@@@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); +} diff --git a/tools/clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl b/tools/clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl new file mode 100644 index 0000000000..d34d4aa421 --- /dev/null +++ b/tools/clang/test/CodeGenHLSL/groupsharedArgs/VectorTest.hlsl @@ -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> , <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); +} diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/ExplicitCast.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/ExplicitCast.hlsl new file mode 100644 index 0000000000..55652e1866 --- /dev/null +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/ExplicitCast.hlsl @@ -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'}} +} diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/ExportNoInlineTest.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/ExportNoInlineTest.hlsl new file mode 100644 index 0000000000..56f8042491 --- /dev/null +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/ExportNoInlineTest.hlsl @@ -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; +} diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/InOut.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/InOut.hlsl new file mode 100644 index 0000000000..3596b2f03f --- /dev/null +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/InOut.hlsl @@ -0,0 +1,25 @@ +// RUN: %dxc -T lib_6_3 -HV 202x -verify %s + +groupshared uint SharedData; + +void fn1(inout uint Sh) { + Sh = 5; +} + +void fn2(inout groupshared uint Sh); +// expected-error@-1{{'inout' and 'groupshared' cannot be used together for a parameter}} +void fn3(in groupshared uint Sh); +// expected-error@-1{{'in' and 'groupshared' cannot be used together for a parameter}} +void fn4(out groupshared uint Sh); +// expected-error@-1{{'out' and 'groupshared' cannot be used together for a parameter}} +void fn5(groupshared inout uint Sh); +// expected-error@-1{{'inout' and 'groupshared' cannot be used together for a parameter}} +void fn6(groupshared in uint Sh); +// expected-error@-1{{'in' and 'groupshared' cannot be used together for a parameter}} +void fn7(groupshared out uint Sh); +// expected-error@-1{{'out' and 'groupshared' cannot be used together for a parameter}} + +void fn8() { + fn1(SharedData); +// expected-warning@-1{{Passing groupshared variable to a parameter annotated with inout. See 'groupshared' parameter annotation added in 202x}} +} diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/NotGroupSharedTest.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/NotGroupSharedTest.hlsl new file mode 100644 index 0000000000..d6e8b4d4c3 --- /dev/null +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/NotGroupSharedTest.hlsl @@ -0,0 +1,13 @@ +// RUN: %dxc -T cs_6_3 -enable-16bit-types -HV 202x -verify %s + +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; +} + +[numthreads(4, 1, 1)] +void main(uint3 TID : SV_GroupThreadID) { + half tmp = 1.0; + fn1(tmp); + // expected-error@-1{{no matching function for call to 'fn1'}} +} diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/Pre202xWarning.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/Pre202xWarning.hlsl new file mode 100644 index 0000000000..1382be09a5 --- /dev/null +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/Pre202xWarning.hlsl @@ -0,0 +1,12 @@ +// RUN: %dxc -T lib_6_3 -HV 2021 -verify %s + +groupshared uint SharedData; + +void fn1(groupshared uint Sh) { +// expected-warning@-1{{Support for groupshared parameter annotation not added until HLSL 202x}} + Sh = 5; +} + +void fn2() { + fn1(SharedData); +} diff --git a/tools/clang/test/SemaHLSL/v202x/groupshared/ScalarTest.hlsl b/tools/clang/test/SemaHLSL/v202x/groupshared/ScalarTest.hlsl new file mode 100644 index 0000000000..58f1804a22 --- /dev/null +++ b/tools/clang/test/SemaHLSL/v202x/groupshared/ScalarTest.hlsl @@ -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: no known conversion from '__attribute__((address_space(3))) uint16_t' to '__attribute__((address_space(3))) half' for 1st argument}} + Sh = 5; +} + +void fn2() { + fn1(SharedData); + // expected-error@-1{{no matching function for call to 'fn1'}} +} diff --git a/tools/clang/test/SemaHLSL/varmods-syntax.hlsl b/tools/clang/test/SemaHLSL/varmods-syntax.hlsl index 8bb5bb2fc5..17fa7cd810 100644 --- a/tools/clang/test/SemaHLSL/varmods-syntax.hlsl +++ b/tools/clang/test/SemaHLSL/varmods-syntax.hlsl @@ -1,4 +1,4 @@ -// RUN: %dxc -Tlib_6_3 -verify %s +// RUN: %dxc -Tlib_6_3 -HV 202x -verify %s // The following is meant to be processed by the CodeTags extension in the "VS For Everything" Visual Studio extension: /* @@ -497,33 +497,33 @@ struct s_inout { // Parameters // modify(lines, gen_code('float4 foo_%(id)s(%(mods)s float4 val) { return val; }', storage_combos)) // GENERATED_CODE:BEGIN -float4 foo_gro_ext(groupshared extern float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_ext': function must return a value}} */ +float4 foo_gro_ext(groupshared extern float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_ext': function must return a value}} */ float4 foo_ext_sta(extern static float4 val) { return val; } /* expected-error {{cannot combine with previous 'extern' declaration specifier}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'extern'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_ext_sta': function must return a value}} */ float4 foo_sta_uni(static uniform float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'static'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_sta_uni': function must return a value}} */ -float4 foo_gro(groupshared float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro': function must return a value}} */ -float4 foo_gro_pre(groupshared precise float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre': function must return a value}} */ -float4 foo_gro_pre_sta(groupshared precise static float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_sta': function must return a value}} */ -float4 foo_gro_pre_sta_vol(groupshared precise static volatile float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_sta_vol': function must return a value}} */ -float4 foo_gro_pre_sta_vol_con(groupshared precise static volatile const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_sta_vol_con': function must return a value}} */ -float4 foo_gro_pre_sta_con(groupshared precise static const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_sta_con': function must return a value}} */ -float4 foo_gro_pre_uni(groupshared precise uniform float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_uni': function must return a value}} */ -float4 foo_gro_pre_uni_vol(groupshared precise uniform volatile float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_uni_vol': function must return a value}} */ -float4 foo_gro_pre_uni_vol_con(groupshared precise uniform volatile const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_uni_vol_con': function must return a value}} */ -float4 foo_gro_pre_uni_con(groupshared precise uniform const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_uni_con': function must return a value}} */ -float4 foo_gro_pre_vol(groupshared precise volatile float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_vol': function must return a value}} */ -float4 foo_gro_pre_vol_con(groupshared precise volatile const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_vol_con': function must return a value}} */ -float4 foo_gro_pre_con(groupshared precise const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_con': function must return a value}} */ -float4 foo_gro_sta(groupshared static float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_sta': function must return a value}} */ -float4 foo_gro_sta_vol(groupshared static volatile float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_sta_vol': function must return a value}} */ -float4 foo_gro_sta_vol_con(groupshared static volatile const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_sta_vol_con': function must return a value}} */ -float4 foo_gro_sta_con(groupshared static const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_sta_con': function must return a value}} */ -float4 foo_gro_uni(groupshared uniform float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_uni': function must return a value}} */ -float4 foo_gro_uni_vol(groupshared uniform volatile float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_uni_vol': function must return a value}} */ -float4 foo_gro_uni_vol_con(groupshared uniform volatile const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_uni_vol_con': function must return a value}} */ -float4 foo_gro_uni_con(groupshared uniform const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_uni_con': function must return a value}} */ -float4 foo_gro_vol(groupshared volatile float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_vol': function must return a value}} */ -float4 foo_gro_vol_con(groupshared volatile const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_vol_con': function must return a value}} */ -float4 foo_gro_con(groupshared const float4 val) { return val; } /* expected-error {{'groupshared' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_con': function must return a value}} */ +float4 foo_gro(groupshared float4 val) { return val; } /* fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro': function must return a value}} */ +float4 foo_gro_pre(groupshared precise float4 val) { return val; } /* fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre': function must return a value}} */ +float4 foo_gro_pre_sta(groupshared precise static float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_sta': function must return a value}} */ +float4 foo_gro_pre_sta_vol(groupshared precise static volatile float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_sta_vol': function must return a value}} */ +float4 foo_gro_pre_sta_vol_con(groupshared precise static volatile const float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_sta_vol_con': function must return a value}} */ +float4 foo_gro_pre_sta_con(groupshared precise static const float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_sta_con': function must return a value}} */ +float4 foo_gro_pre_uni(groupshared precise uniform float4 val) { return val; } /* fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_uni': function must return a value}} */ +float4 foo_gro_pre_uni_vol(groupshared precise uniform volatile float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_uni_vol': function must return a value}} */ +float4 foo_gro_pre_uni_vol_con(groupshared precise uniform volatile const float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_uni_vol_con': function must return a value}} */ +float4 foo_gro_pre_uni_con(groupshared precise uniform const float4 val) { return val; } /* fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_uni_con': function must return a value}} */ +float4 foo_gro_pre_vol(groupshared precise volatile float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_vol': function must return a value}} */ +float4 foo_gro_pre_vol_con(groupshared precise volatile const float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_vol_con': function must return a value}} */ +float4 foo_gro_pre_con(groupshared precise const float4 val) { return val; } /* fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_pre_con': function must return a value}} */ +float4 foo_gro_sta(groupshared static float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_sta': function must return a value}} */ +float4 foo_gro_sta_vol(groupshared static volatile float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_sta_vol': function must return a value}} */ +float4 foo_gro_sta_vol_con(groupshared static volatile const float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_sta_vol_con': function must return a value}} */ +float4 foo_gro_sta_con(groupshared static const float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_sta_con': function must return a value}} */ +float4 foo_gro_uni(groupshared uniform float4 val) { return val; } /* fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_uni': function must return a value}} */ +float4 foo_gro_uni_vol(groupshared uniform volatile float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_uni_vol': function must return a value}} */ +float4 foo_gro_uni_vol_con(groupshared uniform volatile const float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_uni_vol_con': function must return a value}} */ +float4 foo_gro_uni_con(groupshared uniform const float4 val) { return val; } /* fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_uni_con': function must return a value}} */ +float4 foo_gro_vol(groupshared volatile float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_vol': function must return a value}} */ +float4 foo_gro_vol_con(groupshared volatile const float4 val) { return val; } /* expected-error {{'volatile' is not a valid modifier for a parameter}} fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_vol_con': function must return a value}} */ +float4 foo_gro_con(groupshared const float4 val) { return val; } /* fxc-error {{X3000: syntax error: unexpected token 'groupshared'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_gro_con': function must return a value}} */ float4 foo_ext(extern float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'extern'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_ext': function must return a value}} */ float4 foo_ext_pre(extern precise float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'extern'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_ext_pre': function must return a value}} */ float4 foo_ext_pre_uni(extern precise uniform float4 val) { return val; } /* expected-error {{invalid storage class specifier in function declarator}} fxc-error {{X3000: syntax error: unexpected token 'extern'}} fxc-error {{X3004: undeclared identifier 'val'}} fxc-error {{X3080: 'foo_ext_pre_uni': function must return a value}} */