Skip to content

Commit 4f05096

Browse files
authored
Propagate location from destination alloca in salvageDebugInfo(). (#58763)
`salvageDebugInfo` is called during SIL Mem2Reg and could produce misleading debug info in the following case: ``` %a = alloc_stack $MyModel.TangentVector, var, name "self", argno 1, implicit, loc "debug2.swift":37:17 ... ... store %b to %a : $*MyModel.TangentVector ``` Such SIL could be created as a result of inlining (where store comes from the inlined function). Before this patch we'd end with `debug_value` instruction with variable information, but without or incorrect location. This caused LLVM IR debug info verifier assertions when there might be another instruction with complete debug info (including location) for the same argument. After this patch we always reuse it from destination alloca Fixes #58660
1 parent 6ac87ba commit 4f05096

File tree

3 files changed

+71
-4
lines changed

3 files changed

+71
-4
lines changed

lib/SIL/IR/SILPrinter.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2774,6 +2774,10 @@ void SILInstruction::print(raw_ostream &OS) const {
27742774
SILPrinter(Ctx).print(this);
27752775
}
27762776

2777+
void NonSingleValueInstruction::dump() const {
2778+
SILNode::dump();
2779+
}
2780+
27772781
/// Pretty-print the SILBasicBlock to errs.
27782782
void SILBasicBlock::dump() const {
27792783
print(llvm::errs());

lib/SILOptimizer/Utils/InstOptUtils.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,13 +1801,17 @@ void swift::salvageDebugInfo(SILInstruction *I) {
18011801

18021802
if (auto *SI = dyn_cast<StoreInst>(I)) {
18031803
if (SILValue DestVal = SI->getDest())
1804-
// TODO: Generalize this into "get the attached debug info
1805-
// on `DestVal`".
18061804
if (auto *ASI = dyn_cast_or_null<AllocStackInst>(
18071805
DestVal.getDefiningInstruction())) {
1808-
if (auto VarInfo = ASI->getVarInfo())
1806+
if (auto VarInfo = ASI->getVarInfo()) {
1807+
// Always propagate destination location for incoming arguments (as
1808+
// their location must be unique) as well as when store source
1809+
// location is compiler-generated.
1810+
bool UseDestLoc = VarInfo->ArgNo || SI->getLoc().isAutoGenerated();
18091811
SILBuilder(SI, ASI->getDebugScope())
1810-
.createDebugValue(SI->getLoc(), SI->getSrc(), *VarInfo);
1812+
.createDebugValue(UseDestLoc ? ASI->getLoc() : SI->getLoc(),
1813+
SI->getSrc(), *VarInfo);
1814+
}
18111815
}
18121816
}
18131817

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// RUN: %target-build-swift %s
2+
// RUN: %target-swift-frontend -emit-sil -O -g %s | %FileCheck %s
3+
4+
// Issue #58660: Specifically-shaped differentiable functions yield "conflicting debug info for argument" assertion failure
5+
// Ensure that proper location is preserved after sil-mem2reg location-less stores (created during inlining)
6+
7+
import _Differentiation
8+
9+
// May be a `struct` or `class`.
10+
class MyState: Differentiable {
11+
// All of these must be stored instance properties. There must be at least 7
12+
// differentiable properties of any type.
13+
var property1: Float = 0
14+
var property2: Float = 0
15+
var property3: Float = 0
16+
var property4: Float = 0
17+
var property5: Float = 0
18+
var property6: Float = 0
19+
var property7: Float = 0
20+
}
21+
22+
struct MyModel: Differentiable {
23+
// May be `var` or `let`, but must not be `@noDerivative`. Must be a stored
24+
// instance property.
25+
let property1 = MyState()
26+
27+
// Must be an instance property, either stored or computed.
28+
var property2: Float {
29+
// `get` must exist, and may add `mutating` attribute.
30+
get { 0 }
31+
// Cannot add `nonmutating` attribute to `set`.
32+
set { }
33+
}
34+
35+
// Must be an instance member. May be a function or computed property, but not
36+
// a stored property.
37+
var member3: Float {
38+
// May not add `mutating` attribute.
39+
get { 0 }
40+
}
41+
42+
@differentiable(reverse)
43+
mutating func member4() {
44+
// CHECK-LABEL: // pullback of MyModel.member4()
45+
// CHECK-NOT: debug_value %{{.*}} : $MyModel.TangentVector, var, name "self", argno 1, implicit, scope
46+
// CHECK: bb1(%{{.*}} : $_AD__$s4main7MyModelV7member4yyF_bb1__PB__src_0_wrt_0):
47+
// CHECK: debug_value %{{.*}} : $MyModel.TangentVector, var, name "self", argno 1, implicit, loc
48+
// Must be a differentiable type.
49+
var localVar: Float = 0
50+
51+
// Must be assigned from the value of `localVar`, not the value of anything else.
52+
property2 = localVar
53+
54+
// `false` may instead be any expression that returns a `Bool`.
55+
if false {
56+
localVar = member3
57+
}
58+
}
59+
}

0 commit comments

Comments
 (0)