Skip to content

Commit 891392e

Browse files
[SPIRV] Emit DebugFunction/Definition for both wrapper and real functions (microsoft#6966)
microsoft#6758 unfortunately caused a regression for shaders compiled without -fcgl. This PR extends the original fix and corrects the regression. We now emit DebugFunction and DebugFunctionDefinition pairs for both the wrapper and the main functions, and a DebugEntrypoint that points at the wrapper function. This survives inlining.
1 parent 72b353a commit 891392e

8 files changed

+160
-90
lines changed

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 96 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,48 +1442,34 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
14421442
// This will allow the entry-point name to be something like
14431443
// myNamespace::myEntrypointFunc.
14441444
std::string funcName = getFnName(decl);
1445-
std::string debugFuncName = funcName;
1446-
1445+
std::string srcFuncName = "src." + funcName;
14471446
SpirvFunction *func = declIdMapper.getOrRegisterFn(decl);
1447+
SpirvFunction *srcFunc = nullptr;
14481448

14491449
auto loc = decl->getLocStart();
14501450
auto range = decl->getSourceRange();
14511451
RichDebugInfo *info = nullptr;
14521452
SpirvDebugFunction *debugFunction = nullptr;
1453+
SpirvDebugFunction *srcDebugFunction = nullptr;
14531454
SpirvDebugInstruction *outer_scope = spvContext.getCurrentLexicalScope();
1454-
const auto &sm = astContext.getSourceManager();
1455-
if (spirvOptions.debugInfoRich && decl->hasBody()) {
1456-
const uint32_t line = sm.getPresumedLineNumber(loc);
1457-
const uint32_t column = sm.getPresumedColumnNumber(loc);
1458-
info = getOrCreateRichDebugInfo(loc);
1459-
1460-
auto *source = info->source;
1461-
// Note that info->scopeStack.back() is a lexical scope of the function
1462-
// caller.
1463-
auto *parentScope = info->compilationUnit;
1464-
// TODO: figure out the proper flag based on the function decl.
1465-
// using FlagIsPublic for now.
1466-
uint32_t flags = 3u;
1467-
// The line number in the source program at which the function scope begins.
1468-
auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart());
1469-
debugFunction = spvBuilder.createDebugFunction(decl, debugFuncName, source,
1470-
line, column, parentScope,
1471-
"", flags, scopeLine, func);
1472-
func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction));
1473-
1474-
spvContext.pushDebugLexicalScope(info, debugFunction);
1475-
}
14761455

14771456
bool isEntry = false;
14781457
const auto iter = functionInfoMap.find(decl);
14791458
if (iter != functionInfoMap.end()) {
14801459
const auto &entryInfo = iter->second;
14811460
if (entryInfo->isEntryFunction) {
14821461
isEntry = true;
1483-
funcName = "src." + funcName;
14841462
// Create wrapper for the entry function
1485-
if (!emitEntryFunctionWrapper(decl, func))
1463+
srcFunc = func;
1464+
1465+
func = emitEntryFunctionWrapper(decl, &info, &debugFunction, srcFunc);
1466+
if (func == nullptr)
14861467
return;
1468+
if (spirvOptions.debugInfoRich && decl->hasBody()) {
1469+
// use the HLSL name the debug user will expect to see
1470+
srcDebugFunction = emitDebugFunction(decl, srcFunc, &info, funcName);
1471+
}
1472+
14871473
// Generate DebugEntryPoint if function definition
14881474
if (spirvOptions.debugInfoVulkan && debugFunction) {
14891475
auto *cu = dyn_cast<SpirvDebugCompilationUnit>(outer_scope);
@@ -1492,15 +1478,30 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
14921478
clang::getGitCommitHash(),
14931479
spirvOptions.clOptions);
14941480
}
1481+
} else {
1482+
if (spirvOptions.debugInfoRich && decl->hasBody()) {
1483+
debugFunction = emitDebugFunction(decl, func, &info, funcName);
1484+
}
14951485
}
14961486
}
14971487

1488+
if (spirvOptions.debugInfoRich) {
1489+
spvContext.pushDebugLexicalScope(info, debugFunction);
1490+
}
1491+
14981492
const QualType retType =
14991493
declIdMapper.getTypeAndCreateCounterForPotentialAliasVar(decl);
15001494

