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