Files
swift-mirror/test/DebugInfo/inlined-generics-basic.swift
Adrian Prantl 99cf35cdce [SILOptimzer] Fix a crash caused by SILCombine mishandling inlined variables
This showed up on and off again on the source-compatibility testsuite project hummingbird.

The gist of the problem is that transformations may not rewrite the
type of an inlined instance of a variable without also createing a
deep copy of the inlined function with a different name (and e.g., a
specialization suffix). Otherwise the modified inlined variable will
cause an inconsistency when later compiler passes try to create the
abstract declaration of that inlined function as there would be
conflicting declarations for that variable.

Since SILDebugScope isn't yet available in the SwiftCompilerSources
this fix just drop these variables, but it would be absolutely
possible to preserve them by using the same mechanism that SILCloner
uses to create a deep copy of the inlined function scopes.

rdar://163167975
2025-11-07 17:06:33 -08:00

130 lines
6.2 KiB
Swift

// SIL.
// RUN: %target-swift-frontend -parse-as-library -module-name A \
// RUN: -Xllvm -sil-print-types -Xllvm -sil-print-debuginfo %s -g -O -o - -emit-sil \
// RUN: | %FileCheck %s --check-prefix=SIL
// IR.
// RUN: %target-swift-frontend -parse-as-library -module-name A \
// RUN: %s -g -O -o - -emit-ir \
// RUN: | %FileCheck %s --check-prefix=IR
// REQUIRES: swift_in_compiler
import StdlibUnittest
@inline(never)
func yes() -> Bool { return true }
#sourceLocation(file: "use.swift", line: 1)
@inline(never) func use<V>(_ v: V) { _blackHole(v) }
#sourceLocation(file: "h.swift", line: 1)
@inline(__always) func h<U>(_ u: U) {
yes()
use(u)
}
#sourceLocation(file: "g.swift", line: 1)
@inline(__always) func g<T>(_ t: T) {
if (yes()) {
h(t)
}
}
// SIL: sil_scope [[F:.*]] { {{.*}}parent @$s1A1CC1fyyqd__lF
// SIL: sil_scope [[F1G:.*]] { loc "f.swift":2:5 parent [[F]] }
// SIL: sil_scope [[F1G1:.*]] { loc "g.swift":2:3 {{.*}}inlined_at [[F1G]] }
// SIL: sil_scope [[F1G3:.*]] { loc "g.swift":3:5 {{.*}}inlined_at [[F1G]] }
// SIL: sil_scope [[F1G3H:.*]] { loc "h.swift":1:24
// SIL-SAME: parent @{{.*}}1h{{.*}} inlined_at [[F1G3]] }
#sourceLocation(file: "C.swift", line: 1)
public class C<R> {
let r : R
init(_ _r: R) { r = _r }
// SIL-LABEL: // C.f<A>(_:)
// IR-LABEL: define {{.*}} @"$s1A1CC1fyyqd__lF"
// IR-SAME: %[[ARG_0:.*]], {{.*}} %[[ARG_S:.*]],
#sourceLocation(file: "f.swift", line: 1)
public func f<S>(_ s: S) {
// SIL: debug_value %0 : $*S, let, name "s", argno 1, expr op_deref, {{.*}} scope [[F]]
// SIL: function_ref {{.*}}yes{{.*}} scope [[F1G1]]
// SIL: function_ref {{.*}}use{{.*}} scope [[F1G3H]]
// IR: #dbg_value(ptr %[[ARG_S]], ![[MD_1_0:[0-9]+]]
// IR: %[[RS_PAIR:.*]] = alloca i8, i{{.*}} %
// IR: #dbg_value(ptr %[[ARG_0]], ![[S:[0-9]+]]
// IR: #dbg_value(ptr %[[ARG_0]], ![[GS_T:[0-9]+]]
// IR: #dbg_value(ptr %[[ARG_0]], ![[GS_U:[0-9]+]]
// IR: call {{.*}}3use
#sourceLocation(file: "f.swift", line: 2)
g(s)
// Jump-threading removes the basic block containing debug_value
// "t" before the second call to `g(r)`. When this happens, the
// ref_element_addr in that removed block is left with a single
// debug_value use, so they are both deleted. This means we have
// no debug value for "t" in the call to `g(r)`.
// dbg_value({{.*}}, ![[GR_T:[0-9]+]]
// IR: #dbg_value({{.*}}, ![[GR_U:[0-9]+]], !DIExp
// IR: call {{.*}}3use
#sourceLocation(file: "f.swift", line: 3)
g(r)
// IR: #dbg_value(ptr %[[RS_PAIR]], ![[GRS_T:[0-9]+]],
// IR: #dbg_value(ptr %[[RS_PAIR]], ![[GRS_U:[0-9]+]],
// IR: call {{.*}}3use
#sourceLocation(file: "f.swift", line: 4)
g((r, s))
// Note to maintainers: the relative order of the constant dbg_values here
// seem to flip back and forth.
// IR: #dbg_value(i{{.*}} 0, ![[GI_U:[0-9]+]]
// IR: #dbg_value(i{{.*}} 0, ![[GI_T:[0-9]+]]
// IR: call {{.*}}3use{{.*}}(i{{.*}} 0)
#sourceLocation(file: "f.swift", line: 5)
g(Int(0))
// IR: #dbg_value(i1 false, ![[GB_U:[0-9]+]]
// IR: #dbg_value(i1 false, ![[GB_T:[0-9]+]]
// IR: call {{.*}}3use{{.*}}(i1 false)
#sourceLocation(file: "f.swift", line: 6)
g(false)
}
}
// SIL-LABEL: } // end sil function '$s1A1CC1fyyqd__lF'
// IR-LABEL: ret void
// IR: ![[BOOL:[0-9]+]] = !DICompositeType({{.*}}name: "Bool"
// IR: ![[LET_BOOL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[BOOL]])
// IR: ![[INT:[0-9]+]] = !DICompositeType({{.*}}name: "Int"
// IR: ![[LET_INT:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[INT]])
// IR-DAG: ![[TAU_0_0:[0-9]+]] = {{.*}}DW_TAG_structure_type, name: "$sxD", file
// IR-DAG: ![[LET_TAU_0_0:[0-9]+]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TAU_0_0]])
// IR-DAG: ![[TAU_1_0:[0-9]+]] = {{.*}}DW_TAG_structure_type, name: "$sqd__D", file
// IR-DAG: ![[MD_1_0]] = !DILocalVariable(name: "$\CF\84_1_0"
// IR-DAG: ![[GRS_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GRS_T:[0-9]+]], {{.*}}type: ![[LET_TUPLE:[0-9]+]]
// IR-DAG: ![[SP_GRS_T]] = {{.*}}linkageName: "$s1A1gyyxlFx_qd__t_Ti5"
// IR-DAG: ![[GRS_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GRS_U:[0-9]+]], {{.*}}type: ![[LET_TUPLE:[0-9]+]]
// IR-DAG: ![[SP_GRS_U]] = {{.*}}linkageName: "$s1A1hyyxlFx_Ti5x_qd__t_Ti5"
// IR-DAG: ![[LET_TUPLE]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TUPLE:[0-9]+]])
// IR-DAG: ![[TUPLE]] = {{.*}}DW_TAG_structure_type, name: "$sx_qd__tD"
// IR-DAG: ![[S]] = !DILocalVariable(name: "s", {{.*}} type: ![[LET_TAU_1_0:[0-9]+]]
// IR-DAG: ![[LET_TAU_1_0]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: ![[TAU_1_0]])
// IR-DAG: ![[GS_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GS_T:[0-9]+]], {{.*}} type: ![[LET_TAU_1_0]])
// IR-DAG: ![[SP_GS_T]] = {{.*}}linkageName: "$s1A1gyyxlFqd___Ti5"
// IR-DAG: ![[GS_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GS_U:[0-9]+]], {{.*}} type: ![[LET_TAU_1_0]])
// IR-DAG: ![[SP_GS_U]] = {{.*}}linkageName: "$s1A1hyyxlFx_Ti5qd___Ti5"
// Debug info for this variable is removed. See the note above the call to g(r).
// ![[GR_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GR_T:[0-9]+]], {{.*}}type: ![[LET_TAU_0_0]])
// S has the same generic parameter numbering s T and U.
// ![[SP_GR_T]] = {{.*}}linkageName: "$s1A1gyyxlF"
// IR-DAG: ![[GR_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GR_U:[0-9]+]], {{.*}}type: ![[LET_TAU_0_0]])
// IR-DAG: ![[SP_GR_U]] = {{.*}}linkageName: "$s1A1hyyxlFx_Ti5x_Ti5"
// IR-DAG: ![[GI_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GI_G:[0-9]+]], {{.*}}type: ![[LET_INT]])
// IR-DAG: ![[SP_GI_G]] = {{.*}}linkageName: "$s1A1gyyxlFSi_Tg5"
// IR-DAG: ![[GI_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GI_U:[0-9]+]], {{.*}}type: ![[LET_INT]])
// IR-DAG: ![[SP_GI_U]] = {{.*}}linkageName: "$s1A1hyyxlFx_Ti5Si_TG5"
// IR-DAG: ![[GB_T]] = !DILocalVariable(name: "t", {{.*}} scope: ![[SP_GB_G:[0-9]+]], {{.*}}type: ![[LET_BOOL]])
// IR-DAG: ![[SP_GB_G]] = {{.*}}linkageName: "$s1A1gyyxlFSb_Tg5"
// IR-DAG: ![[GB_U]] = !DILocalVariable(name: "u", {{.*}} scope: ![[SP_GB_U:[0-9]+]], {{.*}}type: ![[LET_BOOL]])
// IR-DAG: ![[SP_GB_U]] = {{.*}}linkageName: "$s1A1hyyxlFx_Ti5Sb_TG5"