1501-
spvBuilder.beginFunction(retType, decl->getLocStart(), funcName,
1502-
decl->hasAttr<HLSLPreciseAttr>(),
1503-
decl->hasAttr<NoInlineAttr>(), func);
1495+
if (srcFunc) {
1496+
spvBuilder.beginFunction(retType, decl->getLocStart(), srcFuncName,
1497+
decl->hasAttr<HLSLPreciseAttr>(),
1498+
decl->hasAttr<NoInlineAttr>(), srcFunc);
1499+
1500+
} else {
1501+
spvBuilder.beginFunction(retType, decl->getLocStart(), funcName,
1502+
decl->hasAttr<HLSLPreciseAttr>(),
1503+
decl->hasAttr<NoInlineAttr>(), func);
1504+
}
15041505

15051506
bool isNonStaticMemberFn = false;
15061507
if (const auto *memberFn = dyn_cast<CXXMethodDecl>(decl)) {
@@ -1551,7 +1552,9 @@ void SpirvEmitter::doFunctionDecl(const FunctionDecl *decl) {
15511552

15521553
// Add DebugFunctionDefinition if we are emitting
15531554
// NonSemantic.Shader.DebugInfo.100 debug info
1554-
if (spirvOptions.debugInfoVulkan && debugFunction)
1555+
if (spirvOptions.debugInfoVulkan && srcDebugFunction)
1556+
spvBuilder.createDebugFunctionDef(srcDebugFunction, srcFunc);
1557+
else if (spirvOptions.debugInfoVulkan && debugFunction)
15551558
spvBuilder.createDebugFunctionDef(debugFunction, func);
15561559

15571560
// Process all statments in the body.
@@ -13331,11 +13334,17 @@ bool SpirvEmitter::processTessellationShaderAttributes(
1333113334
}
1333213335

1333313336
bool SpirvEmitter::emitEntryFunctionWrapperForRayTracing(
13334-
const FunctionDecl *decl, SpirvFunction *entryFuncInstr) {
13337+
const FunctionDecl *decl, SpirvDebugFunction *debugFunction,
13338+
SpirvFunction *entryFuncInstr) {
1333513339
// The entry basic block.
1333613340
auto *entryLabel = spvBuilder.createBasicBlock();
1333713341
spvBuilder.setInsertPoint(entryLabel);
1333813342

13343+
// Add DebugFunctionDefinition if we are emitting
13344+
// NonSemantic.Shader.DebugInfo.100 debug info.
13345+
if (spirvOptions.debugInfoVulkan && debugFunction)
13346+
spvBuilder.createDebugFunctionDef(debugFunction, entryFunction);
13347+
1333913348
// Initialize all global variables at the beginning of the wrapper
1334013349
for (const VarDecl *varDecl : toInitGloalVars) {
1334113350
const auto varInfo =
@@ -13598,8 +13607,36 @@ bool SpirvEmitter::processMeshOrAmplificationShaderAttributes(
1359813607
return true;
1359913608
}
1360013609

13601-
bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
13602-
SpirvFunction *entryFuncInstr) {
13610+
SpirvDebugFunction *SpirvEmitter::emitDebugFunction(const FunctionDecl *decl,
13611+
SpirvFunction *func,
13612+
RichDebugInfo **info,
13613+
std::string name) {
13614+
auto loc = decl->getLocStart();
13615+
const auto &sm = astContext.getSourceManager();
13616+
const uint32_t line = sm.getPresumedLineNumber(loc);
13617+
const uint32_t column = sm.getPresumedColumnNumber(loc);
13618+
*info = getOrCreateRichDebugInfo(loc);
13619+
13620+
SpirvDebugSource *source = (*info)->source;
13621+
// Note that info->scopeStack.back() is a lexical scope of the function
13622+
// caller.
13623+
SpirvDebugInstruction *parentScope = (*info)->compilationUnit;
13624+
// TODO: figure out the proper flag based on the function decl.
13625+
// using FlagIsPublic for now.
13626+
uint32_t flags = 3u;
13627+
// The line number in the source program at which the function scope begins.
13628+
auto scopeLine = sm.getPresumedLineNumber(decl->getBody()->getLocStart());
13629+
SpirvDebugFunction *debugFunction =
13630+
spvBuilder.createDebugFunction(decl, name, source, line, column,
13631+
parentScope, "", flags, scopeLine, func);
13632+
func->setDebugScope(new (spvContext) SpirvDebugScope(debugFunction));
13633+
13634+
return debugFunction;
13635+
}
13636+
13637+
SpirvFunction *SpirvEmitter::emitEntryFunctionWrapper(
13638+
const FunctionDecl *decl, RichDebugInfo **info,
13639+
SpirvDebugFunction **debugFunction, SpirvFunction *entryFuncInstr) {
1360313640
// HS specific attributes
1360413641
uint32_t numOutputControlPoints = 0;
1360513642
SpirvInstruction *outputControlPointIdVal =
@@ -13620,6 +13657,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1362013657
entryFunction = spvBuilder.beginFunction(
1362113658
astContext.VoidTy, decl->getLocStart(), decl->getName());
1362213659

13660+
if (spirvOptions.debugInfoRich && decl->hasBody()) {
13661+
*debugFunction = emitDebugFunction(decl, entryFunction, info, "wrapper");
13662+
}
13663+
1362313664
// Specify that entryFunction is an entry function wrapper.
1362413665
entryFunction->setEntryFunctionWrapper();
1362513666

@@ -13634,7 +13675,10 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1363413675
entryInfo->entryFunction = entryFunction;
1363513676

1363613677
if (spvContext.isRay()) {
13637-
return emitEntryFunctionWrapperForRayTracing(decl, entryFuncInstr);
13678+
return emitEntryFunctionWrapperForRayTracing(decl, *debugFunction,
13679+
entryFuncInstr)
13680+
? entryFunction
13681+
: nullptr;
1363813682
}
1363913683
// Handle attributes specific to each shader stage
1364013684
if (spvContext.isPS()) {
@@ -13643,7 +13687,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1364313687
processComputeShaderAttributes(decl);
1364413688
} else if (spvContext.isHS()) {
1364513689
if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))
13646-
return false;
13690+
return nullptr;
1364713691

1364813692
// The input array size for HS is specified in the InputPatch parameter.
1364913693
for (const auto *param : decl->params())
@@ -13655,7 +13699,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1365513699
outputArraySize = numOutputControlPoints;
1365613700
} else if (spvContext.isDS()) {
1365713701
if (!processTessellationShaderAttributes(decl, &numOutputControlPoints))
13658-
return false;
13702+
return nullptr;
1365913703

1366013704
// The input array size for HS is specified in the OutputPatch parameter.
1366113705
for (const auto *param : decl->params())
@@ -13666,11 +13710,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1366613710
// The per-vertex output of DS is not an array.
1366713711
} else if (spvContext.isGS()) {
1366813712
if (!processGeometryShaderAttributes(decl, &inputArraySize))
13669-
return false;
13713+
return nullptr;
1367013714
// The per-vertex output of GS is not an array.
1367113715
} else if (spvContext.isMS() || spvContext.isAS()) {
1367213716
if (!processMeshOrAmplificationShaderAttributes(decl, &outputArraySize))
13673-
return false;
13717+
return nullptr;
1367413718
}
1367513719

1367613720
// Go through all parameters and record the declaration of SV_ClipDistance
@@ -13686,14 +13730,14 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1368613730
for (const auto *param : decl->params()) {
1368713731
if (canActAsInParmVar(param))
1368813732
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, true))
13689-
return false;
13733+
return nullptr;
1369013734
if (canActAsOutParmVar(param))
1369113735
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(param, false))
13692-
return false;
13736+
return nullptr;
1369313737
}
1369413738
// Also consider the SV_ClipDistance/SV_CullDistance in the return type
1369513739
if (!declIdMapper.glPerVertex.recordGlPerVertexDeclFacts(decl, false))
13696-
return false;
13740+
return nullptr;
1369713741

