Make LLVM IR emission a bit more concise and readable. (#3078)

Provide LLVM IR names for named types, and not for unnamed types.

Use shorter names for IR values.
This commit is contained in:
Richard Smith
2023-08-09 03:09:03 +00:00
committed by GitHub
parent 2947877518
commit 927375f9c6
32 changed files with 202 additions and 218 deletions
+2 -4
View File
@@ -161,8 +161,7 @@ auto LoweringContext::BuildType(SemanticsNodeId node_id) -> llvm::Type* {
<< field_type_id;
subtypes.push_back(GetType(field_type_id));
}
return llvm::StructType::create(*llvm_context_, subtypes,
"StructLiteralType");
return llvm::StructType::get(*llvm_context_, subtypes);
}
case SemanticsNodeKind::TupleType: {
// TODO: Investigate special-casing handling of empty tuples so that they
@@ -175,8 +174,7 @@ auto LoweringContext::BuildType(SemanticsNodeId node_id) -> llvm::Type* {
for (auto ref_id : refs) {
subtypes.push_back(GetType(ref_id));
}
return llvm::StructType::create(*llvm_context_, subtypes,
"TupleLiteralType");
return llvm::StructType::get(*llvm_context_, subtypes);
}
default: {
CARBON_FATAL() << "Cannot use node as type: " << node_id;
+14 -3
View File
@@ -35,8 +35,7 @@ class LoweringContext {
auto GetType(SemanticsTypeId type_id) -> llvm::Type* {
// InvalidType should not be passed in.
if (type_id == SemanticsTypeId::TypeType) {
// `type` is lowered to an empty LLVM StructType.
return llvm::StructType::get(llvm_context());
return GetTypeType();
}
CARBON_CHECK(type_id.index >= 0) << type_id;
return types_[type_id.index];
@@ -44,7 +43,7 @@ class LoweringContext {
// Returns a lowered value to use for a value of type `type`.
auto GetTypeAsValue() -> llvm::Value* {
return llvm::ConstantStruct::getAnon(llvm_context(), {});
return llvm::ConstantStruct::get(GetTypeType());
}
auto llvm_context() -> llvm::LLVMContext& { return *llvm_context_; }
@@ -65,6 +64,15 @@ class LoweringContext {
// caller.
auto BuildType(SemanticsNodeId node_id) -> llvm::Type*;
// Returns the empty LLVM struct type used to represent the type `type`.
auto GetTypeType() -> llvm::StructType* {
if (!type_type_) {
// `type` is lowered to an empty LLVM StructType.
type_type_ = llvm::StructType::create(*llvm_context_, {}, "type");
}
return type_type_;
}
// State for building the LLVM IR.
llvm::LLVMContext* llvm_context_;
std::unique_ptr<llvm::Module> llvm_module_;
@@ -81,6 +89,9 @@ class LoweringContext {
// Provides lowered versions of types.
llvm::SmallVector<llvm::Type*> types_;
// Lowered version of the builtin type `type`.
llvm::StructType* type_type_ = nullptr;
};
} // namespace Carbon
+5 -5
View File
@@ -135,7 +135,7 @@ auto LoweringHandleCall(LoweringFunctionContext& context,
// 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, "TupleLiteralValue"));
/*ArraySize=*/nullptr, "call.result"));
} else {
context.SetLocal(node_id, context.builder().CreateCall(
function, args, function->getName()));
@@ -167,7 +167,7 @@ auto LoweringHandleIndex(LoweringFunctionContext& context,
.GetIntegerLiteral(index_node.GetAsIntegerLiteral())
.getZExtValue();
auto* gep = context.builder().CreateStructGEP(
llvm_type, context.GetLocal(tuple_node_id), index, "Index");
llvm_type, context.GetLocal(tuple_node_id), index, "tuple.index");
context.SetLocal(node_id, gep);
}
@@ -248,8 +248,8 @@ auto LoweringHandleTupleValue(LoweringFunctionContext& context,
SemanticsNodeId node_id, SemanticsNode node)
-> void {
auto* llvm_type = context.GetType(node.type_id());
auto* alloca = context.builder().CreateAlloca(
llvm_type, /*ArraySize=*/nullptr, "TupleLiteralValue");
auto* alloca =
context.builder().CreateAlloca(llvm_type, /*ArraySize=*/nullptr, "tuple");
context.SetLocal(node_id, alloca);
auto refs = context.semantics_ir().GetNodeBlock(node.GetAsTupleValue());
@@ -275,7 +275,7 @@ auto LoweringHandleStructValue(LoweringFunctionContext& context,
-> void {
auto* llvm_type = context.GetType(node.type_id());
auto* alloca = context.builder().CreateAlloca(
llvm_type, /*ArraySize=*/nullptr, "StructLiteralValue");
llvm_type, /*ArraySize=*/nullptr, "struct");
context.SetLocal(node_id, alloca);
auto refs = context.semantics_ir().GetNodeBlock(node.GetAsStructValue());
+6 -4
View File
@@ -15,10 +15,12 @@ fn F64() -> type {
// CHECK:STDOUT: ; ModuleID = 'type_values.carbon'
// CHECK:STDOUT: source_filename = "type_values.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: define {} @I32() {
// CHECK:STDOUT: ret {} zeroinitializer
// CHECK:STDOUT: %type = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define %type @I32() {
// CHECK:STDOUT: ret %type zeroinitializer
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define {} @F64() {
// CHECK:STDOUT: ret {} zeroinitializer
// CHECK:STDOUT: define %type @F64() {
// CHECK:STDOUT: ret %type zeroinitializer
// CHECK:STDOUT: }
+10 -12
View File
@@ -15,20 +15,18 @@ fn Main() {
// CHECK:STDOUT: ; ModuleID = 'empty_struct.carbon'
// CHECK:STDOUT: source_filename = "empty_struct.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %StructLiteralType = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define %StructLiteralType @Echo(%StructLiteralType %a) {
// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %1 = load %StructLiteralType, ptr %StructLiteralValue, align 1
// CHECK:STDOUT: ret %StructLiteralType %1
// CHECK:STDOUT: define {} @Echo({} %a) {
// CHECK:STDOUT: %struct = alloca {}, align 8
// CHECK:STDOUT: %1 = load {}, ptr %struct, align 1
// CHECK:STDOUT: ret {} %1
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %var = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %StructLiteralValue1 = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %1 = load %StructLiteralType, ptr %StructLiteralValue1, align 1
// CHECK:STDOUT: %Echo = call %StructLiteralType @Echo(%StructLiteralType %1)
// CHECK:STDOUT: store %StructLiteralType %Echo, ptr %var, align 1
// CHECK:STDOUT: %struct = alloca {}, align 8
// CHECK:STDOUT: %var = 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 %var, align 1
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -15,18 +15,16 @@ fn Main() {
// CHECK:STDOUT: ; ModuleID = 'empty_tuple.carbon'
// CHECK:STDOUT: source_filename = "empty_tuple.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define %TupleLiteralType @Echo(%TupleLiteralType %a) {
// CHECK:STDOUT: ret %TupleLiteralType %a
// CHECK:STDOUT: define {} @Echo({} %a) {
// CHECK:STDOUT: ret {} %a
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %var = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %TupleLiteralValue1 = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %1 = load %TupleLiteralType, ptr %TupleLiteralValue1, align 1
// CHECK:STDOUT: %Echo = call %TupleLiteralType @Echo(%TupleLiteralType %1)
// CHECK:STDOUT: store %TupleLiteralType %Echo, ptr %var, align 1
// CHECK:STDOUT: %tuple = alloca {}, align 8
// CHECK:STDOUT: %var = 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 %var, align 1
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -16,23 +16,21 @@ fn Main() {
// CHECK:STDOUT: ; ModuleID = 'implicit_empty_tuple_as_arg.carbon'
// CHECK:STDOUT: source_filename = "implicit_empty_tuple_as_arg.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Foo() {
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define %TupleLiteralType @Bar(%TupleLiteralType %a) {
// CHECK:STDOUT: ret %TupleLiteralType %a
// CHECK:STDOUT: define {} @Bar({} %a) {
// CHECK:STDOUT: ret {} %a
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %var = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %tuple = alloca {}, align 8
// CHECK:STDOUT: %var = alloca {}, align 8
// CHECK:STDOUT: call void @Foo()
// CHECK:STDOUT: %TupleLiteralValue1 = alloca {}, align 8
// CHECK:STDOUT: %1 = load %TupleLiteralType, ptr %TupleLiteralValue1, align 1
// CHECK:STDOUT: %Bar = call %TupleLiteralType @Bar(%TupleLiteralType %1)
// CHECK:STDOUT: store %TupleLiteralType %Bar, ptr %var, align 1
// 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 %var, align 1
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -19,6 +19,6 @@ fn Main() {
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: call void @Foo(i32 1)
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -20,8 +20,8 @@ fn Main() {
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: call void @Foo(i32 1)
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: call void @Foo(i32 1)
// CHECK:STDOUT: %TupleLiteralValue1 = alloca {}, align 8
// CHECK:STDOUT: %call.result1 = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -19,6 +19,6 @@ fn Main() {
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: call void @Foo(i32 1, i32 2)
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -20,8 +20,8 @@ fn Main() {
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: call void @Foo(i32 1, i32 2)
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: call void @Foo(i32 1, i32 2)
// CHECK:STDOUT: %TupleLiteralValue1 = alloca {}, align 8
// CHECK:STDOUT: %call.result1 = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -19,6 +19,6 @@ fn Main() {
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: call void @Foo()
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -15,18 +15,16 @@ fn Main() {
// CHECK:STDOUT: ; ModuleID = 'return_implicit.carbon'
// CHECK:STDOUT: source_filename = "return_implicit.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define void @MakeImplicitEmptyTuple() {
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %var = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %tuple = alloca {}, align 8
// CHECK:STDOUT: %var = alloca {}, align 8
// CHECK:STDOUT: call void @MakeImplicitEmptyTuple()
// CHECK:STDOUT: %TupleLiteralValue1 = alloca {}, align 8
// CHECK:STDOUT: %1 = load %TupleLiteralType, ptr %TupleLiteralValue1, align 1
// CHECK:STDOUT: store %TupleLiteralType %1, ptr %var, align 1
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: %1 = load {}, ptr %call.result, align 1
// CHECK:STDOUT: store {} %1, ptr %var, align 1
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
+1 -1
View File
@@ -23,6 +23,6 @@ fn Main() {
// CHECK:STDOUT: store i32 0, ptr %var, align 4
// CHECK:STDOUT: %1 = load i32, ptr %var, align 4
// CHECK:STDOUT: call void @DoNothing(i32 %1)
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -15,6 +15,6 @@ fn G(n: i32) { F(n); }
// CHECK:STDOUT:
// CHECK:STDOUT: define void @G(i32 %n) {
// CHECK:STDOUT: call void @F(i32 %n)
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
@@ -10,8 +10,6 @@ fn Echo(a: {}) {
// CHECK:STDOUT: ; ModuleID = 'empty_struct.carbon'
// CHECK:STDOUT: source_filename = "empty_struct.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %StructLiteralType = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Echo(%StructLiteralType %a) {
// CHECK:STDOUT: define void @Echo({} %a) {
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
+3 -3
View File
@@ -37,16 +37,16 @@ fn If(b: bool) {
// CHECK:STDOUT:
// CHECK:STDOUT: 1: ; preds = %0
// CHECK:STDOUT: call void @F()
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// 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: %TupleLiteralValue1 = alloca {}, align 8
// 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: %TupleLiteralValue2 = alloca {}, align 8
// CHECK:STDOUT: %call.result2 = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
+2 -2
View File
@@ -30,11 +30,11 @@ fn If(b: bool) {
// CHECK:STDOUT:
// CHECK:STDOUT: 1: ; preds = %0
// CHECK:STDOUT: call void @F()
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// 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: %TupleLiteralValue1 = alloca {}, align 8
// CHECK:STDOUT: %call.result1 = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
+19 -20
View File
@@ -14,34 +14,33 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'member_access.carbon'
// CHECK:STDOUT: source_filename = "member_access.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type { {}, {}, {} }
// CHECK:STDOUT: %TupleLiteralType.0 = type { i32, i32, i32 }
// CHECK:STDOUT: %type = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 0
// CHECK:STDOUT: store {} zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %2 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 1
// CHECK:STDOUT: store {} zeroinitializer, ptr %2, align 1
// CHECK:STDOUT: %3 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 2
// CHECK:STDOUT: store {} zeroinitializer, ptr %3, align 1
// CHECK:STDOUT: %var = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %TupleLiteralValue1 = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %4 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 0
// CHECK:STDOUT: %tuple = alloca { %type, %type, %type }, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds { %type, %type, %type }, ptr %tuple, i32 0, i32 0
// CHECK:STDOUT: store %type zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %2 = getelementptr inbounds { %type, %type, %type }, ptr %tuple, i32 0, i32 1
// CHECK:STDOUT: store %type zeroinitializer, ptr %2, align 1
// CHECK:STDOUT: %3 = getelementptr inbounds { %type, %type, %type }, ptr %tuple, i32 0, i32 2
// CHECK:STDOUT: store %type zeroinitializer, ptr %3, align 1
// CHECK:STDOUT: %var = alloca { i32, i32, i32 }, align 8
// CHECK:STDOUT: %tuple1 = alloca { i32, i32, i32 }, align 8
// CHECK:STDOUT: %4 = getelementptr inbounds { i32, i32, i32 }, ptr %tuple1, i32 0, i32 0
// CHECK:STDOUT: store i32 0, ptr %4, align 4
// CHECK:STDOUT: %5 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 1
// CHECK:STDOUT: %5 = getelementptr inbounds { i32, i32, i32 }, ptr %tuple1, i32 0, i32 1
// CHECK:STDOUT: store i32 1, ptr %5, align 4
// CHECK:STDOUT: %6 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 2
// CHECK:STDOUT: %6 = getelementptr inbounds { i32, i32, i32 }, ptr %tuple1, i32 0, i32 2
// CHECK:STDOUT: store i32 2, ptr %6, align 4
// CHECK:STDOUT: %7 = load %TupleLiteralType.0, ptr %TupleLiteralValue1, align 4
// CHECK:STDOUT: store %TupleLiteralType.0 %7, ptr %var, align 4
// CHECK:STDOUT: %7 = load { i32, i32, i32 }, ptr %tuple1, align 4
// CHECK:STDOUT: store { i32, i32, i32 } %7, ptr %var, align 4
// CHECK:STDOUT: %var2 = alloca i32, align 4
// CHECK:STDOUT: %Index = getelementptr inbounds %TupleLiteralType.0, ptr %var, i32 0, i32 0
// CHECK:STDOUT: %8 = load i32, ptr %Index, align 4
// CHECK:STDOUT: %tuple.index = getelementptr inbounds { i32, i32, i32 }, ptr %var, i32 0, i32 0
// CHECK:STDOUT: %8 = load i32, ptr %tuple.index, align 4
// CHECK:STDOUT: store i32 %8, ptr %var2, align 4
// CHECK:STDOUT: %var3 = alloca i32, align 4
// CHECK:STDOUT: %Index4 = getelementptr inbounds %TupleLiteralType.0, ptr %var, i32 0, i32 2
// CHECK:STDOUT: %9 = load i32, ptr %Index4, align 4
// CHECK:STDOUT: %tuple.index4 = getelementptr inbounds { i32, i32, i32 }, ptr %var, i32 0, i32 2
// CHECK:STDOUT: %9 = load i32, ptr %tuple.index4, align 4
// CHECK:STDOUT: store i32 %9, ptr %var3, align 4
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }
+1 -1
View File
@@ -30,6 +30,6 @@ fn Bar() {
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Bar() {
// CHECK:STDOUT: call void @Baz.1()
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
+1 -1
View File
@@ -23,6 +23,6 @@ fn Foo.Bar.Baz() {
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Baz() {
// CHECK:STDOUT: call void @Wiz()
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
+12 -13
View File
@@ -14,25 +14,24 @@ fn Main() {
// CHECK:STDOUT: ; ModuleID = 'assignment.carbon'
// CHECK:STDOUT: source_filename = "assignment.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type { {}, {} }
// CHECK:STDOUT: %TupleLiteralType.0 = type { i32, i32 }
// CHECK:STDOUT: %type = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define void @Main() {
// CHECK:STDOUT: %var = alloca i32, align 4
// CHECK:STDOUT: store i32 12, ptr %var, align 4
// CHECK:STDOUT: store i32 -7, ptr %var, align 4
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 0
// CHECK:STDOUT: store {} zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %2 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 1
// CHECK:STDOUT: store {} zeroinitializer, ptr %2, align 1
// CHECK:STDOUT: %var1 = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %TupleLiteralValue2 = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %3 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue2, i32 0, i32 0
// CHECK:STDOUT: %tuple = alloca { %type, %type }, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds { %type, %type }, ptr %tuple, i32 0, i32 0
// CHECK:STDOUT: store %type zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %2 = getelementptr inbounds { %type, %type }, ptr %tuple, i32 0, i32 1
// CHECK:STDOUT: store %type zeroinitializer, ptr %2, align 1
// CHECK:STDOUT: %var1 = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %tuple2 = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %3 = getelementptr inbounds { i32, i32 }, ptr %tuple2, i32 0, i32 0
// CHECK:STDOUT: store i32 1, ptr %3, align 4
// CHECK:STDOUT: %4 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue2, i32 0, i32 1
// CHECK:STDOUT: %4 = getelementptr inbounds { i32, i32 }, ptr %tuple2, i32 0, i32 1
// CHECK:STDOUT: store i32 2, ptr %4, align 4
// CHECK:STDOUT: %5 = load %TupleLiteralType.0, ptr %TupleLiteralValue2, align 4
// CHECK:STDOUT: store %TupleLiteralType.0 %5, ptr %var1, align 4
// CHECK:STDOUT: %5 = load { i32, i32 }, ptr %tuple2, align 4
// CHECK:STDOUT: store { i32, i32 } %5, ptr %var1, align 4
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
+8 -10
View File
@@ -15,22 +15,20 @@ fn F() {
// CHECK:STDOUT: ; ModuleID = 'address_of_field.carbon'
// CHECK:STDOUT: source_filename = "address_of_field.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %StructLiteralType = type { i32, i32 }
// CHECK:STDOUT:
// CHECK:STDOUT: declare void @G(ptr)
// CHECK:STDOUT:
// CHECK:STDOUT: define void @F() {
// CHECK:STDOUT: %var = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 0
// CHECK:STDOUT: %var = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %struct = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %a = getelementptr inbounds { i32, i32 }, ptr %struct, i32 0, i32 0
// CHECK:STDOUT: store i32 1, ptr %a, align 4
// CHECK:STDOUT: %b = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 1
// CHECK:STDOUT: %b = getelementptr inbounds { i32, i32 }, ptr %struct, i32 0, i32 1
// CHECK:STDOUT: store i32 2, ptr %b, align 4
// CHECK:STDOUT: %1 = load %StructLiteralType, ptr %StructLiteralValue, align 4
// CHECK:STDOUT: store %StructLiteralType %1, ptr %var, align 4
// CHECK:STDOUT: %b1 = getelementptr inbounds %StructLiteralType, ptr %var, i32 0, i32 1
// CHECK:STDOUT: %1 = load { i32, i32 }, ptr %struct, align 4
// CHECK:STDOUT: store { i32, i32 } %1, ptr %var, align 4
// CHECK:STDOUT: %b1 = getelementptr inbounds { i32, i32 }, ptr %var, i32 0, i32 1
// CHECK:STDOUT: %2 = load ptr, ptr %b1, align 8
// CHECK:STDOUT: call void @G(ptr %2)
// CHECK:STDOUT: %TupleLiteralValue = alloca {}, align 8
// CHECK:STDOUT: %call.result = alloca {}, align 8
// CHECK:STDOUT: ret void
// CHECK:STDOUT: }
+9 -11
View File
@@ -13,17 +13,15 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'empty.carbon'
// CHECK:STDOUT: source_filename = "empty.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %StructLiteralType = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %var = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %StructLiteralValue1 = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %1 = load %StructLiteralType, ptr %StructLiteralValue1, align 1
// CHECK:STDOUT: store %StructLiteralType %1, ptr %var, align 1
// CHECK:STDOUT: %StructLiteralValue2 = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %var3 = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %2 = load %StructLiteralType, ptr %var, align 1
// CHECK:STDOUT: store %StructLiteralType %2, ptr %var3, align 1
// CHECK:STDOUT: %struct = alloca {}, align 8
// CHECK:STDOUT: %var = alloca {}, align 8
// CHECK:STDOUT: %struct1 = alloca {}, align 8
// CHECK:STDOUT: %1 = load {}, ptr %struct1, align 1
// CHECK:STDOUT: store {} %1, ptr %var, align 1
// CHECK:STDOUT: %struct2 = alloca {}, align 8
// CHECK:STDOUT: %var3 = alloca {}, align 8
// CHECK:STDOUT: %2 = load {}, ptr %var, align 1
// CHECK:STDOUT: store {} %2, ptr %var3, align 1
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }
+7 -9
View File
@@ -14,19 +14,17 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'member_access.carbon'
// CHECK:STDOUT: source_filename = "member_access.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %StructLiteralType = type { double, i32 }
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %var = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 0
// CHECK:STDOUT: %var = alloca { double, i32 }, align 8
// CHECK:STDOUT: %struct = alloca { double, i32 }, align 8
// CHECK:STDOUT: %a = getelementptr inbounds { double, i32 }, ptr %struct, i32 0, i32 0
// CHECK:STDOUT: store double 0.000000e+00, ptr %a, align 8
// CHECK:STDOUT: %b = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 1
// CHECK:STDOUT: %b = getelementptr inbounds { double, i32 }, ptr %struct, i32 0, i32 1
// CHECK:STDOUT: store i32 1, ptr %b, align 4
// CHECK:STDOUT: %1 = load %StructLiteralType, ptr %StructLiteralValue, align 8
// CHECK:STDOUT: store %StructLiteralType %1, ptr %var, align 8
// CHECK:STDOUT: %1 = load { double, i32 }, ptr %struct, align 8
// CHECK:STDOUT: store { double, i32 } %1, ptr %var, align 8
// CHECK:STDOUT: %var1 = alloca i32, align 4
// CHECK:STDOUT: %b2 = getelementptr inbounds %StructLiteralType, ptr %var, i32 0, i32 1
// CHECK:STDOUT: %b2 = getelementptr inbounds { double, i32 }, ptr %var, i32 0, i32 1
// CHECK:STDOUT: %2 = load i32, ptr %b2, align 4
// CHECK:STDOUT: store i32 %2, ptr %var1, align 4
// CHECK:STDOUT: %var3 = alloca i32, align 4
+4 -4
View File
@@ -12,11 +12,11 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'nested_struct.carbon'
// CHECK:STDOUT: source_filename = "nested_struct.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %StructLiteralType.0 = type { {} }
// CHECK:STDOUT: %type = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType.0, align 8
// CHECK:STDOUT: %b = getelementptr inbounds %StructLiteralType.0, ptr %StructLiteralValue, i32 0, i32 0
// CHECK:STDOUT: store {} zeroinitializer, ptr %b, align 1
// CHECK:STDOUT: %struct = alloca { %type }, align 8
// CHECK:STDOUT: %b = getelementptr inbounds { %type }, ptr %struct, i32 0, i32 0
// CHECK:STDOUT: store %type zeroinitializer, ptr %b, align 1
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }
+8 -10
View File
@@ -13,17 +13,15 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'one_entry.carbon'
// CHECK:STDOUT: source_filename = "one_entry.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %StructLiteralType = type { i32 }
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %var = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 0
// CHECK:STDOUT: %var = alloca { i32 }, align 8
// CHECK:STDOUT: %struct = alloca { i32 }, align 8
// CHECK:STDOUT: %a = getelementptr inbounds { i32 }, ptr %struct, i32 0, i32 0
// CHECK:STDOUT: store i32 4, ptr %a, align 4
// CHECK:STDOUT: %1 = load %StructLiteralType, ptr %StructLiteralValue, align 4
// CHECK:STDOUT: store %StructLiteralType %1, ptr %var, align 4
// CHECK:STDOUT: %var1 = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %2 = load %StructLiteralType, ptr %var, align 4
// CHECK:STDOUT: store %StructLiteralType %2, ptr %var1, align 4
// CHECK:STDOUT: %1 = load { i32 }, ptr %struct, align 4
// CHECK:STDOUT: store { i32 } %1, ptr %var, align 4
// CHECK:STDOUT: %var1 = alloca { i32 }, align 8
// CHECK:STDOUT: %2 = load { i32 }, ptr %var, align 4
// CHECK:STDOUT: store { i32 } %2, ptr %var1, align 4
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }
+9 -11
View File
@@ -13,19 +13,17 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'two_entries.carbon'
// CHECK:STDOUT: source_filename = "two_entries.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %StructLiteralType = type { i32, i32 }
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %var = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %StructLiteralValue = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %a = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 0
// CHECK:STDOUT: %var = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %struct = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %a = getelementptr inbounds { i32, i32 }, ptr %struct, i32 0, i32 0
// CHECK:STDOUT: store i32 1, ptr %a, align 4
// CHECK:STDOUT: %b = getelementptr inbounds %StructLiteralType, ptr %StructLiteralValue, i32 0, i32 1
// CHECK:STDOUT: %b = getelementptr inbounds { i32, i32 }, ptr %struct, i32 0, i32 1
// CHECK:STDOUT: store i32 2, ptr %b, align 4
// CHECK:STDOUT: %1 = load %StructLiteralType, ptr %StructLiteralValue, align 4
// CHECK:STDOUT: store %StructLiteralType %1, ptr %var, align 4
// CHECK:STDOUT: %var1 = alloca %StructLiteralType, align 8
// CHECK:STDOUT: %2 = load %StructLiteralType, ptr %var, align 4
// CHECK:STDOUT: store %StructLiteralType %2, ptr %var1, align 4
// CHECK:STDOUT: %1 = load { i32, i32 }, ptr %struct, align 4
// CHECK:STDOUT: store { i32, i32 } %1, ptr %var, align 4
// CHECK:STDOUT: %var1 = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %2 = load { i32, i32 }, ptr %var, align 4
// CHECK:STDOUT: store { i32, i32 } %2, ptr %var1, align 4
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }
+9 -11
View File
@@ -13,17 +13,15 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'empty.carbon'
// CHECK:STDOUT: source_filename = "empty.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %var = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %TupleLiteralValue1 = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %1 = load %TupleLiteralType, ptr %TupleLiteralValue1, align 1
// CHECK:STDOUT: store %TupleLiteralType %1, ptr %var, align 1
// CHECK:STDOUT: %TupleLiteralValue2 = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %var3 = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %2 = load %TupleLiteralType, ptr %var, align 1
// CHECK:STDOUT: store %TupleLiteralType %2, ptr %var3, align 1
// CHECK:STDOUT: %tuple = alloca {}, align 8
// CHECK:STDOUT: %var = alloca {}, align 8
// CHECK:STDOUT: %tuple1 = alloca {}, align 8
// CHECK:STDOUT: %1 = load {}, ptr %tuple1, align 1
// CHECK:STDOUT: store {} %1, ptr %var, align 1
// CHECK:STDOUT: %tuple2 = alloca {}, align 8
// CHECK:STDOUT: %var3 = alloca {}, align 8
// CHECK:STDOUT: %2 = load {}, ptr %var, align 1
// CHECK:STDOUT: store {} %2, ptr %var3, align 1
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }
+7 -8
View File
@@ -12,15 +12,14 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'nested_tuple.carbon'
// CHECK:STDOUT: source_filename = "nested_tuple.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type { {} }
// CHECK:STDOUT: %TupleLiteralType.0 = type { %TupleLiteralType }
// CHECK:STDOUT: %type = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 0
// CHECK:STDOUT: store {} zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %TupleLiteralValue1 = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %2 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 0
// CHECK:STDOUT: store ptr %TupleLiteralValue, ptr %2, align 8
// CHECK:STDOUT: %tuple = alloca { %type }, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds { %type }, ptr %tuple, i32 0, i32 0
// CHECK:STDOUT: store %type zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %tuple1 = alloca { { %type } }, align 8
// CHECK:STDOUT: %2 = getelementptr inbounds { { %type } }, ptr %tuple1, i32 0, i32 0
// CHECK:STDOUT: store ptr %tuple, ptr %2, align 8
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }
+15 -16
View File
@@ -13,24 +13,23 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'one_entry.carbon'
// CHECK:STDOUT: source_filename = "one_entry.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type { {} }
// CHECK:STDOUT: %TupleLiteralType.0 = type { i32 }
// CHECK:STDOUT: %type = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 0
// CHECK:STDOUT: store {} zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %var = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %TupleLiteralValue1 = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %2 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 0
// CHECK:STDOUT: %tuple = alloca { %type }, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds { %type }, ptr %tuple, i32 0, i32 0
// CHECK:STDOUT: store %type zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %var = alloca { i32 }, align 8
// CHECK:STDOUT: %tuple1 = alloca { i32 }, align 8
// CHECK:STDOUT: %2 = getelementptr inbounds { i32 }, ptr %tuple1, i32 0, i32 0
// CHECK:STDOUT: store i32 1, ptr %2, align 4
// CHECK:STDOUT: %3 = load %TupleLiteralType.0, ptr %TupleLiteralValue1, align 4
// CHECK:STDOUT: store %TupleLiteralType.0 %3, ptr %var, align 4
// CHECK:STDOUT: %TupleLiteralValue2 = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %4 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue2, i32 0, i32 0
// CHECK:STDOUT: store {} zeroinitializer, ptr %4, align 1
// CHECK:STDOUT: %var3 = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %5 = load %TupleLiteralType.0, ptr %var, align 4
// CHECK:STDOUT: store %TupleLiteralType.0 %5, ptr %var3, align 4
// CHECK:STDOUT: %3 = load { i32 }, ptr %tuple1, align 4
// CHECK:STDOUT: store { i32 } %3, ptr %var, align 4
// CHECK:STDOUT: %tuple2 = alloca { %type }, align 8
// CHECK:STDOUT: %4 = getelementptr inbounds { %type }, ptr %tuple2, i32 0, i32 0
// CHECK:STDOUT: store %type zeroinitializer, ptr %4, align 1
// CHECK:STDOUT: %var3 = alloca { i32 }, align 8
// CHECK:STDOUT: %5 = load { i32 }, ptr %var, align 4
// CHECK:STDOUT: store { i32 } %5, ptr %var3, align 4
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }
+20 -21
View File
@@ -13,30 +13,29 @@ fn Run() -> i32 {
// CHECK:STDOUT: ; ModuleID = 'two_entries.carbon'
// CHECK:STDOUT: source_filename = "two_entries.carbon"
// CHECK:STDOUT:
// CHECK:STDOUT: %TupleLiteralType = type { {}, {} }
// CHECK:STDOUT: %TupleLiteralType.0 = type { i32, i32 }
// CHECK:STDOUT: %type = type {}
// CHECK:STDOUT:
// CHECK:STDOUT: define i32 @Run() {
// CHECK:STDOUT: %TupleLiteralValue = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 0
// CHECK:STDOUT: store {} zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %2 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue, i32 0, i32 1
// CHECK:STDOUT: store {} zeroinitializer, ptr %2, align 1
// CHECK:STDOUT: %var = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %TupleLiteralValue1 = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %3 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 0
// CHECK:STDOUT: %tuple = alloca { %type, %type }, align 8
// CHECK:STDOUT: %1 = getelementptr inbounds { %type, %type }, ptr %tuple, i32 0, i32 0
// CHECK:STDOUT: store %type zeroinitializer, ptr %1, align 1
// CHECK:STDOUT: %2 = getelementptr inbounds { %type, %type }, ptr %tuple, i32 0, i32 1
// CHECK:STDOUT: store %type zeroinitializer, ptr %2, align 1
// CHECK:STDOUT: %var = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %tuple1 = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %3 = getelementptr inbounds { i32, i32 }, ptr %tuple1, i32 0, i32 0
// CHECK:STDOUT: store i32 12, ptr %3, align 4
// CHECK:STDOUT: %4 = getelementptr inbounds %TupleLiteralType.0, ptr %TupleLiteralValue1, i32 0, i32 1
// CHECK:STDOUT: %4 = getelementptr inbounds { i32, i32 }, ptr %tuple1, i32 0, i32 1
// CHECK:STDOUT: store i32 7, ptr %4, align 4
// CHECK:STDOUT: %5 = load %TupleLiteralType.0, ptr %TupleLiteralValue1, align 4
// CHECK:STDOUT: store %TupleLiteralType.0 %5, ptr %var, align 4
// CHECK:STDOUT: %TupleLiteralValue2 = alloca %TupleLiteralType, align 8
// CHECK:STDOUT: %6 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue2, i32 0, i32 0
// CHECK:STDOUT: store {} zeroinitializer, ptr %6, align 1
// CHECK:STDOUT: %7 = getelementptr inbounds %TupleLiteralType, ptr %TupleLiteralValue2, i32 0, i32 1
// CHECK:STDOUT: store {} zeroinitializer, ptr %7, align 1
// CHECK:STDOUT: %var3 = alloca %TupleLiteralType.0, align 8
// CHECK:STDOUT: %8 = load %TupleLiteralType.0, ptr %var, align 4
// CHECK:STDOUT: store %TupleLiteralType.0 %8, ptr %var3, align 4
// CHECK:STDOUT: %5 = load { i32, i32 }, ptr %tuple1, align 4
// CHECK:STDOUT: store { i32, i32 } %5, ptr %var, align 4
// CHECK:STDOUT: %tuple2 = alloca { %type, %type }, align 8
// CHECK:STDOUT: %6 = getelementptr inbounds { %type, %type }, ptr %tuple2, i32 0, i32 0
// CHECK:STDOUT: store %type zeroinitializer, ptr %6, align 1
// CHECK:STDOUT: %7 = getelementptr inbounds { %type, %type }, ptr %tuple2, i32 0, i32 1
// CHECK:STDOUT: store %type zeroinitializer, ptr %7, align 1
// CHECK:STDOUT: %var3 = alloca { i32, i32 }, align 8
// CHECK:STDOUT: %8 = load { i32, i32 }, ptr %var, align 4
// CHECK:STDOUT: store { i32, i32 } %8, ptr %var3, align 4
// CHECK:STDOUT: ret i32 0
// CHECK:STDOUT: }