Skip to content

Commit 593d9d3

Browse files
committed
[DebugInfo] Return complete variable info from getVarInfo by default
getVarInfo() now always returns a variable with a location and scope. To opt out of this change, getVarInfo(false) returns an incomplete variable. This can be used to work around bugs, but should only really be used for printing. The complete var info will also contain the type, except for debug_values, as its type depends on another instruction, which may be inconsistent if called mid-pass. All locations in debug variables are now also stripped of flags, to avoid issues when comparing or hashing debug variables.
1 parent f5da396 commit 593d9d3

18 files changed

+99
-76
lines changed

docs/HowToUpdateDebugInfo.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ debug_value %0 : $*T, let, name "address", type $UnsafeRawPointer
108108
The variable will usually have an associated expression yielding the correct
109109
type.
110110

111+
> [!Note]
112+
> As there are no pointers in Swift, the type should never be an address type.
113+
111114
### Variable expressions
112115

113116
A variable can have an associated expression if the value needs computation.

include/swift/SIL/DebugUtils.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,16 +437,24 @@ struct DebugVarCarryingInst : VarDeclCarryingInst {
437437

438438
Kind getKind() const { return Kind(VarDeclCarryingInst::getKind()); }
439439

440-
std::optional<SILDebugVariable> getVarInfo() const {
440+
/// Returns the debug variable information attached to the instruction.
441+
///
442+
/// \param complete If true, always retrieve the complete variable with
443+
/// location and scope, and the type if possible. If false, only return the
444+
/// values if they are stored (if they are different from the instruction's
445+
/// location, scope, and type). This should only be set to false in
446+
/// SILPrinter. Incomplete var info is unpredictable, as it will sometimes
447+
/// have location and scope and sometimes not.
448+
std::optional<SILDebugVariable> getVarInfo(bool complete = true) const {
441449
switch (getKind()) {
442450
case Kind::Invalid:
443451
llvm_unreachable("Invalid?!");
444452
case Kind::DebugValue:
445-
return cast<DebugValueInst>(**this)->getVarInfo();
453+
return cast<DebugValueInst>(**this)->getVarInfo(complete);
446454
case Kind::AllocStack:
447-
return cast<AllocStackInst>(**this)->getVarInfo();
455+
return cast<AllocStackInst>(**this)->getVarInfo(complete);
448456
case Kind::AllocBox:
449-
return cast<AllocBoxInst>(**this)->getVarInfo();
457+
return cast<AllocBoxInst>(**this)->getVarInfo(complete);
450458
}
451459
llvm_unreachable("covered switch");
452460
}

include/swift/SIL/SILBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ class SILBuilder {
425425
#endif
426426
// Don't apply location overrides on variables.
427427
if (Var && !Var->Loc)
428-
Var->Loc = Loc;
428+
Var->Loc = Loc.strippedForDebugVariable();
429429
return insert(AllocStackInst::create(
430430
getSILDebugLocation(Loc, true), elementType, getFunction(),
431431
substituteAnonymousArgs(Name, Var, Loc), dynamic, isLexical,

include/swift/SIL/SILInstruction.h

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,9 +1875,9 @@ class TailAllocatedDebugVariable {
18751875
bool isLet() const { return Bits.Data.Constant; }
18761876

18771877
std::optional<SILDebugVariable>
1878-
get(VarDecl *VD, const char *buf, std::optional<SILType> AuxVarType = {},
1879-
std::optional<SILLocation> DeclLoc = {},
1880-
const SILDebugScope *DeclScope = nullptr,
1878+
get(VarDecl *VD, const char *buf, std::optional<SILType> AuxVarType,
1879+
std::optional<SILLocation> DeclLoc,
1880+
const SILDebugScope *DeclScope,
18811881
llvm::ArrayRef<SILDIExprElement> DIExprElements = {}) const {
18821882
if (!Bits.Data.HasValue)
18831883
return std::nullopt;
@@ -2087,11 +2087,18 @@ class AllocStackInst final
20872087
SILLocation getVarLoc() const {
20882088
if (hasAuxDebugLocation())
20892089
return *getTrailingObjects<SILLocation>();
2090-
return getLoc();
2090+
return getLoc().strippedForDebugVariable();
20912091
}
20922092

20932093
/// Return the debug variable information attached to this instruction.
2094-
std::optional<SILDebugVariable> getVarInfo() const {
2094+
///
2095+
/// \param complete If true, always retrieve the complete variable with
2096+
/// location, scope, and element type. If false, only return the
2097+
/// values if they are stored (if they are different from the instruction's
2098+
/// location, scope, and type). This should only be set to false in
2099+
/// SILPrinter. Incomplete var info is unpredictable, as it will sometimes
2100+
/// have location and scope and sometimes not.
2101+
std::optional<SILDebugVariable> getVarInfo(bool complete = true) const {
20952102
// If we used to have debug info attached but our debug info is now
20962103
// invalidated, just bail.
20972104
if (sharedUInt8().AllocStackInst.hasInvalidatedVarInfo) {
@@ -2103,11 +2110,18 @@ class AllocStackInst final
21032110
const SILDebugScope *VarDeclScope = nullptr;
21042111
if (HasAuxDebugVariableType)
21052112
AuxVarType = *getTrailingObjects<SILType>();
2113+
else if (complete)
2114+
AuxVarType = getElementType();
21062115

21072116
if (hasAuxDebugLocation())
21082117
VarDeclLoc = *getTrailingObjects<SILLocation>();
2118+
else if (complete)
2119+
VarDeclLoc = getLoc().strippedForDebugVariable();
2120+
21092121
if (hasAuxDebugScope())
21102122
VarDeclScope = *getTrailingObjects<const SILDebugScope *>();
2123+
else if (complete)
2124+
VarDeclScope = getDebugScope();
21112125

21122126
llvm::ArrayRef<SILDIExprElement> DIExprElements(
21132127
getTrailingObjects<SILDIExprElement>(), NumDIExprOperands);
@@ -2509,8 +2523,13 @@ class AllocBoxInst final
25092523
SILType getAddressType() const;
25102524

25112525
/// Return the debug variable information attached to this instruction.
2512-
std::optional<SILDebugVariable> getVarInfo() const {
2513-
return VarInfo.get(getDecl(), getTrailingObjects<char>());
2526+
std::optional<SILDebugVariable> getVarInfo(bool complete = true) const {
2527+
if (complete)
2528+
return VarInfo.get(getDecl(), getTrailingObjects<char>(),
2529+
getAddressType().getObjectType(),
2530+
getLoc().strippedForDebugVariable(),
2531+
getDebugScope());
2532+
return VarInfo.get(getDecl(), getTrailingObjects<char>(), {}, {}, nullptr);
25142533
};
25152534

25162535
void setUsesMoveableValueDebugInfo() {
@@ -5385,21 +5404,41 @@ class DebugValueInst final
53855404
SILLocation getVarLoc() const {
53865405
if (hasAuxDebugLocation())
53875406
return *getTrailingObjects<SILLocation>();
5388-
return getLoc();
5407+
return getLoc().strippedForDebugVariable();
53895408
}
53905409

53915410
/// Return the debug variable information attached to this instruction.
5392-
std::optional<SILDebugVariable> getVarInfo() const {
5411+
///
5412+
/// \param complete If true, always retrieve the complete variable with
5413+
/// location and scope, and the type if possible. If false, only return the
5414+
/// values if they are stored (if they are different from the instruction's
5415+
/// location, scope, and type). This should only be set to false in
5416+
/// SILPrinter. Incomplete var info is unpredictable, as it will sometimes
5417+
/// have location and scope and sometimes not.
5418+
///
5419+
/// \note The type is not included because it can change during a pass.
5420+
/// Passes must make sure to not lose the type information.
5421+
std::optional<SILDebugVariable> getVarInfo(bool complete = true) const {
53935422
std::optional<SILType> AuxVarType;
53945423
std::optional<SILLocation> VarDeclLoc;
53955424
const SILDebugScope *VarDeclScope = nullptr;
5425+
53965426
if (HasAuxDebugVariableType)
53975427
AuxVarType = *getTrailingObjects<SILType>();
5428+
// TODO: passes break if we set the type here, as the type of the operand
5429+
// can be changed during a pass.
5430+
// else if (complete)
5431+
// AuxVarType = getOperand()->getType().getObjectType();
53985432

53995433
if (hasAuxDebugLocation())
54005434
VarDeclLoc = *getTrailingObjects<SILLocation>();
5435+
else if (complete)
5436+
VarDeclLoc = getLoc().strippedForDebugVariable();
5437+
54015438
if (hasAuxDebugScope())
54025439
VarDeclScope = *getTrailingObjects<const SILDebugScope *>();
5440+
else if (complete)
5441+
VarDeclScope = getDebugScope();
54035442

54045443
llvm::ArrayRef<SILDIExprElement> DIExprElements(
54055444
getTrailingObjects<SILDIExprElement>(), NumDIExprOperands);

lib/IRGen/IRGenSIL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ class IRGenSILFunction :
679679
if (!VarInfo)
680680
return StringRef();
681681

682-
StringRef Name = i->getVarInfo()->Name;
682+
StringRef Name = VarInfo->Name;
683683
// The $match variables generated by the type checker are not
684684
// guaranteed to be unique within their scope, but they have
685685
// unique VarDecls.

lib/SIL/IR/SILBasicBlock.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,10 @@ transferNodesFromList(llvm::ilist_traits<SILBasicBlock> &SrcTraits,
342342

343343
II.setDebugScope(ScopeCloner.getOrCreateClonedScope(II.getDebugScope()));
344344
// Special handling for SILDebugVariable.
345+
// Fetch incomplete var info to avoid calling setDebugVarScope on
346+
// alloc_box, crashing.
345347
if (auto DVI = DebugVarCarryingInst(&II))
346-
if (auto VarInfo = DVI.getVarInfo())
348+
if (auto VarInfo = DVI.getVarInfo(false))
347349
if (VarInfo->Scope)
348350
DVI.setDebugVarScope(
349351
ScopeCloner.getOrCreateClonedScope(VarInfo->Scope));

lib/SIL/IR/SILInstructions.cpp

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -199,26 +199,10 @@ StringRef TailAllocatedDebugVariable::getName(const char *buf) const {
199199

200200
std::optional<SILDebugVariable>
201201
SILDebugVariable::createFromAllocation(const AllocationInst *AI) {
202-
std::optional<SILDebugVariable> VarInfo;
203202
if (const auto *ASI = dyn_cast_or_null<AllocStackInst>(AI))
204-
VarInfo = ASI->getVarInfo();
203+
return ASI->getVarInfo();
205204
// TODO: Support AllocBoxInst
206-
207-
if (!VarInfo)
208-
return {};
209-
210-
// Coalesce the debug loc attached on AI into VarInfo
211-
SILType Type = AI->getType();
212-
SILLocation InstLoc = AI->getLoc();
213-
const SILDebugScope *InstDS = AI->getDebugScope();
214-
if (!VarInfo->Type)
215-
VarInfo->Type = Type;
216-
if (!VarInfo->Loc)
217-
VarInfo->Loc = InstLoc;
218-
if (!VarInfo->Scope)
219-
VarInfo->Scope = InstDS;
220-
221-
return VarInfo;
205+
return {};
222206
}
223207

224208
AllocStackInst::AllocStackInst(
@@ -268,7 +252,7 @@ AllocStackInst *AllocStackInst::create(SILDebugLocation Loc,
268252
UsesMoveableValueDebugInfo_t wasMoved) {
269253
// Don't store the same information twice.
270254
if (Var) {
271-
if (Var->Loc == Loc.getLocation())
255+
if (Var->Loc == Loc.getLocation().strippedForDebugVariable())
272256
Var->Loc = {};
273257
if (Var->Scope == Loc.getScope())
274258
Var->Scope = nullptr;
@@ -473,7 +457,7 @@ DebugValueInst *DebugValueInst::create(SILDebugLocation DebugLoc,
473457
UsesMoveableValueDebugInfo_t wasMoved,
474458
bool trace) {
475459
// Don't store the same information twice.
476-
if (Var.Loc == DebugLoc.getLocation())
460+
if (Var.Loc == DebugLoc.getLocation().strippedForDebugVariable())
477461
Var.Loc = {};
478462
if (Var.Scope == DebugLoc.getScope())
479463
Var.Scope = nullptr;

lib/SIL/IR/SILPrinter.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,7 +1446,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
14461446
if (AVI->usesMoveableValueDebugInfo() && !AVI->getType().isMoveOnly())
14471447
*this << "[moveable_value_debuginfo] ";
14481448
*this << AVI->getElementType();
1449-
printDebugVar(AVI->getVarInfo(),
1449+
printDebugVar(AVI->getVarInfo(false),
14501450
&AVI->getModule().getASTContext().SourceMgr);
14511451
}
14521452
void visitAllocVectorInst(AllocVectorInst *AVI) {
@@ -1503,7 +1503,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
15031503
}
15041504

15051505
*this << ABI->getType();
1506-
printDebugVar(ABI->getVarInfo(),
1506+
printDebugVar(ABI->getVarInfo(false),
15071507
&ABI->getModule().getASTContext().SourceMgr);
15081508
}
15091509

@@ -1915,7 +1915,7 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
19151915
if (DVI->hasTrace())
19161916
*this << "[trace] ";
19171917
*this << getIDAndType(DVI->getOperand());
1918-
printDebugVar(DVI->getVarInfo(),
1918+
printDebugVar(DVI->getVarInfo(false),
19191919
&DVI->getModule().getASTContext().SourceMgr);
19201920
}
19211921

lib/SILOptimizer/Differentiation/Common.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,12 +266,12 @@ void collectMinimalIndicesForFunctionCall(
266266
std::optional<std::pair<SILDebugLocation, SILDebugVariable>>
267267
findDebugLocationAndVariable(SILValue originalValue) {
268268
if (auto *asi = dyn_cast<AllocStackInst>(originalValue))
269-
return swift::transform(asi->getVarInfo(), [&](SILDebugVariable var) {
269+
return swift::transform(asi->getVarInfo(false), [&](SILDebugVariable var) {
270270
return std::make_pair(asi->getDebugLocation(), var);
271271
});
272272
for (auto *use : originalValue->getUses()) {
273273
if (auto *dvi = dyn_cast<DebugValueInst>(use->getUser()))
274-
return swift::transform(dvi->getVarInfo(), [&](SILDebugVariable var) {
274+
return swift::transform(dvi->getVarInfo(false), [&](SILDebugVariable var) {
275275
// We need to drop `op_deref` here as we're transferring debug info
276276
// location from debug_value instruction (which describes how to get value)
277277
// into alloc_stack (which describes the location)

lib/SILOptimizer/Transforms/DeadObjectElimination.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -871,9 +871,6 @@ DeadObjectElimination::buildDIExpression(SILInstruction *current) {
871871
return {};
872872
if (!var->Type)
873873
var->Type = dvci->getElementType();
874-
var->Loc = dvci->getVarLoc();
875-
if (!var->Scope)
876-
var->Scope = dvci->getDebugScope();
877874
return var;
878875
}
879876
if (auto *tupleAddr = dyn_cast<TupleElementAddrInst>(current)) {

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1833,14 +1833,6 @@ static void transferStoreDebugValue(DebugVarCarryingInst DefiningInst,
18331833
auto VarInfo = DefiningInst.getVarInfo();
18341834
if (!VarInfo)
18351835
return;
1836-
// Transfer the location and scope of the debug value to the debug variable,
1837-
// unless they are the same, in which case we don't need to store it twice.
1838-
// That way, the variable will point to its declaration, and the debug_value
1839-
// will point to the assignment point.
1840-
if (!VarInfo->Loc && !SI->getLoc().hasSameSourceLocation(DefiningInst->getLoc()))
1841-
VarInfo->Loc = DefiningInst->getLoc();
1842-
if (!VarInfo->Scope && SI->getDebugScope() != DefiningInst->getDebugScope())
1843-
VarInfo->Scope = DefiningInst->getDebugScope();
18441836
// Fix the op_deref.
18451837
if (!isa<CopyAddrInst>(SI) && VarInfo->DIExpr.startsWithDeref())
18461838
VarInfo->DIExpr.eraseElement(VarInfo->DIExpr.element_begin());

lib/SILOptimizer/Utils/OptimizerStatsUtils.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -421,8 +421,6 @@ struct InstCountVisitor : SILInstructionVisitor<InstCountVisitor> {
421421
return;
422422

423423
llvm::StringRef UniqueName = VarNames.insert(varInfo->Name).first->getKey();
424-
if (!varInfo->Loc)
425-
varInfo->Loc = inst->getLoc();
426424
unsigned line = 0, col = 0;
427425
if (varInfo->Loc && varInfo->Loc->getSourceLoc().isValid()) {
428426
std::tie(line, col) = inst->getModule().getSourceManager()

test/DebugInfo/dead-obj-elim.sil

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ bb0(%0 : $UInt8):
3030
// The store below should be replaced by a debug_value with the same operand as the store (%0)
3131
// The fragment refers to the member being modified
3232
// CHECK-NOT: store
33-
// CHECK: debug_value %0 : $UInt8, var, name "obj", type $*MyObject, expr op_fragment:#MyObject._storage:op_tuple_fragment:$(UInt8, UInt8):1
33+
// CHECK: debug_value %0 : $UInt8, var, name "obj", type $MyObject, expr op_fragment:#MyObject._storage:op_tuple_fragment:$(UInt8, UInt8):1
3434
store %0 to %36 : $*UInt8
35-
// CHECK: debug_value %{{[0-9]}} : $UInt8, var, name "obj", type $*MyObject, expr op_fragment:#MyObject._storage:op_tuple_fragment:$(UInt8, UInt8):0
35+
// CHECK: debug_value %{{[0-9]}} : $UInt8, var, name "obj", type $MyObject, expr op_fragment:#MyObject._storage:op_tuple_fragment:$(UInt8, UInt8):0
3636
store %31 to %35 : $*UInt8
3737
dealloc_stack %2 : $*MyObject
3838
return %31 : $UInt8

test/DebugInfo/debug_value_addr.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ func use<T>(_ t : T) {}
2727

2828
// CHECK-SIL: sil hidden @$s16debug_value_addr11GenericSelfV1xACyxGx_tcfC : $@convention(method) <T> (@in T, @thin GenericSelf<T>.Type) -> GenericSelf<T> {
2929
// CHECK-SIL: bb0(%0 : $*T, %1 : $@thin GenericSelf<T>.Type):
30-
//
31-
// CHECK-SIL-NEXT: alloc_stack [var_decl] $GenericSelf<T>, var, name "self", loc {{.*}}
30+
// TODO: Why is the type repeated below?
31+
// CHECK-SIL-NEXT: alloc_stack [var_decl] $GenericSelf<T>, var, name "self", type $GenericSelf<T>, loc {{.*}}
3232
// CHECK-SIL-NEXT: debug_value %0 : $*T, let, name "x", argno 1, expr op_deref, loc {{.*}}
3333
struct GenericSelf<T> {
3434
init(x: T) {

test/DebugInfo/sroa_debug_value.sil

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ bb0(%0 : $Int64, %1 : $Int64):
3131
// Make sure SROA propagate the debug info to the splitted alloc_stack/debug_value instructions
3232
// CHECK-SROA: %[[ALLOC_X:[0-9]+]] = alloc_stack $Int64, var
3333
// CHECK-SROA-SAME: (name "my_struct", loc "sroa.swift":8:9
34-
// CHECK-SROA-SAME: type $*MyStruct, expr op_fragment:#MyStruct.x
34+
// CHECK-SROA-SAME: type $MyStruct, expr op_fragment:#MyStruct.x
3535
// CHECK-SROA-SAME: loc * "<compiler-generated>":0:0
3636
// CHECK-SROA: %[[ALLOC_Y:[0-9]+]] = alloc_stack $Int64, var
3737
// CHECK-SROA-SAME: (name "my_struct", loc "sroa.swift":8:9
38-
// CHECK-SROA-SAME: type $*MyStruct, expr op_fragment:#MyStruct.y
38+
// CHECK-SROA-SAME: type $MyStruct, expr op_fragment:#MyStruct.y
3939
// CHECK-SROA-SAME: loc * "<compiler-generated>":0:0
4040
// CHECK-SROA: debug_value %[[ALLOC_X]] : $*Int64, let
4141
// CHECK-SROA-SAME: name "my_copy",
@@ -54,11 +54,11 @@ bb0(%0 : $Int64, %1 : $Int64):
5454
dealloc_stack %4 : $*MyStruct, loc "sroa.swift":8:9, scope 2
5555
// Make sure function arguments' SSA values are properly connected to both source variables
5656
// CHECK-MEM2REG: debug_value %0 : $Int64, var, (name "my_struct", loc "sroa.swift":8:9
57-
// CHECK-MEM2REG-SAME: type $*MyStruct, expr op_fragment:#MyStruct.x
57+
// CHECK-MEM2REG-SAME: type $MyStruct, expr op_fragment:#MyStruct.x
5858
// CHECK-MEM2REG: debug_value %0 : $Int64, let, (name "my_copy", loc "sroa.swift":7:10
5959
// CHECK-MEM2REG-SAME: type $MyStruct, expr op_fragment:#MyStruct.x
6060
// CHECK-MEM2REG: debug_value %1 : $Int64, var, (name "my_struct", loc "sroa.swift":8:9
61-
// CHECK-MEM2REG-SAME: type $*MyStruct, expr op_fragment:#MyStruct.y
61+
// CHECK-MEM2REG-SAME: type $MyStruct, expr op_fragment:#MyStruct.y
6262
// CHECK-MEM2REG: debug_value %1 : $Int64, let, (name "my_copy", loc "sroa.swift":7:10
6363
// CHECK-MEM2REG-SAME: type $MyStruct, expr op_fragment:#MyStruct.y
6464
return %0 : $Int64, loc "sroa.swift":11:5, scope 2

test/DebugInfo/sroa_mem2reg.sil

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ bb0(%0 : $Int64, %1 : $Int64):
3535
// Make sure SROA propagate the debug info to the splitted alloc_stack instructions
3636
// CHECK-SROA: alloc_stack $Int64, var
3737
// CHECK-SROA-SAME: (name "my_struct", loc "sroa.swift":8:9
38-
// CHECK-SROA-SAME: type $*MyStruct, expr op_fragment:#MyStruct.x
38+
// CHECK-SROA-SAME: type $MyStruct, expr op_fragment:#MyStruct.x
3939
// CHECK-SROA-SAME: loc * "<compiler-generated>":0:0
4040
// CHECK-SROA: alloc_stack $Int64, var
4141
// CHECK-SROA-SAME: (name "my_struct", loc "sroa.swift":8:9
42-
// CHECK-SROA-SAME: type $*MyStruct, expr op_fragment:#MyStruct.y
42+
// CHECK-SROA-SAME: type $MyStruct, expr op_fragment:#MyStruct.y
4343
// CHECK-SROA-SAME: loc * "<compiler-generated>":0:0
4444
%5 = metatype $@thin MyStruct.Type, loc "sroa.swift":8:21, scope 2
4545
%6 = integer_literal $Builtin.Int64, 0, loc "sroa.swift":8:33, scope 2
@@ -57,17 +57,17 @@ bb0(%0 : $Int64, %1 : $Int64):
5757
// CHECK-MEM2REG: %[[FIELD_Y:[0-9]+]] = struct_extract %[[STRUCT]] : $MyStruct, #MyStruct.y, loc "sroa.swift":8:21
5858
store %1 to %15 : $*Int64, loc "sroa.swift":10:17, scope 2
5959
// Make sure the struct fields' SSA values are properly connected to the source variables via op_fragment
60-
// CHECK-MEM2REG: debug_value %[[FIELD_X]] : $Int64, var, (name "my_struct", loc "sroa.swift":8:9), type $*MyStruct, expr op_fragment:#MyStruct.x
61-
// CHECK-MEM2REG: debug_value %[[FIELD_Y]] : $Int64, var, (name "my_struct", loc "sroa.swift":8:9), type $*MyStruct, expr op_fragment:#MyStruct.y
60+
// CHECK-MEM2REG: debug_value %[[FIELD_X]] : $Int64, var, (name "my_struct", loc "sroa.swift":8:9), type $MyStruct, expr op_fragment:#MyStruct.x
61+
// CHECK-MEM2REG: debug_value %[[FIELD_Y]] : $Int64, var, (name "my_struct", loc "sroa.swift":8:9), type $MyStruct, expr op_fragment:#MyStruct.y
6262
// CHECK-IR: call void @llvm.dbg.value(metadata i64 %0
6363
// CHECK-IR-SAME: metadata ![[STRUCT_MD:[0-9]+]]
6464
// CHECK-IR-SAME: !DIExpression(DW_OP_LLVM_fragment, 0, 64)
6565
// CHECK-IR: call void @llvm.dbg.value(metadata i64 %1
6666
// CHECK-IR-SAME: metadata ![[STRUCT_MD]]
6767
// CHECK-IR-SAME: !DIExpression(DW_OP_LLVM_fragment, 64, 64)
6868
// Make sure function arguments' SSA values are also properly connected to the source variables
69-
// CHECK-MEM2REG: debug_value %0 : $Int64, var, (name "my_struct", loc "sroa.swift":8:9), type $*MyStruct, expr op_fragment:#MyStruct.x
70-
// CHECK-MEM2REG: debug_value %1 : $Int64, var, (name "my_struct", loc "sroa.swift":8:9), type $*MyStruct, expr op_fragment:#MyStruct.y
69+
// CHECK-MEM2REG: debug_value %0 : $Int64, var, (name "my_struct", loc "sroa.swift":8:9), type $MyStruct, expr op_fragment:#MyStruct.x
70+
// CHECK-MEM2REG: debug_value %1 : $Int64, var, (name "my_struct", loc "sroa.swift":8:9), type $MyStruct, expr op_fragment:#MyStruct.y
7171
// CHECK-IR: call void @llvm.dbg.value(metadata i64 %0, metadata ![[ARG1_MD:[0-9]+]]
7272
// CHECK-IR: call void @llvm.dbg.value(metadata i64 %1, metadata ![[ARG2_MD:[0-9]+]]
7373
dealloc_stack %4 : $*MyStruct, loc "sroa.swift":8:9, scope 2

0 commit comments

Comments
 (0)