1369813742
// Calculate the total size of the ClipDistance/CullDistance array and the
1369913743
// offset of SV_ClipDistance/SV_CullDistance variables within the array.
@@ -13715,6 +13759,11 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1371513759
// after the basic block is created and insert point is set.
1371613760
processInlineSpirvAttributes(decl);
1371713761

13762+
// Add DebugFunctionDefinition if we are emitting
13763+
// NonSemantic.Shader.DebugInfo.100 debug info.
13764+
if (spirvOptions.debugInfoVulkan && *debugFunction)
13765+
spvBuilder.createDebugFunctionDef(*debugFunction, entryFunction);
13766+
1371813767
// Initialize all global variables at the beginning of the wrapper
1371913768
for (const VarDecl *varDecl : toInitGloalVars) {
1372013769
// SPIR-V does not have string variables
@@ -13766,7 +13815,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1376613815
SpirvInstruction *loadedValue = nullptr;
1376713816

1376813817
if (!declIdMapper.createStageInputVar(param, &loadedValue, false))
13769-
return false;
13818+
return nullptr;
1377013819

1377113820
// Only initialize the temporary variable if the parameter is indeed used,
1377213821
// or if it is an inout parameter.
@@ -13805,15 +13854,15 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1380513854
// Create stage output variables out of the return type.
1380613855
if (!declIdMapper.createStageOutputVar(decl, numOutputControlPoints,
1380713856
outputControlPointIdVal, retVal))
13808-
return false;
13857+
return nullptr;
1380913858
if (!processHSEntryPointOutputAndPCF(
1381013859
decl, retType, retVal, numOutputControlPoints,
1381113860
outputControlPointIdVal, primitiveIdVar, viewIdVar,
1381213861
hullMainInputPatchParam))
13813-
return false;
13862+
return nullptr;
1381413863
} else {
1381513864
if (!declIdMapper.createStageOutputVar(decl, retVal, /*forPCF*/ false))
13816-
return false;
13865+
return nullptr;
1381713866
}
1381813867

