diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -14,6 +14,7 @@ #include "CGCXXABI.h" #include "CGCleanup.h" #include "CGDebugInfo.h" +#include "CGHLSLRuntime.h" #include "CGOpenCLRuntime.h" #include "CGOpenMPRuntime.h" #include "CodeGenFunction.h" @@ -2588,6 +2589,10 @@ } } + // Emit HLSL specific initialization for parameters with attributes + if (getLangOpts().HLSL && D.hasAttrs()) + DoStore = DoStore && !CGM.getHLSLRuntime().emitParamAttrs(*this, D, lv); + // Store the initial value into the alloca. if (DoStore) EmitStoreOfScalar(ArgVal, lv, /* isInitialization */ true); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -26,9 +26,14 @@ class Type; class VarDecl; +namespace CodeGen { +class LValue; +} + namespace CodeGen { class CodeGenModule; +class CodeGenFunction; class CGHLSLRuntime { protected: @@ -42,6 +47,9 @@ void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV); + /// Returns true if an attribute was handled, false otherwise. + bool emitParamAttrs(CodeGenFunction &CGF, const VarDecl &D, LValue &LV); + void finishCodeGen(); }; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -13,8 +13,11 @@ //===----------------------------------------------------------------------===// #include "CGHLSLRuntime.h" +#include "CGValue.h" +#include "CodeGenFunction.h" #include "CodeGenModule.h" #include "clang/Basic/TargetOptions.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -86,3 +89,15 @@ Ctx, {ValueAsMetadata::get(GV), MDString::get(Ctx, QT.getAsString()), ConstantAsMetadata::get(B.getInt32(Counter))})); } + +bool CGHLSLRuntime::emitParamAttrs(CodeGenFunction &CGF, const VarDecl &D, + LValue &LV) { + if (D.hasAttr()) { + llvm::Function *DxGroupIndex = + CGM.getIntrinsic(Intrinsic::dx_flattened_thread_id_in_group); + CallInst *CI = CGF.Builder.CreateCall(FunctionCallee(DxGroupIndex)); + CGF.Builder.CreateStore(CI, LV.getAddress(CGF)); + return true; + } + return false; +} diff --git a/clang/test/CodeGenHLSL/semantics/GroupIndex-codegen.hlsl b/clang/test/CodeGenHLSL/semantics/GroupIndex-codegen.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/GroupIndex-codegen.hlsl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - %s + +[numthreads(1,1,1)] +void main(unsigned GI : SV_GroupIndex) { +} + +// CHECK: %GI.addr = alloca i32, align 4 +// CHECK-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group() +// CHECK-NEXT: store i32 %0, ptr %GI.addr, align 4