diff --git a/toolchain/lowering/lowering_context.cpp b/toolchain/lowering/lowering_context.cpp index 4002e0009355d..a5e91d155ab55 100644 --- a/toolchain/lowering/lowering_context.cpp +++ b/toolchain/lowering/lowering_context.cpp @@ -57,31 +57,55 @@ auto LoweringContext::Run() -> std::unique_ptr { auto LoweringContext::BuildFunctionDeclaration(SemIR::FunctionId function_id) -> llvm::Function* { - auto function = semantics_ir().GetFunction(function_id); + const auto& function = semantics_ir().GetFunction(function_id); + const bool has_return_slot = function.return_slot_id.is_valid(); + const int first_param = has_return_slot ? 1 : 0; + + SemIR::InitializingRepresentation return_rep = + function.return_type_id.is_valid() + ? SemIR::GetInitializingRepresentation(semantics_ir(), + function.return_type_id) + : SemIR::InitializingRepresentation{ + .kind = SemIR::InitializingRepresentation::None}; + CARBON_CHECK(return_rep.has_return_slot() == has_return_slot); // TODO: Lower type information for the arguments prior to building args. auto param_refs = semantics_ir().GetNodeBlock(function.param_refs_id); llvm::SmallVector args; - args.resize_for_overwrite(param_refs.size()); + args.resize_for_overwrite(first_param + param_refs.size()); + if (has_return_slot) { + args[0] = GetType(function.return_type_id)->getPointerTo(); + } for (auto [i, param_ref] : llvm::enumerate(param_refs)) { - args[i] = GetType(semantics_ir().GetNode(param_ref).type_id()); + args[first_param + i] = + GetType(semantics_ir().GetNode(param_ref).type_id()); } - // If return type is not valid, the function does not have a return type. - // Hence, set return type to void. - llvm::Type* return_type = function.return_type_id.is_valid() - ? GetType(function.return_type_id) - : llvm::Type::getVoidTy(llvm_context()); + // If the initializing representation doesn't produce a value, set the return + // type to void. + llvm::Type* return_type = + return_rep.kind == SemIR::InitializingRepresentation::ByCopy + ? GetType(function.return_type_id) + : llvm::Type::getVoidTy(llvm_context()); + llvm::FunctionType* function_type = llvm::FunctionType::get(return_type, args, /*isVarArg=*/false); auto* llvm_function = llvm::Function::Create( function_type, llvm::Function::ExternalLinkage, semantics_ir().GetString(function.name_id), llvm_module()); + if (has_return_slot) { + auto* return_slot = llvm_function->getArg(0); + return_slot->addAttr(llvm::Attribute::getWithStructRetType( + llvm_context(), GetType(function.return_type_id))); + return_slot->setName("return"); + } + // Set parameter names. for (auto [i, param_ref] : llvm::enumerate(param_refs)) { auto name_id = semantics_ir().GetNode(param_ref).GetAsParameter(); - llvm_function->getArg(i)->setName(semantics_ir().GetString(name_id)); + llvm_function->getArg(first_param + i) + ->setName(semantics_ir().GetString(name_id)); } return llvm_function; @@ -89,7 +113,7 @@ auto LoweringContext::BuildFunctionDeclaration(SemIR::FunctionId function_id) auto LoweringContext::BuildFunctionDefinition(SemIR::FunctionId function_id) -> void { - auto function = semantics_ir().GetFunction(function_id); + const auto& function = semantics_ir().GetFunction(function_id); const auto& body_block_ids = function.body_block_ids; if (body_block_ids.empty()) { // Function is probably defined in another file; not an error. @@ -99,14 +123,21 @@ auto LoweringContext::BuildFunctionDefinition(SemIR::FunctionId function_id) llvm::Function* llvm_function = GetFunction(function_id); LoweringFunctionContext function_lowering(*this, llvm_function); + const bool has_return_slot = function.return_slot_id.is_valid(); + const int first_param = has_return_slot ? 1 : 0; + // Add parameters to locals. auto param_refs = semantics_ir().GetNodeBlock(function.param_refs_id); + if (has_return_slot) { + function_lowering.SetLocal(function.return_slot_id, + llvm_function->getArg(0)); + } for (auto [i, param_ref] : llvm::enumerate(param_refs)) { - function_lowering.SetLocal(param_ref, llvm_function->getArg(i)); + function_lowering.SetLocal(param_ref, + llvm_function->getArg(first_param + i)); } // Lower all blocks. - // TODO: Determine the set of reachable blocks, and only lower those ones. for (auto block_id : body_block_ids) { CARBON_VLOG() << "Lowering " << block_id << "\n"; auto* llvm_block = function_lowering.GetBlock(block_id); diff --git a/toolchain/lowering/lowering_handle.cpp b/toolchain/lowering/lowering_handle.cpp index 3bc1f797c85a8..a56edff2ca607 100644 --- a/toolchain/lowering/lowering_handle.cpp +++ b/toolchain/lowering/lowering_handle.cpp @@ -172,21 +172,32 @@ auto LoweringHandleBuiltin(LoweringFunctionContext& /*context*/, auto LoweringHandleCall(LoweringFunctionContext& context, SemIR::NodeId node_id, SemIR::Node node) -> void { auto [refs_id, function_id] = node.GetAsCall(); - auto* function = context.GetFunction(function_id); + auto* llvm_function = context.GetFunction(function_id); + const auto& function = context.semantics_ir().GetFunction(function_id); + std::vector args; - for (auto ref_id : context.semantics_ir().GetNodeBlock(refs_id)) { + llvm::ArrayRef arg_ids = + context.semantics_ir().GetNodeBlock(refs_id); + + if (function.return_slot_id.is_valid()) { + args.push_back(context.GetLocal(arg_ids.back())); + arg_ids = arg_ids.drop_back(); + } + + for (auto ref_id : arg_ids) { args.push_back(context.GetLocalLoaded(ref_id)); } - if (function->getReturnType()->isVoidTy()) { - context.builder().CreateCall(function, args); - // TODO: use empty tuple type. - // TODO: don't create the empty tuple if the call does not get assigned. - context.SetLocal(node_id, context.builder().CreateAlloca( - llvm::StructType::get(context.llvm_context()), - /*ArraySize=*/nullptr, "call.result")); + + if (llvm_function->getReturnType()->isVoidTy()) { + context.builder().CreateCall(llvm_function, args); + // TODO: A function with a void return type shouldn't be referred to by + // other nodes. + context.SetLocal(node_id, + llvm::UndefValue::get(context.GetType(node.type_id()))); } else { - context.SetLocal(node_id, context.builder().CreateCall( - function, args, function->getName())); + context.SetLocal(node_id, + context.builder().CreateCall(llvm_function, args, + llvm_function->getName())); } } @@ -222,6 +233,12 @@ auto LoweringHandleNamespace(LoweringFunctionContext& /*context*/, // No action to take. } +auto LoweringHandleNoOp(LoweringFunctionContext& /*context*/, + SemIR::NodeId /*node_id*/, SemIR::Node /*node*/) + -> void { + // No action to take. +} + auto LoweringHandleParameter(LoweringFunctionContext& /*context*/, SemIR::NodeId /*node_id*/, SemIR::Node /*node*/) -> void { diff --git a/toolchain/lowering/lowering_handle_expression_category.cpp b/toolchain/lowering/lowering_handle_expression_category.cpp new file mode 100644 index 0000000000000..7cffe4a4477a0 --- /dev/null +++ b/toolchain/lowering/lowering_handle_expression_category.cpp @@ -0,0 +1,22 @@ +// 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 "toolchain/lowering/lowering_function_context.h" + +namespace Carbon { + +auto LoweringHandleBindValue(LoweringFunctionContext& context, + SemIR::NodeId node_id, SemIR::Node node) -> void { + context.SetLocal(node_id, context.GetLocalLoaded(node.GetAsBindValue())); +} + +auto LoweringHandleMaterializeTemporary(LoweringFunctionContext& context, + SemIR::NodeId node_id, SemIR::Node node) + -> void { + context.SetLocal( + node_id, context.builder().CreateAlloca(context.GetType(node.type_id()), + nullptr, "temp")); +} + +} // namespace Carbon diff --git a/toolchain/lowering/testdata/array/assign_return_value.carbon b/toolchain/lowering/testdata/array/assign_return_value.carbon index 2c280ed42ae29..a9ec9f19942ab 100644 --- a/toolchain/lowering/testdata/array/assign_return_value.carbon +++ b/toolchain/lowering/testdata/array/assign_return_value.carbon @@ -13,27 +13,30 @@ fn Run() { // CHECK:STDOUT: ; ModuleID = 'assign_return_value.carbon' // CHECK:STDOUT: source_filename = "assign_return_value.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: define { i32, i32 } @F() { +// CHECK:STDOUT: define void @F(ptr sret({ i32, i32 }) %return) { // CHECK:STDOUT: %tuple = alloca { i32, i32 }, align 8 // CHECK:STDOUT: %1 = getelementptr inbounds { i32, i32 }, ptr %tuple, i32 0, i32 0 // CHECK:STDOUT: store i32 12, ptr %1, align 4 // CHECK:STDOUT: %2 = getelementptr inbounds { i32, i32 }, ptr %tuple, i32 0, i32 1 // CHECK:STDOUT: store i32 24, ptr %2, align 4 // CHECK:STDOUT: %3 = load { i32, i32 }, ptr %tuple, align 4 -// CHECK:STDOUT: ret { i32, i32 } %3 +// CHECK:STDOUT: store { i32, i32 } %3, ptr %return, align 4 +// CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: define void @Run() { // CHECK:STDOUT: %t = alloca [2 x i32], align 4 -// CHECK:STDOUT: %F = call { i32, i32 } @F() +// CHECK:STDOUT: %temp = alloca { i32, i32 }, align 8 +// CHECK:STDOUT: call void @F(ptr %temp) +// CHECK:STDOUT: %1 = load { i32, i32 }, ptr %temp, align 4 // CHECK:STDOUT: %array = alloca [2 x i32], align 4 -// CHECK:STDOUT: %array.element = extractvalue { i32, i32 } %F, 0 -// CHECK:STDOUT: %1 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 0 -// CHECK:STDOUT: store i32 %array.element, ptr %1, align 4 -// CHECK:STDOUT: %array.element1 = extractvalue { i32, i32 } %F, 1 -// CHECK:STDOUT: %2 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 1 -// CHECK:STDOUT: store i32 %array.element1, ptr %2, align 4 -// CHECK:STDOUT: %3 = load [2 x i32], ptr %array, align 4 -// CHECK:STDOUT: store [2 x i32] %3, ptr %t, align 4 +// CHECK:STDOUT: %array.element = extractvalue { i32, i32 } %1, 0 +// CHECK:STDOUT: %2 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 0 +// CHECK:STDOUT: store i32 %array.element, ptr %2, align 4 +// CHECK:STDOUT: %array.element1 = extractvalue { i32, i32 } %1, 1 +// CHECK:STDOUT: %3 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 1 +// CHECK:STDOUT: store i32 %array.element1, ptr %3, align 4 +// CHECK:STDOUT: %4 = load [2 x i32], ptr %array, align 4 +// CHECK:STDOUT: store [2 x i32] %4, ptr %t, align 4 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/array/base.carbon b/toolchain/lowering/testdata/array/base.carbon index 7535f326707b5..4c14d9588aff2 100644 --- a/toolchain/lowering/testdata/array/base.carbon +++ b/toolchain/lowering/testdata/array/base.carbon @@ -105,20 +105,18 @@ fn Run() { // CHECK:STDOUT: %34 = load { i32, i32, i32 }, ptr %tuple19, align 4 // CHECK:STDOUT: store { i32, i32, i32 } %34, ptr %d, align 4 // CHECK:STDOUT: %e = alloca [3 x i32], align 4 +// CHECK:STDOUT: %35 = load { i32, i32, i32 }, ptr %d, align 4 // CHECK:STDOUT: %array20 = alloca [3 x i32], align 4 -// CHECK:STDOUT: %array.element21 = getelementptr inbounds { i32, i32, i32 }, ptr %d, i32 0, i32 0 -// CHECK:STDOUT: %35 = load i32, ptr %array.element21, align 4 +// CHECK:STDOUT: %array.element21 = extractvalue { i32, i32, i32 } %35, 0 // CHECK:STDOUT: %36 = getelementptr inbounds [3 x i32], ptr %array20, i32 0, i32 0 -// CHECK:STDOUT: store i32 %35, ptr %36, align 4 -// CHECK:STDOUT: %array.element22 = getelementptr inbounds { i32, i32, i32 }, ptr %d, i32 0, i32 1 -// CHECK:STDOUT: %37 = load i32, ptr %array.element22, align 4 -// CHECK:STDOUT: %38 = getelementptr inbounds [3 x i32], ptr %array20, i32 0, i32 1 -// CHECK:STDOUT: store i32 %37, ptr %38, align 4 -// CHECK:STDOUT: %array.element23 = getelementptr inbounds { i32, i32, i32 }, ptr %d, i32 0, i32 2 -// CHECK:STDOUT: %39 = load i32, ptr %array.element23, align 4 -// CHECK:STDOUT: %40 = getelementptr inbounds [3 x i32], ptr %array20, i32 0, i32 2 -// CHECK:STDOUT: store i32 %39, ptr %40, align 4 -// CHECK:STDOUT: %41 = load [3 x i32], ptr %array20, align 4 -// CHECK:STDOUT: store [3 x i32] %41, ptr %e, align 4 +// CHECK:STDOUT: store i32 %array.element21, ptr %36, align 4 +// CHECK:STDOUT: %array.element22 = extractvalue { i32, i32, i32 } %35, 1 +// CHECK:STDOUT: %37 = getelementptr inbounds [3 x i32], ptr %array20, i32 0, i32 1 +// CHECK:STDOUT: store i32 %array.element22, ptr %37, align 4 +// CHECK:STDOUT: %array.element23 = extractvalue { i32, i32, i32 } %35, 2 +// CHECK:STDOUT: %38 = getelementptr inbounds [3 x i32], ptr %array20, i32 0, i32 2 +// CHECK:STDOUT: store i32 %array.element23, ptr %38, align 4 +// CHECK:STDOUT: %39 = load [3 x i32], ptr %array20, align 4 +// CHECK:STDOUT: store [3 x i32] %39, ptr %e, align 4 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/basics/type_values.carbon b/toolchain/lowering/testdata/basics/type_values.carbon index 8441016ab0631..7b2b8d014db74 100644 --- a/toolchain/lowering/testdata/basics/type_values.carbon +++ b/toolchain/lowering/testdata/basics/type_values.carbon @@ -15,12 +15,10 @@ fn F64() -> type { // CHECK:STDOUT: ; ModuleID = 'type_values.carbon' // CHECK:STDOUT: source_filename = "type_values.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: %type = type {} -// CHECK:STDOUT: -// CHECK:STDOUT: define %type @I32() { -// CHECK:STDOUT: ret %type zeroinitializer +// CHECK:STDOUT: define void @I32() { +// CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: define %type @F64() { -// CHECK:STDOUT: ret %type zeroinitializer +// CHECK:STDOUT: define void @F64() { +// CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/empty_struct.carbon b/toolchain/lowering/testdata/function/call/empty_struct.carbon index 8fc7bbbf4f687..6b2521185adca 100644 --- a/toolchain/lowering/testdata/function/call/empty_struct.carbon +++ b/toolchain/lowering/testdata/function/call/empty_struct.carbon @@ -15,10 +15,9 @@ fn Main() { // CHECK:STDOUT: ; ModuleID = 'empty_struct.carbon' // CHECK:STDOUT: source_filename = "empty_struct.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: define {} @Echo({} %a) { +// CHECK:STDOUT: define void @Echo({} %a) { // CHECK:STDOUT: %struct = alloca {}, align 8 -// CHECK:STDOUT: %1 = load {}, ptr %struct, align 1 -// CHECK:STDOUT: ret {} %1 +// CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: define void @Main() { @@ -26,7 +25,6 @@ fn Main() { // CHECK:STDOUT: %b = alloca {}, align 8 // CHECK:STDOUT: %struct1 = alloca {}, align 8 // CHECK:STDOUT: %1 = load {}, ptr %struct1, align 1 -// CHECK:STDOUT: %Echo = call {} @Echo({} %1) -// CHECK:STDOUT: store {} %Echo, ptr %b, align 1 +// CHECK:STDOUT: call void @Echo({} %1) // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/empty_tuple.carbon b/toolchain/lowering/testdata/function/call/empty_tuple.carbon index 365751a58c4fa..a4e86ef3e1e76 100644 --- a/toolchain/lowering/testdata/function/call/empty_tuple.carbon +++ b/toolchain/lowering/testdata/function/call/empty_tuple.carbon @@ -15,8 +15,8 @@ fn Main() { // CHECK:STDOUT: ; ModuleID = 'empty_tuple.carbon' // CHECK:STDOUT: source_filename = "empty_tuple.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: define {} @Echo({} %a) { -// CHECK:STDOUT: ret {} %a +// CHECK:STDOUT: define void @Echo({} %a) { +// CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: define void @Main() { @@ -24,7 +24,6 @@ fn Main() { // CHECK:STDOUT: %b = alloca {}, align 8 // CHECK:STDOUT: %tuple1 = alloca {}, align 8 // CHECK:STDOUT: %1 = load {}, ptr %tuple1, align 1 -// CHECK:STDOUT: %Echo = call {} @Echo({} %1) -// CHECK:STDOUT: store {} %Echo, ptr %b, align 1 +// CHECK:STDOUT: call void @Echo({} %1) // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/implicit_empty_tuple_as_arg.carbon b/toolchain/lowering/testdata/function/call/implicit_empty_tuple_as_arg.carbon index 6720acfde74d3..01cdb08d82fa3 100644 --- a/toolchain/lowering/testdata/function/call/implicit_empty_tuple_as_arg.carbon +++ b/toolchain/lowering/testdata/function/call/implicit_empty_tuple_as_arg.carbon @@ -20,17 +20,16 @@ fn Main() { // CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: define {} @Bar({} %a) { -// CHECK:STDOUT: ret {} %a +// CHECK:STDOUT: define void @Bar({} %a) { +// CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: define void @Main() { // CHECK:STDOUT: %tuple = alloca {}, align 8 // CHECK:STDOUT: %x = alloca {}, align 8 // CHECK:STDOUT: call void @Foo() -// CHECK:STDOUT: %call.result = alloca {}, align 8 -// CHECK:STDOUT: %1 = load {}, ptr %call.result, align 1 -// CHECK:STDOUT: %Bar = call {} @Bar({} %1) -// CHECK:STDOUT: store {} %Bar, ptr %x, align 1 +// CHECK:STDOUT: %temp = alloca {}, align 8 +// CHECK:STDOUT: %1 = load {}, ptr %temp, align 1 +// CHECK:STDOUT: call void @Bar({} %1) // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/params_one.carbon b/toolchain/lowering/testdata/function/call/params_one.carbon index 081732d491354..e2b98e29196b8 100644 --- a/toolchain/lowering/testdata/function/call/params_one.carbon +++ b/toolchain/lowering/testdata/function/call/params_one.carbon @@ -19,6 +19,5 @@ fn Main() { // CHECK:STDOUT: // CHECK:STDOUT: define void @Main() { // CHECK:STDOUT: call void @Foo(i32 1) -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/params_one_comma.carbon b/toolchain/lowering/testdata/function/call/params_one_comma.carbon index af48d73452581..87582a5d6e317 100644 --- a/toolchain/lowering/testdata/function/call/params_one_comma.carbon +++ b/toolchain/lowering/testdata/function/call/params_one_comma.carbon @@ -20,8 +20,6 @@ fn Main() { // CHECK:STDOUT: // CHECK:STDOUT: define void @Main() { // CHECK:STDOUT: call void @Foo(i32 1) -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: call void @Foo(i32 1) -// CHECK:STDOUT: %call.result1 = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/params_two.carbon b/toolchain/lowering/testdata/function/call/params_two.carbon index 252653615f2d7..841722e141ee2 100644 --- a/toolchain/lowering/testdata/function/call/params_two.carbon +++ b/toolchain/lowering/testdata/function/call/params_two.carbon @@ -19,6 +19,5 @@ fn Main() { // CHECK:STDOUT: // CHECK:STDOUT: define void @Main() { // CHECK:STDOUT: call void @Foo(i32 1, i32 2) -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/params_two_comma.carbon b/toolchain/lowering/testdata/function/call/params_two_comma.carbon index 9c22f7472f3c5..b22a4330e30fb 100644 --- a/toolchain/lowering/testdata/function/call/params_two_comma.carbon +++ b/toolchain/lowering/testdata/function/call/params_two_comma.carbon @@ -20,8 +20,6 @@ fn Main() { // CHECK:STDOUT: // CHECK:STDOUT: define void @Main() { // CHECK:STDOUT: call void @Foo(i32 1, i32 2) -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: call void @Foo(i32 1, i32 2) -// CHECK:STDOUT: %call.result1 = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/params_zero.carbon b/toolchain/lowering/testdata/function/call/params_zero.carbon index 4617480b19a5f..bf994c16dddda 100644 --- a/toolchain/lowering/testdata/function/call/params_zero.carbon +++ b/toolchain/lowering/testdata/function/call/params_zero.carbon @@ -19,6 +19,5 @@ fn Main() { // CHECK:STDOUT: // CHECK:STDOUT: define void @Main() { // CHECK:STDOUT: call void @Foo() -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/return_implicit.carbon b/toolchain/lowering/testdata/function/call/return_implicit.carbon index 7346a5808751e..a82f5c0e081f5 100644 --- a/toolchain/lowering/testdata/function/call/return_implicit.carbon +++ b/toolchain/lowering/testdata/function/call/return_implicit.carbon @@ -23,8 +23,5 @@ fn Main() { // CHECK:STDOUT: %tuple = alloca {}, align 8 // CHECK:STDOUT: %b = alloca {}, align 8 // CHECK:STDOUT: call void @MakeImplicitEmptyTuple() -// CHECK:STDOUT: %call.result = alloca {}, align 8 -// CHECK:STDOUT: %1 = load {}, ptr %call.result, align 1 -// CHECK:STDOUT: store {} %1, ptr %b, align 1 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/call/var_param.carbon b/toolchain/lowering/testdata/function/call/var_param.carbon index 8b0c1ba787ca3..c4ca2373e1605 100644 --- a/toolchain/lowering/testdata/function/call/var_param.carbon +++ b/toolchain/lowering/testdata/function/call/var_param.carbon @@ -23,6 +23,5 @@ fn Main() { // CHECK:STDOUT: store i32 0, ptr %a, align 4 // CHECK:STDOUT: %1 = load i32, ptr %a, align 4 // CHECK:STDOUT: call void @DoNothing(i32 %1) -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/function/declaration/simple.carbon b/toolchain/lowering/testdata/function/declaration/simple.carbon index 3505e687be240..7792d0b2859b5 100644 --- a/toolchain/lowering/testdata/function/declaration/simple.carbon +++ b/toolchain/lowering/testdata/function/declaration/simple.carbon @@ -15,6 +15,5 @@ fn G(n: i32) { F(n); } // CHECK:STDOUT: // CHECK:STDOUT: define void @G(i32 %n) { // CHECK:STDOUT: call void @F(i32 %n) -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/if/else.carbon b/toolchain/lowering/testdata/if/else.carbon index 21848e35af765..67af395d45dc6 100644 --- a/toolchain/lowering/testdata/if/else.carbon +++ b/toolchain/lowering/testdata/if/else.carbon @@ -37,16 +37,13 @@ fn If(b: bool) { // CHECK:STDOUT: // CHECK:STDOUT: 1: ; preds = %0 // CHECK:STDOUT: call void @F() -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: br label %3 // CHECK:STDOUT: // CHECK:STDOUT: 2: ; preds = %0 // CHECK:STDOUT: call void @G() -// CHECK:STDOUT: %call.result1 = alloca {}, align 8 // CHECK:STDOUT: br label %3 // CHECK:STDOUT: // CHECK:STDOUT: 3: ; preds = %2, %1 // CHECK:STDOUT: call void @H() -// CHECK:STDOUT: %call.result2 = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/if/no_else.carbon b/toolchain/lowering/testdata/if/no_else.carbon index d6f899d5d8b98..928b8fa6cc004 100644 --- a/toolchain/lowering/testdata/if/no_else.carbon +++ b/toolchain/lowering/testdata/if/no_else.carbon @@ -30,11 +30,9 @@ fn If(b: bool) { // CHECK:STDOUT: // CHECK:STDOUT: 1: ; preds = %0 // CHECK:STDOUT: call void @F() -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: br label %2 // CHECK:STDOUT: // CHECK:STDOUT: 2: ; preds = %1, %0 // CHECK:STDOUT: call void @G() -// CHECK:STDOUT: %call.result1 = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/if_expression/basic.carbon b/toolchain/lowering/testdata/if_expression/basic.carbon index 88b5ebc2921a3..8fd9dde431991 100644 --- a/toolchain/lowering/testdata/if_expression/basic.carbon +++ b/toolchain/lowering/testdata/if_expression/basic.carbon @@ -23,17 +23,23 @@ fn Select(b: bool) -> i32 { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: define i32 @Select(i1 %b) { -// CHECK:STDOUT: br i1 %b, label %1, label %2 +// CHECK:STDOUT: br i1 %b, label %1, label %3 // CHECK:STDOUT: // CHECK:STDOUT: 1: ; preds = %0 // CHECK:STDOUT: %F = call i32 @F() -// CHECK:STDOUT: br label %3 +// CHECK:STDOUT: %temp = alloca i32, align 4 +// CHECK:STDOUT: store i32 %F, ptr %temp, align 4 +// CHECK:STDOUT: %2 = load i32, ptr %temp, align 4 +// CHECK:STDOUT: br label %5 // CHECK:STDOUT: -// CHECK:STDOUT: 2: ; preds = %0 +// CHECK:STDOUT: 3: ; preds = %0 // CHECK:STDOUT: %G = call i32 @G() -// CHECK:STDOUT: br label %3 +// CHECK:STDOUT: %temp1 = alloca i32, align 4 +// CHECK:STDOUT: store i32 %G, ptr %temp1, align 4 +// CHECK:STDOUT: %4 = load i32, ptr %temp1, align 4 +// CHECK:STDOUT: br label %5 // CHECK:STDOUT: -// CHECK:STDOUT: 3: ; preds = %2, %1 -// CHECK:STDOUT: %4 = phi i32 [ %F, %1 ], [ %G, %2 ] -// CHECK:STDOUT: ret i32 %4 +// CHECK:STDOUT: 5: ; preds = %3, %1 +// CHECK:STDOUT: %6 = phi i32 [ %2, %1 ], [ %4, %3 ] +// CHECK:STDOUT: ret i32 %6 // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/index/array_element_access.carbon b/toolchain/lowering/testdata/index/array_element_access.carbon index b90963cf88133..14d5f53957804 100644 --- a/toolchain/lowering/testdata/index/array_element_access.carbon +++ b/toolchain/lowering/testdata/index/array_element_access.carbon @@ -17,17 +17,18 @@ fn Run() { // CHECK:STDOUT: ; ModuleID = 'array_element_access.carbon' // CHECK:STDOUT: source_filename = "array_element_access.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: define { i32, i32 } @A() { +// CHECK:STDOUT: define void @A(ptr sret({ i32, i32 }) %return) { // CHECK:STDOUT: %tuple = alloca { i32, i32 }, align 8 // CHECK:STDOUT: %1 = getelementptr inbounds { i32, i32 }, ptr %tuple, i32 0, i32 0 // CHECK:STDOUT: store i32 1, ptr %1, align 4 // CHECK:STDOUT: %2 = getelementptr inbounds { i32, i32 }, ptr %tuple, i32 0, i32 1 // CHECK:STDOUT: store i32 2, ptr %2, align 4 // CHECK:STDOUT: %3 = load { i32, i32 }, ptr %tuple, align 4 -// CHECK:STDOUT: ret { i32, i32 } %3 +// CHECK:STDOUT: store { i32, i32 } %3, ptr %return, align 4 +// CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: define [2 x i32] @B() { +// CHECK:STDOUT: define void @B(ptr sret([2 x i32]) %return) { // CHECK:STDOUT: %tuple = alloca { i32, i32 }, align 8 // CHECK:STDOUT: %1 = getelementptr inbounds { i32, i32 }, ptr %tuple, i32 0, i32 0 // CHECK:STDOUT: store i32 1, ptr %1, align 4 @@ -43,33 +44,40 @@ fn Run() { // CHECK:STDOUT: %6 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 1 // CHECK:STDOUT: store i32 %5, ptr %6, align 4 // CHECK:STDOUT: %7 = load [2 x i32], ptr %array, align 4 -// CHECK:STDOUT: ret [2 x i32] %7 +// CHECK:STDOUT: store [2 x i32] %7, ptr %return, align 4 +// CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: define void @Run() { // CHECK:STDOUT: %a = alloca [2 x i32], align 4 -// CHECK:STDOUT: %A = call { i32, i32 } @A() +// CHECK:STDOUT: %temp = alloca { i32, i32 }, align 8 +// CHECK:STDOUT: call void @A(ptr %temp) +// CHECK:STDOUT: %1 = load { i32, i32 }, ptr %temp, align 4 // CHECK:STDOUT: %array = alloca [2 x i32], align 4 -// CHECK:STDOUT: %array.element = extractvalue { i32, i32 } %A, 0 -// CHECK:STDOUT: %1 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 0 -// CHECK:STDOUT: store i32 %array.element, ptr %1, align 4 -// CHECK:STDOUT: %array.element1 = extractvalue { i32, i32 } %A, 1 -// CHECK:STDOUT: %2 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 1 -// CHECK:STDOUT: store i32 %array.element1, ptr %2, align 4 -// CHECK:STDOUT: %3 = load [2 x i32], ptr %array, align 4 -// CHECK:STDOUT: store [2 x i32] %3, ptr %a, align 4 +// CHECK:STDOUT: %array.element = extractvalue { i32, i32 } %1, 0 +// CHECK:STDOUT: %2 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 0 +// CHECK:STDOUT: store i32 %array.element, ptr %2, align 4 +// CHECK:STDOUT: %array.element1 = extractvalue { i32, i32 } %1, 1 +// CHECK:STDOUT: %3 = getelementptr inbounds [2 x i32], ptr %array, i32 0, i32 1 +// CHECK:STDOUT: store i32 %array.element1, ptr %3, align 4 +// CHECK:STDOUT: %4 = load [2 x i32], ptr %array, align 4 +// CHECK:STDOUT: store [2 x i32] %4, ptr %a, align 4 // CHECK:STDOUT: %b = alloca i32, align 4 -// CHECK:STDOUT: %A2 = call { i32, i32 } @A() -// CHECK:STDOUT: %tuple.index = extractvalue { i32, i32 } %A2, 0 -// CHECK:STDOUT: store i32 %tuple.index, ptr %b, align 4 +// CHECK:STDOUT: %temp2 = alloca { i32, i32 }, align 8 +// CHECK:STDOUT: call void @A(ptr %temp2) +// CHECK:STDOUT: %tuple.index = getelementptr inbounds { i32, i32 }, ptr %temp2, i32 0, i32 0 +// CHECK:STDOUT: %5 = load i32, ptr %tuple.index, align 4 +// CHECK:STDOUT: store i32 %5, ptr %b, align 4 // CHECK:STDOUT: %c = alloca i32, align 4 -// CHECK:STDOUT: %4 = load i32, ptr %b, align 4 -// CHECK:STDOUT: %array.index = getelementptr inbounds [2 x i32], ptr %a, i32 %4 -// CHECK:STDOUT: %5 = load i32, ptr %array.index, align 4 -// CHECK:STDOUT: store i32 %5, ptr %c, align 4 +// CHECK:STDOUT: %6 = load i32, ptr %b, align 4 +// CHECK:STDOUT: %array.index = getelementptr inbounds [2 x i32], ptr %a, i32 %6 +// CHECK:STDOUT: %7 = load i32, ptr %array.index, align 4 +// CHECK:STDOUT: store i32 %7, ptr %c, align 4 // CHECK:STDOUT: %d = alloca i32, align 4 -// CHECK:STDOUT: %B = call [2 x i32] @B() -// CHECK:STDOUT: %array.index3 = extractvalue [2 x i32] %B, 1 -// CHECK:STDOUT: store i32 %array.index3, ptr %d, align 4 +// CHECK:STDOUT: %temp3 = alloca [2 x i32], align 4 +// CHECK:STDOUT: call void @B(ptr %temp3) +// CHECK:STDOUT: %array.index4 = getelementptr inbounds [2 x i32], ptr %temp3, i32 0, i32 1 +// CHECK:STDOUT: %8 = load i32, ptr %array.index4, align 4 +// CHECK:STDOUT: store i32 %8, ptr %d, align 4 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/index/tuple_return_value_access.carbon b/toolchain/lowering/testdata/index/tuple_return_value_access.carbon index ad2ddc83fbad1..d0698776764e0 100644 --- a/toolchain/lowering/testdata/index/tuple_return_value_access.carbon +++ b/toolchain/lowering/testdata/index/tuple_return_value_access.carbon @@ -13,20 +13,23 @@ fn Run() { // CHECK:STDOUT: ; ModuleID = 'tuple_return_value_access.carbon' // CHECK:STDOUT: source_filename = "tuple_return_value_access.carbon" // CHECK:STDOUT: -// CHECK:STDOUT: define { i32, i32 } @F() { +// CHECK:STDOUT: define void @F(ptr sret({ i32, i32 }) %return) { // CHECK:STDOUT: %tuple = alloca { i32, i32 }, align 8 // CHECK:STDOUT: %1 = getelementptr inbounds { i32, i32 }, ptr %tuple, i32 0, i32 0 // CHECK:STDOUT: store i32 12, ptr %1, align 4 // CHECK:STDOUT: %2 = getelementptr inbounds { i32, i32 }, ptr %tuple, i32 0, i32 1 // CHECK:STDOUT: store i32 24, ptr %2, align 4 // CHECK:STDOUT: %3 = load { i32, i32 }, ptr %tuple, align 4 -// CHECK:STDOUT: ret { i32, i32 } %3 +// CHECK:STDOUT: store { i32, i32 } %3, ptr %return, align 4 +// CHECK:STDOUT: ret void // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: define void @Run() { // CHECK:STDOUT: %t = alloca i32, align 4 -// CHECK:STDOUT: %F = call { i32, i32 } @F() -// CHECK:STDOUT: %tuple.index = extractvalue { i32, i32 } %F, 1 -// CHECK:STDOUT: store i32 %tuple.index, ptr %t, align 4 +// CHECK:STDOUT: %temp = alloca { i32, i32 }, align 8 +// CHECK:STDOUT: call void @F(ptr %temp) +// CHECK:STDOUT: %tuple.index = getelementptr inbounds { i32, i32 }, ptr %temp, i32 0, i32 1 +// CHECK:STDOUT: %1 = load i32, ptr %tuple.index, align 4 +// CHECK:STDOUT: store i32 %1, ptr %t, align 4 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/namespace/function.carbon b/toolchain/lowering/testdata/namespace/function.carbon index 9776134ee1421..393df2acd0807 100644 --- a/toolchain/lowering/testdata/namespace/function.carbon +++ b/toolchain/lowering/testdata/namespace/function.carbon @@ -30,6 +30,5 @@ fn Bar() { // CHECK:STDOUT: // CHECK:STDOUT: define void @Bar() { // CHECK:STDOUT: call void @Baz.1() -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/namespace/nested.carbon b/toolchain/lowering/testdata/namespace/nested.carbon index 9749fa7022883..f51a391c9b0a0 100644 --- a/toolchain/lowering/testdata/namespace/nested.carbon +++ b/toolchain/lowering/testdata/namespace/nested.carbon @@ -23,6 +23,5 @@ fn Foo.Bar.Baz() { // CHECK:STDOUT: // CHECK:STDOUT: define void @Baz() { // CHECK:STDOUT: call void @Wiz() -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/operators/and.carbon b/toolchain/lowering/testdata/operators/and.carbon index 418c98a51447e..600d5718ac556 100644 --- a/toolchain/lowering/testdata/operators/and.carbon +++ b/toolchain/lowering/testdata/operators/and.carbon @@ -24,13 +24,19 @@ fn And() -> bool { // CHECK:STDOUT: // CHECK:STDOUT: define i1 @And() { // CHECK:STDOUT: %F = call i1 @F() -// CHECK:STDOUT: br i1 %F, label %1, label %2 +// CHECK:STDOUT: %temp = alloca i1, align 1 +// CHECK:STDOUT: store i1 %F, ptr %temp, align 1 +// CHECK:STDOUT: %1 = load i1, ptr %temp, align 1 +// CHECK:STDOUT: br i1 %1, label %2, label %4 // CHECK:STDOUT: -// CHECK:STDOUT: 1: ; preds = %0 +// CHECK:STDOUT: 2: ; preds = %0 // CHECK:STDOUT: %G = call i1 @G() -// CHECK:STDOUT: br label %2 +// CHECK:STDOUT: %temp1 = alloca i1, align 1 +// CHECK:STDOUT: store i1 %G, ptr %temp1, align 1 +// CHECK:STDOUT: %3 = load i1, ptr %temp1, align 1 +// CHECK:STDOUT: br label %4 // CHECK:STDOUT: -// CHECK:STDOUT: 2: ; preds = %1, %0 -// CHECK:STDOUT: %3 = phi i1 [ false, %0 ], [ %G, %1 ] -// CHECK:STDOUT: ret i1 %3 +// CHECK:STDOUT: 4: ; preds = %2, %0 +// CHECK:STDOUT: %5 = phi i1 [ false, %0 ], [ %3, %2 ] +// CHECK:STDOUT: ret i1 %5 // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/operators/or.carbon b/toolchain/lowering/testdata/operators/or.carbon index b5214337ac68b..307e51bd9aff1 100644 --- a/toolchain/lowering/testdata/operators/or.carbon +++ b/toolchain/lowering/testdata/operators/or.carbon @@ -24,14 +24,20 @@ fn Or() -> bool { // CHECK:STDOUT: // CHECK:STDOUT: define i1 @Or() { // CHECK:STDOUT: %F = call i1 @F() -// CHECK:STDOUT: %1 = xor i1 %F, true -// CHECK:STDOUT: br i1 %1, label %2, label %3 +// CHECK:STDOUT: %temp = alloca i1, align 1 +// CHECK:STDOUT: store i1 %F, ptr %temp, align 1 +// CHECK:STDOUT: %1 = load i1, ptr %temp, align 1 +// CHECK:STDOUT: %2 = xor i1 %1, true +// CHECK:STDOUT: br i1 %2, label %3, label %5 // CHECK:STDOUT: -// CHECK:STDOUT: 2: ; preds = %0 +// CHECK:STDOUT: 3: ; preds = %0 // CHECK:STDOUT: %G = call i1 @G() -// CHECK:STDOUT: br label %3 +// CHECK:STDOUT: %temp1 = alloca i1, align 1 +// CHECK:STDOUT: store i1 %G, ptr %temp1, align 1 +// CHECK:STDOUT: %4 = load i1, ptr %temp1, align 1 +// CHECK:STDOUT: br label %5 // CHECK:STDOUT: -// CHECK:STDOUT: 3: ; preds = %2, %0 -// CHECK:STDOUT: %4 = phi i1 [ true, %0 ], [ %G, %2 ] -// CHECK:STDOUT: ret i1 %4 +// CHECK:STDOUT: 5: ; preds = %3, %0 +// CHECK:STDOUT: %6 = phi i1 [ true, %0 ], [ %4, %3 ] +// CHECK:STDOUT: ret i1 %6 // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/pointer/address_of_field.carbon b/toolchain/lowering/testdata/pointer/address_of_field.carbon index d5596aaac8a75..624e59e6f33fb 100644 --- a/toolchain/lowering/testdata/pointer/address_of_field.carbon +++ b/toolchain/lowering/testdata/pointer/address_of_field.carbon @@ -29,6 +29,5 @@ fn F() { // CHECK:STDOUT: %b1 = getelementptr inbounds { i32, i32 }, ptr %s, i32 0, i32 1 // CHECK:STDOUT: %2 = load ptr, ptr %b1, align 8 // CHECK:STDOUT: call void @G(ptr %2) -// CHECK:STDOUT: %call.result = alloca {}, align 8 // CHECK:STDOUT: ret void // CHECK:STDOUT: } diff --git a/toolchain/lowering/testdata/pointer/basic.carbon b/toolchain/lowering/testdata/pointer/basic.carbon index 6a10ba48de418..bae2a3c384cce 100644 --- a/toolchain/lowering/testdata/pointer/basic.carbon +++ b/toolchain/lowering/testdata/pointer/basic.carbon @@ -26,5 +26,8 @@ fn F() -> i32 { // CHECK:STDOUT: store i32 0, ptr %n, align 4 // CHECK:STDOUT: %1 = load ptr, ptr %n, align 8 // CHECK:STDOUT: %G = call i32 @G(ptr %1) -// CHECK:STDOUT: ret i32 %G +// CHECK:STDOUT: %temp = alloca i32, align 4 +// CHECK:STDOUT: store i32 %G, ptr %temp, align 4 +// CHECK:STDOUT: %2 = load i32, ptr %temp, align 4 +// CHECK:STDOUT: ret i32 %2 // CHECK:STDOUT: } diff --git a/toolchain/semantics/semantics_context.cpp b/toolchain/semantics/semantics_context.cpp index 94293aff3b595..bfe071797c527 100644 --- a/toolchain/semantics/semantics_context.cpp +++ b/toolchain/semantics/semantics_context.cpp @@ -263,6 +263,184 @@ auto Context::is_current_position_reachable() -> bool { } } +auto Context::Initialize(ParseTree::Node parse_node, SemIR::NodeId target_id, + SemIR::NodeId value_id) -> void { + // Implicitly convert the value to the type of the target. + auto type_id = semantics_ir().GetNode(target_id).type_id(); + auto expr_id = ImplicitAsRequired(parse_node, value_id, type_id); + SemIR::Node expr = semantics_ir().GetNode(expr_id); + + // Perform initialization now that we have an expression of the right type. + switch (SemIR::GetExpressionCategory(semantics_ir(), expr_id)) { + case SemIR::ExpressionCategory::NotExpression: + CARBON_FATAL() << "Converting non-expression node " << expr + << " to initializing expression"; + + case SemIR::ExpressionCategory::DurableReference: + case SemIR::ExpressionCategory::EphemeralReference: + // The design uses a custom "copy initialization" process here. We model + // that as value binding followed by direct initialization. + // + // TODO: Determine whether this is observably different from the design, + // and change either the toolchain or the design so they match. + expr_id = AddNode(SemIR::Node::BindValue::Make(expr.parse_node(), + expr.type_id(), expr_id)); + [[fallthrough]]; + + case SemIR::ExpressionCategory::Value: + // TODO: For class types, use an interface to determine how to perform + // this operation. + AddNode(SemIR::Node::Assign::Make(expr.parse_node(), target_id, expr_id)); + return; + + case SemIR::ExpressionCategory::Initializing: + MarkInitializerFor(expr_id, target_id); + return; + } +} + +auto Context::ConvertToValueExpression(SemIR::NodeId expr_id) -> SemIR::NodeId { + switch (SemIR::GetExpressionCategory(semantics_ir(), expr_id)) { + case SemIR::ExpressionCategory::NotExpression: + CARBON_FATAL() << "Converting non-expression node " + << semantics_ir().GetNode(expr_id) + << " to value expression"; + + case SemIR::ExpressionCategory::Initializing: + // Commit to using a temporary for this initializing expression. + // TODO: Don't create a temporary if the initializing representation is + // already a value representation. + expr_id = FinalizeTemporary(expr_id, /*discarded=*/false); + [[fallthrough]]; + + case SemIR::ExpressionCategory::DurableReference: + case SemIR::ExpressionCategory::EphemeralReference: { + // TODO: Support types with custom value representations. + SemIR::Node expr = semantics_ir().GetNode(expr_id); + return AddNode(SemIR::Node::BindValue::Make(expr.parse_node(), + expr.type_id(), expr_id)); + } + + case SemIR::ExpressionCategory::Value: + return expr_id; + } +} + +auto Context::FinalizeTemporary(SemIR::NodeId init_id, bool discarded) + -> SemIR::NodeId { + // TODO: See if we can refactor this with MarkInitializerFor once recursion + // through struct and tuple values is properly handled. + while (true) { + SemIR::Node init = semantics_ir().GetNode(init_id); + CARBON_CHECK(SemIR::GetExpressionCategory(semantics_ir(), init_id) == + SemIR::ExpressionCategory::Initializing) + << "Can only materialize initializing expressions, found " << init; + switch (init.kind()) { + default: + CARBON_FATAL() << "Initialization from unexpected node " << init; + + case SemIR::NodeKind::StructValue: + case SemIR::NodeKind::TupleValue: + CARBON_FATAL() << init << " is not modeled as initializing yet"; + + case SemIR::NodeKind::StubReference: { + init_id = init.GetAsStubReference(); + continue; + } + + case SemIR::NodeKind::Call: { + auto [refs_id, callee_id] = init.GetAsCall(); + if (semantics_ir().GetFunction(callee_id).return_slot_id.is_valid()) { + // The return slot should have a materialized temporary in it. + auto temporary_id = semantics_ir().GetNodeBlock(refs_id).back(); + CARBON_CHECK(semantics_ir().GetNode(temporary_id).kind() == + SemIR::NodeKind::MaterializeTemporary) + << "Return slot for function call does not contain a temporary; " + << "initialized multiple times? Have " + << semantics_ir().GetNode(temporary_id); + return temporary_id; + } + + if (discarded) { + // Don't invent a temporary that we're going to discard. + return SemIR::NodeId::Invalid; + } + + // The function has no return slot, but we want to produce a temporary + // object. Materialize one now. + auto temporary_id = AddNode(SemIR::Node::MaterializeTemporary::Make( + init.parse_node(), init.type_id())); + if (SemIR::GetInitializingRepresentation(semantics_ir(), init.type_id()) + .kind != SemIR::InitializingRepresentation::None) { + AddNode(SemIR::Node::Assign::Make(init.parse_node(), temporary_id, + init_id)); + } else { + // TODO: Should we create an empty value and Assign it to the + // temporary? + } + return temporary_id; + } + } + } +} + +auto Context::MarkInitializerFor(SemIR::NodeId init_id, SemIR::NodeId target_id) + -> void { + while (true) { + SemIR::Node init = semantics_ir().GetNode(init_id); + CARBON_CHECK(SemIR::GetExpressionCategory(semantics_ir(), init_id) == + SemIR::ExpressionCategory::Initializing) + << "initialization from non-initializing node " << init; + switch (init.kind()) { + default: + CARBON_FATAL() << "Initialization from unexpected node " << init; + + case SemIR::NodeKind::StructValue: + case SemIR::NodeKind::TupleValue: + CARBON_FATAL() << init << " is not modeled as initializing yet"; + + case SemIR::NodeKind::StubReference: + init_id = init.GetAsStubReference(); + continue; + + case SemIR::NodeKind::Call: { + // If the callee has a return slot, point it at our target. + auto [refs_id, callee_id] = init.GetAsCall(); + if (semantics_ir().GetFunction(callee_id).return_slot_id.is_valid()) { + // Replace the return slot with our given target, and remove the + // tentatively-created temporary. + auto temporary_id = std::exchange( + semantics_ir().GetNodeBlock(refs_id).back(), target_id); + auto temporary = semantics_ir().GetNode(temporary_id); + CARBON_CHECK(temporary.kind() == + SemIR::NodeKind::MaterializeTemporary) + << "Return slot for function call does not contain a temporary; " + << "initialized multiple times? Have " << temporary; + semantics_ir().ReplaceNode( + temporary_id, SemIR::Node::NoOp::Make(temporary.parse_node())); + } else if (SemIR::GetInitializingRepresentation(semantics_ir(), + init.type_id()) + .kind != SemIR::InitializingRepresentation::None) { + AddNode( + SemIR::Node::Assign::Make(init.parse_node(), target_id, init_id)); + } + return; + } + } + } +} + +auto Context::HandleDiscardedExpression(SemIR::NodeId expr_id) -> void { + // If we discard an initializing expression, materialize it first. + if (SemIR::GetExpressionCategory(semantics_ir(), expr_id) == + SemIR::ExpressionCategory::Initializing) { + FinalizeTemporary(expr_id, /*discarded=*/true); + } + + // TODO: This will eventually need to do some "do not discard" analysis. + (void)expr_id; +} + auto Context::ImplicitAsForArgs( SemIR::NodeBlockId arg_refs_id, ParseTree::Node param_parse_node, SemIR::NodeBlockId param_refs_id, @@ -274,8 +452,8 @@ auto Context::ImplicitAsForArgs( return true; } - auto arg_refs = semantics_ir_->GetNodeBlock(arg_refs_id); - auto param_refs = semantics_ir_->GetNodeBlock(param_refs_id); + auto& arg_refs = semantics_ir_->GetNodeBlock(arg_refs_id); + const auto& param_refs = semantics_ir_->GetNodeBlock(param_refs_id); // If sizes mismatch, fail early. if (arg_refs.size() != param_refs.size()) { @@ -308,6 +486,13 @@ auto Context::ImplicitAsForArgs( semantics_ir_->StringifyType(as_type_id)); return false; } + + // TODO: Convert to the proper expression category. For now, we assume + // parameters are all `let` bindings. + if (!diagnostic) { + // TODO: Insert the conversion in the proper place in the node block. + arg_refs[i] = ConvertToValueExpression(value_id); + } } return true; @@ -333,12 +518,6 @@ auto Context::ImplicitAsRequired(ParseTree::Node parse_node, return output_value_id; } -auto Context::ImplicitAsBool(ParseTree::Node parse_node, SemIR::NodeId value_id) - -> SemIR::NodeId { - return ImplicitAsRequired(parse_node, value_id, - CanonicalizeType(SemIR::NodeId::BuiltinBoolType)); -} - auto Context::ImplicitAsImpl(SemIR::NodeId value_id, SemIR::TypeId as_type_id, SemIR::NodeId* output_value_id) -> ImplicitAsKind { // Start by making sure both sides are valid. If any part is invalid, the @@ -386,6 +565,9 @@ auto Context::ImplicitAsImpl(SemIR::NodeId value_id, SemIR::TypeId as_type_id, std::all_of(type_block.begin(), type_block.end(), [&](auto type) { return type == element_type; })) { if (output_value_id != nullptr) { + // TODO: We should convert an initializing expression of tuple type + // to an initializing expression of array type. + value_id = ConvertToValueExpression(value_id); *output_value_id = AddNode(SemIR::Node::ArrayValue::Make( value.parse_node(), as_type_id, value_id)); } diff --git a/toolchain/semantics/semantics_context.h b/toolchain/semantics/semantics_context.h index 7be99a98a3640..1d3268ed12862 100644 --- a/toolchain/semantics/semantics_context.h +++ b/toolchain/semantics/semantics_context.h @@ -110,6 +110,40 @@ class Context { // Returns whether the current position in the current block is reachable. auto is_current_position_reachable() -> bool; + // Converts the given expression to an ephemeral reference to a temporary if + // it is an initializing expression. + auto MaterializeIfInitializing(SemIR::NodeId expr_id) -> SemIR::NodeId { + if (GetExpressionCategory(semantics_ir(), expr_id) == + SemIR::ExpressionCategory::Initializing) { + return FinalizeTemporary(expr_id, /*discarded=*/false); + } + return expr_id; + } + + // Convert the given expression to a value expression of the same type. + auto ConvertToValueExpression(SemIR::NodeId expr_id) -> SemIR::NodeId; + + // Performs initialization of `target_id` from `value_id`. + auto Initialize(ParseTree::Node parse_node, SemIR::NodeId target_id, + SemIR::NodeId value_id) -> void; + + // Converts `value_id` to a value expression of type `type_id`. + auto ConvertToValueOfType(ParseTree::Node parse_node, SemIR::NodeId value_id, + SemIR::TypeId type_id) -> SemIR::NodeId { + return ConvertToValueExpression( + ImplicitAsRequired(parse_node, value_id, type_id)); + } + + // Converts `value_id` to a value expression of type `bool`. + auto ConvertToBoolValue(ParseTree::Node parse_node, SemIR::NodeId value_id) + -> SemIR::NodeId { + return ConvertToValueOfType( + parse_node, value_id, CanonicalizeType(SemIR::NodeId::BuiltinBoolType)); + } + + // Handles an expression whose result is discarded. + auto HandleDiscardedExpression(SemIR::NodeId id) -> void; + // Runs ImplicitAsImpl for a set of arguments and parameters. // // This will eventually need to support checking against multiple possible @@ -129,10 +163,6 @@ class Context { auto ImplicitAsRequired(ParseTree::Node parse_node, SemIR::NodeId value_id, SemIR::TypeId as_type_id) -> SemIR::NodeId; - // Runs ImplicitAsRequired for a conversion to `bool`. - auto ImplicitAsBool(ParseTree::Node parse_node, SemIR::NodeId value_id) - -> SemIR::NodeId; - // Canonicalizes a type which is tracked as a single node. // TODO: This should eventually return a type ID. auto CanonicalizeType(SemIR::NodeId node_id) -> SemIR::TypeId; @@ -170,7 +200,7 @@ class Context { } return CanonicalizeType( - ImplicitAsRequired(parse_node, value_id, SemIR::TypeId::TypeType)); + ConvertToValueOfType(parse_node, value_id, SemIR::TypeId::TypeType)); } // Removes any top-level `const` qualifiers from a type. @@ -256,6 +286,18 @@ class Context { // TODO: This likely needs to track things which need to be destructed. }; + // Commits to using a temporary to store the result of the initializing + // expression described by `init_id`, and returns the location of the + // temporary. If `discarded` is `true`, the result is discarded, and no + // temporary will be created if possible; if no temporary is created, the + // return value will be `SemIR::NodeId::Invalid`. + auto FinalizeTemporary(SemIR::NodeId init_id, bool discarded) + -> SemIR::NodeId; + + // Marks the initializer `init_id` as initializing `target_id`. + auto MarkInitializerFor(SemIR::NodeId target_id, SemIR::NodeId init_id) + -> void; + // Runs ImplicitAs behavior to convert `value` to `as_type`, returning the // result type. The result will be the node to use to replace `value`. // diff --git a/toolchain/semantics/semantics_handle_call_expression.cpp b/toolchain/semantics/semantics_handle_call_expression.cpp index 2b60234d4579e..620cc15eff6d9 100644 --- a/toolchain/semantics/semantics_handle_call_expression.cpp +++ b/toolchain/semantics/semantics_handle_call_expression.cpp @@ -41,13 +41,25 @@ auto HandleCallExpression(Context& context, ParseTree::Node parse_node) callable.param_refs_id, /*diagnostic=*/nullptr)); - // TODO: Propagate return types from callable. - SemIR::TypeId type_id = callable.return_type_id; - // For functions with an implicit return type, set the return type to empty + // For functions with an implicit return type, the return type is the empty // tuple type. - if (type_id == SemIR::TypeId::Invalid) { + SemIR::TypeId type_id = callable.return_type_id; + if (!type_id.is_valid()) { type_id = context.CanonicalizeTupleType(call_expr_parse_node, {}); } + + // If there is a return slot, add a corresponding argument. + if (callable.return_slot_id.is_valid()) { + if (refs_id == SemIR::NodeBlockId::Empty) { + refs_id = context.semantics_ir().AddNodeBlock(); + } + // Tentatively put a materialized temporary in the function's return slot. + // This will be replaced if necessary when we perform initialization. + auto return_slot_id = + context.AddNode(SemIR::Node::MaterializeTemporary::Make( + call_expr_parse_node, callable.return_type_id)); + context.semantics_ir().GetNodeBlock(refs_id).push_back(return_slot_id); + } auto call_node_id = context.AddNode(SemIR::Node::Call::Make( call_expr_parse_node, type_id, refs_id, function_id)); diff --git a/toolchain/semantics/semantics_handle_function.cpp b/toolchain/semantics/semantics_handle_function.cpp index 84d3a78571bbd..a20337b17d037 100644 --- a/toolchain/semantics/semantics_handle_function.cpp +++ b/toolchain/semantics/semantics_handle_function.cpp @@ -20,11 +20,21 @@ static auto BuildFunctionDeclaration(Context& context) // prior to the call. context.node_block_stack().Pop(); - SemIR::TypeId return_type_id = SemIR::TypeId::Invalid; + auto return_type_id = SemIR::TypeId::Invalid; + auto return_slot_id = SemIR::NodeId::Invalid; if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) == ParseNodeKind::ReturnType) { - return_type_id = context.node_stack().Pop(); + return_slot_id = context.node_stack().Pop(); + return_type_id = context.semantics_ir().GetNode(return_slot_id).type_id(); + + // The function only has a return slot if it uses in-place initialization. + if (!SemIR::GetInitializingRepresentation(context.semantics_ir(), + return_type_id) + .has_return_slot()) { + return_slot_id = SemIR::NodeId::Invalid; + } } + SemIR::NodeBlockId param_refs_id = context.node_stack().Pop(); auto name_context = context.declaration_name_stack().Pop(); @@ -42,6 +52,7 @@ static auto BuildFunctionDeclaration(Context& context) : SemIR::StringId(SemIR::StringId::InvalidIndex), .param_refs_id = param_refs_id, .return_type_id = return_type_id, + .return_slot_id = return_slot_id, .body_block_ids = {}}); auto decl_id = context.AddNode( SemIR::Node::FunctionDeclaration::Make(fn_node, function_id)); @@ -121,8 +132,12 @@ auto HandleReturnType(Context& context, ParseTree::Node parse_node) -> bool { // Propagate the type expression. auto [type_parse_node, type_node_id] = context.node_stack().PopExpressionWithParseNode(); - auto cast_node_id = context.ExpressionAsType(type_parse_node, type_node_id); - context.node_stack().Push(parse_node, cast_node_id); + auto type_id = context.ExpressionAsType(type_parse_node, type_node_id); + // TODO: Use a dedicated node rather than VarStorage here. + context.AddNodeAndPush( + parse_node, + SemIR::Node::VarStorage::Make( + parse_node, type_id, context.semantics_ir().AddString("return"))); return true; } diff --git a/toolchain/semantics/semantics_handle_if_expression.cpp b/toolchain/semantics/semantics_handle_if_expression.cpp index f1bf18205029a..2bd3c89d3049d 100644 --- a/toolchain/semantics/semantics_handle_if_expression.cpp +++ b/toolchain/semantics/semantics_handle_if_expression.cpp @@ -12,7 +12,7 @@ auto HandleIfExpressionIf(Context& context, ParseTree::Node if_node) -> bool { context.node_stack().Push(if_node); // Convert the condition to `bool`, and branch on it. - cond_value_id = context.ImplicitAsBool(if_node, cond_value_id); + cond_value_id = context.ConvertToBoolValue(if_node, cond_value_id); auto then_block_id = context.AddDominatedBlockAndBranchIf(if_node, cond_value_id); auto else_block_id = context.AddDominatedBlockAndBranch(if_node); @@ -27,6 +27,12 @@ auto HandleIfExpressionIf(Context& context, ParseTree::Node if_node) -> bool { auto HandleIfExpressionThen(Context& context, ParseTree::Node then_node) -> bool { + // Convert the first operand to a value. + auto [then_value_node, then_value_id] = + context.node_stack().PopExpressionWithParseNode(); + context.node_stack().Push(then_value_node, + context.ConvertToValueExpression(then_value_id)); + context.node_stack().Push(then_node, context.node_block_stack().Pop()); context.AddCurrentCodeBlockToFunction(); return true; @@ -46,7 +52,7 @@ auto HandleIfExpressionElse(Context& context, ParseTree::Node else_node) // TODO: Find a common type, and convert both operands to it instead. auto result_type_id = context.semantics_ir().GetNode(then_value_id).type_id(); else_value_id = - context.ImplicitAsRequired(else_node, else_value_id, result_type_id); + context.ConvertToValueOfType(else_node, else_value_id, result_type_id); auto else_end_block_id = context.node_block_stack().Pop(); // Create a resumption block and branches to it. diff --git a/toolchain/semantics/semantics_handle_if_statement.cpp b/toolchain/semantics/semantics_handle_if_statement.cpp index 659eba40a16e6..22400befec3ed 100644 --- a/toolchain/semantics/semantics_handle_if_statement.cpp +++ b/toolchain/semantics/semantics_handle_if_statement.cpp @@ -15,7 +15,7 @@ auto HandleIfConditionStart(Context& /*context*/, auto HandleIfCondition(Context& context, ParseTree::Node parse_node) -> bool { // Convert the condition to `bool`. auto cond_value_id = context.node_stack().PopExpression(); - cond_value_id = context.ImplicitAsBool(parse_node, cond_value_id); + cond_value_id = context.ConvertToBoolValue(parse_node, cond_value_id); // Create the then block and the else block, and branch to the right one. If // there is no `else`, the then block will terminate with a branch to the diff --git a/toolchain/semantics/semantics_handle_index.cpp b/toolchain/semantics/semantics_handle_index.cpp index a57776295174c..2d59204748246 100644 --- a/toolchain/semantics/semantics_handle_index.cpp +++ b/toolchain/semantics/semantics_handle_index.cpp @@ -24,6 +24,7 @@ auto HandleIndexExpression(Context& context, ParseTree::Node parse_node) auto index_node_id = context.node_stack().PopExpression(); auto index_node = context.semantics_ir().GetNode(index_node_id); auto name_node_id = context.node_stack().PopExpression(); + name_node_id = context.MaterializeIfInitializing(name_node_id); auto name_node = context.semantics_ir().GetNode(name_node_id); auto name_type_id = context.semantics_ir().GetTypeAllowBuiltinTypes(name_node.type_id()); diff --git a/toolchain/semantics/semantics_handle_name.cpp b/toolchain/semantics/semantics_handle_name.cpp index 0d5cbb64e4bbf..21d0aebcda6d8 100644 --- a/toolchain/semantics/semantics_handle_name.cpp +++ b/toolchain/semantics/semantics_handle_name.cpp @@ -13,6 +13,10 @@ auto HandleMemberAccessExpression(Context& context, ParseTree::Node parse_node) SemIR::StringId name_id = context.node_stack().Pop(); auto base_id = context.node_stack().PopExpression(); + + // Materialize a temporary for the base expression if necessary. + base_id = context.MaterializeIfInitializing(base_id); + auto base = context.semantics_ir().GetNode(base_id); if (base.kind() == SemIR::NodeKind::Namespace) { // For a namespace, just resolve the name. diff --git a/toolchain/semantics/semantics_handle_operator.cpp b/toolchain/semantics/semantics_handle_operator.cpp index f936be8946753..4575106ad7d03 100644 --- a/toolchain/semantics/semantics_handle_operator.cpp +++ b/toolchain/semantics/semantics_handle_operator.cpp @@ -16,8 +16,9 @@ auto HandleInfixOperator(Context& context, ParseTree::Node parse_node) -> bool { case TokenKind::Plus: // TODO: This should search for a compatible interface. For now, it's a // very trivial check of validity on the operation. - lhs_id = context.ImplicitAsRequired( + lhs_id = context.ConvertToValueOfType( parse_node, lhs_id, context.semantics_ir().GetNode(rhs_id).type_id()); + rhs_id = context.ConvertToValueExpression(rhs_id); context.AddNodeAndPush( parse_node, @@ -31,7 +32,7 @@ auto HandleInfixOperator(Context& context, ParseTree::Node parse_node) -> bool { // The first operand is wrapped in a ShortCircuitOperand, which we // already handled by creating a RHS block and a resumption block, which // are the current block and its enclosing block. - rhs_id = context.ImplicitAsBool(parse_node, rhs_id); + rhs_id = context.ConvertToBoolValue(parse_node, rhs_id); // When the second operand is evaluated, the result of `and` and `or` is // its value. @@ -58,10 +59,12 @@ auto HandleInfixOperator(Context& context, ParseTree::Node parse_node) -> bool { "Expression is not assignable."); context.emitter().Emit(lhs_node, AssignmentToNonAssignable); } - context.ImplicitAsRequired( - parse_node, rhs_id, context.semantics_ir().GetNode(lhs_id).type_id()); - context.AddNodeAndPush( - parse_node, SemIR::Node::Assign::Make(parse_node, lhs_id, rhs_id)); + context.Initialize(parse_node, lhs_id, rhs_id); + // We model assignment as an expression, so we need to push a value for + // it, even though it doesn't produce a value. + // TODO: Consider changing our parse tree to model assignment as a + // different kind of statement than an expression statement. + context.node_stack().Push(parse_node, lhs_id); return true; } default: @@ -143,7 +146,7 @@ auto HandlePrefixOperator(Context& context, ParseTree::Node parse_node) } case TokenKind::Not: - value_id = context.ImplicitAsBool(parse_node, value_id); + value_id = context.ConvertToBoolValue(parse_node, value_id); context.AddNodeAndPush( parse_node, SemIR::Node::UnaryOperatorNot::Make( @@ -176,6 +179,7 @@ auto HandlePrefixOperator(Context& context, ParseTree::Node parse_node) } builder.Emit(); } + value_id = context.ConvertToValueExpression(value_id); context.AddNodeAndPush( parse_node, SemIR::Node::Dereference::Make(parse_node, result_type_id, value_id)); @@ -191,7 +195,7 @@ auto HandleShortCircuitOperand(Context& context, ParseTree::Node parse_node) -> bool { // Convert the condition to `bool`. auto cond_value_id = context.node_stack().PopExpression(); - cond_value_id = context.ImplicitAsBool(parse_node, cond_value_id); + cond_value_id = context.ConvertToBoolValue(parse_node, cond_value_id); auto bool_type_id = context.semantics_ir().GetNode(cond_value_id).type_id(); // Compute the branch value: the condition for `and`, inverted for `or`. diff --git a/toolchain/semantics/semantics_handle_paren.cpp b/toolchain/semantics/semantics_handle_paren.cpp index 12644d3caafb7..a9421f69bd15e 100644 --- a/toolchain/semantics/semantics_handle_paren.cpp +++ b/toolchain/semantics/semantics_handle_paren.cpp @@ -30,13 +30,29 @@ auto HandleParenExpressionOrTupleLiteralStart(Context& context, return true; } +static auto HandleTupleLiteralElement(Context& context) -> void { + // Convert the operand to a value. + // TODO: We need to decide how tuple literals interact with expression + // categories. + auto [value_node, value_id] = + context.node_stack().PopExpressionWithParseNode(); + value_id = context.ConvertToValueExpression(value_id); + context.node_stack().Push(value_node, value_id); +} + auto HandleTupleLiteralComma(Context& context, ParseTree::Node /*parse_node*/) -> bool { + HandleTupleLiteralElement(context); context.ParamOrArgComma(/*for_args=*/true); return true; } auto HandleTupleLiteral(Context& context, ParseTree::Node parse_node) -> bool { + if (context.parse_tree().node_kind(context.node_stack().PeekParseNode()) != + ParseNodeKind::ParenExpressionOrTupleLiteralStart) { + HandleTupleLiteralElement(context); + } + auto refs_id = context.ParamOrArgEnd( /*for_args=*/true, ParseNodeKind::ParenExpressionOrTupleLiteralStart); diff --git a/toolchain/semantics/semantics_handle_statement.cpp b/toolchain/semantics/semantics_handle_statement.cpp index 64182e1222308..4288434802691 100644 --- a/toolchain/semantics/semantics_handle_statement.cpp +++ b/toolchain/semantics/semantics_handle_statement.cpp @@ -9,10 +9,7 @@ namespace Carbon::Check { auto HandleExpressionStatement(Context& context, ParseTree::Node /*parse_node*/) -> bool { - // Pop the expression without investigating its contents. - // TODO: This will probably eventually need to do some "do not discard" - // analysis. - context.node_stack().PopExpression(); + context.HandleDiscardedExpression(context.node_stack().PopExpression()); return true; } @@ -55,12 +52,24 @@ auto HandleReturnStatement(Context& context, ParseTree::Node parse_node) .Build(parse_node, ReturnStatementDisallowExpression) .Note(fn_node.parse_node(), ReturnStatementImplicitNote) .Emit(); + + context.AddNode(SemIR::Node::ReturnExpression::Make(parse_node, arg)); + } else if (callable.return_slot_id.is_valid()) { + context.Initialize(parse_node, callable.return_slot_id, arg); + + context.AddNode(SemIR::Node::Return::Make(parse_node)); } else { - arg = - context.ImplicitAsRequired(parse_node, arg, callable.return_type_id); - } + arg = context.ConvertToValueOfType(parse_node, arg, + callable.return_type_id); - context.AddNode(SemIR::Node::ReturnExpression::Make(parse_node, arg)); + if (SemIR::GetInitializingRepresentation(context.semantics_ir(), + callable.return_type_id) + .kind == SemIR::InitializingRepresentation::None) { + context.AddNode(SemIR::Node::Return::Make(parse_node)); + } else { + context.AddNode(SemIR::Node::ReturnExpression::Make(parse_node, arg)); + } + } } // Switch to a new, unreachable, empty node block. This typically won't diff --git a/toolchain/semantics/semantics_handle_struct.cpp b/toolchain/semantics/semantics_handle_struct.cpp index e8e9b0d80bc02..6660fbf9c0ef0 100644 --- a/toolchain/semantics/semantics_handle_struct.cpp +++ b/toolchain/semantics/semantics_handle_struct.cpp @@ -48,6 +48,11 @@ auto HandleStructFieldValue(Context& context, ParseTree::Node parse_node) context.node_stack().PopExpressionWithParseNode(); SemIR::StringId name_id = context.node_stack().Pop(); + // Convert the operand to a value. + // TODO: We need to decide how struct literals interact with expression + // categories. + value_node_id = context.ConvertToValueExpression(value_node_id); + // Store the name for the type. auto type_block_id = context.args_type_info_stack().PeekForAdd(); context.semantics_ir().AddNode( diff --git a/toolchain/semantics/semantics_handle_variable.cpp b/toolchain/semantics/semantics_handle_variable.cpp index a3144d9ae1b4b..fb6009ee6f52a 100644 --- a/toolchain/semantics/semantics_handle_variable.cpp +++ b/toolchain/semantics/semantics_handle_variable.cpp @@ -28,10 +28,7 @@ auto HandleVariableDeclaration(Context& context, ParseTree::Node parse_node) context.AddNameToLookup(var.parse_node(), name_id, var_id); // If there was an initializer, assign it to storage. if (has_init) { - auto cast_value_id = - context.ImplicitAsRequired(parse_node, expr_node_id, var.type_id()); - context.AddNode( - SemIR::Node::Assign::Make(parse_node, var_id, cast_value_id)); + context.Initialize(parse_node, var_id, expr_node_id); } context.node_stack() diff --git a/toolchain/semantics/semantics_ir.cpp b/toolchain/semantics/semantics_ir.cpp index 33a3d12dc0b72..a3328a1d34be8 100644 --- a/toolchain/semantics/semantics_ir.cpp +++ b/toolchain/semantics/semantics_ir.cpp @@ -220,6 +220,7 @@ static auto GetTypePrecedence(NodeKind kind) -> int { case NodeKind::ArrayValue: case NodeKind::Assign: case NodeKind::BinaryOperatorAdd: + case NodeKind::BindValue: case NodeKind::BlockArg: case NodeKind::BoolLiteral: case NodeKind::Branch: @@ -230,7 +231,9 @@ static auto GetTypePrecedence(NodeKind kind) -> int { case NodeKind::FunctionDeclaration: case NodeKind::IntegerLiteral: case NodeKind::Invalid: + case NodeKind::MaterializeTemporary: case NodeKind::Namespace: + case NodeKind::NoOp: case NodeKind::Parameter: case NodeKind::RealLiteral: case NodeKind::Return: @@ -375,6 +378,7 @@ auto File::StringifyType(TypeId type_id, bool in_type_context) const case NodeKind::ArrayValue: case NodeKind::Assign: case NodeKind::BinaryOperatorAdd: + case NodeKind::BindValue: case NodeKind::BlockArg: case NodeKind::BoolLiteral: case NodeKind::Branch: @@ -382,11 +386,13 @@ auto File::StringifyType(TypeId type_id, bool in_type_context) const case NodeKind::BranchWithArg: case NodeKind::Builtin: case NodeKind::Call: - case NodeKind::Dereference: case NodeKind::CrossReference: + case NodeKind::Dereference: case NodeKind::FunctionDeclaration: case NodeKind::IntegerLiteral: + case NodeKind::MaterializeTemporary: case NodeKind::Namespace: + case NodeKind::NoOp: case NodeKind::Parameter: case NodeKind::RealLiteral: case NodeKind::Return: @@ -423,9 +429,9 @@ auto File::StringifyType(TypeId type_id, bool in_type_context) const return str; } -auto GetExpressionCategory(const File& semantics_ir, NodeId node_id) +auto GetExpressionCategory(const File& file, NodeId node_id) -> ExpressionCategory { - const File* ir = &semantics_ir; + const File* ir = &file; while (true) { auto node = ir->GetNode(node_id); switch (node.kind()) { @@ -436,6 +442,7 @@ auto GetExpressionCategory(const File& semantics_ir, NodeId node_id) case NodeKind::BranchWithArg: case NodeKind::FunctionDeclaration: case NodeKind::Namespace: + case NodeKind::NoOp: case NodeKind::Return: case NodeKind::ReturnExpression: case NodeKind::StructTypeField: @@ -443,18 +450,15 @@ auto GetExpressionCategory(const File& semantics_ir, NodeId node_id) case NodeKind::CrossReference: { auto [xref_id, xref_node_id] = node.GetAsCrossReference(); - ir = &semantics_ir.GetCrossReferenceIR(xref_id); + ir = &ir->GetCrossReferenceIR(xref_id); node_id = xref_node_id; continue; } - case NodeKind::Call: - // TODO: This should eventually be Initializing. - return ExpressionCategory::Value; - case NodeKind::AddressOf: case NodeKind::ArrayType: case NodeKind::BinaryOperatorAdd: + case NodeKind::BindValue: case NodeKind::BlockArg: case NodeKind::BoolLiteral: case NodeKind::Builtin: @@ -501,11 +505,152 @@ auto GetExpressionCategory(const File& semantics_ir, NodeId node_id) // struct/tuple value construction. return ExpressionCategory::Value; + case NodeKind::Call: + return ExpressionCategory::Initializing; + case NodeKind::Dereference: case NodeKind::VarStorage: return ExpressionCategory::DurableReference; + + case NodeKind::MaterializeTemporary: + return ExpressionCategory::EphemeralReference; } } } +auto GetValueRepresentation(const File& file, TypeId type_id) + -> ValueRepresentation { + const File* ir = &file; + NodeId node_id = ir->GetTypeAllowBuiltinTypes(type_id); + while (true) { + auto node = ir->GetNode(node_id); + switch (node.kind()) { + case NodeKind::AddressOf: + case NodeKind::ArrayIndex: + case NodeKind::ArrayValue: + case NodeKind::Assign: + case NodeKind::BinaryOperatorAdd: + case NodeKind::BindValue: + case NodeKind::BlockArg: + case NodeKind::BoolLiteral: + case NodeKind::Branch: + case NodeKind::BranchIf: + case NodeKind::BranchWithArg: + case NodeKind::Call: + case NodeKind::Dereference: + case NodeKind::FunctionDeclaration: + case NodeKind::IntegerLiteral: + case NodeKind::Invalid: + case NodeKind::MaterializeTemporary: + case NodeKind::Namespace: + case NodeKind::NoOp: + case NodeKind::Parameter: + case NodeKind::RealLiteral: + case NodeKind::Return: + case NodeKind::ReturnExpression: + case NodeKind::StringLiteral: + case NodeKind::StructAccess: + case NodeKind::StructTypeField: + case NodeKind::StructValue: + case NodeKind::TupleIndex: + case NodeKind::TupleValue: + case NodeKind::UnaryOperatorNot: + case NodeKind::VarStorage: + CARBON_FATAL() << "Type refers to non-type node " << node; + + case NodeKind::CrossReference: { + auto [xref_id, xref_node_id] = node.GetAsCrossReference(); + ir = &ir->GetCrossReferenceIR(xref_id); + node_id = xref_node_id; + continue; + } + + case NodeKind::StubReference: { + node_id = node.GetAsStubReference(); + continue; + } + + case NodeKind::ArrayType: + // For arrays, it's convenient to always use a pointer representation, + // even when the array has zero or one element, in order to support + // indexing. + return {.kind = ValueRepresentation::Pointer, .type = type_id}; + + case NodeKind::StructType: { + auto& fields = ir->GetNodeBlock(node.GetAsStructType()); + if (fields.empty()) { + // An empty struct has an empty representation. + return {.kind = ValueRepresentation::None, .type = TypeId::Invalid}; + } + if (fields.size() == 1) { + // A struct with one field has the same representation as its field. + auto [field_name_id, field_type_id] = + ir->GetNode(fields.front()).GetAsStructTypeField(); + node_id = ir->GetTypeAllowBuiltinTypes(field_type_id); + continue; + } + // For any other struct, use a pointer representation. + return {.kind = ValueRepresentation::Pointer, .type = type_id}; + } + + case NodeKind::TupleType: { + auto& elements = ir->GetTypeBlock(node.GetAsTupleType()); + if (elements.empty()) { + // An empty tuple has an empty representation. + return {.kind = ValueRepresentation::None, .type = TypeId::Invalid}; + } + if (elements.size() == 1) { + // A one-tuple has the same representation as its sole element. + node_id = ir->GetTypeAllowBuiltinTypes(elements.front()); + continue; + } + // For any other tuple, use a pointer representation. + return {.kind = ValueRepresentation::Pointer, .type = type_id}; + } + + case NodeKind::Builtin: + switch (node.GetAsBuiltin()) { + case BuiltinKind::TypeType: + case BuiltinKind::Error: + case BuiltinKind::Invalid: + return {.kind = ValueRepresentation::None, .type = TypeId::Invalid}; + case BuiltinKind::BoolType: + case BuiltinKind::IntegerType: + case BuiltinKind::FloatingPointType: + return {.kind = ValueRepresentation::Copy, .type = type_id}; + case BuiltinKind::StringType: + // TODO: Decide on string value semantics. This should probably be a + // custom value representation carrying a pointer and size or + // similar. + return {.kind = ValueRepresentation::Pointer, .type = type_id}; + } + + case NodeKind::PointerType: + return {.kind = ValueRepresentation::Copy, .type = type_id}; + + case NodeKind::ConstType: + node_id = ir->GetTypeAllowBuiltinTypes(node.GetAsConstType()); + continue; + } + } +} + +auto GetInitializingRepresentation(const File& file, TypeId type_id) + -> InitializingRepresentation { + auto value_rep = GetValueRepresentation(file, type_id); + switch (value_rep.kind) { + case ValueRepresentation::None: + return {.kind = InitializingRepresentation::None}; + + case ValueRepresentation::Copy: + // TODO: Use in-place initialization for types that have non-trivial + // destructive move. + return {.kind = InitializingRepresentation::ByCopy}; + + case ValueRepresentation::Pointer: + case ValueRepresentation::Custom: + return {.kind = InitializingRepresentation::InPlace}; + } +} + } // namespace Carbon::SemIR diff --git a/toolchain/semantics/semantics_ir.h b/toolchain/semantics/semantics_ir.h index f732a705f5f17..523a396ad7b1e 100644 --- a/toolchain/semantics/semantics_ir.h +++ b/toolchain/semantics/semantics_ir.h @@ -22,6 +22,9 @@ struct Function { if (return_type_id.is_valid()) { out << ", return_type: " << return_type_id; } + if (return_slot_id.is_valid()) { + out << ", return_slot: " << return_slot_id; + } if (!body_block_ids.empty()) { out << llvm::formatv( ", body: [{0}]", @@ -37,6 +40,12 @@ struct Function { NodeBlockId param_refs_id; // The return type. This will be invalid if the return type wasn't specified. TypeId return_type_id; + // The storage for the return value, which is a reference expression whose + // type is the return type of the function. Will be invalid if the function + // doesn't have a return slot. If this is valid, a call to the function is + // expected to have an additional final argument corresponding to the return + // slot. + NodeId return_slot_id; // A list of the statically reachable code blocks in the body of the // function, in lexical order. The first block is the entry block. This will // be empty for declarations that don't have a visible definition. @@ -155,6 +164,11 @@ class File { return node_id; } + // Overwrites a given node with a new value. + auto ReplaceNode(NodeId node_id, Node node) -> void { + nodes_[node_id.index] = node; + } + // Returns the requested node. auto GetNode(NodeId node_id) const -> Node { return nodes_[node_id.index]; } @@ -347,9 +361,66 @@ enum class ExpressionCategory { }; // Returns the expression category for a node. -auto GetExpressionCategory(const File& semantics_ir, NodeId node_id) +auto GetExpressionCategory(const File& file, NodeId node_id) -> ExpressionCategory; +// The value representation to use when passing by value. +struct ValueRepresentation { + enum Kind { + // The type has no value representation. This is used for empty types, such + // as `()`, where there is no value. + None, + // The value representation is a copy of the value. On call boundaries, the + // value itself will be passed. `type` is the value type. + // TODO: `type` should be `const`-qualified, but is currently not. + Copy, + // The value representation is a pointer to an object. When used as a + // parameter, the argument is a reference expression. `type` is the pointee + // type. + // TODO: `type` should be `const`-qualified, but is currently not. + Pointer, + // The value representation has been customized, and has the same behavior + // as the value representation of some other type. + // TODO: This is not implemented or used yet. + Custom, + }; + // The kind of value representation used by this type. + Kind kind; + // The type used to model the value representation. + TypeId type; +}; + +// Returns information about the value representation to use for a type. +auto GetValueRepresentation(const File& file, TypeId type_id) + -> ValueRepresentation; + +// The initializing representation to use when returning by value. +struct InitializingRepresentation { + enum Kind { + // The type has no initializing representation. This is used for empty + // types, where no initialization is necessary. + None, + // An initializing expression produces a value, which is copied into the + // initialized object. + ByCopy, + // An initializing expression takes a location as input, which is + // initialized as a side effect of evaluating the expression. + InPlace, + // TODO: Consider adding a kind where the expression takes an advisory + // location and returns a value plus an indicator of whether the location + // was actually initialized. + }; + // The kind of initializing representation used by this type. + Kind kind; + + // Returns whether a return slot is used when returning this type. + bool has_return_slot() const { return kind == InPlace; } +}; + +// Returns information about the initializing representation to use for a type. +auto GetInitializingRepresentation(const File& file, TypeId type_id) + -> InitializingRepresentation; + } // namespace Carbon::SemIR #endif // CARBON_TOOLCHAIN_SEMANTICS_SEMANTICS_IR_H_ diff --git a/toolchain/semantics/semantics_ir_formatter.cpp b/toolchain/semantics/semantics_ir_formatter.cpp index 5bfe01826634d..dc81411649aa3 100644 --- a/toolchain/semantics/semantics_ir_formatter.cpp +++ b/toolchain/semantics/semantics_ir_formatter.cpp @@ -57,6 +57,13 @@ class NodeNamer { fn.name_id.is_valid() ? semantics_ir.GetString(fn.name_id).str() : ""); CollectNamesInBlock(fn_scope, fn.param_refs_id); + if (fn.return_slot_id.is_valid()) { + nodes[fn.return_slot_id.index] = { + fn_scope, + GetScopeInfo(fn_scope).nodes.AllocateName( + *this, semantics_ir.GetNode(fn.return_slot_id).parse_node(), + "return")}; + } if (!fn.body_block_ids.empty()) { AddBlockLabel(fn_scope, fn.body_block_ids.front(), "entry", fn_loc); } @@ -325,6 +332,9 @@ class NodeNamer { // Use bound names where available. Otherwise, assign a backup name. for (auto node_id : semantics_ir_.GetNodeBlock(block_id)) { + if (!node_id.is_valid()) { + continue; + } auto node = semantics_ir_.GetNode(node_id); switch (node.kind()) { case NodeKind::Branch: { @@ -426,6 +436,10 @@ class Formatter { llvm::ListSeparator sep; for (const NodeId param_id : semantics_ir_.GetNodeBlock(fn.param_refs_id)) { out_ << sep; + if (!param_id.is_valid()) { + out_ << "invalid"; + continue; + } FormatNodeName(param_id); out_ << ": "; FormatType(semantics_ir_.GetNode(param_id).type_id()); @@ -433,6 +447,10 @@ class Formatter { out_ << ")"; if (fn.return_type_id.is_valid()) { out_ << " -> "; + if (fn.return_slot_id.is_valid()) { + FormatNodeName(fn.return_slot_id); + out_ << ": "; + } FormatType(fn.return_type_id); } @@ -567,7 +585,29 @@ class Formatter { out_ << " "; auto [args_id, callee_id] = node.GetAsCall(); FormatArg(callee_id); - FormatArg(args_id); + + llvm::ArrayRef args = semantics_ir_.GetNodeBlock(args_id); + + bool has_return_slot = + semantics_ir_.GetFunction(callee_id).return_slot_id.is_valid(); + NodeId return_slot_id = NodeId::Invalid; + if (has_return_slot) { + return_slot_id = args.back(); + args = args.drop_back(); + } + + llvm::ListSeparator sep; + out_ << '('; + for (auto node_id : args) { + out_ << sep; + FormatArg(node_id); + } + out_ << ')'; + + if (has_return_slot) { + out_ << " to "; + FormatArg(return_slot_id); + } } template <> diff --git a/toolchain/semantics/semantics_node.h b/toolchain/semantics/semantics_node.h index 3bd2c5c5faf00..8851256f1abb7 100644 --- a/toolchain/semantics/semantics_node.h +++ b/toolchain/semantics/semantics_node.h @@ -317,6 +317,8 @@ class Node { using BinaryOperatorAdd = Node::Factory; + using BindValue = Factory; + using BlockArg = Factory; using BoolLiteral = Factory; @@ -373,9 +375,13 @@ class Node { using IntegerLiteral = Factory; + using MaterializeTemporary = Factory; + using Namespace = FactoryNoType; + using NoOp = FactoryNoType; + using Parameter = Factory; using PointerType = Factory; diff --git a/toolchain/semantics/semantics_node_kind.def b/toolchain/semantics/semantics_node_kind.def index 38746a4cfcae8..acb52a71d33fd 100644 --- a/toolchain/semantics/semantics_node_kind.def +++ b/toolchain/semantics/semantics_node_kind.def @@ -51,6 +51,7 @@ CARBON_SEMANTICS_NODE_KIND_IMPL(ArrayType, "array_type", Typed, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(ArrayValue, "array_value", Typed, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(Assign, "assign", None, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(BinaryOperatorAdd, "add", Typed, NotTerminator) +CARBON_SEMANTICS_NODE_KIND_IMPL(BindValue, "bind_value", Typed, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(BlockArg, "block_arg", Typed, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(BoolLiteral, "bool_literal", Typed, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(Branch, "br", None, Terminator) @@ -65,7 +66,10 @@ CARBON_SEMANTICS_NODE_KIND_IMPL(FunctionDeclaration, "fn_decl", Untyped, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(IntegerLiteral, "int_literal", Typed, NotTerminator) +CARBON_SEMANTICS_NODE_KIND_IMPL(MaterializeTemporary, "materialize_temporary", + Typed, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(Namespace, "namespace", Untyped, NotTerminator) +CARBON_SEMANTICS_NODE_KIND_IMPL(NoOp, "no_op", None, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(Parameter, "parameter", Typed, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(PointerType, "ptr_type", Typed, NotTerminator) CARBON_SEMANTICS_NODE_KIND_IMPL(RealLiteral, "real_literal", Typed, diff --git a/toolchain/semantics/semantics_node_stack.h b/toolchain/semantics/semantics_node_stack.h index 5c6e404b83eb3..aa653a5573562 100644 --- a/toolchain/semantics/semantics_node_stack.h +++ b/toolchain/semantics/semantics_node_stack.h @@ -253,6 +253,7 @@ class NodeStack { case ParseNodeKind::PatternBinding: case ParseNodeKind::PostfixOperator: case ParseNodeKind::PrefixOperator: + case ParseNodeKind::ReturnType: case ParseNodeKind::ShortCircuitOperand: case ParseNodeKind::StructFieldValue: case ParseNodeKind::StructLiteral: @@ -268,8 +269,6 @@ class NodeStack { return IdKind::FunctionId; case ParseNodeKind::Name: return IdKind::StringId; - case ParseNodeKind::ReturnType: - return IdKind::TypeId; case ParseNodeKind::ArrayExpressionSemi: case ParseNodeKind::CodeBlockStart: case ParseNodeKind::FunctionIntroducer: diff --git a/toolchain/semantics/testdata/array/assign_return_value.carbon b/toolchain/semantics/testdata/array/assign_return_value.carbon index 83d7f543623b5..45345f8db3c32 100644 --- a/toolchain/semantics/testdata/array/assign_return_value.carbon +++ b/toolchain/semantics/testdata/array/assign_return_value.carbon @@ -13,7 +13,7 @@ fn Run() { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type2, body: [block4]}, -// CHECK:STDOUT: {name: str1, param_refs: block0, body: [block6]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block6]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 0, @@ -23,6 +23,7 @@ fn Run() { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, +// CHECK:STDOUT: return, // CHECK:STDOUT: Run, // CHECK:STDOUT: t, // CHECK:STDOUT: ] @@ -30,7 +31,7 @@ fn Run() { // CHECK:STDOUT: node+1, // CHECK:STDOUT: nodeIntegerType, // CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+11, +// CHECK:STDOUT: node+12, // CHECK:STDOUT: ] // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: [ @@ -45,18 +46,22 @@ fn Run() { // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock0, type: typeTypeType}, // CHECK:STDOUT: {kind: TupleValue, arg0: block2, type: type0}, // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock1, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type2}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+5, type: type1}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+6, type: type1}, // CHECK:STDOUT: {kind: TupleValue, arg0: block5, type: type2}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+7}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+8}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, -// CHECK:STDOUT: {kind: ArrayType, arg0: node+10, arg1: type1, type: typeTypeType}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type3}, +// CHECK:STDOUT: {kind: ArrayType, arg0: node+11, arg1: type1, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type3}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type2}, -// CHECK:STDOUT: {kind: ArrayValue, arg0: node+13, type: type3}, -// CHECK:STDOUT: {kind: Assign, arg0: node+12, arg1: node+14}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+15, arg1: node+14}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+15, type: type2}, +// CHECK:STDOUT: {kind: ArrayValue, arg0: node+17, type: type3}, +// CHECK:STDOUT: {kind: Assign, arg0: node+13, arg1: node+18}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -67,31 +72,35 @@ fn Run() { // CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, // CHECK:STDOUT: node+12, // CHECK:STDOUT: node+13, // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, // CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+17, +// CHECK:STDOUT: node+18, +// CHECK:STDOUT: node+19, +// CHECK:STDOUT: node+20, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -114,7 +123,10 @@ fn Run() { // CHECK:STDOUT: %.loc10_17: type = array_type %.loc10_16, i32 // CHECK:STDOUT: %t: [i32; 1] = var "t" // CHECK:STDOUT: %.loc10_22.1: (i32,) = call @F() -// CHECK:STDOUT: %.loc10_22.2: [i32; 1] = array_value %.loc10_22.1 -// CHECK:STDOUT: assign %t, %.loc10_22.2 +// CHECK:STDOUT: %.loc10_22.2: (i32,) = materialize_temporary +// CHECK:STDOUT: assign %.loc10_22.2, %.loc10_22.1 +// CHECK:STDOUT: %.loc10_22.3: (i32,) = bind_value %.loc10_22.2 +// CHECK:STDOUT: %.loc10_22.4: [i32; 1] = array_value %.loc10_22.3 +// CHECK:STDOUT: assign %t, %.loc10_22.4 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/array/assign_var.carbon b/toolchain/semantics/testdata/array/assign_var.carbon index e9f7ebb4efced..55c771fabc0ec 100644 --- a/toolchain/semantics/testdata/array/assign_var.carbon +++ b/toolchain/semantics/testdata/array/assign_var.carbon @@ -59,8 +59,9 @@ var b: [i32; 3] = a; // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int3, type: type1}, // CHECK:STDOUT: {kind: ArrayType, arg0: node+15, arg1: type1, type: typeTypeType}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type3}, -// CHECK:STDOUT: {kind: ArrayValue, arg0: node+6, type: type3}, -// CHECK:STDOUT: {kind: Assign, arg0: node+17, arg1: node+18}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+6, type: type2}, +// CHECK:STDOUT: {kind: ArrayValue, arg0: node+18, type: type3}, +// CHECK:STDOUT: {kind: Assign, arg0: node+17, arg1: node+19}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -86,6 +87,7 @@ var b: [i32; 3] = a; // CHECK:STDOUT: node+17, // CHECK:STDOUT: node+18, // CHECK:STDOUT: node+19, +// CHECK:STDOUT: node+20, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -118,6 +120,7 @@ var b: [i32; 3] = a; // CHECK:STDOUT: %.loc8_14: i32 = int_literal 3 // CHECK:STDOUT: %.loc8_15: type = array_type %.loc8_14, i32 // CHECK:STDOUT: %b: [i32; 3] = var "b" -// CHECK:STDOUT: %.loc7_5: [i32; 3] = array_value %a -// CHECK:STDOUT: assign %b, %.loc7_5 +// CHECK:STDOUT: %.loc7_5.1: (i32, i32, i32) = bind_value %a +// CHECK:STDOUT: %.loc7_5.2: [i32; 3] = array_value %.loc7_5.1 +// CHECK:STDOUT: assign %b, %.loc7_5.2 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/const/collapse.carbon b/toolchain/semantics/testdata/const/collapse.carbon index c87f434b87949..2a6523259f612 100644 --- a/toolchain/semantics/testdata/const/collapse.carbon +++ b/toolchain/semantics/testdata/const/collapse.carbon @@ -23,6 +23,7 @@ fn F(p: const i32**) -> const (const i32)** { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, // CHECK:STDOUT: p, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -41,6 +42,7 @@ fn F(p: const i32**) -> const (const i32)** { // CHECK:STDOUT: {kind: ConstType, arg0: type1, type: typeTypeType}, // CHECK:STDOUT: {kind: PointerType, arg0: type1, type: typeTypeType}, // CHECK:STDOUT: {kind: PointerType, arg0: type2, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type3}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: node+3}, // CHECK:STDOUT: ] @@ -56,15 +58,16 @@ fn F(p: const i32**) -> const (const i32)** { // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/const/fail_collapse.carbon b/toolchain/semantics/testdata/const/fail_collapse.carbon index ebcf622624c08..6fbf700c984cd 100644 --- a/toolchain/semantics/testdata/const/fail_collapse.carbon +++ b/toolchain/semantics/testdata/const/fail_collapse.carbon @@ -25,6 +25,7 @@ fn G(p: const (const i32)**) -> i32** { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: G, // CHECK:STDOUT: p, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -44,6 +45,7 @@ fn G(p: const (const i32)**) -> i32** { // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type3}, // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, // CHECK:STDOUT: {kind: PointerType, arg0: type4, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type5}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: nodeError}, // CHECK:STDOUT: ] @@ -58,15 +60,16 @@ fn G(p: const (const i32)**) -> i32** { // CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/function/call/empty_struct.carbon b/toolchain/semantics/testdata/function/call/empty_struct.carbon index 5e47dd46e59cb..0a837380c142f 100644 --- a/toolchain/semantics/testdata/function/call/empty_struct.carbon +++ b/toolchain/semantics/testdata/function/call/empty_struct.carbon @@ -15,7 +15,7 @@ fn Main() { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block2, return_type: type0, body: [block4]}, -// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block5]}, +// CHECK:STDOUT: {name: str3, param_refs: block0, body: [block5]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -24,6 +24,7 @@ fn Main() { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Echo, // CHECK:STDOUT: a, +// CHECK:STDOUT: return, // CHECK:STDOUT: Main, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ @@ -36,11 +37,12 @@ fn Main() { // CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, +// CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+7, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type0}, // CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0, type: type0}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] @@ -52,25 +54,26 @@ fn Main() { // CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, // CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -81,7 +84,7 @@ fn Main() { // CHECK:STDOUT: // CHECK:STDOUT: fn @Echo(%a: {}) -> {} { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: return %a +// CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @Main() { diff --git a/toolchain/semantics/testdata/function/call/empty_tuple.carbon b/toolchain/semantics/testdata/function/call/empty_tuple.carbon index c545555321d1b..7cdd796a7a474 100644 --- a/toolchain/semantics/testdata/function/call/empty_tuple.carbon +++ b/toolchain/semantics/testdata/function/call/empty_tuple.carbon @@ -15,7 +15,7 @@ fn Main() { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block2, return_type: type0, body: [block4]}, -// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block5]}, +// CHECK:STDOUT: {name: str3, param_refs: block0, body: [block5]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -24,6 +24,7 @@ fn Main() { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Echo, // CHECK:STDOUT: a, +// CHECK:STDOUT: return, // CHECK:STDOUT: Main, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ @@ -38,11 +39,12 @@ fn Main() { // CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, +// CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+7, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type0}, // CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0, type: type0}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] @@ -54,25 +56,26 @@ fn Main() { // CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, // CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -83,7 +86,7 @@ fn Main() { // CHECK:STDOUT: // CHECK:STDOUT: fn @Echo(%a: ()) -> () { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: return %a +// CHECK:STDOUT: return // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: fn @Main() { diff --git a/toolchain/semantics/testdata/function/call/fail_return_type_mismatch.carbon b/toolchain/semantics/testdata/function/call/fail_return_type_mismatch.carbon index 6b0c49b693c55..70c6a2ec5cbaf 100644 --- a/toolchain/semantics/testdata/function/call/fail_return_type_mismatch.carbon +++ b/toolchain/semantics/testdata/function/call/fail_return_type_mismatch.carbon @@ -15,8 +15,8 @@ fn Run() { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, -// CHECK:STDOUT: {name: str1, param_refs: block0, body: [block3]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block4]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -25,6 +25,7 @@ fn Run() { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Foo, +// CHECK:STDOUT: return, // CHECK:STDOUT: Run, // CHECK:STDOUT: x, // CHECK:STDOUT: ] @@ -35,13 +36,14 @@ fn Run() { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type1}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+4, arg1: nodeError}, +// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: nodeError}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -49,17 +51,20 @@ fn Run() { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+4, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/function/call/i32.carbon b/toolchain/semantics/testdata/function/call/i32.carbon index 20859a081931b..2cd392ebe07f5 100644 --- a/toolchain/semantics/testdata/function/call/i32.carbon +++ b/toolchain/semantics/testdata/function/call/i32.carbon @@ -15,7 +15,7 @@ fn Main() { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block2, return_type: type0, body: [block4]}, -// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block5]}, +// CHECK:STDOUT: {name: str3, param_refs: block0, body: [block5]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 1, @@ -25,6 +25,7 @@ fn Main() { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Echo, // CHECK:STDOUT: a, +// CHECK:STDOUT: return, // CHECK:STDOUT: Main, // CHECK:STDOUT: b, // CHECK:STDOUT: ] @@ -35,14 +36,15 @@ fn Main() { // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: node+0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str4, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+5, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+6, type: type0}, // CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+4, arg1: node+7}, +// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+8}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -50,27 +52,28 @@ fn Main() { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, +// CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+1, -// CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/function/call/return_implicit.carbon b/toolchain/semantics/testdata/function/call/return_implicit.carbon index 6b5c6e7f7208d..acd7ef4879f4a 100644 --- a/toolchain/semantics/testdata/function/call/return_implicit.carbon +++ b/toolchain/semantics/testdata/function/call/return_implicit.carbon @@ -40,7 +40,6 @@ fn Main() { // CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+6}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -59,7 +58,6 @@ fn Main() { // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, -// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -79,6 +77,5 @@ fn Main() { // CHECK:STDOUT: %.loc11_11.2: () = tuple_value () // CHECK:STDOUT: %b: () = var "b" // CHECK:STDOUT: %.loc11_37: () = call @MakeImplicitEmptyTuple() -// CHECK:STDOUT: assign %b, %.loc11_37 // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/if/fail_reachable_fallthrough.carbon b/toolchain/semantics/testdata/if/fail_reachable_fallthrough.carbon index a9ba66dfa36eb..c0c1ae2355083 100644 --- a/toolchain/semantics/testdata/if/fail_reachable_fallthrough.carbon +++ b/toolchain/semantics/testdata/if/fail_reachable_fallthrough.carbon @@ -36,8 +36,8 @@ fn If3(b: bool) -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block2, return_type: type1, body: [block4, block5, block6, block7]}, -// CHECK:STDOUT: {name: str2, param_refs: block9, return_type: type1, body: [block10, block11, block12, block13]}, -// CHECK:STDOUT: {name: str3, param_refs: block15, return_type: type1, body: [block16, block17, block18]}, +// CHECK:STDOUT: {name: str3, param_refs: block9, return_type: type1, body: [block10, block11, block12, block13]}, +// CHECK:STDOUT: {name: str4, param_refs: block15, return_type: type1, body: [block16, block17, block18]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 1, @@ -49,6 +49,7 @@ fn If3(b: bool) -> i32 { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: If1, // CHECK:STDOUT: b, +// CHECK:STDOUT: return, // CHECK:STDOUT: If2, // CHECK:STDOUT: If3, // CHECK:STDOUT: ] @@ -60,25 +61,28 @@ fn If3(b: bool) -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: BranchIf, arg0: block5, arg1: node+0}, // CHECK:STDOUT: {kind: Branch, arg0: block6}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+5}, // CHECK:STDOUT: {kind: Branch, arg0: block7}, // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block11, arg1: node+7}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block11, arg1: node+8}, // CHECK:STDOUT: {kind: Branch, arg0: block12}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+11}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+13}, // CHECK:STDOUT: {kind: Branch, arg0: block13}, // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function2}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block17, arg1: node+14}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block17, arg1: node+16}, // CHECK:STDOUT: {kind: Branch, arg0: block18}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int2, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+18}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+21}, // CHECK:STDOUT: {kind: Branch, arg0: block18}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -86,60 +90,63 @@ fn If3(b: bool) -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, +// CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+1, -// CHECK:STDOUT: node+8, -// CHECK:STDOUT: node+15, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, -// CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+18, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, -// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+13, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+11, // CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+15, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+13, // CHECK:STDOUT: node+14, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+14, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+16, // CHECK:STDOUT: node+17, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+18, +// CHECK:STDOUT: node+16, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+19, +// CHECK:STDOUT: node+20, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+21, +// CHECK:STDOUT: node+22, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: ], diff --git a/toolchain/semantics/testdata/if/fail_scope.carbon b/toolchain/semantics/testdata/if/fail_scope.carbon index 4ed6ad5e4392a..fef77d4a4de75 100644 --- a/toolchain/semantics/testdata/if/fail_scope.carbon +++ b/toolchain/semantics/testdata/if/fail_scope.carbon @@ -27,6 +27,7 @@ fn VarScope(b: bool) -> i32 { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: VarScope, // CHECK:STDOUT: b, +// CHECK:STDOUT: return, // CHECK:STDOUT: n, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ @@ -37,13 +38,15 @@ fn VarScope(b: bool) -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: BranchIf, arg0: block5, arg1: node+0}, // CHECK:STDOUT: {kind: Branch, arg0: block6}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+4, arg1: node+5}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4}, +// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+6}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+5, type: type1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+8}, // CHECK:STDOUT: {kind: Branch, arg0: block6}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: nodeError}, // CHECK:STDOUT: ] @@ -52,25 +55,27 @@ fn VarScope(b: bool) -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, +// CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -84,9 +89,10 @@ fn VarScope(b: bool) -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: !if.then: // CHECK:STDOUT: %n: i32 = var "n" -// CHECK:STDOUT: %.loc9: i32 = int_literal 2 -// CHECK:STDOUT: assign %n, %.loc9 -// CHECK:STDOUT: return %n +// CHECK:STDOUT: %.loc9_18: i32 = int_literal 2 +// CHECK:STDOUT: assign %n, %.loc9_18 +// CHECK:STDOUT: %.loc9_9: i32 = bind_value %n +// CHECK:STDOUT: return %.loc9_9 // CHECK:STDOUT: // CHECK:STDOUT: !if.else: // CHECK:STDOUT: return diff --git a/toolchain/semantics/testdata/if/unreachable_fallthrough.carbon b/toolchain/semantics/testdata/if/unreachable_fallthrough.carbon index aea3b81a4e8d1..fde5e7a4e18f8 100644 --- a/toolchain/semantics/testdata/if/unreachable_fallthrough.carbon +++ b/toolchain/semantics/testdata/if/unreachable_fallthrough.carbon @@ -26,6 +26,7 @@ fn If(b: bool) -> i32 { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: If, // CHECK:STDOUT: b, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeBoolType, @@ -35,37 +36,39 @@ fn If(b: bool) -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: BranchIf, arg0: block5, arg1: node+0}, // CHECK:STDOUT: {kind: Branch, arg0: block6}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+5}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+6}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+7}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, +// CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/if_expression/basic.carbon b/toolchain/semantics/testdata/if_expression/basic.carbon index 49e03b6d23f15..36327f2efa3e5 100644 --- a/toolchain/semantics/testdata/if_expression/basic.carbon +++ b/toolchain/semantics/testdata/if_expression/basic.carbon @@ -21,6 +21,7 @@ fn F(b: bool, n: i32, m: i32) -> i32 { // CHECK:STDOUT: b, // CHECK:STDOUT: n, // CHECK:STDOUT: m, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeBoolType, @@ -32,15 +33,16 @@ fn F(b: bool, n: i32, m: i32) -> i32 { // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: Parameter, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: Parameter, arg0: str3, type: type1}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str4, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: BranchIf, arg0: block5, arg1: node+0}, // CHECK:STDOUT: {kind: Branch, arg0: block6}, // CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node+1, arg1: node+2, type: type1}, // CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node+2, arg1: node+1, type: type1}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block7, arg1: node+6}, // CHECK:STDOUT: {kind: BranchWithArg, arg0: block7, arg1: node+7}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block7, arg1: node+8}, // CHECK:STDOUT: {kind: BlockArg, arg0: block7, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+10}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+11}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -49,6 +51,7 @@ fn F(b: bool, n: i32, m: i32) -> i32 { // CHECK:STDOUT: node+0, // CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -56,23 +59,23 @@ fn F(b: bool, n: i32, m: i32) -> i32 { // CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+3, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, -// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+8, // CHECK:STDOUT: node+10, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+11, +// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/if_expression/constant_condition.carbon b/toolchain/semantics/testdata/if_expression/constant_condition.carbon index cad918d6b5556..28dde1ebbc203 100644 --- a/toolchain/semantics/testdata/if_expression/constant_condition.carbon +++ b/toolchain/semantics/testdata/if_expression/constant_condition.carbon @@ -17,10 +17,10 @@ fn G() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, -// CHECK:STDOUT: {name: str1, param_refs: block0, return_type: type0, body: [block3]}, -// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type0, body: [block4, block5, block6, block7]}, -// CHECK:STDOUT: {name: str3, param_refs: block0, return_type: type0, body: [block8, block9, block10, block11]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type0, body: [block5]}, +// CHECK:STDOUT: {name: str3, param_refs: block0, return_type: type0, body: [block7, block8, block9, block10]}, +// CHECK:STDOUT: {name: str4, param_refs: block0, return_type: type0, body: [block12, block13, block14, block15]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 1, @@ -30,6 +30,7 @@ fn G() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: A, +// CHECK:STDOUT: return, // CHECK:STDOUT: B, // CHECK:STDOUT: F, // CHECK:STDOUT: G, @@ -41,84 +42,124 @@ fn G() -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+6}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function2}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type1}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block5, arg1: node+7}, -// CHECK:STDOUT: {kind: Branch, arg0: block6}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block8, arg1: node+10}, +// CHECK:STDOUT: {kind: Branch, arg0: block9}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: node+13}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+14, type: type0}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function1, type: type0}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block7, arg1: node+10}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block7, arg1: node+11}, -// CHECK:STDOUT: {kind: BlockArg, arg0: block7, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+14}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+18, arg1: node+17}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+18, type: type0}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block10, arg1: node+16}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block10, arg1: node+20}, +// CHECK:STDOUT: {kind: BlockArg, arg0: block10, type: type0}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+23}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function3}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: false, type: type1}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block9, arg1: node+17}, -// CHECK:STDOUT: {kind: Branch, arg0: block10}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block13, arg1: node+27}, +// CHECK:STDOUT: {kind: Branch, arg0: block14}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+31, arg1: node+30}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+31, type: type0}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function1, type: type0}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block11, arg1: node+20}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block11, arg1: node+21}, -// CHECK:STDOUT: {kind: BlockArg, arg0: block11, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+24}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+35, arg1: node+34}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+35, type: type0}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block15, arg1: node+33}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block15, arg1: node+37}, +// CHECK:STDOUT: {kind: BlockArg, arg0: block15, type: type0}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+40}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+6, -// CHECK:STDOUT: node+16, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+26, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+8, -// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+11, // CHECK:STDOUT: node+13, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, +// CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+21, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+17, // CHECK:STDOUT: node+18, // CHECK:STDOUT: node+19, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+20, // CHECK:STDOUT: node+22, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+21, // CHECK:STDOUT: node+23, +// CHECK:STDOUT: node+24, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+24, // CHECK:STDOUT: node+25, // CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+27, +// CHECK:STDOUT: node+28, +// CHECK:STDOUT: node+29, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+30, +// CHECK:STDOUT: node+31, +// CHECK:STDOUT: node+32, +// CHECK:STDOUT: node+33, +// CHECK:STDOUT: node+38, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+34, +// CHECK:STDOUT: node+35, +// CHECK:STDOUT: node+36, +// CHECK:STDOUT: node+37, +// CHECK:STDOUT: node+39, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+40, +// CHECK:STDOUT: node+41, +// CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: // CHECK:STDOUT: package { @@ -146,12 +187,18 @@ fn G() -> i32 { // CHECK:STDOUT: if %.loc11_13 br !if.expr.then else br !if.expr.else // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.then: -// CHECK:STDOUT: %.loc11_24: i32 = call @A() -// CHECK:STDOUT: br !if.expr.result(%.loc11_24) +// CHECK:STDOUT: %.loc11_24.1: i32 = call @A() +// CHECK:STDOUT: %.loc11_24.2: i32 = materialize_temporary +// CHECK:STDOUT: assign %.loc11_24.2, %.loc11_24.1 +// CHECK:STDOUT: %.loc11_24.3: i32 = bind_value %.loc11_24.2 +// CHECK:STDOUT: br !if.expr.result(%.loc11_24.3) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.else: -// CHECK:STDOUT: %.loc11_33: i32 = call @B() -// CHECK:STDOUT: br !if.expr.result(%.loc11_33) +// CHECK:STDOUT: %.loc11_33.1: i32 = call @B() +// CHECK:STDOUT: %.loc11_33.2: i32 = materialize_temporary +// CHECK:STDOUT: assign %.loc11_33.2, %.loc11_33.1 +// CHECK:STDOUT: %.loc11_33.3: i32 = bind_value %.loc11_33.2 +// CHECK:STDOUT: br !if.expr.result(%.loc11_33.3) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.result: // CHECK:STDOUT: %.loc11_10: i32 = block_arg !if.expr.result @@ -164,12 +211,18 @@ fn G() -> i32 { // CHECK:STDOUT: if %.loc15_13 br !if.expr.then else br !if.expr.else // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.then: -// CHECK:STDOUT: %.loc15_25: i32 = call @A() -// CHECK:STDOUT: br !if.expr.result(%.loc15_25) +// CHECK:STDOUT: %.loc15_25.1: i32 = call @A() +// CHECK:STDOUT: %.loc15_25.2: i32 = materialize_temporary +// CHECK:STDOUT: assign %.loc15_25.2, %.loc15_25.1 +// CHECK:STDOUT: %.loc15_25.3: i32 = bind_value %.loc15_25.2 +// CHECK:STDOUT: br !if.expr.result(%.loc15_25.3) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.else: -// CHECK:STDOUT: %.loc15_34: i32 = call @B() -// CHECK:STDOUT: br !if.expr.result(%.loc15_34) +// CHECK:STDOUT: %.loc15_34.1: i32 = call @B() +// CHECK:STDOUT: %.loc15_34.2: i32 = materialize_temporary +// CHECK:STDOUT: assign %.loc15_34.2, %.loc15_34.1 +// CHECK:STDOUT: %.loc15_34.3: i32 = bind_value %.loc15_34.2 +// CHECK:STDOUT: br !if.expr.result(%.loc15_34.3) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.result: // CHECK:STDOUT: %.loc15_10: i32 = block_arg !if.expr.result diff --git a/toolchain/semantics/testdata/if_expression/control_flow.carbon b/toolchain/semantics/testdata/if_expression/control_flow.carbon index 57225db55a62a..f5137b744d4e6 100644 --- a/toolchain/semantics/testdata/if_expression/control_flow.carbon +++ b/toolchain/semantics/testdata/if_expression/control_flow.carbon @@ -13,9 +13,9 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, -// CHECK:STDOUT: {name: str1, param_refs: block0, return_type: type0, body: [block3]}, -// CHECK:STDOUT: {name: str2, param_refs: block5, return_type: type0, body: [block6, block7, block8, block9]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type0, body: [block5]}, +// CHECK:STDOUT: {name: str3, param_refs: block7, return_type: type0, body: [block8, block9, block10, block11]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 1, @@ -25,6 +25,7 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: A, +// CHECK:STDOUT: return, // CHECK:STDOUT: B, // CHECK:STDOUT: F, // CHECK:STDOUT: b, @@ -36,60 +37,82 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4}, -// CHECK:STDOUT: {kind: Parameter, arg0: str3, type: type1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+6}, +// CHECK:STDOUT: {kind: Parameter, arg0: str4, type: type1}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function2}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block7, arg1: node+6}, -// CHECK:STDOUT: {kind: Branch, arg0: block8}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block9, arg1: node+8}, +// CHECK:STDOUT: {kind: Branch, arg0: block10}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: node+13}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+14, type: type0}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function1, type: type0}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+10}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+11}, -// CHECK:STDOUT: {kind: BlockArg, arg0: block9, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+14}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+18, arg1: node+17}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+18, type: type0}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block11, arg1: node+16}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block11, arg1: node+20}, +// CHECK:STDOUT: {kind: BlockArg, arg0: block11, type: type0}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+23}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, -// CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+10, -// CHECK:STDOUT: node+12, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+11, -// CHECK:STDOUT: node+13, +// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+13, // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, +// CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+21, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+17, +// CHECK:STDOUT: node+18, +// CHECK:STDOUT: node+19, +// CHECK:STDOUT: node+20, +// CHECK:STDOUT: node+22, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+23, +// CHECK:STDOUT: node+24, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -116,12 +139,18 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: if %b br !if.expr.then else br !if.expr.else // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.then: -// CHECK:STDOUT: %.loc11_21: i32 = call @A() -// CHECK:STDOUT: br !if.expr.result(%.loc11_21) +// CHECK:STDOUT: %.loc11_21.1: i32 = call @A() +// CHECK:STDOUT: %.loc11_21.2: i32 = materialize_temporary +// CHECK:STDOUT: assign %.loc11_21.2, %.loc11_21.1 +// CHECK:STDOUT: %.loc11_21.3: i32 = bind_value %.loc11_21.2 +// CHECK:STDOUT: br !if.expr.result(%.loc11_21.3) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.else: -// CHECK:STDOUT: %.loc11_30: i32 = call @B() -// CHECK:STDOUT: br !if.expr.result(%.loc11_30) +// CHECK:STDOUT: %.loc11_30.1: i32 = call @B() +// CHECK:STDOUT: %.loc11_30.2: i32 = materialize_temporary +// CHECK:STDOUT: assign %.loc11_30.2, %.loc11_30.1 +// CHECK:STDOUT: %.loc11_30.3: i32 = bind_value %.loc11_30.2 +// CHECK:STDOUT: br !if.expr.result(%.loc11_30.3) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.result: // CHECK:STDOUT: %.loc11_10: i32 = block_arg !if.expr.result diff --git a/toolchain/semantics/testdata/if_expression/nested.carbon b/toolchain/semantics/testdata/if_expression/nested.carbon index 69620e4e3dda1..470c82c40ae31 100644 --- a/toolchain/semantics/testdata/if_expression/nested.carbon +++ b/toolchain/semantics/testdata/if_expression/nested.carbon @@ -25,6 +25,7 @@ fn F(a: bool, b: bool, c: bool) -> i32 { // CHECK:STDOUT: a, // CHECK:STDOUT: b, // CHECK:STDOUT: c, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeBoolType, @@ -36,6 +37,7 @@ fn F(a: bool, b: bool, c: bool) -> i32 { // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: Parameter, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: Parameter, arg0: str3, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str4, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: BranchIf, arg0: block5, arg1: node+0}, // CHECK:STDOUT: {kind: Branch, arg0: block6}, @@ -43,20 +45,20 @@ fn F(a: bool, b: bool, c: bool) -> i32 { // CHECK:STDOUT: {kind: Branch, arg0: block8}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+8}, // CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+9}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+10}, // CHECK:STDOUT: {kind: BlockArg, arg0: block9, type: type1}, // CHECK:STDOUT: {kind: BranchIf, arg0: block10, arg1: node+2}, // CHECK:STDOUT: {kind: Branch, arg0: block11}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int2, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int3, type: type1}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block12, arg1: node+15}, // CHECK:STDOUT: {kind: BranchWithArg, arg0: block12, arg1: node+16}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block12, arg1: node+17}, // CHECK:STDOUT: {kind: BlockArg, arg0: block12, type: type1}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block13, arg1: node+12}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block13, arg1: node+19}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block13, arg1: node+13}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block13, arg1: node+20}, // CHECK:STDOUT: {kind: BlockArg, arg0: block13, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+22}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+23}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -65,6 +67,7 @@ fn F(a: bool, b: bool, c: bool) -> i32 { // CHECK:STDOUT: node+0, // CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -72,47 +75,47 @@ fn F(a: bool, b: bool, c: bool) -> i32 { // CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+13, // CHECK:STDOUT: node+14, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+8, -// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+15, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+9, // CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+10, // CHECK:STDOUT: node+12, -// CHECK:STDOUT: node+20, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+15, -// CHECK:STDOUT: node+17, +// CHECK:STDOUT: node+13, +// CHECK:STDOUT: node+21, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+16, // CHECK:STDOUT: node+18, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+17, // CHECK:STDOUT: node+19, -// CHECK:STDOUT: node+21, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+20, // CHECK:STDOUT: node+22, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+23, +// CHECK:STDOUT: node+24, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/index/array_element_access.carbon b/toolchain/semantics/testdata/index/array_element_access.carbon index 71a78d140d755..d6d1c6b107ecc 100644 --- a/toolchain/semantics/testdata/index/array_element_access.carbon +++ b/toolchain/semantics/testdata/index/array_element_access.carbon @@ -56,10 +56,12 @@ var d: i32 = a[b]; // CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int4, type: type0}, // CHECK:STDOUT: {kind: ArrayIndex, arg0: node+2, arg1: node+15, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: node+16}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+16, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: node+17}, // CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type0}, // CHECK:STDOUT: {kind: ArrayIndex, arg0: node+2, arg1: node+11, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+18, arg1: node+19}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+20, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+19, arg1: node+21}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -86,6 +88,8 @@ var d: i32 = a[b]; // CHECK:STDOUT: node+18, // CHECK:STDOUT: node+19, // CHECK:STDOUT: node+20, +// CHECK:STDOUT: node+21, +// CHECK:STDOUT: node+22, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, @@ -110,9 +114,11 @@ var d: i32 = a[b]; // CHECK:STDOUT: assign %b, %.loc8 // CHECK:STDOUT: %c: i32 = var "c" // CHECK:STDOUT: %.loc9_16: i32 = int_literal 0 -// CHECK:STDOUT: %.loc9_17: i32 = array_index %a, %.loc9_16 -// CHECK:STDOUT: assign %c, %.loc9_17 +// CHECK:STDOUT: %.loc9_17.1: i32 = array_index %a, %.loc9_16 +// CHECK:STDOUT: %.loc9_17.2: i32 = bind_value %.loc9_17.1 +// CHECK:STDOUT: assign %c, %.loc9_17.2 // CHECK:STDOUT: %d: i32 = var "d" -// CHECK:STDOUT: %.loc10: i32 = array_index %a, %b -// CHECK:STDOUT: assign %d, %.loc10 +// CHECK:STDOUT: %.loc10_17.1: i32 = array_index %a, %b +// CHECK:STDOUT: %.loc10_17.2: i32 = bind_value %.loc10_17.1 +// CHECK:STDOUT: assign %d, %.loc10_17.2 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/index/fail_empty_tuple_access.carbon b/toolchain/semantics/testdata/index/fail_empty_tuple_access.carbon index 5a499233b2eea..638a22a0fcfc0 100644 --- a/toolchain/semantics/testdata/index/fail_empty_tuple_access.carbon +++ b/toolchain/semantics/testdata/index/fail_empty_tuple_access.carbon @@ -42,6 +42,7 @@ fn Run() { // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock0, type: typeTypeType}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -59,6 +60,7 @@ fn Run() { // CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -77,5 +79,6 @@ fn Run() { // CHECK:STDOUT: %.loc13_4.1: type = tuple_type () // CHECK:STDOUT: %.loc13_4.2: () = call @F() // CHECK:STDOUT: %.loc13_7: i32 = int_literal 0 +// CHECK:STDOUT: %.loc13_4.3: () = materialize_temporary // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/index/fail_tuple_large_index.carbon b/toolchain/semantics/testdata/index/fail_tuple_large_index.carbon index 737fa17e8dea3..12ae96d9724f0 100644 --- a/toolchain/semantics/testdata/index/fail_tuple_large_index.carbon +++ b/toolchain/semantics/testdata/index/fail_tuple_large_index.carbon @@ -51,10 +51,11 @@ var c: i32 = b[0xFFFFFFFFFFFFFFFFF]; // CHECK:STDOUT: {kind: StubReference, arg0: nodeIntegerType, type: typeTypeType}, // CHECK:STDOUT: {kind: TupleValue, arg0: block4, type: type0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+11, arg1: node+4}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+4, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+11, arg1: node+12}, // CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+13, arg1: nodeError}, +// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: nodeError}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -76,6 +77,7 @@ var c: i32 = b[0xFFFFFFFFFFFFFFFFF]; // CHECK:STDOUT: node+13, // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, +// CHECK:STDOUT: node+16, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -101,7 +103,8 @@ var c: i32 = b[0xFFFFFFFFFFFFFFFFF]; // CHECK:STDOUT: %.loc8_9: type = stub_reference i32 // CHECK:STDOUT: %.loc8_13: (type,) = tuple_value (%.loc8_9) // CHECK:STDOUT: %b: (i32,) = var "b" -// CHECK:STDOUT: assign %b, %a +// CHECK:STDOUT: %.loc7_5: (i32,) = bind_value %a +// CHECK:STDOUT: assign %b, %.loc7_5 // CHECK:STDOUT: %c: i32 = var "c" // CHECK:STDOUT: %.loc12: i32 = int_literal -1 // CHECK:STDOUT: assign %c, diff --git a/toolchain/semantics/testdata/index/tuple_element_access.carbon b/toolchain/semantics/testdata/index/tuple_element_access.carbon index 4cba2ec1be7cf..22bca63bb0473 100644 --- a/toolchain/semantics/testdata/index/tuple_element_access.carbon +++ b/toolchain/semantics/testdata/index/tuple_element_access.carbon @@ -48,11 +48,13 @@ var c: i32 = b[0]; // CHECK:STDOUT: {kind: StubReference, arg0: nodeIntegerType, type: typeTypeType}, // CHECK:STDOUT: {kind: TupleValue, arg0: block4, type: type0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+11, arg1: node+4}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+4, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+11, arg1: node+12}, // CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, -// CHECK:STDOUT: {kind: TupleIndex, arg0: node+11, arg1: node+14, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+13, arg1: node+15}, +// CHECK:STDOUT: {kind: TupleIndex, arg0: node+11, arg1: node+15, type: type1}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+16, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: node+17}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -75,6 +77,8 @@ var c: i32 = b[0]; // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, // CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+17, +// CHECK:STDOUT: node+18, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -100,9 +104,11 @@ var c: i32 = b[0]; // CHECK:STDOUT: %.loc8_9: type = stub_reference i32 // CHECK:STDOUT: %.loc8_13: (type,) = tuple_value (%.loc8_9) // CHECK:STDOUT: %b: (i32,) = var "b" -// CHECK:STDOUT: assign %b, %a +// CHECK:STDOUT: %.loc7_5: (i32,) = bind_value %a +// CHECK:STDOUT: assign %b, %.loc7_5 // CHECK:STDOUT: %c: i32 = var "c" // CHECK:STDOUT: %.loc9_16: i32 = int_literal 0 -// CHECK:STDOUT: %.loc9_17: i32 = tuple_index %b, %.loc9_16 -// CHECK:STDOUT: assign %c, %.loc9_17 +// CHECK:STDOUT: %.loc9_17.1: i32 = tuple_index %b, %.loc9_16 +// CHECK:STDOUT: %.loc9_17.2: i32 = bind_value %.loc9_17.1 +// CHECK:STDOUT: assign %c, %.loc9_17.2 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/index/tuple_return_value_access.carbon b/toolchain/semantics/testdata/index/tuple_return_value_access.carbon index db9e4ebd0a399..8ee9d5fb18c2c 100644 --- a/toolchain/semantics/testdata/index/tuple_return_value_access.carbon +++ b/toolchain/semantics/testdata/index/tuple_return_value_access.carbon @@ -13,7 +13,7 @@ fn Run() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type2, body: [block4]}, -// CHECK:STDOUT: {name: str1, param_refs: block0, return_type: type1, body: [block6]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type1, body: [block7]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 0, @@ -23,6 +23,7 @@ fn Run() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, +// CHECK:STDOUT: return, // CHECK:STDOUT: Run, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ @@ -43,16 +44,21 @@ fn Run() -> i32 { // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock0, type: typeTypeType}, // CHECK:STDOUT: {kind: TupleValue, arg0: block2, type: type0}, // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock1, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type2}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+5, type: type1}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+6, type: type1}, // CHECK:STDOUT: {kind: TupleValue, arg0: block5, type: type2}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+7}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+8}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type2}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, -// CHECK:STDOUT: {kind: TupleIndex, arg0: node+10, arg1: node+11, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+12}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: node+12}, +// CHECK:STDOUT: {kind: TupleIndex, arg0: node+14, arg1: node+13, type: type1}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+16, type: type1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+17}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -62,28 +68,35 @@ fn Run() -> i32 { // CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+10, -// CHECK:STDOUT: node+11, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+12, // CHECK:STDOUT: node+13, +// CHECK:STDOUT: node+14, +// CHECK:STDOUT: node+15, +// CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+17, +// CHECK:STDOUT: node+18, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -102,8 +115,11 @@ fn Run() -> i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @Run() -> i32 { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc10_11: (i32,) = call @F() +// CHECK:STDOUT: %.loc10_11.1: (i32,) = call @F() // CHECK:STDOUT: %.loc10_14: i32 = int_literal 0 -// CHECK:STDOUT: %.loc10_15: i32 = tuple_index %.loc10_11, %.loc10_14 -// CHECK:STDOUT: return %.loc10_15 +// CHECK:STDOUT: %.loc10_11.2: (i32,) = materialize_temporary +// CHECK:STDOUT: assign %.loc10_11.2, %.loc10_11.1 +// CHECK:STDOUT: %.loc10_15.1: i32 = tuple_index %.loc10_11.2, %.loc10_14 +// CHECK:STDOUT: %.loc10_15.2: i32 = bind_value %.loc10_15.1 +// CHECK:STDOUT: return %.loc10_15.2 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/operators/and.carbon b/toolchain/semantics/testdata/operators/and.carbon index 48ec3b2076651..f9bd5bb09f1b9 100644 --- a/toolchain/semantics/testdata/operators/and.carbon +++ b/toolchain/semantics/testdata/operators/and.carbon @@ -13,9 +13,9 @@ fn And() -> bool { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, -// CHECK:STDOUT: {name: str1, param_refs: block0, return_type: type0, body: [block3]}, -// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type0, body: [block4, block5, block6]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type0, body: [block5]}, +// CHECK:STDOUT: {name: str3, param_refs: block0, return_type: type0, body: [block7, block8, block9]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -23,6 +23,7 @@ fn And() -> bool { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, +// CHECK:STDOUT: return, // CHECK:STDOUT: G, // CHECK:STDOUT: And, // CHECK:STDOUT: ] @@ -32,51 +33,75 @@ fn And() -> bool { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+6}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function2}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+11, arg1: node+10}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+11, type: type0}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: false, type: type0}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block5, arg1: node+7}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block6, arg1: node+8}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block8, arg1: node+13}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+14}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function1, type: type0}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block6, arg1: node+11}, -// CHECK:STDOUT: {kind: BlockArg, arg0: block6, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+13}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+18, arg1: node+17}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+18, type: type0}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+20}, +// CHECK:STDOUT: {kind: BlockArg, arg0: block9, type: type0}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+22}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+9, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+8, -// CHECK:STDOUT: node+9, -// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, // CHECK:STDOUT: node+12, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+13, // CHECK:STDOUT: node+14, +// CHECK:STDOUT: node+15, +// CHECK:STDOUT: node+16, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+17, +// CHECK:STDOUT: node+18, +// CHECK:STDOUT: node+19, +// CHECK:STDOUT: node+20, +// CHECK:STDOUT: node+21, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+22, +// CHECK:STDOUT: node+23, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -100,13 +125,19 @@ fn And() -> bool { // CHECK:STDOUT: // CHECK:STDOUT: fn @And() -> bool { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc11_11: bool = call @F() +// CHECK:STDOUT: %.loc11_11.1: bool = call @F() +// CHECK:STDOUT: %.loc11_11.2: bool = materialize_temporary +// CHECK:STDOUT: assign %.loc11_11.2, %.loc11_11.1 +// CHECK:STDOUT: %.loc11_11.3: bool = bind_value %.loc11_11.2 // CHECK:STDOUT: %.loc11_14.1: bool = bool_literal false -// CHECK:STDOUT: if %.loc11_11 br !and.rhs else br !and.result(%.loc11_14.1) +// CHECK:STDOUT: if %.loc11_11.3 br !and.rhs else br !and.result(%.loc11_14.1) // CHECK:STDOUT: // CHECK:STDOUT: !and.rhs: -// CHECK:STDOUT: %.loc11_19: bool = call @G() -// CHECK:STDOUT: br !and.result(%.loc11_19) +// CHECK:STDOUT: %.loc11_19.1: bool = call @G() +// CHECK:STDOUT: %.loc11_19.2: bool = materialize_temporary +// CHECK:STDOUT: assign %.loc11_19.2, %.loc11_19.1 +// CHECK:STDOUT: %.loc11_19.3: bool = bind_value %.loc11_19.2 +// CHECK:STDOUT: br !and.result(%.loc11_19.3) // CHECK:STDOUT: // CHECK:STDOUT: !and.result: // CHECK:STDOUT: %.loc11_14.2: bool = block_arg !and.result diff --git a/toolchain/semantics/testdata/operators/assignment.carbon b/toolchain/semantics/testdata/operators/assignment.carbon index 24da4f75b78bd..1f7d5648ec59e 100644 --- a/toolchain/semantics/testdata/operators/assignment.carbon +++ b/toolchain/semantics/testdata/operators/assignment.carbon @@ -118,19 +118,21 @@ fn Main() { // CHECK:STDOUT: {kind: VarStorage, arg0: str4, type: type4}, // CHECK:STDOUT: {kind: AddressOf, arg0: node+1, type: type4}, // CHECK:STDOUT: {kind: Assign, arg0: node+45, arg1: node+46}, -// CHECK:STDOUT: {kind: Dereference, arg0: node+45, type: type0}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+45, type: type4}, +// CHECK:STDOUT: {kind: Dereference, arg0: node+48, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int12, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+48, arg1: node+49}, +// CHECK:STDOUT: {kind: Assign, arg0: node+49, arg1: node+50}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type5}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block8, arg1: node+51}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block8, arg1: node+52}, // CHECK:STDOUT: {kind: Branch, arg0: block9}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+45, type: type4}, // CHECK:STDOUT: {kind: AddressOf, arg0: node+1, type: type4}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block10, arg1: node+45}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block10, arg1: node+54}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block10, arg1: node+55}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block10, arg1: node+56}, // CHECK:STDOUT: {kind: BlockArg, arg0: block10, type: type4}, -// CHECK:STDOUT: {kind: Dereference, arg0: node+57, type: type0}, +// CHECK:STDOUT: {kind: Dereference, arg0: node+59, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int13, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+58, arg1: node+59}, +// CHECK:STDOUT: {kind: Assign, arg0: node+60, arg1: node+61}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -191,6 +193,7 @@ fn Main() { // CHECK:STDOUT: node+51, // CHECK:STDOUT: node+52, // CHECK:STDOUT: node+53, +// CHECK:STDOUT: node+54, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+6, @@ -214,17 +217,18 @@ fn Main() { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+55, +// CHECK:STDOUT: node+57, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+54, // CHECK:STDOUT: node+56, +// CHECK:STDOUT: node+58, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+57, -// CHECK:STDOUT: node+58, // CHECK:STDOUT: node+59, // CHECK:STDOUT: node+60, // CHECK:STDOUT: node+61, +// CHECK:STDOUT: node+62, +// CHECK:STDOUT: node+63, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -277,14 +281,16 @@ fn Main() { // CHECK:STDOUT: %p: i32* = var "p" // CHECK:STDOUT: %.loc19_17: i32* = address_of %a // CHECK:STDOUT: assign %p, %.loc19_17 -// CHECK:STDOUT: %.loc20_3: i32 = dereference %p +// CHECK:STDOUT: %.loc19_7.1: i32* = bind_value %p +// CHECK:STDOUT: %.loc20_3: i32 = dereference %.loc19_7.1 // CHECK:STDOUT: %.loc20_8: i32 = int_literal 5 // CHECK:STDOUT: assign %.loc20_3, %.loc20_8 // CHECK:STDOUT: %.loc22_8: bool = bool_literal true // CHECK:STDOUT: if %.loc22_8 br !if.expr.then else br !if.expr.else // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.then: -// CHECK:STDOUT: br !if.expr.result(%p) +// CHECK:STDOUT: %.loc19_7.2: i32* = bind_value %p +// CHECK:STDOUT: br !if.expr.result(%.loc19_7.2) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.else: // CHECK:STDOUT: %.loc22_25: i32* = address_of %a diff --git a/toolchain/semantics/testdata/operators/binary_op.carbon b/toolchain/semantics/testdata/operators/binary_op.carbon index 3521c082a20b3..7e2617cf3b034 100644 --- a/toolchain/semantics/testdata/operators/binary_op.carbon +++ b/toolchain/semantics/testdata/operators/binary_op.carbon @@ -10,7 +10,7 @@ fn Main() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 12, @@ -20,6 +20,7 @@ fn Main() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -27,11 +28,12 @@ fn Main() -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0}, -// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node+1, arg1: node+2, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+3}, +// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node+2, arg1: node+3, type: type0}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -41,9 +43,12 @@ fn Main() -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/operators/fail_assigment_to_non_assignable.carbon b/toolchain/semantics/testdata/operators/fail_assigment_to_non_assignable.carbon index 6c0a6d55b68b2..6877b3dece3b4 100644 --- a/toolchain/semantics/testdata/operators/fail_assigment_to_non_assignable.carbon +++ b/toolchain/semantics/testdata/operators/fail_assigment_to_non_assignable.carbon @@ -48,7 +48,7 @@ fn Main() { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0}, -// CHECK:STDOUT: {name: str1, param_refs: block0, body: [block2, block11, block12, block13, block14, block15, block16]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block3, block12, block13, block14, block15, block16, block17]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 1, @@ -74,6 +74,7 @@ fn Main() { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, +// CHECK:STDOUT: return, // CHECK:STDOUT: Main, // CHECK:STDOUT: n, // CHECK:STDOUT: x, @@ -82,8 +83,8 @@ fn Main() { // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, -// CHECK:STDOUT: node+12, -// CHECK:STDOUT: node+40, +// CHECK:STDOUT: node+13, +// CHECK:STDOUT: node+43, // CHECK:STDOUT: nodeBoolType, // CHECK:STDOUT: ] // CHECK:STDOUT: type_blocks: [ @@ -93,75 +94,80 @@ fn Main() { // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+3}, +// CHECK:STDOUT: {kind: Assign, arg0: node+3, arg1: node+4}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int2, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+6}, +// CHECK:STDOUT: {kind: Assign, arg0: node+6, arg1: node+7}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int3, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+9, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int4, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+10, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+11, type: type0}, // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock0, type: typeTypeType}, -// CHECK:STDOUT: {kind: TupleValue, arg0: block3, type: type1}, +// CHECK:STDOUT: {kind: TupleValue, arg0: block4, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int5, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+14, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+15, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int6, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+16, type: type0}, -// CHECK:STDOUT: {kind: TupleValue, arg0: block4, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+13, arg1: node+18}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, -// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int7, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+20, arg1: node+21}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+20, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+20, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+17, type: type0}, // CHECK:STDOUT: {kind: TupleValue, arg0: block5, type: type1}, -// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int8, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+14, arg1: node+19}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type0}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int7, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+21, arg1: node+22}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+21, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+24, type: type0}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+21, type: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+26, type: type0}, -// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int9, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+28, type: type0}, // CHECK:STDOUT: {kind: TupleValue, arg0: block6, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+25, arg1: node+30}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int8, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+29, type: type0}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int9, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+31, type: type0}, +// CHECK:STDOUT: {kind: TupleValue, arg0: block7, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+28, arg1: node+33}, // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, -// CHECK:STDOUT: {kind: Assign, arg0: nodeIntegerType, arg1: node+32}, +// CHECK:STDOUT: {kind: Assign, arg0: nodeIntegerType, arg1: node+35}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int10, type: type0}, -// CHECK:STDOUT: {kind: StructTypeField, arg0: str3, arg1: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+34, type: type0}, -// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int11, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str4, arg1: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+37, type: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block7, type: typeTypeType}, -// CHECK:STDOUT: {kind: StructValue, arg0: block8, type: type2}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int11, type: type0}, +// CHECK:STDOUT: {kind: StructTypeField, arg0: str5, arg1: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+40, type: type0}, +// CHECK:STDOUT: {kind: StructType, arg0: block8, type: typeTypeType}, +// CHECK:STDOUT: {kind: StructValue, arg0: block9, type: type2}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int12, type: type0}, -// CHECK:STDOUT: {kind: StructTypeField, arg0: str3, arg1: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+42, type: type0}, -// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int13, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str4, arg1: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+45, type: type0}, -// CHECK:STDOUT: {kind: StructValue, arg0: block10, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+41, arg1: node+48}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int13, type: type0}, +// CHECK:STDOUT: {kind: StructTypeField, arg0: str5, arg1: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+48, type: type0}, +// CHECK:STDOUT: {kind: StructValue, arg0: block11, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+44, arg1: node+51}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type3}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block11, arg1: node+50}, -// CHECK:STDOUT: {kind: Branch, arg0: block12}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block12, arg1: node+53}, +// CHECK:STDOUT: {kind: Branch, arg0: block13}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int14, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int15, type: type0}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block13, arg1: node+53}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block13, arg1: node+54}, -// CHECK:STDOUT: {kind: BlockArg, arg0: block13, type: type0}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block14, arg1: node+56}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block14, arg1: node+57}, +// CHECK:STDOUT: {kind: BlockArg, arg0: block14, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int16, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+57, arg1: node+58}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str5, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+60, arg1: node+61}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str6, type: type0}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type3}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block14, arg1: node+61}, -// CHECK:STDOUT: {kind: Branch, arg0: block15}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block16, arg1: node+60}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block16, arg1: node+60}, -// CHECK:STDOUT: {kind: BlockArg, arg0: block16, type: type0}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block15, arg1: node+64}, +// CHECK:STDOUT: {kind: Branch, arg0: block16}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+63, type: type0}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+63, type: type0}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block17, arg1: node+67}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block17, arg1: node+68}, +// CHECK:STDOUT: {kind: BlockArg, arg0: block17, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int17, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+66, arg1: node+67}, +// CHECK:STDOUT: {kind: Assign, arg0: node+71, arg1: node+72}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -169,10 +175,12 @@ fn Main() { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, @@ -205,82 +213,87 @@ fn Main() { // CHECK:STDOUT: node+32, // CHECK:STDOUT: node+33, // CHECK:STDOUT: node+34, +// CHECK:STDOUT: node+35, // CHECK:STDOUT: node+36, // CHECK:STDOUT: node+37, // CHECK:STDOUT: node+39, // CHECK:STDOUT: node+40, -// CHECK:STDOUT: node+41, // CHECK:STDOUT: node+42, +// CHECK:STDOUT: node+43, // CHECK:STDOUT: node+44, // CHECK:STDOUT: node+45, // CHECK:STDOUT: node+47, // CHECK:STDOUT: node+48, -// CHECK:STDOUT: node+49, // CHECK:STDOUT: node+50, // CHECK:STDOUT: node+51, // CHECK:STDOUT: node+52, +// CHECK:STDOUT: node+53, +// CHECK:STDOUT: node+54, +// CHECK:STDOUT: node+55, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+9, -// CHECK:STDOUT: node+11, +// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+15, -// CHECK:STDOUT: node+17, +// CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+18, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+23, -// CHECK:STDOUT: node+24, +// CHECK:STDOUT: node+25, +// CHECK:STDOUT: node+27, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+27, -// CHECK:STDOUT: node+29, +// CHECK:STDOUT: node+30, +// CHECK:STDOUT: node+32, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+35, // CHECK:STDOUT: node+38, +// CHECK:STDOUT: node+41, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+36, // CHECK:STDOUT: node+39, +// CHECK:STDOUT: node+42, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+43, // CHECK:STDOUT: node+46, +// CHECK:STDOUT: node+49, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+44, // CHECK:STDOUT: node+47, +// CHECK:STDOUT: node+50, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+53, -// CHECK:STDOUT: node+55, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+54, // CHECK:STDOUT: node+56, +// CHECK:STDOUT: node+58, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+57, -// CHECK:STDOUT: node+58, // CHECK:STDOUT: node+59, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+60, // CHECK:STDOUT: node+61, // CHECK:STDOUT: node+62, // CHECK:STDOUT: node+63, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+64, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+65, +// CHECK:STDOUT: node+66, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+66, // CHECK:STDOUT: node+67, -// CHECK:STDOUT: node+68, // CHECK:STDOUT: node+69, // CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+68, +// CHECK:STDOUT: node+70, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+71, +// CHECK:STDOUT: node+72, +// CHECK:STDOUT: node+73, +// CHECK:STDOUT: node+74, +// CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: // CHECK:STDOUT: package { @@ -311,10 +324,12 @@ fn Main() { // CHECK:STDOUT: %.loc21_17: (i32, i32) = tuple_value (%.loc21_13.2, %.loc21_16.2) // CHECK:STDOUT: assign %.loc21_8.2, %.loc21_17 // CHECK:STDOUT: %n: i32 = var "n" -// CHECK:STDOUT: %.loc22: i32 = int_literal 0 -// CHECK:STDOUT: assign %n, %.loc22 -// CHECK:STDOUT: %.loc26_4: i32 = stub_reference %n -// CHECK:STDOUT: %.loc26_7: i32 = stub_reference %n +// CHECK:STDOUT: %.loc22_16: i32 = int_literal 0 +// CHECK:STDOUT: assign %n, %.loc22_16 +// CHECK:STDOUT: %.loc22_7.1: i32 = bind_value %n +// CHECK:STDOUT: %.loc26_4: i32 = stub_reference %.loc22_7.1 +// CHECK:STDOUT: %.loc22_7.2: i32 = bind_value %n +// CHECK:STDOUT: %.loc26_7: i32 = stub_reference %.loc22_7.2 // CHECK:STDOUT: %.loc26_8: (i32, i32) = tuple_value (%.loc26_4, %.loc26_7) // CHECK:STDOUT: %.loc26_13.1: i32 = int_literal 1 // CHECK:STDOUT: %.loc26_13.2: i32 = stub_reference %.loc26_13.1 @@ -356,10 +371,12 @@ fn Main() { // CHECK:STDOUT: if %.loc45_7 br !if.expr.then.loc45 else br !if.expr.else.loc45 // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.then.loc45: -// CHECK:STDOUT: br !if.expr.result.loc45(%a) +// CHECK:STDOUT: %.loc41_7.1: i32 = bind_value %a +// CHECK:STDOUT: br !if.expr.result.loc45(%.loc41_7.1) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.else.loc45: -// CHECK:STDOUT: br !if.expr.result.loc45(%a) +// CHECK:STDOUT: %.loc41_7.2: i32 = bind_value %a +// CHECK:STDOUT: br !if.expr.result.loc45(%.loc41_7.2) // CHECK:STDOUT: // CHECK:STDOUT: !if.expr.result.loc45: // CHECK:STDOUT: %.loc45_4: i32 = block_arg !if.expr.result.loc45 diff --git a/toolchain/semantics/testdata/operators/fail_type_mismatch.carbon b/toolchain/semantics/testdata/operators/fail_type_mismatch.carbon index eeaeaacb08b2b..5888b33a6ed06 100644 --- a/toolchain/semantics/testdata/operators/fail_type_mismatch.carbon +++ b/toolchain/semantics/testdata/operators/fail_type_mismatch.carbon @@ -13,7 +13,7 @@ fn Main() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 12, @@ -23,6 +23,7 @@ fn Main() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -31,10 +32,11 @@ fn Main() -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type1}, -// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: nodeError, arg1: node+2, type: typeError}, +// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: nodeError, arg1: node+3, type: typeError}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: nodeError}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -45,9 +47,12 @@ fn Main() -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/operators/fail_type_mismatch_assignment.carbon b/toolchain/semantics/testdata/operators/fail_type_mismatch_assignment.carbon index d17df6a636dac..cc7474f8a1dcd 100644 --- a/toolchain/semantics/testdata/operators/fail_type_mismatch_assignment.carbon +++ b/toolchain/semantics/testdata/operators/fail_type_mismatch_assignment.carbon @@ -38,7 +38,7 @@ fn Main() { // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: node+2}, // CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: node+4}, +// CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: nodeError}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -67,6 +67,6 @@ fn Main() { // CHECK:STDOUT: %.loc8: i32 = int_literal 3 // CHECK:STDOUT: assign %a, %.loc8 // CHECK:STDOUT: %.loc12: f64 = real_literal 56e-1 -// CHECK:STDOUT: assign %a, %.loc12 +// CHECK:STDOUT: assign %a, // CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/operators/fail_type_mismatch_once.carbon b/toolchain/semantics/testdata/operators/fail_type_mismatch_once.carbon index 08b62c947b831..a8afd2926fd7f 100644 --- a/toolchain/semantics/testdata/operators/fail_type_mismatch_once.carbon +++ b/toolchain/semantics/testdata/operators/fail_type_mismatch_once.carbon @@ -15,7 +15,7 @@ fn Main() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 12, @@ -26,6 +26,7 @@ fn Main() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -34,12 +35,13 @@ fn Main() -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type1}, -// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: nodeError, arg1: node+2, type: typeError}, +// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: nodeError, arg1: node+3, type: typeError}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0}, -// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: nodeError, arg1: node+4, type: typeError}, +// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: nodeError, arg1: node+5, type: typeError}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: nodeError}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -50,11 +52,14 @@ fn Main() -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/operators/or.carbon b/toolchain/semantics/testdata/operators/or.carbon index 6f18d26860fe3..c18b825333ca3 100644 --- a/toolchain/semantics/testdata/operators/or.carbon +++ b/toolchain/semantics/testdata/operators/or.carbon @@ -13,9 +13,9 @@ fn Or() -> bool { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, -// CHECK:STDOUT: {name: str1, param_refs: block0, return_type: type0, body: [block3]}, -// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type0, body: [block4, block5, block6]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type0, body: [block5]}, +// CHECK:STDOUT: {name: str3, param_refs: block0, return_type: type0, body: [block7, block8, block9]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -23,6 +23,7 @@ fn Or() -> bool { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, +// CHECK:STDOUT: return, // CHECK:STDOUT: G, // CHECK:STDOUT: Or, // CHECK:STDOUT: ] @@ -32,53 +33,77 @@ fn Or() -> bool { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+4}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+6}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function2}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, -// CHECK:STDOUT: {kind: UnaryOperatorNot, arg0: node+7, type: type0}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+11, arg1: node+10}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+11, type: type0}, +// CHECK:STDOUT: {kind: UnaryOperatorNot, arg0: node+13, type: type0}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type0}, -// CHECK:STDOUT: {kind: BranchIf, arg0: block5, arg1: node+8}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block6, arg1: node+9}, +// CHECK:STDOUT: {kind: BranchIf, arg0: block8, arg1: node+14}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+15}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function1, type: type0}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: block6, arg1: node+12}, -// CHECK:STDOUT: {kind: BlockArg, arg0: block6, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+14}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+19, arg1: node+18}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+19, type: type0}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: block9, arg1: node+21}, +// CHECK:STDOUT: {kind: BlockArg, arg0: block9, type: type0}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+23}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+9, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+8, -// CHECK:STDOUT: node+9, -// CHECK:STDOUT: node+10, -// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: node+12, // CHECK:STDOUT: node+13, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, +// CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+17, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+18, +// CHECK:STDOUT: node+19, +// CHECK:STDOUT: node+20, +// CHECK:STDOUT: node+21, +// CHECK:STDOUT: node+22, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+23, +// CHECK:STDOUT: node+24, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -102,14 +127,20 @@ fn Or() -> bool { // CHECK:STDOUT: // CHECK:STDOUT: fn @Or() -> bool { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc11_11: bool = call @F() -// CHECK:STDOUT: %.loc11_14.1: bool = not %.loc11_11 +// CHECK:STDOUT: %.loc11_11.1: bool = call @F() +// CHECK:STDOUT: %.loc11_11.2: bool = materialize_temporary +// CHECK:STDOUT: assign %.loc11_11.2, %.loc11_11.1 +// CHECK:STDOUT: %.loc11_11.3: bool = bind_value %.loc11_11.2 +// CHECK:STDOUT: %.loc11_14.1: bool = not %.loc11_11.3 // CHECK:STDOUT: %.loc11_14.2: bool = bool_literal true // CHECK:STDOUT: if %.loc11_14.1 br !or.rhs else br !or.result(%.loc11_14.2) // CHECK:STDOUT: // CHECK:STDOUT: !or.rhs: -// CHECK:STDOUT: %.loc11_18: bool = call @G() -// CHECK:STDOUT: br !or.result(%.loc11_18) +// CHECK:STDOUT: %.loc11_18.1: bool = call @G() +// CHECK:STDOUT: %.loc11_18.2: bool = materialize_temporary +// CHECK:STDOUT: assign %.loc11_18.2, %.loc11_18.1 +// CHECK:STDOUT: %.loc11_18.3: bool = bind_value %.loc11_18.2 +// CHECK:STDOUT: br !or.result(%.loc11_18.3) // CHECK:STDOUT: // CHECK:STDOUT: !or.result: // CHECK:STDOUT: %.loc11_14.3: bool = block_arg !or.result diff --git a/toolchain/semantics/testdata/operators/unary_op.carbon b/toolchain/semantics/testdata/operators/unary_op.carbon index a9ef7aebd75c6..4687ebb2fdd53 100644 --- a/toolchain/semantics/testdata/operators/unary_op.carbon +++ b/toolchain/semantics/testdata/operators/unary_op.carbon @@ -19,6 +19,7 @@ fn Not(b: bool) -> bool { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Not, // CHECK:STDOUT: b, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeBoolType, @@ -27,25 +28,27 @@ fn Not(b: bool) -> bool { // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: UnaryOperatorNot, arg0: node+0, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+3}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, +// CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/pointer/address_of_deref.carbon b/toolchain/semantics/testdata/pointer/address_of_deref.carbon index 3afa7d4d2c64e..546f11a54bca2 100644 --- a/toolchain/semantics/testdata/pointer/address_of_deref.carbon +++ b/toolchain/semantics/testdata/pointer/address_of_deref.carbon @@ -11,7 +11,7 @@ fn F() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 0, @@ -20,25 +20,28 @@ fn F() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, +// CHECK:STDOUT: return, // CHECK:STDOUT: n, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, -// CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, // CHECK:STDOUT: ] // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ -// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: node+2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+3}, // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+1, type: type1}, -// CHECK:STDOUT: {kind: Dereference, arg0: node+5, type: type0}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+6, type: type1}, -// CHECK:STDOUT: {kind: Dereference, arg0: node+7, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+8}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+2, type: type1}, +// CHECK:STDOUT: {kind: Dereference, arg0: node+6, type: type0}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+7, type: type1}, +// CHECK:STDOUT: {kind: Dereference, arg0: node+8, type: type0}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+9, type: type0}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+10}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -48,6 +51,8 @@ fn F() -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, @@ -56,6 +61,8 @@ fn F() -> i32 { // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -72,6 +79,7 @@ fn F() -> i32 { // CHECK:STDOUT: %.loc9_13.2: i32* = address_of %n // CHECK:STDOUT: %.loc9_12: i32 = dereference %.loc9_13.2 // CHECK:STDOUT: %.loc9_11: i32* = address_of %.loc9_12 -// CHECK:STDOUT: %.loc9_10: i32 = dereference %.loc9_11 -// CHECK:STDOUT: return %.loc9_10 +// CHECK:STDOUT: %.loc9_10.1: i32 = dereference %.loc9_11 +// CHECK:STDOUT: %.loc9_10.2: i32 = bind_value %.loc9_10.1 +// CHECK:STDOUT: return %.loc9_10.2 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/pointer/basic.carbon b/toolchain/semantics/testdata/pointer/basic.carbon index ad640649470e3..7aecece551571 100644 --- a/toolchain/semantics/testdata/pointer/basic.carbon +++ b/toolchain/semantics/testdata/pointer/basic.carbon @@ -13,7 +13,7 @@ fn F() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 0, @@ -22,26 +22,30 @@ fn F() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, +// CHECK:STDOUT: return, // CHECK:STDOUT: n, // CHECK:STDOUT: p, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, -// CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, // CHECK:STDOUT: ] // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ -// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+1, arg1: node+2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+3}, // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+1, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+6}, -// CHECK:STDOUT: {kind: Dereference, arg0: node+5, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+8}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type1}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+2, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+6, arg1: node+7}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+6, type: type1}, +// CHECK:STDOUT: {kind: Dereference, arg0: node+9, type: type0}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+10, type: type0}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+11}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -51,6 +55,8 @@ fn F() -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, @@ -59,6 +65,9 @@ fn F() -> i32 { // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, +// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -75,6 +84,8 @@ fn F() -> i32 { // CHECK:STDOUT: %p: i32* = var "p" // CHECK:STDOUT: %.loc9_17: i32* = address_of %n // CHECK:STDOUT: assign %p, %.loc9_17 -// CHECK:STDOUT: %.loc11: i32 = dereference %p -// CHECK:STDOUT: return %.loc11 +// CHECK:STDOUT: %.loc9_7: i32* = bind_value %p +// CHECK:STDOUT: %.loc11_10.1: i32 = dereference %.loc9_7 +// CHECK:STDOUT: %.loc11_10.2: i32 = bind_value %.loc11_10.1 +// CHECK:STDOUT: return %.loc11_10.2 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/pointer/fail_address_of_value.carbon b/toolchain/semantics/testdata/pointer/fail_address_of_value.carbon index 5aa598fef41f9..9ee135d089921 100644 --- a/toolchain/semantics/testdata/pointer/fail_address_of_value.carbon +++ b/toolchain/semantics/testdata/pointer/fail_address_of_value.carbon @@ -40,7 +40,7 @@ fn AddressOfOperator() { // CHECK:STDERR: &(1 + 1); // CHECK:STDERR: ^ &(1 + 1); - // CHECK:STDERR: fail_address_of_value.carbon:[[@LINE+3]]:3: Cannot take the address of non-reference expression. + // CHECK:STDERR: fail_address_of_value.carbon:[[@LINE+3]]:3: Cannot take the address of a temporary object. // CHECK:STDERR: &H().a; // CHECK:STDERR: ^ &H().a; @@ -85,13 +85,13 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0}, -// CHECK:STDOUT: {name: str1, param_refs: block0, return_type: type1}, -// CHECK:STDOUT: {name: str3, param_refs: block0, body: [block4]}, -// CHECK:STDOUT: {name: str5, param_refs: block0, body: [block8]}, +// CHECK:STDOUT: {name: str2, param_refs: block0, return_type: type1}, +// CHECK:STDOUT: {name: str4, param_refs: block0, body: [block5]}, // CHECK:STDOUT: {name: str6, param_refs: block0, body: [block9]}, // CHECK:STDOUT: {name: str7, param_refs: block0, body: [block10]}, // CHECK:STDOUT: {name: str8, param_refs: block0, body: [block11]}, -// CHECK:STDOUT: {name: str9, param_refs: block14, body: [block15]}, +// CHECK:STDOUT: {name: str9, param_refs: block0, body: [block12]}, +// CHECK:STDOUT: {name: str10, param_refs: block15, body: [block16]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 0, @@ -109,6 +109,7 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: G, +// CHECK:STDOUT: return, // CHECK:STDOUT: H, // CHECK:STDOUT: a, // CHECK:STDOUT: AddressOfLiteral, @@ -123,19 +124,19 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, -// CHECK:STDOUT: node+2, -// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: nodeBoolType, -// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: nodeFloatingPointType, -// CHECK:STDOUT: node+12, +// CHECK:STDOUT: node+14, // CHECK:STDOUT: nodeStringType, -// CHECK:STDOUT: node+15, -// CHECK:STDOUT: node+21, +// CHECK:STDOUT: node+17, // CHECK:STDOUT: node+23, -// CHECK:STDOUT: node+29, -// CHECK:STDOUT: node+49, -// CHECK:STDOUT: node+51, +// CHECK:STDOUT: node+25, +// CHECK:STDOUT: node+31, +// CHECK:STDOUT: node+53, +// CHECK:STDOUT: node+55, // CHECK:STDOUT: ] // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: [ @@ -144,77 +145,81 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, -// CHECK:STDOUT: {kind: StructTypeField, arg0: str2, arg1: type0}, -// CHECK:STDOUT: {kind: StructType, arg0: block3, type: typeTypeType}, +// CHECK:STDOUT: {kind: StructTypeField, arg0: str3, arg1: type0}, +// CHECK:STDOUT: {kind: StructType, arg0: block4, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function2}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+5, type: type2}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+7, type: type2}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type3}, // CHECK:STDOUT: {kind: PointerType, arg0: type3, type: typeTypeType}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+8, type: type4}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+10, type: type4}, // CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type5}, // CHECK:STDOUT: {kind: PointerType, arg0: type5, type: typeTypeType}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+11, type: type6}, -// CHECK:STDOUT: {kind: StringLiteral, arg0: str4, type: type7}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+13, type: type6}, +// CHECK:STDOUT: {kind: StringLiteral, arg0: str5, type: type7}, // CHECK:STDOUT: {kind: PointerType, arg0: type7, type: typeTypeType}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+14, type: type8}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+16, type: type8}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+17, type: type0}, -// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int2, type: type0}, // CHECK:STDOUT: {kind: StubReference, arg0: node+19, type: type0}, +// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int2, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+21, type: type0}, // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock0, type: typeTypeType}, -// CHECK:STDOUT: {kind: TupleValue, arg0: block5, type: type9}, +// CHECK:STDOUT: {kind: TupleValue, arg0: block6, type: type9}, // CHECK:STDOUT: {kind: PointerType, arg0: type9, type: typeTypeType}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+22, type: type10}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+24, type: type10}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int3, type: type0}, -// CHECK:STDOUT: {kind: StructTypeField, arg0: str2, arg1: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+25, type: type0}, -// CHECK:STDOUT: {kind: StructValue, arg0: block7, type: type1}, +// CHECK:STDOUT: {kind: StructTypeField, arg0: str3, arg1: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+27, type: type0}, +// CHECK:STDOUT: {kind: StructValue, arg0: block8, type: type1}, // CHECK:STDOUT: {kind: PointerType, arg0: type1, type: typeTypeType}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+28, type: type11}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+30, type: type11}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function3}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int4, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int5, type: type0}, -// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node+33, arg1: node+34, type: type0}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+35, type: type2}, +// CHECK:STDOUT: {kind: BinaryOperatorAdd, arg0: node+35, arg1: node+36, type: type0}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+37, type: type2}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function1, type: type1}, -// CHECK:STDOUT: {kind: StructAccess, arg0: node+37, arg1: member0, type: type0}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+38, type: type2}, +// CHECK:STDOUT: {kind: MaterializeTemporary, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+40, arg1: node+39}, +// CHECK:STDOUT: {kind: StructAccess, arg0: node+40, arg1: member0, type: type0}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+42, type: type2}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type3}, -// CHECK:STDOUT: {kind: UnaryOperatorNot, arg0: node+40, type: type3}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+41, type: type4}, +// CHECK:STDOUT: {kind: UnaryOperatorNot, arg0: node+44, type: type3}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+45, type: type4}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function4}, // CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+45, type: type2}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+49, type: type2}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function5}, // CHECK:STDOUT: {kind: PointerType, arg0: typeTypeType, type: typeTypeType}, // CHECK:STDOUT: {kind: AddressOf, arg0: nodeIntegerType, type: type12}, // CHECK:STDOUT: {kind: ConstType, arg0: type0, type: typeTypeType}, // CHECK:STDOUT: {kind: PointerType, arg0: type13, type: typeTypeType}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+52, type: type12}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+56, type: type12}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function6}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int6, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+56, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+60, type: type0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int7, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+58, type: type0}, -// CHECK:STDOUT: {kind: TupleValue, arg0: block12, type: type9}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+62, type: type0}, +// CHECK:STDOUT: {kind: TupleValue, arg0: block13, type: type9}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int8, type: type0}, -// CHECK:STDOUT: {kind: TupleIndex, arg0: node+60, arg1: node+61, type: type0}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+62, type: type2}, +// CHECK:STDOUT: {kind: TupleIndex, arg0: node+64, arg1: node+65, type: type0}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+66, type: type2}, // CHECK:STDOUT: {kind: Return}, -// CHECK:STDOUT: {kind: Parameter, arg0: str10, type: type0}, +// CHECK:STDOUT: {kind: Parameter, arg0: str11, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function7}, // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str11, type: type2}, -// CHECK:STDOUT: {kind: AddressOf, arg0: node+65, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+68, arg1: node+69}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str12, type: type2}, +// CHECK:STDOUT: {kind: AddressOf, arg0: node+69, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+72, arg1: node+73}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -222,24 +227,26 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+4, -// CHECK:STDOUT: node+32, -// CHECK:STDOUT: node+44, -// CHECK:STDOUT: node+48, -// CHECK:STDOUT: node+55, -// CHECK:STDOUT: node+66, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+34, +// CHECK:STDOUT: node+48, +// CHECK:STDOUT: node+52, +// CHECK:STDOUT: node+59, +// CHECK:STDOUT: node+70, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, -// CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, @@ -259,25 +266,25 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: node+23, // CHECK:STDOUT: node+24, // CHECK:STDOUT: node+25, +// CHECK:STDOUT: node+26, // CHECK:STDOUT: node+27, -// CHECK:STDOUT: node+28, // CHECK:STDOUT: node+29, // CHECK:STDOUT: node+30, // CHECK:STDOUT: node+31, +// CHECK:STDOUT: node+32, +// CHECK:STDOUT: node+33, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+18, // CHECK:STDOUT: node+20, +// CHECK:STDOUT: node+22, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+26, +// CHECK:STDOUT: node+28, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+27, +// CHECK:STDOUT: node+29, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+33, -// CHECK:STDOUT: node+34, // CHECK:STDOUT: node+35, // CHECK:STDOUT: node+36, // CHECK:STDOUT: node+37, @@ -287,8 +294,7 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: node+41, // CHECK:STDOUT: node+42, // CHECK:STDOUT: node+43, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ +// CHECK:STDOUT: node+44, // CHECK:STDOUT: node+45, // CHECK:STDOUT: node+46, // CHECK:STDOUT: node+47, @@ -297,37 +303,42 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: node+49, // CHECK:STDOUT: node+50, // CHECK:STDOUT: node+51, -// CHECK:STDOUT: node+52, -// CHECK:STDOUT: node+53, -// CHECK:STDOUT: node+54, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+53, +// CHECK:STDOUT: node+54, +// CHECK:STDOUT: node+55, // CHECK:STDOUT: node+56, // CHECK:STDOUT: node+57, // CHECK:STDOUT: node+58, -// CHECK:STDOUT: node+59, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+60, // CHECK:STDOUT: node+61, // CHECK:STDOUT: node+62, // CHECK:STDOUT: node+63, // CHECK:STDOUT: node+64, +// CHECK:STDOUT: node+65, +// CHECK:STDOUT: node+66, +// CHECK:STDOUT: node+67, +// CHECK:STDOUT: node+68, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+57, -// CHECK:STDOUT: node+59, +// CHECK:STDOUT: node+61, +// CHECK:STDOUT: node+63, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+65, +// CHECK:STDOUT: node+69, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+65, +// CHECK:STDOUT: node+69, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+67, -// CHECK:STDOUT: node+68, -// CHECK:STDOUT: node+69, -// CHECK:STDOUT: node+70, // CHECK:STDOUT: node+71, +// CHECK:STDOUT: node+72, +// CHECK:STDOUT: node+73, +// CHECK:STDOUT: node+74, +// CHECK:STDOUT: node+75, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -382,8 +393,10 @@ fn AddressOfParameter(param: i32) { // CHECK:STDOUT: %.loc42_9: i32 = int_literal 1 // CHECK:STDOUT: %.loc42_7: i32 = add %.loc42_5, %.loc42_9 // CHECK:STDOUT: %.loc42_3: i32* = address_of %.loc42_7 -// CHECK:STDOUT: %.loc46_5: {.a: i32} = call @H() -// CHECK:STDOUT: %.loc46_7: i32 = struct_access %.loc46_5, member0 +// CHECK:STDOUT: %.loc46_5.1: {.a: i32} = call @H() +// CHECK:STDOUT: %.loc46_5.2: {.a: i32} = materialize_temporary +// CHECK:STDOUT: assign %.loc46_5.2, %.loc46_5.1 +// CHECK:STDOUT: %.loc46_7: i32 = struct_access %.loc46_5.2, member0 // CHECK:STDOUT: %.loc46_3: i32* = address_of %.loc46_7 // CHECK:STDOUT: %.loc50_9: bool = bool_literal true // CHECK:STDOUT: %.loc50_5: bool = not %.loc50_9 diff --git a/toolchain/semantics/testdata/pointer/fail_type_mismatch.carbon b/toolchain/semantics/testdata/pointer/fail_type_mismatch.carbon index ed0016b207d8b..52d07b9b3b157 100644 --- a/toolchain/semantics/testdata/pointer/fail_type_mismatch.carbon +++ b/toolchain/semantics/testdata/pointer/fail_type_mismatch.carbon @@ -22,6 +22,7 @@ fn ConstMismatch(p: const {}*) -> const ({}*) { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: ConstMismatch, // CHECK:STDOUT: p, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: node+0, @@ -41,6 +42,7 @@ fn ConstMismatch(p: const {}*) -> const ({}*) { // CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, // CHECK:STDOUT: {kind: ConstType, arg0: type3, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type4}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: nodeError}, // CHECK:STDOUT: ] @@ -56,15 +58,16 @@ fn ConstMismatch(p: const {}*) -> const ({}*) { // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+9, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/pointer/nested_const.carbon b/toolchain/semantics/testdata/pointer/nested_const.carbon index 1c61a7adb3d4a..e4e731db59637 100644 --- a/toolchain/semantics/testdata/pointer/nested_const.carbon +++ b/toolchain/semantics/testdata/pointer/nested_const.carbon @@ -20,6 +20,7 @@ fn F(p: const (const (const i32*)*)) -> const i32 { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, // CHECK:STDOUT: p, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -39,10 +40,13 @@ fn F(p: const (const (const i32*)*)) -> const i32 { // CHECK:STDOUT: {kind: ConstType, arg0: type4, type: typeTypeType}, // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type5}, // CHECK:STDOUT: {kind: ConstType, arg0: type0, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: Dereference, arg0: node+5, type: type3}, -// CHECK:STDOUT: {kind: Dereference, arg0: node+8, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+9}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+9, type: type3}, +// CHECK:STDOUT: {kind: Dereference, arg0: node+10, type: type1}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+11, type: type1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+12}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -55,17 +59,20 @@ fn F(p: const (const (const i32*)*)) -> const i32 { // CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, // CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, +// CHECK:STDOUT: node+12, +// CHECK:STDOUT: node+13, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -75,7 +82,9 @@ fn F(p: const (const (const i32*)*)) -> const i32 { // CHECK:STDOUT: // CHECK:STDOUT: fn @F(%p: const (const (const i32*)*)) -> const i32 { // CHECK:STDOUT: !entry: -// CHECK:STDOUT: %.loc9_11: const (const i32*) = dereference %p -// CHECK:STDOUT: %.loc9_10: const i32 = dereference %.loc9_11 -// CHECK:STDOUT: return %.loc9_10 +// CHECK:STDOUT: %.loc9_11.1: const (const i32*) = dereference %p +// CHECK:STDOUT: %.loc9_11.2: const (const i32*) = bind_value %.loc9_11.1 +// CHECK:STDOUT: %.loc9_10.1: const i32 = dereference %.loc9_11.2 +// CHECK:STDOUT: %.loc9_10.2: const i32 = bind_value %.loc9_10.1 +// CHECK:STDOUT: return %.loc9_10.2 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/pointer/types.carbon b/toolchain/semantics/testdata/pointer/types.carbon index d1abebc677fdf..7caa6bad2f87d 100644 --- a/toolchain/semantics/testdata/pointer/types.carbon +++ b/toolchain/semantics/testdata/pointer/types.carbon @@ -15,7 +15,7 @@ fn ConstPtr(p: const i32*) -> (const i32)* { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ // CHECK:STDOUT: {name: str0, param_refs: block2, return_type: type1, body: [block4]}, -// CHECK:STDOUT: {name: str2, param_refs: block6, return_type: type3, body: [block7]}, +// CHECK:STDOUT: {name: str3, param_refs: block6, return_type: type3, body: [block7]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -24,13 +24,14 @@ fn ConstPtr(p: const i32*) -> (const i32)* { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Ptr, // CHECK:STDOUT: p, +// CHECK:STDOUT: return, // CHECK:STDOUT: ConstPtr, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, // CHECK:STDOUT: node+0, -// CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ] // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] @@ -38,6 +39,7 @@ fn ConstPtr(p: const i32*) -> (const i32)* { // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type1}, // CHECK:STDOUT: {kind: PointerType, arg0: type0, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1}, // CHECK:STDOUT: {kind: ConstType, arg0: type0, type: typeTypeType}, @@ -45,8 +47,9 @@ fn ConstPtr(p: const i32*) -> (const i32)* { // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type3}, // CHECK:STDOUT: {kind: ConstType, arg0: type0, type: typeTypeType}, // CHECK:STDOUT: {kind: PointerType, arg0: type2, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type3}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+7}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+8}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -55,29 +58,31 @@ fn ConstPtr(p: const i32*) -> (const i32)* { // CHECK:STDOUT: node+0, // CHECK:STDOUT: node+1, // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+10, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+5, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+11, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+11, +// CHECK:STDOUT: node+13, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/return/code_after_return_value.carbon b/toolchain/semantics/testdata/return/code_after_return_value.carbon index 512eb61fdb70e..6e06871b253b2 100644 --- a/toolchain/semantics/testdata/return/code_after_return_value.carbon +++ b/toolchain/semantics/testdata/return/code_after_return_value.carbon @@ -30,6 +30,7 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, // CHECK:STDOUT: b, +// CHECK:STDOUT: return, // CHECK:STDOUT: n, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ @@ -40,20 +41,21 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, -// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+3}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int2, type: type1}, // CHECK:STDOUT: {kind: BlockArg, arg0: unreachable, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+4, arg1: node+7}, +// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+8}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: false, type: type0}, // CHECK:STDOUT: {kind: UnaryOperatorNot, arg0: node+0, type: type0}, // CHECK:STDOUT: {kind: BoolLiteral, arg0: true, type: type0}, // CHECK:STDOUT: {kind: BranchWithArg, arg0: unreachable, arg1: node+0}, // CHECK:STDOUT: {kind: BlockArg, arg0: unreachable, type: type0}, -// CHECK:STDOUT: {kind: BranchWithArg, arg0: unreachable, arg1: node+13}, +// CHECK:STDOUT: {kind: BranchWithArg, arg0: unreachable, arg1: node+14}, // CHECK:STDOUT: {kind: BlockArg, arg0: unreachable, type: type0}, // CHECK:STDOUT: {kind: Branch, arg0: unreachable}, // CHECK:STDOUT: ] @@ -62,16 +64,17 @@ fn F(b: bool) -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, +// CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/return/fail_missing_return.carbon b/toolchain/semantics/testdata/return/fail_missing_return.carbon index 82921fd481c8e..8816595db0ae6 100644 --- a/toolchain/semantics/testdata/return/fail_missing_return.carbon +++ b/toolchain/semantics/testdata/return/fail_missing_return.carbon @@ -12,7 +12,7 @@ fn Main() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -20,6 +20,7 @@ fn Main() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -27,6 +28,7 @@ fn Main() -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -36,6 +38,9 @@ fn Main() -> i32 { // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+1, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/return/fail_missing_return_empty_tuple.carbon b/toolchain/semantics/testdata/return/fail_missing_return_empty_tuple.carbon index dc60288c3ebf0..504f4bd0eb148 100644 --- a/toolchain/semantics/testdata/return/fail_missing_return_empty_tuple.carbon +++ b/toolchain/semantics/testdata/return/fail_missing_return_empty_tuple.carbon @@ -20,6 +20,7 @@ fn F() -> () { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: F, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: node+0, @@ -31,6 +32,7 @@ fn F() -> () { // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock0, type: typeTypeType}, // CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -39,9 +41,10 @@ fn F() -> () { // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: ], diff --git a/toolchain/semantics/testdata/return/fail_type_mismatch.carbon b/toolchain/semantics/testdata/return/fail_type_mismatch.carbon index 2463cae4a7a87..8824310c2c11f 100644 --- a/toolchain/semantics/testdata/return/fail_type_mismatch.carbon +++ b/toolchain/semantics/testdata/return/fail_type_mismatch.carbon @@ -13,7 +13,7 @@ fn Main() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -22,6 +22,7 @@ fn Main() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -30,6 +31,7 @@ fn Main() -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type1}, // CHECK:STDOUT: {kind: ReturnExpression, arg0: nodeError}, @@ -42,7 +44,10 @@ fn Main() -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/return/fail_value_missing.carbon b/toolchain/semantics/testdata/return/fail_value_missing.carbon index 8d54678cf171e..3955478b27b22 100644 --- a/toolchain/semantics/testdata/return/fail_value_missing.carbon +++ b/toolchain/semantics/testdata/return/fail_value_missing.carbon @@ -13,7 +13,7 @@ fn Main() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: ] @@ -21,6 +21,7 @@ fn Main() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -28,6 +29,7 @@ fn Main() -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] @@ -40,6 +42,9 @@ fn Main() -> i32 { // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, // CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+2, +// CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: // CHECK:STDOUT: package { diff --git a/toolchain/semantics/testdata/return/struct.carbon b/toolchain/semantics/testdata/return/struct.carbon index 5f73b3f98e165..c09f30339cc7e 100644 --- a/toolchain/semantics/testdata/return/struct.carbon +++ b/toolchain/semantics/testdata/return/struct.carbon @@ -20,6 +20,7 @@ fn Main() -> {.a: i32} { // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, // CHECK:STDOUT: a, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -30,12 +31,13 @@ fn Main() -> {.a: i32} { // CHECK:STDOUT: nodes: [ // CHECK:STDOUT: {kind: StructTypeField, arg0: str1, arg1: type0}, // CHECK:STDOUT: {kind: StructType, arg0: block2, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: StructTypeField, arg0: str1, arg1: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+3, type: type0}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+4, type: type0}, // CHECK:STDOUT: {kind: StructValue, arg0: block6, type: type1}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+6}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+7}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -43,24 +45,25 @@ fn Main() -> {.a: i32} { // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: node+1, +// CHECK:STDOUT: node+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+4, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/return/tuple.carbon b/toolchain/semantics/testdata/return/tuple.carbon index 7e757f7470646..739f98f3fe6f4 100644 --- a/toolchain/semantics/testdata/return/tuple.carbon +++ b/toolchain/semantics/testdata/return/tuple.carbon @@ -11,7 +11,7 @@ fn Main() -> (i32, i32) { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type2, body: [block4]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type2, return_slot: node+5, body: [block4]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 15, @@ -21,6 +21,7 @@ fn Main() -> (i32, i32) { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: node+2, @@ -43,13 +44,15 @@ fn Main() -> (i32, i32) { // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock0, type: typeTypeType}, // CHECK:STDOUT: {kind: TupleValue, arg0: block2, type: type0}, // CHECK:STDOUT: {kind: TupleType, arg0: typeBlock1, type: typeTypeType}, +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type2}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type1}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+6, type: type1}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+7, type: type1}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int1, type: type1}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type1}, +// CHECK:STDOUT: {kind: StubReference, arg0: node+9, type: type1}, // CHECK:STDOUT: {kind: TupleValue, arg0: block5, type: type2}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+10}, +// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+11}, +// CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -60,25 +63,27 @@ fn Main() -> (i32, i32) { // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, // CHECK:STDOUT: node+1, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, +// CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, // CHECK:STDOUT: node+8, // CHECK:STDOUT: node+9, // CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, +// CHECK:STDOUT: node+12, +// CHECK:STDOUT: node+13, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, -// CHECK:STDOUT: node+9, +// CHECK:STDOUT: node+8, +// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -86,12 +91,13 @@ fn Main() -> (i32, i32) { // CHECK:STDOUT: %.loc8 = fn_decl @Main // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: fn @Main() -> (i32, i32) { +// CHECK:STDOUT: fn @Main() -> %return: (i32, i32) { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %.loc9_11.1: i32 = int_literal 15 // CHECK:STDOUT: %.loc9_11.2: i32 = stub_reference %.loc9_11.1 // CHECK:STDOUT: %.loc9_15.1: i32 = int_literal 35 // CHECK:STDOUT: %.loc9_15.2: i32 = stub_reference %.loc9_15.1 // CHECK:STDOUT: %.loc9_17: (i32, i32) = tuple_value (%.loc9_11.2, %.loc9_15.2) -// CHECK:STDOUT: return %.loc9_17 +// CHECK:STDOUT: assign %return, %.loc9_17 +// CHECK:STDOUT: return // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/return/value.carbon b/toolchain/semantics/testdata/return/value.carbon index c2e24a33de045..76119ad5abaeb 100644 --- a/toolchain/semantics/testdata/return/value.carbon +++ b/toolchain/semantics/testdata/return/value.carbon @@ -10,7 +10,7 @@ fn Main() -> i32 { // CHECK:STDOUT: cross_reference_irs_size: 1 // CHECK:STDOUT: functions: [ -// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]}, +// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]}, // CHECK:STDOUT: ] // CHECK:STDOUT: integer_literals: [ // CHECK:STDOUT: 0, @@ -19,6 +19,7 @@ fn Main() -> i32 { // CHECK:STDOUT: ] // CHECK:STDOUT: strings: [ // CHECK:STDOUT: Main, +// CHECK:STDOUT: return, // CHECK:STDOUT: ] // CHECK:STDOUT: types: [ // CHECK:STDOUT: nodeIntegerType, @@ -26,9 +27,10 @@ fn Main() -> i32 { // CHECK:STDOUT: type_blocks: [ // CHECK:STDOUT: ] // CHECK:STDOUT: nodes: [ +// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, -// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1}, +// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -38,7 +40,10 @@ fn Main() -> i32 { // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+1, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, +// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: diff --git a/toolchain/semantics/testdata/struct/empty.carbon b/toolchain/semantics/testdata/struct/empty.carbon index 60098f2c5879b..f4725011831d3 100644 --- a/toolchain/semantics/testdata/struct/empty.carbon +++ b/toolchain/semantics/testdata/struct/empty.carbon @@ -31,7 +31,8 @@ var y: {} = x; // CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+3}, // CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+6, arg1: node+2}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+2, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+6, arg1: node+7}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -45,6 +46,7 @@ var y: {} = x; // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -56,5 +58,6 @@ var y: {} = x; // CHECK:STDOUT: assign %x, %.loc7_14 // CHECK:STDOUT: %.loc8: {} = struct_value () // CHECK:STDOUT: %y: {} = var "y" -// CHECK:STDOUT: assign %y, %x +// CHECK:STDOUT: %.loc7_5: {} = bind_value %x +// CHECK:STDOUT: assign %y, %.loc7_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/struct/member_access.carbon b/toolchain/semantics/testdata/struct/member_access.carbon index f692738c8debf..6190bcd7aa4e0 100644 --- a/toolchain/semantics/testdata/struct/member_access.carbon +++ b/toolchain/semantics/testdata/struct/member_access.carbon @@ -46,9 +46,11 @@ var z: i32 = y; // CHECK:STDOUT: {kind: Assign, arg0: node+3, arg1: node+10}, // CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type1}, // CHECK:STDOUT: {kind: StructAccess, arg0: node+3, arg1: member1, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+12, arg1: node+13}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+13, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+12, arg1: node+14}, // CHECK:STDOUT: {kind: VarStorage, arg0: str4, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+15, arg1: node+12}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+12, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+16, arg1: node+17}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -69,6 +71,8 @@ var z: i32 = y; // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, // CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+17, +// CHECK:STDOUT: node+18, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -94,8 +98,10 @@ var z: i32 = y; // CHECK:STDOUT: %.loc7_46: {.a: f64, .b: i32} = struct_value (%.loc7_33, %.loc7_43) // CHECK:STDOUT: assign %x, %.loc7_46 // CHECK:STDOUT: %y: i32 = var "y" -// CHECK:STDOUT: %.loc8: i32 = struct_access %x, member1 -// CHECK:STDOUT: assign %y, %.loc8 +// CHECK:STDOUT: %.loc8_15.1: i32 = struct_access %x, member1 +// CHECK:STDOUT: %.loc8_15.2: i32 = bind_value %.loc8_15.1 +// CHECK:STDOUT: assign %y, %.loc8_15.2 // CHECK:STDOUT: %z: i32 = var "z" -// CHECK:STDOUT: assign %z, %y +// CHECK:STDOUT: %.loc8_5: i32 = bind_value %y +// CHECK:STDOUT: assign %z, %.loc8_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/struct/one_entry.carbon b/toolchain/semantics/testdata/struct/one_entry.carbon index 1d9a231b66b4e..1b94973c81ccb 100644 --- a/toolchain/semantics/testdata/struct/one_entry.carbon +++ b/toolchain/semantics/testdata/struct/one_entry.carbon @@ -38,7 +38,8 @@ var y: {.a: i32} = x; // CHECK:STDOUT: {kind: StructTypeField, arg0: str1, arg1: type0}, // CHECK:STDOUT: {kind: StructType, arg0: block5, type: typeTypeType}, // CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+10, arg1: node+2}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+2, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+10, arg1: node+11}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -55,6 +56,7 @@ var y: {.a: i32} = x; // CHECK:STDOUT: node+9, // CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, +// CHECK:STDOUT: node+12, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -79,5 +81,6 @@ var y: {.a: i32} = x; // CHECK:STDOUT: assign %x, %.loc7_27 // CHECK:STDOUT: %.loc8: type = struct_type {.a: i32} // CHECK:STDOUT: %y: {.a: i32} = var "y" -// CHECK:STDOUT: assign %y, %x +// CHECK:STDOUT: %.loc7_5: {.a: i32} = bind_value %x +// CHECK:STDOUT: assign %y, %.loc7_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/struct/tuple_as_element.carbon b/toolchain/semantics/testdata/struct/tuple_as_element.carbon index 140591769c0c1..303c73dbb51bf 100644 --- a/toolchain/semantics/testdata/struct/tuple_as_element.carbon +++ b/toolchain/semantics/testdata/struct/tuple_as_element.carbon @@ -61,7 +61,8 @@ var y: {.a: i32, .b: (i32,)} = x; // CHECK:STDOUT: {kind: StructTypeField, arg0: str2, arg1: type2}, // CHECK:STDOUT: {kind: StructType, arg0: block7, type: typeTypeType}, // CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type3}, -// CHECK:STDOUT: {kind: Assign, arg0: node+23, arg1: node+7}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+7, type: type3}, +// CHECK:STDOUT: {kind: Assign, arg0: node+23, arg1: node+24}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -90,6 +91,7 @@ var y: {.a: i32, .b: (i32,)} = x; // CHECK:STDOUT: node+22, // CHECK:STDOUT: node+23, // CHECK:STDOUT: node+24, +// CHECK:STDOUT: node+25, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -137,5 +139,6 @@ var y: {.a: i32, .b: (i32,)} = x; // CHECK:STDOUT: %.loc8_27: (type,) = tuple_value (%.loc8_23) // CHECK:STDOUT: %.loc8_28: type = struct_type {.a: i32, .b: (i32,)} // CHECK:STDOUT: %y: {.a: i32, .b: (i32,)} = var "y" -// CHECK:STDOUT: assign %y, %x +// CHECK:STDOUT: %.loc7_5: {.a: i32, .b: (i32,)} = bind_value %x +// CHECK:STDOUT: assign %y, %.loc7_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/struct/two_entries.carbon b/toolchain/semantics/testdata/struct/two_entries.carbon index 9db4bf7af52be..ba506a668464e 100644 --- a/toolchain/semantics/testdata/struct/two_entries.carbon +++ b/toolchain/semantics/testdata/struct/two_entries.carbon @@ -45,7 +45,8 @@ var y: {.a: i32, .b: i32} = x; // CHECK:STDOUT: {kind: StructTypeField, arg0: str2, arg1: type0}, // CHECK:STDOUT: {kind: StructType, arg0: block5, type: typeTypeType}, // CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type1}, -// CHECK:STDOUT: {kind: Assign, arg0: node+15, arg1: node+3}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+3, type: type1}, +// CHECK:STDOUT: {kind: Assign, arg0: node+15, arg1: node+16}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -66,6 +67,7 @@ var y: {.a: i32, .b: i32} = x; // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, // CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+17, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -96,5 +98,6 @@ var y: {.a: i32, .b: i32} = x; // CHECK:STDOUT: assign %x, %.loc7_44 // CHECK:STDOUT: %.loc8: type = struct_type {.a: i32, .b: i32} // CHECK:STDOUT: %y: {.a: i32, .b: i32} = var "y" -// CHECK:STDOUT: assign %y, %x +// CHECK:STDOUT: %.loc7_5: {.a: i32, .b: i32} = bind_value %x +// CHECK:STDOUT: assign %y, %.loc7_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/tuples/empty.carbon b/toolchain/semantics/testdata/tuples/empty.carbon index 974dccf692277..928ada3447190 100644 --- a/toolchain/semantics/testdata/tuples/empty.carbon +++ b/toolchain/semantics/testdata/tuples/empty.carbon @@ -33,7 +33,8 @@ var y: () = x; // CHECK:STDOUT: {kind: Assign, arg0: node+2, arg1: node+3}, // CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+6, arg1: node+2}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+2, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+6, arg1: node+7}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -47,6 +48,7 @@ var y: () = x; // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, // CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -58,5 +60,6 @@ var y: () = x; // CHECK:STDOUT: assign %x, %.loc7_14 // CHECK:STDOUT: %.loc8: () = tuple_value () // CHECK:STDOUT: %y: () = var "y" -// CHECK:STDOUT: assign %y, %x +// CHECK:STDOUT: %.loc7_5: () = bind_value %x +// CHECK:STDOUT: assign %y, %.loc7_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/tuples/one_element.carbon b/toolchain/semantics/testdata/tuples/one_element.carbon index 03d7ab7e19c44..1d1bf1e636a7b 100644 --- a/toolchain/semantics/testdata/tuples/one_element.carbon +++ b/toolchain/semantics/testdata/tuples/one_element.carbon @@ -45,7 +45,8 @@ var y: (i32,) = x; // CHECK:STDOUT: {kind: StubReference, arg0: nodeIntegerType, type: typeTypeType}, // CHECK:STDOUT: {kind: TupleValue, arg0: block4, type: type0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+11, arg1: node+4}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+4, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+11, arg1: node+12}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -64,6 +65,7 @@ var y: (i32,) = x; // CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, // CHECK:STDOUT: node+12, +// CHECK:STDOUT: node+13, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -89,5 +91,6 @@ var y: (i32,) = x; // CHECK:STDOUT: %.loc8_9: type = stub_reference i32 // CHECK:STDOUT: %.loc8_13: (type,) = tuple_value (%.loc8_9) // CHECK:STDOUT: %y: (i32,) = var "y" -// CHECK:STDOUT: assign %y, %x +// CHECK:STDOUT: %.loc7_5: (i32,) = bind_value %x +// CHECK:STDOUT: assign %y, %.loc7_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/tuples/two_elements.carbon b/toolchain/semantics/testdata/tuples/two_elements.carbon index 8ea69a1789fd9..d73440067438d 100644 --- a/toolchain/semantics/testdata/tuples/two_elements.carbon +++ b/toolchain/semantics/testdata/tuples/two_elements.carbon @@ -52,7 +52,8 @@ var y: (i32, i32) = x; // CHECK:STDOUT: {kind: StubReference, arg0: nodeIntegerType, type: typeTypeType}, // CHECK:STDOUT: {kind: TupleValue, arg0: block4, type: type0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type2}, -// CHECK:STDOUT: {kind: Assign, arg0: node+15, arg1: node+5}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+5, type: type2}, +// CHECK:STDOUT: {kind: Assign, arg0: node+15, arg1: node+16}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -75,6 +76,7 @@ var y: (i32, i32) = x; // CHECK:STDOUT: node+14, // CHECK:STDOUT: node+15, // CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+17, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+0, @@ -107,5 +109,6 @@ var y: (i32, i32) = x; // CHECK:STDOUT: %.loc8_14: type = stub_reference i32 // CHECK:STDOUT: %.loc8_17: (type, type) = tuple_value (%.loc8_9, %.loc8_14) // CHECK:STDOUT: %y: (i32, i32) = var "y" -// CHECK:STDOUT: assign %y, %x +// CHECK:STDOUT: %.loc7_5: (i32, i32) = bind_value %x +// CHECK:STDOUT: assign %y, %.loc7_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/var/global_lookup.carbon b/toolchain/semantics/testdata/var/global_lookup.carbon index 87196da70f28c..79091c708fca8 100644 --- a/toolchain/semantics/testdata/var/global_lookup.carbon +++ b/toolchain/semantics/testdata/var/global_lookup.carbon @@ -29,7 +29,8 @@ var y: i32 = x; // CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0}, // CHECK:STDOUT: {kind: Assign, arg0: node+0, arg1: node+1}, // CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+3, arg1: node+0}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+0, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+3, arg1: node+4}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ // CHECK:STDOUT: [ @@ -40,13 +41,15 @@ var y: i32 = x; // CHECK:STDOUT: node+2, // CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+5, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: // CHECK:STDOUT: package { // CHECK:STDOUT: %x: i32 = var "x" -// CHECK:STDOUT: %.loc7: i32 = int_literal 0 -// CHECK:STDOUT: assign %x, %.loc7 +// CHECK:STDOUT: %.loc7_14: i32 = int_literal 0 +// CHECK:STDOUT: assign %x, %.loc7_14 // CHECK:STDOUT: %y: i32 = var "y" -// CHECK:STDOUT: assign %y, %x +// CHECK:STDOUT: %.loc7_5: i32 = bind_value %x +// CHECK:STDOUT: assign %y, %.loc7_5 // CHECK:STDOUT: } diff --git a/toolchain/semantics/testdata/var/global_lookup_in_scope.carbon b/toolchain/semantics/testdata/var/global_lookup_in_scope.carbon index afb1eea5eeb8f..5287f2f0e65c0 100644 --- a/toolchain/semantics/testdata/var/global_lookup_in_scope.carbon +++ b/toolchain/semantics/testdata/var/global_lookup_in_scope.carbon @@ -35,7 +35,8 @@ fn Main() { // CHECK:STDOUT: {kind: Assign, arg0: node+0, arg1: node+1}, // CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0}, // CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0}, -// CHECK:STDOUT: {kind: Assign, arg0: node+4, arg1: node+0}, +// CHECK:STDOUT: {kind: BindValue, arg0: node+0, type: type0}, +// CHECK:STDOUT: {kind: Assign, arg0: node+4, arg1: node+5}, // CHECK:STDOUT: {kind: Return}, // CHECK:STDOUT: ] // CHECK:STDOUT: node_blocks: [ @@ -51,6 +52,7 @@ fn Main() { // CHECK:STDOUT: node+4, // CHECK:STDOUT: node+5, // CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: @@ -64,6 +66,7 @@ fn Main() { // CHECK:STDOUT: fn @Main() { // CHECK:STDOUT: !entry: // CHECK:STDOUT: %y: i32 = var "y" -// CHECK:STDOUT: assign %y, package.%x +// CHECK:STDOUT: %.loc7: i32 = bind_value package.%x +// CHECK:STDOUT: assign %y, %.loc7 // CHECK:STDOUT: return // CHECK:STDOUT: }