1381913868
// Create and write stage output variables for parameters marked as
@@ -13836,7 +13885,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1383613885
param->getLocStart());
1383713886

1383813887
if (!declIdMapper.createStageOutputVar(param, loadedParam, false))
13839-
return false;
13888+
return nullptr;
1384013889
}
1384113890
}
1384213891

@@ -13851,7 +13900,7 @@ bool SpirvEmitter::emitEntryFunctionWrapper(const FunctionDecl *decl,
1385113900
if (spvContext.isHS())
1385213901
doDecl(patchConstFunc);
1385313902

13854-
return true;
13903+
return entryFunction;
1385513904
}
1385613905

1385713906
bool SpirvEmitter::processHSEntryPointOutputAndPCF(

tools/clang/lib/SPIRV/SpirvEmitter.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,8 +848,14 @@ class SpirvEmitter : public ASTConsumer {
848848
processMeshOrAmplificationShaderAttributes(const FunctionDecl *decl,
849849
uint32_t *outVerticesArraySize);
850850

851-
/// \brief Emits a wrapper function for the entry function and returns true
852-
/// on success.
851+
/// \brief Emits a SpirvDebugFunction to match given SpirvFunction, and
852+
/// returns a pointer to it.
853+
SpirvDebugFunction *emitDebugFunction(const FunctionDecl *decl,
854+
SpirvFunction *func,
855+
RichDebugInfo **info, std::string name);
856+
857+
/// \brief Emits a wrapper function for the entry function and returns a
858+
/// pointer to the wrapper SpirvFunction on success.
853859
///
854860
/// The wrapper function loads the values of all stage input variables and
855861
/// creates composites as expected by the source code entry function. It then
@@ -859,8 +865,10 @@ class SpirvEmitter : public ASTConsumer {
859865
///
860866
/// The wrapper function is also responsible for initializing global static
861867
/// variables for some cases.
862-
bool emitEntryFunctionWrapper(const FunctionDecl *entryFunction,
863-
SpirvFunction *entryFuncId);
868+
SpirvFunction *emitEntryFunctionWrapper(const FunctionDecl *entryFunction,
869+
RichDebugInfo **info,
870+
SpirvDebugFunction **debugFunction,
871+
SpirvFunction *entryFuncId);
864872

865873
/// \brief Emits a wrapper function for the entry functions for raytracing
866874
/// stages and returns true on success.
@@ -870,6 +878,7 @@ class SpirvEmitter : public ASTConsumer {
870878
/// The wrapper function is also responsible for initializing global static
871879
/// variables for some cases.
872880
bool emitEntryFunctionWrapperForRayTracing(const FunctionDecl *entryFunction,
881+
SpirvDebugFunction *debugFunction,
873882
SpirvFunction *entryFuncId);
874883

875884
/// \brief Performs the following operations for the Hull shader:

tools/clang/test/CodeGenSPIRV/rich.debug.debugscope.hlsl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
// CHECK: [[set:%[0-9]+]] = OpExtInstImport "OpenCL.DebugInfo.100"
44
// CHECK: [[compUnit:%[0-9]+]] = OpExtInst %void [[set]] DebugCompilationUnit
55
// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction
6-
// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 15 1 [[main]]
7-
// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 35 3 [[mainFnLexBlock]]
8-
// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 42 20 [[whileLoopLexBlock]]
9-
// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 47 7 [[ifStmtLexBlock]]
10-
// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 20 12 [[mainFnLexBlock]]
6+
// CHECK: [[mainFnLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 17 1 [[main]]
7+
// CHECK: [[whileLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 37 3 [[mainFnLexBlock]]
8+
// CHECK: [[ifStmtLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 44 20 [[whileLoopLexBlock]]
9+
// CHECK: [[tempLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 49 7 [[ifStmtLexBlock]]
10+
// CHECK: [[forLoopLexBlock:%[0-9]+]] = OpExtInst %void [[set]] DebugLexicalBlock {{%[0-9]+}} 22 12 [[mainFnLexBlock]]
11+
// CHECK: [[srcMain:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction
1112

1213
float4 main(float4 color : COLOR) : SV_TARGET
14+
// CHECK: %main = OpFunction
1315
// CHECK: %src_main = OpFunction
14-
// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[main]]
16+
// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[srcMain]]
1517
{
1618
// CHECK: %bb_entry = OpLabel
1719
// CHECK-NEXT: {{%[0-9]+}} = OpExtInst %void [[set]] DebugScope [[mainFnLexBlock]]

tools/clang/test/CodeGenSPIRV/rich.debug.function.param.hlsl

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77
// CHECK: [[emptyStr:%[0-9]+]] = OpString ""
88
// CHECK: [[y:%[0-9]+]] = OpString "y"
99
// CHECK: [[x:%[0-9]+]] = OpString "x"
10-
// CHECK: [[mainName:%[0-9]+]] = OpString "main"
10+
// CHECK: [[mainName:%[0-9]+]] = OpString "wrapper"
1111
// CHECK: [[color:%[0-9]+]] = OpString "color"
12+
// CHECK: [[srcMainName:%[0-9]+]] = OpString "main"
1213

1314
// CHECK: [[int:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Signed
1415
// CHECK: [[float:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeBasic {{%[0-9]+}} %uint_32 Float
1516
// CHECK: [[source:%[0-9]+]] = OpExtInst %void [[set]] DebugSource
16-
// CHECK: [[foo:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[fooName]] {{%[0-9]+}} [[source]] 23 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 24 %foo
17-
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[y]] [[float]] [[source]] 23 23 [[foo]] FlagIsLocal 2
18-
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[x]] [[int]] [[source]] 23 14 [[foo]] FlagIsLocal 1
17+
// CHECK: [[foo:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[fooName]] {{%[0-9]+}} [[source]] 25 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 26 %foo
18+
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[y]] [[float]] [[source]] 25 23 [[foo]] FlagIsLocal 2
19+
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[x]] [[int]] [[source]] 25 14 [[foo]] FlagIsLocal 1
20+
// CHECK: [[srcMain:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] {{%[0-9]+}} [[source]] 30 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 31 %main
1921
// CHECK: [[float4:%[0-9]+]] = OpExtInst %void [[set]] DebugTypeVector [[float]] 4
20-
// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[mainName]] {{%[0-9]+}} [[source]] 28 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 29 %src_main
21-
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[color]] [[float4]] [[source]] 28 20 [[main]] FlagIsLocal 1
22+
// CHECK: {{%[0-9]+}} = OpExtInst %void [[set]] DebugLocalVariable [[color]] [[float4]] [[source]] 30 20 [[srcMain]] FlagIsLocal 1
23+
// CHECK: [[main:%[0-9]+]] = OpExtInst %void [[set]] DebugFunction [[srcMainName]] {{%[0-9]+}} [[source]] 30 1 {{%[0-9]+}} [[emptyStr]] FlagIsProtected|FlagIsPrivate 31 %src_main
2224

2325
void foo(int x, float y)
2426
{

0 commit comments

Comments
 (0)