diff --git a/toolchain/check/convert.cpp b/toolchain/check/convert.cpp index 7fa08d3cf330..75d636caf28f 100644 --- a/toolchain/check/convert.cpp +++ b/toolchain/check/convert.cpp @@ -1451,6 +1451,7 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, if (expr_id == SemIR::ErrorInst::InstId) { return expr_id; } + bool performed_builtin_conversion = expr_id != orig_expr_id; // Defer the action if it's dependent. We do this now rather than before // attempting any conversion so that we can still perform builtin conversions @@ -1552,10 +1553,10 @@ auto Convert(Context& context, SemIR::LocId loc_id, SemIR::InstId expr_id, case SemIR::ExprCategory::Initializing: if (target.is_initializer()) { - if (orig_expr_id == expr_id) { + if (!performed_builtin_conversion) { // Don't fill in the return slot if we created the expression through - // a conversion. In that case, we will have created it with the - // target already set. + // a builtin conversion. In that case, we will have created it with + // the target already set. // TODO: Find a better way to track whether we need to do this. MarkInitializerFor(sem_ir, expr_id, target); } diff --git a/toolchain/check/testdata/as/var_init.carbon b/toolchain/check/testdata/as/var_init.carbon new file mode 100644 index 000000000000..9d1972e172f0 --- /dev/null +++ b/toolchain/check/testdata/as/var_init.carbon @@ -0,0 +1,79 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/convert.carbon +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/as/var_init.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/as/var_init.carbon + +// --- var_init.carbon + +library "[[@TEST_NAME]]"; + +class X { + impl () as Core.ImplicitAs(X) { + fn Convert[self: ()]() -> X { return {}; } + } +} + +fn Convert(t: ()) { + //@dump-sem-ir-begin + var x: X = (); + //@dump-sem-ir-end +} + + +// CHECK:STDOUT: --- var_init.carbon +// CHECK:STDOUT: +// CHECK:STDOUT: constants { +// CHECK:STDOUT: %X: type = class_type @X [concrete] +// CHECK:STDOUT: %empty_tuple.type: type = tuple_type () [concrete] +// CHECK:STDOUT: %ImplicitAs.type.179: type = facet_type <@ImplicitAs, @ImplicitAs(%X)> [concrete] +// CHECK:STDOUT: %ImplicitAs.Convert.type.665: type = fn_type @ImplicitAs.Convert, @ImplicitAs(%X) [concrete] +// CHECK:STDOUT: %ImplicitAs.impl_witness: = impl_witness @X.%ImplicitAs.impl_witness_table [concrete] +// CHECK:STDOUT: %pattern_type.019: type = pattern_type %X [concrete] +// CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert.type: type = fn_type @empty_tuple.type.as.ImplicitAs.impl.Convert [concrete] +// CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert: %empty_tuple.type.as.ImplicitAs.impl.Convert.type = struct_value () [concrete] +// CHECK:STDOUT: %ImplicitAs.facet: %ImplicitAs.type.179 = facet_value %empty_tuple.type, (%ImplicitAs.impl_witness) [concrete] +// CHECK:STDOUT: %.f5e: type = fn_type_with_self_type %ImplicitAs.Convert.type.665, %ImplicitAs.facet [concrete] +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete] +// CHECK:STDOUT: %type_where: type = facet_type > [concrete] +// CHECK:STDOUT: %facet_value: %type_where = facet_value %X, () [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.bd5: type = fn_type @DestroyT.binding.as_type.as.Destroy.impl.Op, @DestroyT.binding.as_type.as.Destroy.impl(%facet_value) [concrete] +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.1c8: %DestroyT.binding.as_type.as.Destroy.impl.Op.type.bd5 = struct_value () [concrete] +// CHECK:STDOUT: %ptr.d17: type = ptr_type %X [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: imports { +// CHECK:STDOUT: } +// CHECK:STDOUT: +// CHECK:STDOUT: fn @Convert(%t.param: %empty_tuple.type) { +// CHECK:STDOUT: !entry: +// CHECK:STDOUT: name_binding_decl { +// CHECK:STDOUT: %x.patt: %pattern_type.019 = ref_binding_pattern x [concrete] +// CHECK:STDOUT: %x.var_patt: %pattern_type.019 = var_pattern %x.patt [concrete] +// CHECK:STDOUT: } +// CHECK:STDOUT: %x.var: ref %X = var %x.var_patt +// CHECK:STDOUT: %.loc12_15.1: %empty_tuple.type = tuple_literal () +// CHECK:STDOUT: %impl.elem0: %.f5e = impl_witness_access constants.%ImplicitAs.impl_witness, element0 [concrete = constants.%empty_tuple.type.as.ImplicitAs.impl.Convert] +// CHECK:STDOUT: %bound_method.loc12_3.1: = bound_method %.loc12_15.1, %impl.elem0 +// CHECK:STDOUT: %.loc12_3.1: ref %X = splice_block %x.var {} +// CHECK:STDOUT: %empty_tuple: %empty_tuple.type = tuple_value () [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %.loc12_15.2: %empty_tuple.type = converted %.loc12_15.1, %empty_tuple [concrete = constants.%empty_tuple] +// CHECK:STDOUT: %empty_tuple.type.as.ImplicitAs.impl.Convert.call: init %X = call %bound_method.loc12_3.1(%.loc12_15.2) to %.loc12_3.1 +// CHECK:STDOUT: %.loc12_3.2: init %X = converted %.loc12_15.1, %empty_tuple.type.as.ImplicitAs.impl.Convert.call +// CHECK:STDOUT: assign %x.var, %.loc12_3.2 +// CHECK:STDOUT: %X.ref: type = name_ref X, file.%X.decl [concrete = constants.%X] +// CHECK:STDOUT: %x: ref %X = ref_binding x, %x.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound: = bound_method %x.var, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.1c8 +// CHECK:STDOUT: +// CHECK:STDOUT: %bound_method.loc12_3.2: = bound_method %x.var, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn +// CHECK:STDOUT: %addr: %ptr.d17 = addr_of %x.var +// CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call: init %empty_tuple.type = call %bound_method.loc12_3.2(%addr) +// CHECK:STDOUT: +// CHECK:STDOUT: } +// CHECK:STDOUT: diff --git a/toolchain/check/testdata/return/import_convert_function.carbon b/toolchain/check/testdata/return/import_convert_function.carbon index ca86722299ed..817a3a7ddc61 100644 --- a/toolchain/check/testdata/return/import_convert_function.carbon +++ b/toolchain/check/testdata/return/import_convert_function.carbon @@ -1048,16 +1048,16 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc7_26.1: ref %C.b00 = converted %.loc7_24.1, %.loc7_24.4 // CHECK:STDOUT: %impl.elem0.loc7_35: %.e33 = impl_witness_access constants.%ImplicitAs.impl_witness.541, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.43b] // CHECK:STDOUT: %bound_method.loc7_35: = bound_method %.loc7_26.1, %impl.elem0.loc7_35 -// CHECK:STDOUT: %.loc7_35.1: ref %D = temporary_storage +// CHECK:STDOUT: %.loc6_15.1: ref %D = splice_block %return {} // CHECK:STDOUT: %.loc7_26.2: %C.b00 = acquire_value %.loc7_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc7: init %D = call %bound_method.loc7_35(%.loc7_26.2) to %.loc7_35.1 -// CHECK:STDOUT: %.loc7_35.2: init %D = converted %.loc7_26.1, %C.as.ImplicitAs.impl.Convert.call.loc7 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc7: init %D = call %bound_method.loc7_35(%.loc7_26.2) to %.loc6_15.1 +// CHECK:STDOUT: %.loc7_35: init %D = converted %.loc7_26.1, %C.as.ImplicitAs.impl.Convert.call.loc7 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc7_24.1: = bound_method %.loc7_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.9ed // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.9ed, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.e56) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.67c] // CHECK:STDOUT: %bound_method.loc7_24.1: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.1 // CHECK:STDOUT: %addr.loc7_24.1: %ptr.697 = addr_of %.loc7_24.4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.1: init %empty_tuple.type = call %bound_method.loc7_24.1(%addr.loc7_24.1) -// CHECK:STDOUT: return %.loc7_35.2 to %return +// CHECK:STDOUT: return %.loc7_35 to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else.loc7: // CHECK:STDOUT: %false.loc8: bool = bool_literal false [concrete = constants.%false] @@ -1082,10 +1082,10 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc8_26.1: ref %C.674 = converted %.loc8_24.1, %.loc8_24.4 // CHECK:STDOUT: %impl.elem0.loc8_35: %.5da = impl_witness_access constants.%ImplicitAs.impl_witness.371, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.e68] // CHECK:STDOUT: %bound_method.loc8_35: = bound_method %.loc8_26.1, %impl.elem0.loc8_35 -// CHECK:STDOUT: %.loc8_35.1: ref %D = temporary_storage +// CHECK:STDOUT: %.loc6_15.2: ref %D = splice_block %return {} // CHECK:STDOUT: %.loc8_26.2: %C.674 = acquire_value %.loc8_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc8: init %D = call %bound_method.loc8_35(%.loc8_26.2) to %.loc8_35.1 -// CHECK:STDOUT: %.loc8_35.2: init %D = converted %.loc8_26.1, %C.as.ImplicitAs.impl.Convert.call.loc8 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc8: init %D = call %bound_method.loc8_35(%.loc8_26.2) to %.loc6_15.2 +// CHECK:STDOUT: %.loc8_35: init %D = converted %.loc8_26.1, %C.as.ImplicitAs.impl.Convert.call.loc8 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc8_24.1: = bound_method %.loc8_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.d98 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.d98, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.4dd) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.466] // CHECK:STDOUT: %bound_method.loc8_24.1: = bound_method %.loc8_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.2 @@ -1096,7 +1096,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %bound_method.loc7_24.2: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.3 // CHECK:STDOUT: %addr.loc7_24.2: %ptr.697 = addr_of %.loc7_24.4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.2: init %empty_tuple.type = call %bound_method.loc7_24.2(%addr.loc7_24.2) -// CHECK:STDOUT: return %.loc8_35.2 to %return +// CHECK:STDOUT: return %.loc8_35 to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else.loc8: // CHECK:STDOUT: %false.loc9: bool = bool_literal false [concrete = constants.%false] @@ -1121,10 +1121,10 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc9_26.1: ref %C.681 = converted %.loc9_24.1, %.loc9_24.4 // CHECK:STDOUT: %impl.elem0.loc9_35: %.b2b = impl_witness_access constants.%ImplicitAs.impl_witness.2a3, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.cb1] // CHECK:STDOUT: %bound_method.loc9_35: = bound_method %.loc9_26.1, %impl.elem0.loc9_35 -// CHECK:STDOUT: %.loc9_35.1: ref %D = temporary_storage +// CHECK:STDOUT: %.loc6_15.3: ref %D = splice_block %return {} // CHECK:STDOUT: %.loc9_26.2: %C.681 = acquire_value %.loc9_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc9: init %D = call %bound_method.loc9_35(%.loc9_26.2) to %.loc9_35.1 -// CHECK:STDOUT: %.loc9_35.2: init %D = converted %.loc9_26.1, %C.as.ImplicitAs.impl.Convert.call.loc9 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc9: init %D = call %bound_method.loc9_35(%.loc9_26.2) to %.loc6_15.3 +// CHECK:STDOUT: %.loc9_35: init %D = converted %.loc9_26.1, %C.as.ImplicitAs.impl.Convert.call.loc9 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc9_24.1: = bound_method %.loc9_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.ce4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.4: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.ce4, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.7fe) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.cfd] // CHECK:STDOUT: %bound_method.loc9_24.1: = bound_method %.loc9_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.4 @@ -1140,7 +1140,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %bound_method.loc7_24.3: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.6 // CHECK:STDOUT: %addr.loc7_24.3: %ptr.697 = addr_of %.loc7_24.4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.3: init %empty_tuple.type = call %bound_method.loc7_24.3(%addr.loc7_24.3) -// CHECK:STDOUT: return %.loc9_35.2 to %return +// CHECK:STDOUT: return %.loc9_35 to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else.loc9: // CHECK:STDOUT: %false.loc10: bool = bool_literal false [concrete = constants.%false] @@ -1165,10 +1165,10 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc10_26.1: ref %C.7ac = converted %.loc10_24.1, %.loc10_24.4 // CHECK:STDOUT: %impl.elem0.loc10_35: %.11b = impl_witness_access constants.%ImplicitAs.impl_witness.29c, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.67e] // CHECK:STDOUT: %bound_method.loc10_35: = bound_method %.loc10_26.1, %impl.elem0.loc10_35 -// CHECK:STDOUT: %.loc10_35.1: ref %D = temporary_storage +// CHECK:STDOUT: %.loc6_15.4: ref %D = splice_block %return {} // CHECK:STDOUT: %.loc10_26.2: %C.7ac = acquire_value %.loc10_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc10: init %D = call %bound_method.loc10_35(%.loc10_26.2) to %.loc10_35.1 -// CHECK:STDOUT: %.loc10_35.2: init %D = converted %.loc10_26.1, %C.as.ImplicitAs.impl.Convert.call.loc10 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc10: init %D = call %bound_method.loc10_35(%.loc10_26.2) to %.loc6_15.4 +// CHECK:STDOUT: %.loc10_35: init %D = converted %.loc10_26.1, %C.as.ImplicitAs.impl.Convert.call.loc10 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc10_24.1: = bound_method %.loc10_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.931 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.7: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.931, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.99b) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.20a] // CHECK:STDOUT: %bound_method.loc10_24.1: = bound_method %.loc10_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.7 @@ -1189,7 +1189,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %bound_method.loc7_24.4: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.10 // CHECK:STDOUT: %addr.loc7_24.4: %ptr.697 = addr_of %.loc7_24.4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.4: init %empty_tuple.type = call %bound_method.loc7_24.4(%addr.loc7_24.4) -// CHECK:STDOUT: return %.loc10_35.2 to %return +// CHECK:STDOUT: return %.loc10_35 to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else.loc10: // CHECK:STDOUT: %false.loc11: bool = bool_literal false [concrete = constants.%false] @@ -1214,10 +1214,10 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc11_26.1: ref %C.89d = converted %.loc11_24.1, %.loc11_24.4 // CHECK:STDOUT: %impl.elem0.loc11_35: %.0dc = impl_witness_access constants.%ImplicitAs.impl_witness.565, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.58d] // CHECK:STDOUT: %bound_method.loc11_35: = bound_method %.loc11_26.1, %impl.elem0.loc11_35 -// CHECK:STDOUT: %.loc11_35.1: ref %D = temporary_storage +// CHECK:STDOUT: %.loc6_15.5: ref %D = splice_block %return {} // CHECK:STDOUT: %.loc11_26.2: %C.89d = acquire_value %.loc11_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc11: init %D = call %bound_method.loc11_35(%.loc11_26.2) to %.loc11_35.1 -// CHECK:STDOUT: %.loc11_35.2: init %D = converted %.loc11_26.1, %C.as.ImplicitAs.impl.Convert.call.loc11 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc11: init %D = call %bound_method.loc11_35(%.loc11_26.2) to %.loc6_15.5 +// CHECK:STDOUT: %.loc11_35: init %D = converted %.loc11_26.1, %C.as.ImplicitAs.impl.Convert.call.loc11 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc11_24.1: = bound_method %.loc11_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.d47 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.11: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.d47, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.b4c) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.fe8] // CHECK:STDOUT: %bound_method.loc11_24.1: = bound_method %.loc11_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.11 @@ -1243,7 +1243,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %bound_method.loc7_24.5: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.15 // CHECK:STDOUT: %addr.loc7_24.5: %ptr.697 = addr_of %.loc7_24.4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.5: init %empty_tuple.type = call %bound_method.loc7_24.5(%addr.loc7_24.5) -// CHECK:STDOUT: return %.loc11_35.2 to %return +// CHECK:STDOUT: return %.loc11_35 to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else.loc11: // CHECK:STDOUT: %false.loc12: bool = bool_literal false [concrete = constants.%false] @@ -1268,10 +1268,10 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc12_26.1: ref %C.f0a = converted %.loc12_24.1, %.loc12_24.4 // CHECK:STDOUT: %impl.elem0.loc12_35: %.332 = impl_witness_access constants.%ImplicitAs.impl_witness.c1a, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.a45] // CHECK:STDOUT: %bound_method.loc12_35: = bound_method %.loc12_26.1, %impl.elem0.loc12_35 -// CHECK:STDOUT: %.loc12_35.1: ref %D = temporary_storage +// CHECK:STDOUT: %.loc6_15.6: ref %D = splice_block %return {} // CHECK:STDOUT: %.loc12_26.2: %C.f0a = acquire_value %.loc12_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc12: init %D = call %bound_method.loc12_35(%.loc12_26.2) to %.loc12_35.1 -// CHECK:STDOUT: %.loc12_35.2: init %D = converted %.loc12_26.1, %C.as.ImplicitAs.impl.Convert.call.loc12 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc12: init %D = call %bound_method.loc12_35(%.loc12_26.2) to %.loc6_15.6 +// CHECK:STDOUT: %.loc12_35: init %D = converted %.loc12_26.1, %C.as.ImplicitAs.impl.Convert.call.loc12 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc12_24.1: = bound_method %.loc12_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.217 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.16: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.217, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.430) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.bcb] // CHECK:STDOUT: %bound_method.loc12_24.1: = bound_method %.loc12_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.16 @@ -1302,7 +1302,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %bound_method.loc7_24.6: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.21 // CHECK:STDOUT: %addr.loc7_24.6: %ptr.697 = addr_of %.loc7_24.4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.6: init %empty_tuple.type = call %bound_method.loc7_24.6(%addr.loc7_24.6) -// CHECK:STDOUT: return %.loc12_35.2 to %return +// CHECK:STDOUT: return %.loc12_35 to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else.loc12: // CHECK:STDOUT: %false.loc13: bool = bool_literal false [concrete = constants.%false] @@ -1327,10 +1327,10 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc13_26.1: ref %C.c60 = converted %.loc13_24.1, %.loc13_24.4 // CHECK:STDOUT: %impl.elem0.loc13_35: %.1bb = impl_witness_access constants.%ImplicitAs.impl_witness.ebf, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.ad0] // CHECK:STDOUT: %bound_method.loc13_35: = bound_method %.loc13_26.1, %impl.elem0.loc13_35 -// CHECK:STDOUT: %.loc13_35.1: ref %D = temporary_storage +// CHECK:STDOUT: %.loc6_15.7: ref %D = splice_block %return {} // CHECK:STDOUT: %.loc13_26.2: %C.c60 = acquire_value %.loc13_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc13: init %D = call %bound_method.loc13_35(%.loc13_26.2) to %.loc13_35.1 -// CHECK:STDOUT: %.loc13_35.2: init %D = converted %.loc13_26.1, %C.as.ImplicitAs.impl.Convert.call.loc13 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc13: init %D = call %bound_method.loc13_35(%.loc13_26.2) to %.loc6_15.7 +// CHECK:STDOUT: %.loc13_35: init %D = converted %.loc13_26.1, %C.as.ImplicitAs.impl.Convert.call.loc13 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc13_24.1: = bound_method %.loc13_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.bf7 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.22: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.bf7, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.14a) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.5e9] // CHECK:STDOUT: %bound_method.loc13_24.1: = bound_method %.loc13_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.22 @@ -1366,7 +1366,7 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %bound_method.loc7_24.7: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.28 // CHECK:STDOUT: %addr.loc7_24.7: %ptr.697 = addr_of %.loc7_24.4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.7: init %empty_tuple.type = call %bound_method.loc7_24.7(%addr.loc7_24.7) -// CHECK:STDOUT: return %.loc13_35.2 to %return +// CHECK:STDOUT: return %.loc13_35 to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else.loc13: // CHECK:STDOUT: %false.loc14: bool = bool_literal false [concrete = constants.%false] @@ -1391,10 +1391,10 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %.loc14_26.1: ref %C.304 = converted %.loc14_24.1, %.loc14_24.4 // CHECK:STDOUT: %impl.elem0.loc14_35: %.bc1 = impl_witness_access constants.%ImplicitAs.impl_witness.b93, element0 [concrete = constants.%C.as.ImplicitAs.impl.Convert.9be] // CHECK:STDOUT: %bound_method.loc14_35: = bound_method %.loc14_26.1, %impl.elem0.loc14_35 -// CHECK:STDOUT: %.loc14_35.1: ref %D = temporary_storage +// CHECK:STDOUT: %.loc6_15.8: ref %D = splice_block %return {} // CHECK:STDOUT: %.loc14_26.2: %C.304 = acquire_value %.loc14_26.1 -// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc14: init %D = call %bound_method.loc14_35(%.loc14_26.2) to %.loc14_35.1 -// CHECK:STDOUT: %.loc14_35.2: init %D = converted %.loc14_26.1, %C.as.ImplicitAs.impl.Convert.call.loc14 +// CHECK:STDOUT: %C.as.ImplicitAs.impl.Convert.call.loc14: init %D = call %bound_method.loc14_35(%.loc14_26.2) to %.loc6_15.8 +// CHECK:STDOUT: %.loc14_35: init %D = converted %.loc14_26.1, %C.as.ImplicitAs.impl.Convert.call.loc14 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc14_24.1: = bound_method %.loc14_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.85d // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.29: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.85d, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.488) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.eb6] // CHECK:STDOUT: %bound_method.loc14_24.1: = bound_method %.loc14_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.29 @@ -1435,13 +1435,13 @@ fn F0(n: i32) -> P.D { // CHECK:STDOUT: %bound_method.loc7_24.8: = bound_method %.loc7_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.36 // CHECK:STDOUT: %addr.loc7_24.8: %ptr.697 = addr_of %.loc7_24.4 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.call.loc7_24.8: init %empty_tuple.type = call %bound_method.loc7_24.8(%addr.loc7_24.8) -// CHECK:STDOUT: return %.loc14_35.2 to %return +// CHECK:STDOUT: return %.loc14_35 to %return // CHECK:STDOUT: // CHECK:STDOUT: !if.else.loc14: // CHECK:STDOUT: %P.ref.loc15: = name_ref P, imports.%P [concrete = imports.%P] // CHECK:STDOUT: %Make.ref: %Make.type = name_ref Make, imports.%P.Make [concrete = constants.%Make] -// CHECK:STDOUT: %.loc6_15: ref %D = splice_block %return {} -// CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc6_15 +// CHECK:STDOUT: %.loc6_15.9: ref %D = splice_block %return {} +// CHECK:STDOUT: %Make.call: init %D = call %Make.ref() to %.loc6_15.9 // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.bound.loc14_24.2: = bound_method %.loc14_24.4, constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.85d // CHECK:STDOUT: %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.37: = specific_function constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.85d, @DestroyT.binding.as_type.as.Destroy.impl.Op(constants.%facet_value.488) [concrete = constants.%DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.eb6] // CHECK:STDOUT: %bound_method.loc14_24.2: = bound_method %.loc14_24.4, %DestroyT.binding.as_type.as.Destroy.impl.Op.specific_fn.37 diff --git a/toolchain/lower/testdata/impl/import_thunk.carbon b/toolchain/lower/testdata/impl/import_thunk.carbon index 3d784d95071d..27e697a82143 100644 --- a/toolchain/lower/testdata/impl/import_thunk.carbon +++ b/toolchain/lower/testdata/impl/import_thunk.carbon @@ -104,13 +104,11 @@ fn Test(a: A) -> C { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc20_19.1.temp = alloca { i32 }, align 8, !dbg !19 // CHECK:STDOUT: %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !20 -// CHECK:STDOUT: %.loc20_19.2.temp = alloca { i32 }, align 8, !dbg !19 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_19.1.temp), !dbg !19 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc16_9.1.temp), !dbg !20 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !20 // CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !19 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_19.2.temp), !dbg !19 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc20_19.2.temp, ptr %.loc20_19.1.temp), !dbg !19 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc20_19.1.temp), !dbg !19 // CHECK:STDOUT: ret void, !dbg !19 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -118,7 +116,7 @@ fn Test(a: A) -> C { // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2 // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { alwaysinline nounwind } @@ -157,14 +155,12 @@ fn Test(a: A) -> C { // CHECK:STDOUT: %.loc7_20.1.temp = alloca { i32 }, align 8, !dbg !7 // CHECK:STDOUT: %.loc7_20.2.temp = alloca { i32 }, align 8, !dbg !7 // CHECK:STDOUT: %.loc7_19.1.temp = alloca { i32 }, align 8, !dbg !8 -// CHECK:STDOUT: %.loc7_21.1.temp = alloca { i32 }, align 8, !dbg !9 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_20.1.temp), !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_20.2.temp), !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_19.1.temp), !dbg !8 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc7_19.1.temp, ptr %a), !dbg !8 // CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc7_20.2.temp, ptr %.loc7_19.1.temp), !dbg !7 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc7_21.1.temp), !dbg !9 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc7_21.1.temp, ptr %.loc7_20.2.temp), !dbg !9 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc7_20.2.temp), !dbg !9 // CHECK:STDOUT: ret void, !dbg !9 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -180,7 +176,7 @@ fn Test(a: A) -> C { // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 3, 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } @@ -216,13 +212,11 @@ fn Test(a: A) -> C { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc9_19.1.temp = alloca { i32 }, align 8, !dbg !11 // CHECK:STDOUT: %.2.temp = alloca { i32 }, align 8 -// CHECK:STDOUT: %.loc9_19.2.temp = alloca { i32 }, align 8, !dbg !11 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc9_19.1.temp), !dbg !11 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.2.temp) // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.2.temp, ptr %a), !dbg !12 // CHECK:STDOUT: call void @"_CF.X.Main:I.Main"(ptr %.loc9_19.1.temp, ptr %.2.temp), !dbg !11 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc9_19.2.temp), !dbg !11 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc9_19.2.temp, ptr %.loc9_19.1.temp), !dbg !11 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc9_19.1.temp), !dbg !11 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -234,7 +228,7 @@ fn Test(a: A) -> C { // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2 // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { alwaysinline nounwind } @@ -265,14 +259,12 @@ fn Test(a: A) -> C { // CHECK:STDOUT: %.loc8_19.1.temp = alloca { i32 }, align 8, !dbg !7 // CHECK:STDOUT: %.loc8_19.2.temp = alloca { i32 }, align 8, !dbg !7 // CHECK:STDOUT: %.loc8_18.1.temp = alloca { i32 }, align 8, !dbg !8 -// CHECK:STDOUT: %.loc8_20.1.temp = alloca { i32 }, align 8, !dbg !9 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_19.1.temp), !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_19.2.temp), !dbg !7 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_18.1.temp), !dbg !8 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc8_18.1.temp, ptr %a), !dbg !8 // CHECK:STDOUT: call void @"_CF.X.Main:I.Main"(ptr %.loc8_19.2.temp, ptr %.loc8_18.1.temp), !dbg !7 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc8_20.1.temp), !dbg !9 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc8_20.1.temp, ptr %.loc8_19.2.temp), !dbg !9 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc8_19.2.temp), !dbg !9 // CHECK:STDOUT: ret void, !dbg !9 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -288,7 +280,7 @@ fn Test(a: A) -> C { // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 3, 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } diff --git a/toolchain/lower/testdata/impl/thunk.carbon b/toolchain/lower/testdata/impl/thunk.carbon index ecb3065bf63f..f25e74d0a3ce 100644 --- a/toolchain/lower/testdata/impl/thunk.carbon +++ b/toolchain/lower/testdata/impl/thunk.carbon @@ -108,13 +108,11 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc20_19.1.temp = alloca { i32 }, align 8, !dbg !19 // CHECK:STDOUT: %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !20 -// CHECK:STDOUT: %.loc20_19.2.temp = alloca { i32 }, align 8, !dbg !19 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_19.1.temp), !dbg !19 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc16_9.1.temp), !dbg !20 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !20 // CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !19 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc20_19.2.temp), !dbg !19 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc20_19.2.temp, ptr %.loc20_19.1.temp), !dbg !19 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc20_19.1.temp), !dbg !19 // CHECK:STDOUT: ret void, !dbg !19 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -124,14 +122,12 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: %.loc24_20.1.temp = alloca { i32 }, align 8, !dbg !22 // CHECK:STDOUT: %.loc24_20.2.temp = alloca { i32 }, align 8, !dbg !22 // CHECK:STDOUT: %.loc24_19.1.temp = alloca { i32 }, align 8, !dbg !23 -// CHECK:STDOUT: %.loc24_21.1.temp = alloca { i32 }, align 8, !dbg !24 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_20.1.temp), !dbg !22 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_20.2.temp), !dbg !22 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_19.1.temp), !dbg !23 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc24_19.1.temp, ptr %a), !dbg !23 // CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc24_20.2.temp, ptr %.loc24_19.1.temp), !dbg !22 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_21.1.temp), !dbg !24 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc24_21.1.temp, ptr %.loc24_20.2.temp), !dbg !24 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc24_20.2.temp), !dbg !24 // CHECK:STDOUT: ret void, !dbg !24 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -139,7 +135,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2 // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 6, 5, 4, 3, 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 4, 3, 2, 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { alwaysinline nounwind } @@ -193,7 +189,6 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: %.loc22_23.3.temp = alloca {}, align 8, !dbg !9 // CHECK:STDOUT: %.loc22_23.7.temp = alloca {}, align 8, !dbg !9 // CHECK:STDOUT: %.loc22_22.1.temp = alloca {}, align 8, !dbg !10 -// CHECK:STDOUT: %.loc22_24.1.temp = alloca {}, align 8, !dbg !11 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_23.1.temp), !dbg !9 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_23.3.temp), !dbg !9 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_23.3.temp, ptr %b), !dbg !9 @@ -201,8 +196,7 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_22.1.temp), !dbg !10 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_22.1.temp, ptr %b), !dbg !10 // CHECK:STDOUT: call void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr %.loc22_23.7.temp, ptr %c, ptr %.loc22_22.1.temp), !dbg !9 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc22_24.1.temp), !dbg !11 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_24.1.temp, ptr %.loc22_23.7.temp), !dbg !11 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc22_23.7.temp), !dbg !11 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -239,20 +233,18 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: %.loc18_31.2.temp = alloca {}, align 8, !dbg !21 // CHECK:STDOUT: %.loc18_31.6.temp = alloca {}, align 8, !dbg !21 // CHECK:STDOUT: %.loc12_21.1.temp = alloca {}, align 8, !dbg !22 -// CHECK:STDOUT: %.loc18_31.7.temp = alloca {}, align 8, !dbg !21 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_31.2.temp), !dbg !21 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc18_31.2.temp, ptr %x), !dbg !21 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_31.6.temp), !dbg !21 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc12_21.1.temp), !dbg !22 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc12_21.1.temp, ptr %x), !dbg !22 // CHECK:STDOUT: call void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr %.loc18_31.6.temp, ptr %self, ptr %.loc12_21.1.temp), !dbg !21 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_31.7.temp), !dbg !21 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc18_31.7.temp, ptr %.loc18_31.6.temp), !dbg !21 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %return, ptr %.loc18_31.6.temp), !dbg !21 // CHECK:STDOUT: ret void, !dbg !21 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 8, 7, 6, 5, 4 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 6, 5, 4, 3 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } diff --git a/toolchain/lower/testdata/primitives/optional.carbon b/toolchain/lower/testdata/primitives/optional.carbon index 051e873a9c24..683771ac142c 100644 --- a/toolchain/lower/testdata/primitives/optional.carbon +++ b/toolchain/lower/testdata/primitives/optional.carbon @@ -21,8 +21,6 @@ fn Convert(o: Core.Optional(i32*)) -> Core.Optional(i32) { } fn AddOrRemoveConst(a: i32, b: const i32) { - // TODO: The code generated for these conversions is wrong: we initialize a - // temporary rather than the local variable. var oa: Core.Optional(i32) = a; var coa: const Core.Optional(i32) = a; var oca: Core.Optional(const i32) = a; @@ -39,16 +37,14 @@ fn AddOrRemoveConst(a: i32, b: const i32) { // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define void @_CConvert.Main(ptr sret({ i32, i1 }) %return, ptr %o) #0 !dbg !4 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: %.loc18_20.1.temp = alloca { i32, i1 }, align 8, !dbg !7 -// CHECK:STDOUT: %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.217efae529e578bc(ptr %o), !dbg !8 -// CHECK:STDOUT: br i1 %Optional.HasValue.call, label %if.then, label %if.else, !dbg !9 +// CHECK:STDOUT: %Optional.HasValue.call = call i1 @_CHasValue.Optional.Core.217efae529e578bc(ptr %o), !dbg !7 +// CHECK:STDOUT: br i1 %Optional.HasValue.call, label %if.then, label %if.else, !dbg !8 // CHECK:STDOUT: // CHECK:STDOUT: if.then: ; preds = %entry -// CHECK:STDOUT: %Optional.Get.call = call ptr @_CGet.Optional.Core.217efae529e578bc(ptr %o), !dbg !10 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_20.1.temp), !dbg !7 -// CHECK:STDOUT: %.loc18_12.2 = load i32, ptr %Optional.Get.call, align 4, !dbg !11 -// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr %.loc18_20.1.temp, i32 %.loc18_12.2), !dbg !7 -// CHECK:STDOUT: ret void, !dbg !7 +// CHECK:STDOUT: %Optional.Get.call = call ptr @_CGet.Optional.Core.217efae529e578bc(ptr %o), !dbg !9 +// CHECK:STDOUT: %.loc18_12.2 = load i32, ptr %Optional.Get.call, align 4, !dbg !10 +// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr %return, i32 %.loc18_12.2), !dbg !11 +// CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: // CHECK:STDOUT: if.else: ; preds = %entry // CHECK:STDOUT: call void @_CNone.Optional.Core.f16306f3d30b9711(ptr %return), !dbg !12 @@ -59,45 +55,29 @@ fn AddOrRemoveConst(a: i32, b: const i32) { // CHECK:STDOUT: define void @_CAddOrRemoveConst.Main(i32 %a, i32 %b) #0 !dbg !14 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %oa.var = alloca { i32, i1 }, align 8, !dbg !15 -// CHECK:STDOUT: %.loc26_3.1.temp = alloca { i32, i1 }, align 8, !dbg !15 // CHECK:STDOUT: %coa.var = alloca { i32, i1 }, align 8, !dbg !16 -// CHECK:STDOUT: %.loc27_3.1.temp = alloca { i32, i1 }, align 8, !dbg !16 // CHECK:STDOUT: %oca.var = alloca { i32, i1 }, align 8, !dbg !17 -// CHECK:STDOUT: %.loc28_3.1.temp = alloca { i32, i1 }, align 8, !dbg !17 // CHECK:STDOUT: %coca.var = alloca { i32, i1 }, align 8, !dbg !18 -// CHECK:STDOUT: %.loc29_3.1.temp = alloca { i32, i1 }, align 8, !dbg !18 // CHECK:STDOUT: %ob.var = alloca { i32, i1 }, align 8, !dbg !19 -// CHECK:STDOUT: %.loc30_3.1.temp = alloca { i32, i1 }, align 8, !dbg !19 // CHECK:STDOUT: %cob.var = alloca { i32, i1 }, align 8, !dbg !20 -// CHECK:STDOUT: %.loc31_3.1.temp = alloca { i32, i1 }, align 8, !dbg !20 // CHECK:STDOUT: %ocb.var = alloca { i32, i1 }, align 8, !dbg !21 -// CHECK:STDOUT: %.loc32_3.1.temp = alloca { i32, i1 }, align 8, !dbg !21 // CHECK:STDOUT: %cocb.var = alloca { i32, i1 }, align 8, !dbg !22 -// CHECK:STDOUT: %.loc33_3.1.temp = alloca { i32, i1 }, align 8, !dbg !22 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %oa.var), !dbg !15 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc26_3.1.temp), !dbg !15 -// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr %.loc26_3.1.temp, i32 %a), !dbg !15 +// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr %oa.var, i32 %a), !dbg !15 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %coa.var), !dbg !16 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc27_3.1.temp), !dbg !16 -// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.7bf331f068e9c2df"(ptr %.loc27_3.1.temp, i32 %a), !dbg !16 +// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.7bf331f068e9c2df"(ptr %coa.var, i32 %a), !dbg !16 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %oca.var), !dbg !17 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc28_3.1.temp), !dbg !17 -// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999"(ptr %.loc28_3.1.temp, i32 %a), !dbg !17 +// CHECK:STDOUT: call void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.aa7929136b20b999"(ptr %oca.var, i32 %a), !dbg !17 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %coca.var), !dbg !18 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc29_3.1.temp), !dbg !18 -// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.988e6ea8b7110d27"(ptr %.loc29_3.1.temp, i32 %a), !dbg !18 +// CHECK:STDOUT: call void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.988e6ea8b7110d27"(ptr %coca.var, i32 %a), !dbg !18 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %ob.var), !dbg !19 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc30_3.1.temp), !dbg !19 -// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.7bf331f068e9c2df"(ptr %.loc30_3.1.temp, i32 %b), !dbg !19 +// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.7bf331f068e9c2df"(ptr %ob.var, i32 %b), !dbg !19 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %cob.var), !dbg !20 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc31_3.1.temp), !dbg !20 -// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.af35f070baa4994b"(ptr %.loc31_3.1.temp, i32 %b), !dbg !20 +// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.af35f070baa4994b"(ptr %cob.var, i32 %b), !dbg !20 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %ocb.var), !dbg !21 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc32_3.1.temp), !dbg !21 -// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.988e6ea8b7110d27"(ptr %.loc32_3.1.temp, i32 %b), !dbg !21 +// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.988e6ea8b7110d27"(ptr %ocb.var, i32 %b), !dbg !21 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %cocb.var), !dbg !22 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc33_3.1.temp), !dbg !22 -// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.42efcbde6ff4083b"(ptr %.loc33_3.1.temp, i32 %b), !dbg !22 +// CHECK:STDOUT: call void @"_CConvert.4a889a7251a91071:ImplicitAs.Core.42efcbde6ff4083b"(ptr %cocb.var, i32 %b), !dbg !22 // CHECK:STDOUT: ret void, !dbg !23 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -114,9 +94,6 @@ fn AddOrRemoveConst(a: i32, b: const i32) { // CHECK:STDOUT: ret ptr %1, !dbg !30 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 -// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define linkonce_odr void @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !31 { // CHECK:STDOUT: call void @"_CConvert.8d16edc1dfe20a7c:OptionalAs.Core.f16306f3d30b9711"(ptr %return, i32 %self), !dbg !32 @@ -129,6 +106,9 @@ fn AddOrRemoveConst(a: i32, b: const i32) { // CHECK:STDOUT: ret void, !dbg !36 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #1 +// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nounwind // CHECK:STDOUT: define linkonce_odr void @"_CConvert.ab0f2d07242360d7:ImplicitAs.Core.7bf331f068e9c2df"(ptr sret({ i32, i1 }) %return, i32 %self) #0 !dbg !37 { // CHECK:STDOUT: %temp = alloca { i32, i1 }, align 8, !dbg !39 @@ -255,8 +235,8 @@ fn AddOrRemoveConst(a: i32, b: const i32) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4 } // CHECK:STDOUT: uselistorder ptr @"_CConvert.f82b7327366b1770:ImplicitAs.Core.dbc2dba5c3cff15b", { 0, 1, 3, 2 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 11, 10, 9, 8, 7, 6, 5, 4 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nounwind } // CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } @@ -271,22 +251,22 @@ fn AddOrRemoveConst(a: i32, b: const i32) { // CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Convert", linkageName: "_CConvert.Main", scope: null, file: !3, line: 16, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} -// CHECK:STDOUT: !7 = !DILocation(line: 18, column: 5, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 17, column: 7, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 17, column: 6, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 18, column: 13, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 18, column: 12, scope: !4) +// CHECK:STDOUT: !7 = !DILocation(line: 17, column: 7, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 17, column: 6, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 18, column: 13, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 18, column: 12, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 18, column: 5, scope: !4) // CHECK:STDOUT: !12 = !DILocation(line: 20, column: 10, scope: !4) // CHECK:STDOUT: !13 = !DILocation(line: 20, column: 3, scope: !4) // CHECK:STDOUT: !14 = distinct !DISubprogram(name: "AddOrRemoveConst", linkageName: "_CAddOrRemoveConst.Main", scope: null, file: !3, line: 23, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !15 = !DILocation(line: 26, column: 3, scope: !14) -// CHECK:STDOUT: !16 = !DILocation(line: 27, column: 3, scope: !14) -// CHECK:STDOUT: !17 = !DILocation(line: 28, column: 3, scope: !14) -// CHECK:STDOUT: !18 = !DILocation(line: 29, column: 3, scope: !14) -// CHECK:STDOUT: !19 = !DILocation(line: 30, column: 3, scope: !14) -// CHECK:STDOUT: !20 = !DILocation(line: 31, column: 3, scope: !14) -// CHECK:STDOUT: !21 = !DILocation(line: 32, column: 3, scope: !14) -// CHECK:STDOUT: !22 = !DILocation(line: 33, column: 3, scope: !14) +// CHECK:STDOUT: !15 = !DILocation(line: 24, column: 3, scope: !14) +// CHECK:STDOUT: !16 = !DILocation(line: 25, column: 3, scope: !14) +// CHECK:STDOUT: !17 = !DILocation(line: 26, column: 3, scope: !14) +// CHECK:STDOUT: !18 = !DILocation(line: 27, column: 3, scope: !14) +// CHECK:STDOUT: !19 = !DILocation(line: 28, column: 3, scope: !14) +// CHECK:STDOUT: !20 = !DILocation(line: 29, column: 3, scope: !14) +// CHECK:STDOUT: !21 = !DILocation(line: 30, column: 3, scope: !14) +// CHECK:STDOUT: !22 = !DILocation(line: 31, column: 3, scope: !14) // CHECK:STDOUT: !23 = !DILocation(line: 23, column: 1, scope: !14) // CHECK:STDOUT: !24 = distinct !DISubprogram(name: "HasValue", linkageName: "_CHasValue.Optional.Core.217efae529e578bc", scope: null, file: !25, line: 32, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !25 = !DIFile(filename: "{{.*}}/prelude/types/optional.carbon", directory: "")