Don't treat dependent types as having a copy value representation. (#6055)

Add `Dependent` value and initializing representations for types whose
representations are unknown because they are dependent. When generating
SemIR in such cases, use a worst-case initializing representation that
both provides a destination address and also propagates a potential
result value.

Use this to fix incorrect lowering and lowering crashes for specific
functions involving generic types that don't use a copy value
representation.

In lowering, be careful to distinguish between whether the initializing
representation for the generic return type uses a return slot (which
affects whether the SemIR declaration and call have one) and whether the
initializing representation for the specific return type uses a return
slot (which affects whether the LLVM IR declaration and call have one).
This commit is contained in:
Richard Smith
2025-09-15 23:59:00 +00:00
committed by GitHub
parent ca40e9d693
commit b44ba47cf3
53 changed files with 1375 additions and 670 deletions
+8 -6
View File
@@ -200,7 +200,7 @@ fn G() -> i32 {
// CHECK:STDOUT: %.Self: %type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %a.param: @F.%array_type.loc6_29.1 (%array_type.743) = value_param call_param0
// CHECK:STDOUT: %.loc6: type = splice_block %array_type.loc6_29.2 [symbolic = %array_type.loc6_29.1 (constants.%array_type.743)] {
// CHECK:STDOUT: %.loc6_29: type = splice_block %array_type.loc6_29.2 [symbolic = %array_type.loc6_29.1 (constants.%array_type.743)] {
// CHECK:STDOUT: %T.ref.loc6_25: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %int_3: Core.IntLiteral = int_value 3 [concrete = constants.%int_3]
// CHECK:STDOUT: %array_type.loc6_29.2: type = array_type %int_3, %T.ref.loc6_25 [symbolic = %array_type.loc6_29.1 (constants.%array_type.743)]
@@ -260,12 +260,13 @@ fn G() -> i32 {
// CHECK:STDOUT: %require_complete.loc6_17: <witness> = require_complete_type %array_type.loc6_29.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.06f)]
// CHECK:STDOUT: %F.specific_fn.loc6_46.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_46.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%a.param: @F.%array_type.loc6_29.1 (%array_type.743)) -> @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: fn(%a.param: @F.%array_type.loc6_29.1 (%array_type.743)) -> %return.param: @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %a.ref: @F.%array_type.loc6_29.1 (%array_type.743) = name_ref a, %a
// CHECK:STDOUT: %F.specific_fn.loc6_46.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %F.specific_fn.loc6_46.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_46.1(%a.ref)
// CHECK:STDOUT: %.loc6_32: ref @F.%T.loc6_6.1 (%T) = splice_block %return {}
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_46.1(%a.ref) to %.loc6_32
// CHECK:STDOUT: return %F.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -872,7 +873,7 @@ fn G() -> i32 {
// CHECK:STDOUT: %.Self: %type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %a.param: @F.%array_type.loc6_29.1 (%array_type.9d4) = value_param call_param0
// CHECK:STDOUT: %.loc6: type = splice_block %array_type.loc6_29.2 [symbolic = %array_type.loc6_29.1 (constants.%array_type.9d4)] {
// CHECK:STDOUT: %.loc6_29: type = splice_block %array_type.loc6_29.2 [symbolic = %array_type.loc6_29.1 (constants.%array_type.9d4)] {
// CHECK:STDOUT: %T.ref.loc6_25: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %int_2: Core.IntLiteral = int_value 2 [concrete = constants.%int_2]
// CHECK:STDOUT: %array_type.loc6_29.2: type = array_type %int_2, %T.ref.loc6_25 [symbolic = %array_type.loc6_29.1 (constants.%array_type.9d4)]
@@ -932,12 +933,13 @@ fn G() -> i32 {
// CHECK:STDOUT: %require_complete.loc6_17: <witness> = require_complete_type %array_type.loc6_29.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.d11)]
// CHECK:STDOUT: %F.specific_fn.loc6_46.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_46.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%a.param: @F.%array_type.loc6_29.1 (%array_type.9d4)) -> @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: fn(%a.param: @F.%array_type.loc6_29.1 (%array_type.9d4)) -> %return.param: @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %a.ref: @F.%array_type.loc6_29.1 (%array_type.9d4) = name_ref a, %a
// CHECK:STDOUT: %F.specific_fn.loc6_46.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %F.specific_fn.loc6_46.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_46.1(%a.ref)
// CHECK:STDOUT: %.loc6_32: ref @F.%T.loc6_6.1 (%T) = splice_block %return {}
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_46.1(%a.ref) to %.loc6_32
// CHECK:STDOUT: return %F.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
+4 -3
View File
@@ -145,7 +145,7 @@ fn G() -> i32 {
// CHECK:STDOUT: %.Self: %type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %T.loc7_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc7_6.1 (constants.%T)]
// CHECK:STDOUT: %p.param: @F.%C.loc7_22.1 (%C.f2e) = value_param call_param0
// CHECK:STDOUT: %.loc7: type = splice_block %C.loc7_22.2 [symbolic = %C.loc7_22.1 (constants.%C.f2e)] {
// CHECK:STDOUT: %.loc7_22: type = splice_block %C.loc7_22.2 [symbolic = %C.loc7_22.1 (constants.%C.f2e)] {
// CHECK:STDOUT: %C.ref: %C.type = name_ref C, file.%C.decl [concrete = constants.%C.generic]
// CHECK:STDOUT: %T.ref.loc7_21: type = name_ref T, %T.loc7_6.2 [symbolic = %T.loc7_6.1 (constants.%T)]
// CHECK:STDOUT: %C.loc7_22.2: type = class_type @C, @C(constants.%T) [symbolic = %C.loc7_22.1 (constants.%C.f2e)]
@@ -272,12 +272,13 @@ fn G() -> i32 {
// CHECK:STDOUT: %require_complete.loc7_17: <witness> = require_complete_type %C.loc7_22.1 [symbolic = %require_complete.loc7_17 (constants.%require_complete.389)]
// CHECK:STDOUT: %F.specific_fn.loc7_39.2: <specific function> = specific_function constants.%F, @F(%T.loc7_6.1) [symbolic = %F.specific_fn.loc7_39.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%p.param: @F.%C.loc7_22.1 (%C.f2e)) -> @F.%T.loc7_6.1 (%T) {
// CHECK:STDOUT: fn(%p.param: @F.%C.loc7_22.1 (%C.f2e)) -> %return.param: @F.%T.loc7_6.1 (%T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %p.ref: @F.%C.loc7_22.1 (%C.f2e) = name_ref p, %p
// CHECK:STDOUT: %F.specific_fn.loc7_39.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %F.specific_fn.loc7_39.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT: %F.call: init @F.%T.loc7_6.1 (%T) = call %F.specific_fn.loc7_39.1(%p.ref)
// CHECK:STDOUT: %.loc7_25: ref @F.%T.loc7_6.1 (%T) = splice_block %return {}
// CHECK:STDOUT: %F.call: init @F.%T.loc7_6.1 (%T) = call %F.specific_fn.loc7_39.1(%p.ref) to %.loc7_25
// CHECK:STDOUT: return %F.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
+3 -2
View File
@@ -235,12 +235,13 @@ fn G(pair: (C, D)) -> D {
// CHECK:STDOUT: %require_complete.loc7_30: <witness> = require_complete_type %tuple.type [symbolic = %require_complete.loc7_30 (constants.%require_complete.fe1)]
// CHECK:STDOUT: %F.specific_fn.loc7_54.2: <specific function> = specific_function constants.%F, @F(%T.loc7_6.1, %U.loc7_16.1) [symbolic = %F.specific_fn.loc7_54.2 (constants.%F.specific_fn.dd9)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%pair.param: @F.%tuple.type (%tuple.type.30b)) -> @F.%U.loc7_16.1 (%U) {
// CHECK:STDOUT: fn(%pair.param: @F.%tuple.type (%tuple.type.30b)) -> %return.param: @F.%U.loc7_16.1 (%U) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %pair.ref: @F.%tuple.type (%tuple.type.30b) = name_ref pair, %pair
// CHECK:STDOUT: %F.specific_fn.loc7_54.1: <specific function> = specific_function %F.ref, @F(constants.%T, constants.%U) [symbolic = %F.specific_fn.loc7_54.2 (constants.%F.specific_fn.dd9)]
// CHECK:STDOUT: %F.call: init @F.%U.loc7_16.1 (%U) = call %F.specific_fn.loc7_54.1(%pair.ref)
// CHECK:STDOUT: %.loc7_40: ref @F.%U.loc7_16.1 (%U) = splice_block %return {}
// CHECK:STDOUT: %F.call: init @F.%U.loc7_16.1 (%U) = call %F.specific_fn.loc7_54.1(%pair.ref) to %.loc7_40
// CHECK:STDOUT: return %F.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
+16 -12
View File
@@ -128,7 +128,7 @@ fn G(p: C*) -> const C {
// CHECK:STDOUT: %.Self: %type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %p.param: @F.%ptr.loc6_20.1 (%ptr.79f) = value_param call_param0
// CHECK:STDOUT: %.loc6: type = splice_block %ptr.loc6_20.2 [symbolic = %ptr.loc6_20.1 (constants.%ptr.79f)] {
// CHECK:STDOUT: %.loc6_20: type = splice_block %ptr.loc6_20.2 [symbolic = %ptr.loc6_20.1 (constants.%ptr.79f)] {
// CHECK:STDOUT: %T.ref.loc6_19: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %ptr.loc6_20.2: type = ptr_type %T.ref.loc6_19 [symbolic = %ptr.loc6_20.1 (constants.%ptr.79f)]
// CHECK:STDOUT: }
@@ -195,12 +195,13 @@ fn G(p: C*) -> const C {
// CHECK:STDOUT: %require_complete.loc6_17: <witness> = require_complete_type %ptr.loc6_20.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.6e5)]
// CHECK:STDOUT: %F.specific_fn.loc6_37.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_37.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc6_20.1 (%ptr.79f)) -> @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc6_20.1 (%ptr.79f)) -> %return.param: @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %p.ref: @F.%ptr.loc6_20.1 (%ptr.79f) = name_ref p, %p
// CHECK:STDOUT: %F.specific_fn.loc6_37.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %F.specific_fn.loc6_37.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_37.1(%p.ref)
// CHECK:STDOUT: %.loc6_23: ref @F.%T.loc6_6.1 (%T) = splice_block %return {}
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_37.1(%p.ref) to %.loc6_23
// CHECK:STDOUT: return %F.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -304,7 +305,7 @@ fn G(p: C*) -> const C {
// CHECK:STDOUT: %.Self: %type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %p.param: @F.%ptr.loc6_26.1 (%ptr.6d4) = value_param call_param0
// CHECK:STDOUT: %.loc6: type = splice_block %ptr.loc6_26.2 [symbolic = %ptr.loc6_26.1 (constants.%ptr.6d4)] {
// CHECK:STDOUT: %.loc6_26: type = splice_block %ptr.loc6_26.2 [symbolic = %ptr.loc6_26.1 (constants.%ptr.6d4)] {
// CHECK:STDOUT: %T.ref.loc6_25: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %const.loc6_19.2: type = const_type %T.ref.loc6_25 [symbolic = %const.loc6_19.1 (constants.%const.a1a)]
// CHECK:STDOUT: %ptr.loc6_26.2: type = ptr_type %const.loc6_19.2 [symbolic = %ptr.loc6_26.1 (constants.%ptr.6d4)]
@@ -374,12 +375,13 @@ fn G(p: C*) -> const C {
// CHECK:STDOUT: %require_complete.loc6_17: <witness> = require_complete_type %ptr.loc6_26.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.20b)]
// CHECK:STDOUT: %F.specific_fn.loc6_43.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc6_26.1 (%ptr.6d4)) -> @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc6_26.1 (%ptr.6d4)) -> %return.param: @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %p.ref: @F.%ptr.loc6_26.1 (%ptr.6d4) = name_ref p, %p
// CHECK:STDOUT: %F.specific_fn.loc6_43.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_43.1(%p.ref)
// CHECK:STDOUT: %.loc6_29: ref @F.%T.loc6_6.1 (%T) = splice_block %return {}
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_43.1(%p.ref) to %.loc6_29
// CHECK:STDOUT: return %F.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -484,7 +486,7 @@ fn G(p: C*) -> const C {
// CHECK:STDOUT: %.Self: %type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %p.param: @F.%ptr.loc6_20.1 (%ptr.79f) = value_param call_param0
// CHECK:STDOUT: %.loc6: type = splice_block %ptr.loc6_20.2 [symbolic = %ptr.loc6_20.1 (constants.%ptr.79f)] {
// CHECK:STDOUT: %.loc6_20: type = splice_block %ptr.loc6_20.2 [symbolic = %ptr.loc6_20.1 (constants.%ptr.79f)] {
// CHECK:STDOUT: %T.ref.loc6_19: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %ptr.loc6_20.2: type = ptr_type %T.ref.loc6_19 [symbolic = %ptr.loc6_20.1 (constants.%ptr.79f)]
// CHECK:STDOUT: }
@@ -553,12 +555,13 @@ fn G(p: C*) -> const C {
// CHECK:STDOUT: %require_complete.loc6_17: <witness> = require_complete_type %ptr.loc6_20.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.6e5)]
// CHECK:STDOUT: %F.specific_fn.loc6_37.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_37.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc6_20.1 (%ptr.79f)) -> @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc6_20.1 (%ptr.79f)) -> %return.param: @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %p.ref: @F.%ptr.loc6_20.1 (%ptr.79f) = name_ref p, %p
// CHECK:STDOUT: %F.specific_fn.loc6_37.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %F.specific_fn.loc6_37.2 (constants.%F.specific_fn.ef1)]
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_37.1(%p.ref)
// CHECK:STDOUT: %.loc6_23: ref @F.%T.loc6_6.1 (%T) = splice_block %return {}
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_37.1(%p.ref) to %.loc6_23
// CHECK:STDOUT: return %F.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }
@@ -658,7 +661,7 @@ fn G(p: C*) -> const C {
// CHECK:STDOUT: %.Self: %type = bind_symbolic_name .Self [symbolic_self = constants.%.Self]
// CHECK:STDOUT: %T.loc6_6.2: type = bind_symbolic_name T, 0 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %p.param: @F.%ptr.loc6_26.1 (%ptr.6d4) = value_param call_param0
// CHECK:STDOUT: %.loc6: type = splice_block %ptr.loc6_26.2 [symbolic = %ptr.loc6_26.1 (constants.%ptr.6d4)] {
// CHECK:STDOUT: %.loc6_26: type = splice_block %ptr.loc6_26.2 [symbolic = %ptr.loc6_26.1 (constants.%ptr.6d4)] {
// CHECK:STDOUT: %T.ref.loc6_25: type = name_ref T, %T.loc6_6.2 [symbolic = %T.loc6_6.1 (constants.%T)]
// CHECK:STDOUT: %const.loc6_19.2: type = const_type %T.ref.loc6_25 [symbolic = %const.loc6_19.1 (constants.%const.a1a)]
// CHECK:STDOUT: %ptr.loc6_26.2: type = ptr_type %const.loc6_19.2 [symbolic = %ptr.loc6_26.1 (constants.%ptr.6d4)]
@@ -728,12 +731,13 @@ fn G(p: C*) -> const C {
// CHECK:STDOUT: %require_complete.loc6_17: <witness> = require_complete_type %ptr.loc6_26.1 [symbolic = %require_complete.loc6_17 (constants.%require_complete.20b)]
// CHECK:STDOUT: %F.specific_fn.loc6_43.2: <specific function> = specific_function constants.%F, @F(%T.loc6_6.1) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn)]
// CHECK:STDOUT:
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc6_26.1 (%ptr.6d4)) -> @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: fn(%p.param: @F.%ptr.loc6_26.1 (%ptr.6d4)) -> %return.param: @F.%T.loc6_6.1 (%T) {
// CHECK:STDOUT: !entry:
// CHECK:STDOUT: %F.ref: %F.type = name_ref F, file.%F.decl [concrete = constants.%F]
// CHECK:STDOUT: %p.ref: @F.%ptr.loc6_26.1 (%ptr.6d4) = name_ref p, %p
// CHECK:STDOUT: %F.specific_fn.loc6_43.1: <specific function> = specific_function %F.ref, @F(constants.%T) [symbolic = %F.specific_fn.loc6_43.2 (constants.%F.specific_fn)]
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_43.1(%p.ref)
// CHECK:STDOUT: %.loc6_29: ref @F.%T.loc6_6.1 (%T) = splice_block %return {}
// CHECK:STDOUT: %F.call: init @F.%T.loc6_6.1 (%T) = call %F.specific_fn.loc6_43.1(%p.ref) to %.loc6_29
// CHECK:STDOUT: return %F.call to %return
// CHECK:STDOUT: }
// CHECK:STDOUT: }