From 1013d1773cdd1874dd10515b582b1e25faae757f Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Thu, 24 Aug 2023 12:35:07 -0700 Subject: [PATCH] Model function calls as initializing expressions (#3089) Start treating function calls as initializing expressions instead of as value expressions. This required adding support for expression categories. Value bindings and temporary materialization conversions are created where necessary to transition between expression categories. For a function call with a return slot, we speculatively create a materialized temporary before the call and either commit to it or replace it with something else later, once we see how the function call expression is actually used. This change follows the direction suggested in #3133 for initializing expressions: depending on the return type of a function, the return value will either be initialized in-place or returned directly. This is visible in the semantics IR, which is a little unfortunate but is probably necessary as this is part of the semantics of the program. --------- Co-authored-by: Chandler Carruth --- toolchain/lowering/lowering_context.cpp | 55 ++++- toolchain/lowering/lowering_handle.cpp | 39 +++- .../lowering_handle_expression_category.cpp | 22 ++ .../testdata/array/assign_return_value.carbon | 25 ++- toolchain/lowering/testdata/array/base.carbon | 24 +- .../testdata/basics/type_values.carbon | 10 +- .../function/call/empty_struct.carbon | 8 +- .../testdata/function/call/empty_tuple.carbon | 7 +- .../call/implicit_empty_tuple_as_arg.carbon | 11 +- .../testdata/function/call/params_one.carbon | 1 - .../function/call/params_one_comma.carbon | 2 - .../testdata/function/call/params_two.carbon | 1 - .../function/call/params_two_comma.carbon | 2 - .../testdata/function/call/params_zero.carbon | 1 - .../function/call/return_implicit.carbon | 3 - .../testdata/function/call/var_param.carbon | 1 - .../function/declaration/simple.carbon | 1 - toolchain/lowering/testdata/if/else.carbon | 3 - toolchain/lowering/testdata/if/no_else.carbon | 2 - .../testdata/if_expression/basic.carbon | 20 +- .../index/array_element_access.carbon | 54 +++-- .../index/tuple_return_value_access.carbon | 13 +- .../testdata/namespace/function.carbon | 1 - .../lowering/testdata/namespace/nested.carbon | 1 - .../lowering/testdata/operators/and.carbon | 18 +- .../lowering/testdata/operators/or.carbon | 20 +- .../testdata/pointer/address_of_field.carbon | 1 - .../lowering/testdata/pointer/basic.carbon | 5 +- toolchain/semantics/semantics_context.cpp | 198 +++++++++++++++- toolchain/semantics/semantics_context.h | 52 ++++- .../semantics_handle_call_expression.cpp | 20 +- .../semantics/semantics_handle_function.cpp | 23 +- .../semantics_handle_if_expression.cpp | 10 +- .../semantics_handle_if_statement.cpp | 2 +- .../semantics/semantics_handle_index.cpp | 1 + toolchain/semantics/semantics_handle_name.cpp | 4 + .../semantics/semantics_handle_operator.cpp | 20 +- .../semantics/semantics_handle_paren.cpp | 16 ++ .../semantics/semantics_handle_statement.cpp | 27 ++- .../semantics/semantics_handle_struct.cpp | 5 + .../semantics/semantics_handle_variable.cpp | 5 +- toolchain/semantics/semantics_ir.cpp | 161 ++++++++++++- toolchain/semantics/semantics_ir.h | 73 +++++- .../semantics/semantics_ir_formatter.cpp | 42 +++- toolchain/semantics/semantics_node.h | 6 + toolchain/semantics/semantics_node_kind.def | 4 + toolchain/semantics/semantics_node_stack.h | 3 +- .../testdata/array/assign_return_value.carbon | 42 ++-- .../testdata/array/assign_var.carbon | 11 +- .../semantics/testdata/const/collapse.carbon | 7 +- .../testdata/const/fail_collapse.carbon | 7 +- .../function/call/empty_struct.carbon | 23 +- .../testdata/function/call/empty_tuple.carbon | 23 +- .../call/fail_return_type_mismatch.carbon | 19 +- .../testdata/function/call/i32.carbon | 23 +- .../function/call/return_implicit.carbon | 3 - .../if/fail_reachable_fallthrough.carbon | 51 +++-- .../semantics/testdata/if/fail_scope.carbon | 28 ++- .../if/unreachable_fallthrough.carbon | 19 +- .../testdata/if_expression/basic.carbon | 17 +- .../if_expression/constant_condition.carbon | 129 +++++++---- .../if_expression/control_flow.carbon | 79 ++++--- .../testdata/if_expression/nested.carbon | 45 ++-- .../index/array_element_access.carbon | 18 +- .../index/fail_empty_tuple_access.carbon | 3 + .../index/fail_tuple_large_index.carbon | 9 +- .../index/tuple_element_access.carbon | 18 +- .../index/tuple_return_value_access.carbon | 42 ++-- .../semantics/testdata/operators/and.carbon | 75 +++++-- .../testdata/operators/assignment.carbon | 36 +-- .../testdata/operators/binary_op.carbon | 11 +- .../fail_assigment_to_non_assignable.carbon | 211 ++++++++++-------- .../operators/fail_type_mismatch.carbon | 9 +- .../fail_type_mismatch_assignment.carbon | 4 +- .../operators/fail_type_mismatch_once.carbon | 11 +- .../semantics/testdata/operators/or.carbon | 77 +++++-- .../testdata/operators/unary_op.carbon | 9 +- .../testdata/pointer/address_of_deref.carbon | 30 ++- .../semantics/testdata/pointer/basic.carbon | 33 ++- .../pointer/fail_address_of_value.carbon | 197 ++++++++-------- .../pointer/fail_type_mismatch.carbon | 7 +- .../testdata/pointer/nested_const.carbon | 23 +- .../semantics/testdata/pointer/types.carbon | 29 ++- .../return/code_after_return_value.carbon | 15 +- .../return/fail_missing_return.carbon | 7 +- .../fail_missing_return_empty_tuple.carbon | 5 +- .../testdata/return/fail_type_mismatch.carbon | 7 +- .../testdata/return/fail_value_missing.carbon | 7 +- .../semantics/testdata/return/struct.carbon | 19 +- .../semantics/testdata/return/tuple.carbon | 26 ++- .../semantics/testdata/return/value.carbon | 9 +- .../semantics/testdata/struct/empty.carbon | 7 +- .../testdata/struct/member_access.carbon | 16 +- .../testdata/struct/one_entry.carbon | 7 +- .../testdata/struct/tuple_as_element.carbon | 7 +- .../testdata/struct/two_entries.carbon | 7 +- .../semantics/testdata/tuples/empty.carbon | 7 +- .../testdata/tuples/one_element.carbon | 7 +- .../testdata/tuples/two_elements.carbon | 7 +- .../testdata/var/global_lookup.carbon | 11 +- .../var/global_lookup_in_scope.carbon | 7 +- 101 files changed, 1802 insertions(+), 777 deletions(-) create mode 100644 toolchain/lowering/lowering_handle_expression_category.cpp diff --git a/toolchain/lowering/lowering_context.cpp b/toolchain/lowering/lowering_context.cpp index 4002e0009355..a5e91d155ab5 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 3bc1f797c85a..a56edff2ca60 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 000000000000..7cffe4a4477a --- /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 2c280ed42ae2..a9ec9f19942a 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 7535f326707b..4c14d9588aff 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 8441016ab063..7b2b8d014db7 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 8fc7bbbf4f68..6b2521185adc 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 365751a58c4f..a4e86ef3e1e7 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 6720acfde74d..01cdb08d82fa 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 081732d49135..e2b98e29196b 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 af48d7345258..87582a5d6e31 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 252653615f2d..841722e141ee 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 9c22f7472f3c..b22a4330e30f 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 4617480b19a5..bf994c16dddd 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 7346a5808751..a82f5c0e081f 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 8b0c1ba787ca..c4ca2373e160 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 3505e687be24..7792d0b2859b 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 21848e35af76..67af395d45dc 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 d6f899d5d8b9..928b8fa6cc00 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 88b5ebc2921a..8fd9dde43199 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 b90963cf8813..14d5f5395780 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 ad2ddc83fbad..d0698776764e 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 9776134ee142..393df2acd080 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 9749fa702288..f51a391c9b0a 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 418c98a51447..600d5718ac55 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 b5214337ac68..307e51bd9aff 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 d5596aaac8a7..624e59e6f33f 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 6a10ba48de41..bae2a3c384cc 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 94293aff3b59..bfe071797c52 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 7be99a98a364..1d3268ed1286 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 2b60234d4579..620cc15eff6d 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 84d3a78571bb..a20337b17d03 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 f1bf18205029..2bd3c89d3049 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 659eba40a16e..22400befec3e 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 a57776295174..2d5920474824 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 0d5cbb64e4bb..21d0aebcda6d 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 f936be894675..4575106ad7d0 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 12644d3caafb..a9421f69bd15 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 64182e122230..428843480269 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(); - } else { - arg = - context.ImplicitAsRequired(parse_node, arg, callable.return_type_id); - } - context.AddNode(SemIR::Node::ReturnExpression::Make(parse_node, arg)); + 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.ConvertToValueOfType(parse_node, arg, + callable.return_type_id); + + 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 e8e9b0d80bc0..6660fbf9c0ef 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 a3144d9ae1b4..fb6009ee6f52 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 33a3d12dc0b7..a3328a1d34be 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 f732a705f5f1..523a396ad7b1 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 5bfe01826634..dc81411649aa 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 3bd2c5c5faf0..8851256f1abb 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 38746a4cfcae..acb52a71d33f 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 5c6e404b83eb..aa653a557356 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 83d7f543623b..45345f8db3c3 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 e9f7ebb4efce..55c771fabc0e 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 c87f434b8794..2a6523259f61 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 ebcf622624c0..6fbf700c984c 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 5e47dd46e59c..0a837380c142 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+5, +// CHECK:STDOUT: node+7, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, -// 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 c545555321d1..7cdd796a7a47 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+5, +// CHECK:STDOUT: node+7, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+6, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+5, -// 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 6b0c49b693c5..70c6a2ec5cba 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 20859a081931..2cd392ebe07f 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+2, +// CHECK:STDOUT: node+4, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+2, -// 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 6b5c6e7f7208..acd7ef4879f4 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 a9ba66dfa36e..c0c1ae235508 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+10, +// CHECK:STDOUT: node+18, +// 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: ], // 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 4ed6ad5e4392..fef77d4a4de7 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: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+2, -// CHECK:STDOUT: node+3, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+3, // CHECK:STDOUT: node+4, +// 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+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 aea3b81a4e8d..fde5e7a4e18f 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: ], -// CHECK:STDOUT: [ // 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: ], +// CHECK:STDOUT: [ // 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 49e03b6d23f1..36327f2efa3e 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 cad918d6b555..28dde1ebbc20 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 57225db55a62..f5137b744d4e 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+5, +// CHECK:STDOUT: node+10, +// 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: ], // 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 69620e4e3dda..470c82c40ae3 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: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+4, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+5, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+6, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+7, -// 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: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+14, +// 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 71a78d140d75..d6d1c6b107ec 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 5a499233b2ee..638a22a0fcfc 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 737fa17e8dea..12ae96d9724f 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 4cba2ec1be7c..22bca63bb047 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 db9e4ebd0a39..8ee9d5fb18c2 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 48ec3b207665..f9bd5bb09f1b 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: node+8, -// CHECK:STDOUT: node+9, -// CHECK:STDOUT: node+10, // CHECK:STDOUT: ], // CHECK:STDOUT: [ +// CHECK:STDOUT: node+8, +// 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 24da4f75b78b..1f7d5648ec59 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: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+54, -// CHECK:STDOUT: node+56, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+57, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+56, // CHECK:STDOUT: node+58, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // 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 3521c082a20b..7e2617cf3b03 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 6c0a6d55b68b..6877b3dece3b 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: IntegerLiteral, arg0: int5, type: type0}, -// CHECK:STDOUT: {kind: StubReference, arg0: node+14, 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: IntegerLiteral, arg0: int5, 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+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: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+9, -// CHECK:STDOUT: node+11, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+15, -// CHECK:STDOUT: node+17, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+23, -// CHECK:STDOUT: node+24, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+27, -// CHECK:STDOUT: node+29, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+35, -// CHECK:STDOUT: node+38, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+36, -// CHECK:STDOUT: node+39, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+43, -// CHECK:STDOUT: node+46, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+44, -// CHECK:STDOUT: node+47, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+53, +// CHECK:STDOUT: node+54, // CHECK:STDOUT: node+55, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+54, +// CHECK:STDOUT: node+10, +// CHECK:STDOUT: node+12, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+16, +// CHECK:STDOUT: node+18, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+25, +// CHECK:STDOUT: node+27, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+30, +// CHECK:STDOUT: node+32, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+38, +// CHECK:STDOUT: node+41, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+39, +// CHECK:STDOUT: node+42, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+46, +// CHECK:STDOUT: node+49, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+47, +// CHECK:STDOUT: node+50, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // 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 eeaeaacb08b2..5888b33a6ed0 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 d17df6a636da..cc7474f8a1dc 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 08b62c947b83..a8afd2926fd7 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 6f18d26860fe..c18b825333ca 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: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // 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 a9ef7aebd75c..4687ebb2fdd5 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 3afa7d4d2c64..546f11a54bca 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 ad640649470e..7aecece55157 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 5aa598fef41f..9ee135d08992 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+2, // CHECK:STDOUT: ], // CHECK:STDOUT: [ -// CHECK:STDOUT: node+1, -// 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: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+18, -// CHECK:STDOUT: node+20, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+26, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+27, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ +// CHECK:STDOUT: node+32, // CHECK:STDOUT: node+33, -// CHECK:STDOUT: node+34, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+20, +// CHECK:STDOUT: node+22, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+28, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+29, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // 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: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+57, -// CHECK:STDOUT: node+59, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+65, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+65, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ +// CHECK:STDOUT: node+66, // CHECK:STDOUT: node+67, // CHECK:STDOUT: node+68, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+61, +// CHECK:STDOUT: node+63, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // CHECK:STDOUT: node+69, -// CHECK:STDOUT: node+70, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+69, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ // 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 ed0016b207d8..52d07b9b3b15 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 1c61a7adb3d4..e4e731db5963 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 d1abebc677fd..7caa6bad2f87 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,30 +58,32 @@ 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: ], -// CHECK:STDOUT: [ -// CHECK:STDOUT: node+7, -// CHECK:STDOUT: ], -// CHECK:STDOUT: [ +// CHECK:STDOUT: node+10, // CHECK:STDOUT: node+11, // CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+8, +// CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+13, +// CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: // CHECK:STDOUT: package { diff --git a/toolchain/semantics/testdata/return/code_after_return_value.carbon b/toolchain/semantics/testdata/return/code_after_return_value.carbon index 512eb61fdb70..6e06871b253b 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 82921fd481c8..8816595db0ae 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 dc60288c3ebf..504f4bd0eb14 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 2463cae4a7a8..8824310c2c11 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 8d54678cf171..3955478b27b2 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 5f73b3f98e16..c09f30339cc7 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,25 +45,26 @@ 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: ], -// CHECK:STDOUT: [ // CHECK:STDOUT: node+3, -// CHECK:STDOUT: node+5, -// CHECK:STDOUT: node+6, -// CHECK:STDOUT: node+7, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+4, +// CHECK:STDOUT: node+6, +// CHECK:STDOUT: node+7, +// CHECK:STDOUT: node+8, // CHECK:STDOUT: ], // CHECK:STDOUT: [ // CHECK:STDOUT: node+5, // CHECK:STDOUT: ], +// CHECK:STDOUT: [ +// CHECK:STDOUT: node+6, +// CHECK:STDOUT: ], // CHECK:STDOUT: ] // CHECK:STDOUT: // CHECK:STDOUT: package { diff --git a/toolchain/semantics/testdata/return/tuple.carbon b/toolchain/semantics/testdata/return/tuple.carbon index 7e757f747064..739f98f3fe6f 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 c2e24a33de04..76119ad5abae 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 60098f2c5879..f4725011831d 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 f692738c8deb..6190bcd7aa4e 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 1d9a231b66b4..1b94973c81cc 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 140591769c0c..303c73dbb51b 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 9db4bf7af52b..ba506a668464 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 974dccf69227..928ada344719 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 03d7ab7e19c4..1d1bf1e636a7 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 8ea69a1789fd..d73440067438 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 87196da70f28..79091c708fca 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 afb1eea5eeb8..5287f2f0e65c 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: }