diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp index e96a416d3d..863d993667 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.cpp @@ -1056,7 +1056,8 @@ SpirvInstruction *DeclResultIdMapper::getDeclEvalInfo(const ValueDecl *decl, SpirvFunctionParameter * DeclResultIdMapper::createFnParam(const ParmVarDecl *param, - uint32_t dbgArgNumber) { + uint32_t dbgArgNumber, + bool decorateIntrinsicAttrs) { const auto type = getTypeOrFnRetType(param); const auto loc = param->getLocation(); const auto range = param->getSourceRange(); @@ -1071,6 +1072,9 @@ DeclResultIdMapper::createFnParam(const ParmVarDecl *param, if (isConstantTextureBuffer(type)) fnParamInstr->setLayoutRule(spirvOptions.cBufferLayoutRule); + if (decorateIntrinsicAttrs && param->hasAttrs()) + decorateWithIntrinsicAttrs(param, fnParamInstr); + assert(astDecls[param].instr == nullptr); registerVariableForDecl(param, fnParamInstr); @@ -5021,18 +5025,17 @@ bool DeclResultIdMapper::tryToCreateConstantVar(const ValueDecl *decl) { } void DeclResultIdMapper::decorateWithIntrinsicAttrs( - const NamedDecl *decl, SpirvVariable *varInst, + const NamedDecl *decl, SpirvInstruction *targetInst, llvm::function_ref extraFunctionForDecoAttr) { if (!decl->hasAttrs()) return; - // TODO: Handle member field in a struct and function parameter. for (auto &attr : decl->getAttrs()) { if (auto decoAttr = dyn_cast(attr)) { spvBuilder.decorateWithLiterals( - varInst, decoAttr->getDecorate(), + targetInst, decoAttr->getDecorate(), {decoAttr->literals_begin(), decoAttr->literals_end()}, - varInst->getSourceLocation()); + targetInst->getSourceLocation()); extraFunctionForDecoAttr(decoAttr); continue; } @@ -5041,15 +5044,15 @@ void DeclResultIdMapper::decorateWithIntrinsicAttrs( for (Expr *arg : decoAttr->arguments()) { args.push_back(theEmitter.doExpr(arg)); } - spvBuilder.decorateWithIds(varInst, decoAttr->getDecorate(), args, - varInst->getSourceLocation()); + spvBuilder.decorateWithIds(targetInst, decoAttr->getDecorate(), args, + targetInst->getSourceLocation()); continue; } if (auto decoAttr = dyn_cast(attr)) { llvm::SmallVector args(decoAttr->arguments_begin(), decoAttr->arguments_end()); - spvBuilder.decorateWithStrings(varInst, decoAttr->getDecorate(), args, - varInst->getSourceLocation()); + spvBuilder.decorateWithStrings(targetInst, decoAttr->getDecorate(), args, + targetInst->getSourceLocation()); continue; } } diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.h b/tools/clang/lib/SPIRV/DeclResultIdMapper.h index 1464ef9570..17ea739fee 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.h +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.h @@ -271,7 +271,8 @@ class DeclResultIdMapper { /// parameter must have "1", not "0", which is what Clang generates for /// LLVM debug metadata. SpirvFunctionParameter *createFnParam(const ParmVarDecl *param, - uint32_t dbgArgNumber = 0); + uint32_t dbgArgNumber = 0, + bool decorateIntrinsicAttrs = true); /// \brief Creates the counter variable associated with the given param. /// This is meant to be used for forward-declared functions and this objects @@ -577,7 +578,7 @@ class DeclResultIdMapper { /// Decorate with spirv intrinsic attributes with lamda function variable /// check void decorateWithIntrinsicAttrs( - const NamedDecl *decl, SpirvVariable *varInst, + const NamedDecl *decl, SpirvInstruction *targetInst, llvm::function_ref extraFunctionForDecoAttr = [](VKDecorateExtAttr *) {}); diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index 765cd60bbf..ce070f55f8 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -1704,8 +1704,8 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) { for (uint32_t i = 0; i < decl->getNumParams(); ++i) { const ParmVarDecl *paramDecl = decl->getParamDecl(i); QualType paramType = paramDecl->getType(); - auto *param = - declIdMapper.createFnParam(paramDecl, i + 1 + isNonStaticMemberFn); + auto *param = declIdMapper.createFnParam( + paramDecl, i + 1 + isNonStaticMemberFn, !isEntry); if (isEntry) { handleNodePayloadArrayType(paramDecl, param); } diff --git a/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.function-parameter.hlsl b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.function-parameter.hlsl new file mode 100644 index 0000000000..fc31f4015d --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/inline-spirv/spv.intrinsicDecorate.function-parameter.hlsl @@ -0,0 +1,20 @@ +// RUN: %dxc -T ps_6_0 -E main -fcgl -Vd -spirv -fcgl %s -spirv | FileCheck %s + +void SimpleAdd([[vk::ext_decorate(/* spv::DecorationAliased */ 20)]] inout float a, + [[vk::ext_decorate(/* spv::DecorationAliased */ 20)]] inout float b) { + a += 1.0; + b += 2.0; +} + +// CHECK: OpDecorate %x Aliased +// CHECK: OpDecorate %a Aliased +// CHECK: OpDecorate %b Aliased +// CHECK: %SimpleAdd = OpFunction %void None {{%[a-zA-Z0-9_]+}} +// CHECK-NEXT: %a = OpFunctionParameter %_ptr_Function_float +// CHECK-NEXT: %b = OpFunctionParameter %_ptr_Function_float + +float4 main() : SV_Target { + [[vk::ext_decorate(/*spv::DecorationAliased*/20)]] float x = 43.0; + SimpleAdd(x, x); + return float4(x, x, x, x); +} \ No newline at end of file