diff --git a/toolchain/lower/function_context.cpp b/toolchain/lower/function_context.cpp index b430c3b7ffb3..f8a4a1e1b964 100644 --- a/toolchain/lower/function_context.cpp +++ b/toolchain/lower/function_context.cpp @@ -198,6 +198,50 @@ auto FunctionContext::MakeSyntheticBlock() -> llvm::BasicBlock* { return synthetic_block_; } +auto FunctionContext::CreateAlloca(llvm::Type* type, const llvm::Twine& name) + -> llvm::AllocaInst* { + // Position the first alloca right before the start of the executable code in + // the function. + llvm::AllocaInst* alloca; + { + llvm::IRBuilderBase::InsertPointGuard guard(builder()); + + auto debug_loc = builder().getCurrentDebugLocation(); + if (after_allocas_) { + builder().SetInsertPoint(after_allocas_); + } else { + builder().SetInsertPointPastAllocas(&llvm_function()); + } + + // IRBuilder tramples over our debug location when setting the insert point, + // so undo that. + builder().SetCurrentDebugLocation(debug_loc); + + // Create an alloca for this variable in the entry block. + alloca = builder().CreateAlloca(type, /*ArraySize=*/nullptr, name); + } + + // Create a lifetime start intrinsic here to indicate where its scope really + // begins. + auto size = llvm_module().getDataLayout().getTypeAllocSize(type); + builder().CreateLifetimeStart( + alloca, llvm::ConstantInt::get(llvm_context(), llvm::APInt(64, size))); + + // If we just created the first alloca, there is now definitely at least one + // instruction after it -- there is a lifetime start instruction if nothing + // else. Use that instruction as our insert point for all future allocas. + if (!after_allocas_) { + auto loc = alloca->getIterator(); + ++loc; + after_allocas_ = &*loc; + } + + // TODO: Create a matching `@llvm.lifetime.end` intrinsic call when the + // variable goes out of scope. + + return alloca; +} + auto FunctionContext::GetDebugLoc(SemIR::InstId inst_id) -> llvm::DebugLoc { if (!di_subprogram_) { return llvm::DebugLoc(); diff --git a/toolchain/lower/function_context.h b/toolchain/lower/function_context.h index 8de77968df8a..e53c4fbcce36 100644 --- a/toolchain/lower/function_context.h +++ b/toolchain/lower/function_context.h @@ -175,19 +175,6 @@ class FunctionContext { return file_context_->GetIntLiteralAsValue(); } - // Returns the instruction immediately after all the existing static allocas. - // This is the insert point for future static allocas. - auto GetInstructionAfterAllocas() const -> llvm::Instruction* { - return after_allocas_; - } - - // Sets the instruction after static allocas. This should be called once, - // after the first alloca is created. - auto SetInstructionAfterAllocas(llvm::Instruction* after_allocas) -> void { - CARBON_CHECK(!after_allocas_); - after_allocas_ = after_allocas; - } - // Create a synthetic block that corresponds to no SemIR::InstBlockId. Such // a block should only ever have a single predecessor, and is used when we // need multiple `llvm::BasicBlock`s to model the linear control flow in a @@ -199,6 +186,11 @@ class FunctionContext { return synthetic_block_ == block; } + // Creates an alloca instruction of the given type, adds it to the entry + // block, and starts the lifetime of the corresponding storage. + auto CreateAlloca(llvm::Type* type, const llvm::Twine& name = llvm::Twine()) + -> llvm::AllocaInst*; + // Returns the debug location to associate with the specified instruction. auto GetDebugLoc(SemIR::InstId inst_id) -> llvm::DebugLoc; diff --git a/toolchain/lower/handle.cpp b/toolchain/lower/handle.cpp index 7c211d5f4821..51ce112e33db 100644 --- a/toolchain/lower/handle.cpp +++ b/toolchain/lower/handle.cpp @@ -296,49 +296,8 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, SemIR::VarStorage /* inst */) -> void { - auto* type = context.GetTypeOfInst(inst_id); - - // Position the first alloca right before the start of the executable code in - // the function. - llvm::AllocaInst* alloca; - { - llvm::IRBuilderBase::InsertPointGuard guard(context.builder()); - - auto debug_loc = context.builder().getCurrentDebugLocation(); - if (auto* after_allocas = context.GetInstructionAfterAllocas()) { - context.builder().SetInsertPoint(after_allocas); - } else { - context.builder().SetInsertPointPastAllocas(&context.llvm_function()); - } - - // IRBuilder tramples over our debug location when setting the insert point, - // so undo that. - context.builder().SetCurrentDebugLocation(debug_loc); - - // Create an alloca for this variable in the entry block. - alloca = context.builder().CreateAlloca(type); - } - - // Create a lifetime start intrinsic here to indicate where its scope really - // begins. - auto size = context.llvm_module().getDataLayout().getTypeAllocSize(type); - context.builder().CreateLifetimeStart( - alloca, - llvm::ConstantInt::get(context.llvm_context(), llvm::APInt(64, size))); - - // If we just created the first alloca, there is now definitely at least one - // instruction after it -- there is a lifetime start instruction if nothing - // else. Use that instruction as our insert point for all future allocas. - if (!context.GetInstructionAfterAllocas()) { - auto loc = alloca->getIterator(); - ++loc; - context.SetInstructionAfterAllocas(&*loc); - } - - // TODO: Create a matching `@llvm.lifetime.end` intrinsic call when the - // variable goes out of scope. - - context.SetLocal(inst_id, alloca); + context.SetLocal(inst_id, + context.CreateAlloca(context.GetTypeOfInst(inst_id))); } auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, diff --git a/toolchain/lower/handle_expr_category.cpp b/toolchain/lower/handle_expr_category.cpp index a36cc896ca94..5affbe111834 100644 --- a/toolchain/lower/handle_expr_category.cpp +++ b/toolchain/lower/handle_expr_category.cpp @@ -44,9 +44,8 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, SemIR::TemporaryStorage /*inst*/) -> void { - auto* type = context.GetTypeOfInst(inst_id); - context.SetLocal(inst_id, - context.builder().CreateAlloca(type, nullptr, "temp")); + context.SetLocal( + inst_id, context.CreateAlloca(context.GetTypeOfInst(inst_id), "temp")); } auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, diff --git a/toolchain/lower/testdata/array/assign_return_value.carbon b/toolchain/lower/testdata/array/assign_return_value.carbon index c972b553ca95..04607a27de70 100644 --- a/toolchain/lower/testdata/array/assign_return_value.carbon +++ b/toolchain/lower/testdata/array/assign_return_value.carbon @@ -32,8 +32,9 @@ fn Run() { // CHECK:STDOUT: define void @main() !dbg !9 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %t.var = alloca [2 x i32], align 4, !dbg !10 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %t.var), !dbg !10 // CHECK:STDOUT: %.loc16_28.1.temp = alloca { i32, i32 }, align 8, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %t.var), !dbg !10 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %.loc16_28.1.temp), !dbg !11 // CHECK:STDOUT: call void @_CF.Main(ptr %.loc16_28.1.temp), !dbg !11 // CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc16_28.1.temp, i32 0, i32 0, !dbg !11 // CHECK:STDOUT: %.loc16_28.3 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !11 @@ -52,6 +53,9 @@ fn Run() { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #1 // CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } +// CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: diff --git a/toolchain/lower/testdata/array/function_param.carbon b/toolchain/lower/testdata/array/function_param.carbon index 15c721a9ef7f..a18aad8e46ab 100644 --- a/toolchain/lower/testdata/array/function_param.carbon +++ b/toolchain/lower/testdata/array/function_param.carbon @@ -33,6 +33,7 @@ fn G() -> i32 { // CHECK:STDOUT: define i32 @_CG.Main() !dbg !9 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc18_20.3.temp = alloca [3 x i32], align 4, !dbg !10 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %.loc18_20.3.temp), !dbg !10 // CHECK:STDOUT: %.loc18_20.4.array.index = getelementptr inbounds [3 x i32], ptr %.loc18_20.3.temp, i32 0, i64 0, !dbg !10 // CHECK:STDOUT: %.loc18_20.7.array.index = getelementptr inbounds [3 x i32], ptr %.loc18_20.3.temp, i32 0, i64 1, !dbg !10 // CHECK:STDOUT: %.loc18_20.10.array.index = getelementptr inbounds [3 x i32], ptr %.loc18_20.3.temp, i32 0, i64 2, !dbg !10 @@ -41,10 +42,14 @@ fn G() -> i32 { // CHECK:STDOUT: ret i32 %F.call, !dbg !12 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #0 +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 // CHECK:STDOUT: -// CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} diff --git a/toolchain/lower/testdata/builtins/no_op.carbon b/toolchain/lower/testdata/builtins/no_op.carbon index 53838967227d..ca04fa29d834 100644 --- a/toolchain/lower/testdata/builtins/no_op.carbon +++ b/toolchain/lower/testdata/builtins/no_op.carbon @@ -51,6 +51,7 @@ fn J() { // CHECK:STDOUT: define void @_CH.Main() !dbg !11 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc27_18.1.temp = alloca {}, align 8, !dbg !12 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc27_18.1.temp), !dbg !12 // CHECK:STDOUT: ret void, !dbg !13 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -58,14 +59,18 @@ fn J() { // CHECK:STDOUT: // CHECK:STDOUT: define void @_CJ.Main() !dbg !14 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: call void @_CI.Main(), !dbg !15 // CHECK:STDOUT: %.loc33_11.1.temp = alloca {}, align 8, !dbg !15 +// CHECK:STDOUT: call void @_CI.Main(), !dbg !15 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc33_11.1.temp), !dbg !15 // CHECK:STDOUT: ret void, !dbg !16 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 // CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } +// CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} diff --git a/toolchain/lower/testdata/class/generic.carbon b/toolchain/lower/testdata/class/generic.carbon index dc787f78d687..e3d844892f39 100644 --- a/toolchain/lower/testdata/class/generic.carbon +++ b/toolchain/lower/testdata/class/generic.carbon @@ -268,12 +268,13 @@ fn AccessTuple() -> (i32, i32, i32) { // CHECK:STDOUT: define void @_CAccessEmpty.Main() !dbg !16 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %c.var = alloca { i1, {} }, align 8, !dbg !17 +// CHECK:STDOUT: %.loc30_17.1.temp = alloca {}, align 8, !dbg !18 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 1, ptr %c.var), !dbg !17 -// CHECK:STDOUT: %.loc29_37.2.v = getelementptr inbounds nuw { i1, {} }, ptr %c.var, i32 0, i32 0, !dbg !18 -// CHECK:STDOUT: %.loc29_37.4.w = getelementptr inbounds nuw { i1, {} }, ptr %c.var, i32 0, i32 1, !dbg !18 +// CHECK:STDOUT: %.loc29_37.2.v = getelementptr inbounds nuw { i1, {} }, ptr %c.var, i32 0, i32 0, !dbg !19 +// CHECK:STDOUT: %.loc29_37.4.w = getelementptr inbounds nuw { i1, {} }, ptr %c.var, i32 0, i32 1, !dbg !19 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %c.var, ptr align 1 @C.val.dcc.loc29_3, i64 1, i1 false), !dbg !17 -// CHECK:STDOUT: call void @_CGetT.C.Main.e43630e9a6c38c3f(ptr %c.var), !dbg !19 -// CHECK:STDOUT: %.loc30_17.1.temp = alloca {}, align 8, !dbg !19 +// CHECK:STDOUT: call void @_CGetT.C.Main.e43630e9a6c38c3f(ptr %c.var), !dbg !18 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc30_17.1.temp), !dbg !18 // CHECK:STDOUT: ret void, !dbg !20 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -324,7 +325,7 @@ fn AccessTuple() -> (i32, i32, i32) { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 3, 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 4, 3, 2, 1, 0 } // CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 3, 2, 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } @@ -351,8 +352,8 @@ fn AccessTuple() -> (i32, i32, i32) { // CHECK:STDOUT: !15 = !DILocation(line: 25, column: 3, scope: !11) // CHECK:STDOUT: !16 = distinct !DISubprogram(name: "AccessEmpty", linkageName: "_CAccessEmpty.Main", scope: null, file: !3, line: 28, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !17 = !DILocation(line: 29, column: 3, scope: !16) -// CHECK:STDOUT: !18 = !DILocation(line: 29, column: 18, scope: !16) -// CHECK:STDOUT: !19 = !DILocation(line: 30, column: 10, scope: !16) +// CHECK:STDOUT: !18 = !DILocation(line: 30, column: 10, scope: !16) +// CHECK:STDOUT: !19 = !DILocation(line: 29, column: 18, scope: !16) // CHECK:STDOUT: !20 = !DILocation(line: 30, column: 3, scope: !16) // CHECK:STDOUT: !21 = distinct !DISubprogram(name: "AccessTuple", linkageName: "_CAccessTuple.Main", scope: null, file: !3, line: 33, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !22 = !DILocation(line: 34, column: 3, scope: !21) diff --git a/toolchain/lower/testdata/function/call/implicit_empty_tuple_as_arg.carbon b/toolchain/lower/testdata/function/call/implicit_empty_tuple_as_arg.carbon index c986162382c5..bff706a40951 100644 --- a/toolchain/lower/testdata/function/call/implicit_empty_tuple_as_arg.carbon +++ b/toolchain/lower/testdata/function/call/implicit_empty_tuple_as_arg.carbon @@ -35,9 +35,10 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !10 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca {}, align 8, !dbg !11 +// CHECK:STDOUT: %.loc19_23.1.temp = alloca {}, align 8, !dbg !12 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %x.var), !dbg !11 // CHECK:STDOUT: call void @_CFoo.Main(), !dbg !12 -// CHECK:STDOUT: %.loc19_23.1.temp = alloca {}, align 8, !dbg !12 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc19_23.1.temp), !dbg !12 // CHECK:STDOUT: call void @_CBar.Main(), !dbg !13 // CHECK:STDOUT: ret void, !dbg !14 // CHECK:STDOUT: } @@ -45,6 +46,9 @@ fn Main() { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 // CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } +// CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} diff --git a/toolchain/lower/testdata/function/call/tuple_param_with_return_slot.carbon b/toolchain/lower/testdata/function/call/tuple_param_with_return_slot.carbon index 49bb62a6a6bd..97045f5eb2d1 100644 --- a/toolchain/lower/testdata/function/call/tuple_param_with_return_slot.carbon +++ b/toolchain/lower/testdata/function/call/tuple_param_with_return_slot.carbon @@ -42,10 +42,16 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !12 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc18_21.1.temp = alloca { i32, i32, i32 }, align 8, !dbg !13 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %.loc18_21.1.temp), !dbg !13 // CHECK:STDOUT: call void @_CF.Main(ptr %.loc18_21.1.temp, { i32 } { i32 1 }, ptr @tuple.11a.loc18_20.6), !dbg !13 // CHECK:STDOUT: ret void, !dbg !14 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: diff --git a/toolchain/lower/testdata/function/generic/call_basic.carbon b/toolchain/lower/testdata/function/generic/call_basic.carbon index 3cd375e6006f..0a9525b63a29 100644 --- a/toolchain/lower/testdata/function/generic/call_basic.carbon +++ b/toolchain/lower/testdata/function/generic/call_basic.carbon @@ -99,26 +99,27 @@ fn M() { // CHECK:STDOUT: %ptr_f64.var = alloca ptr, align 8, !dbg !27 // CHECK:STDOUT: %ptr_i8.var = alloca ptr, align 8, !dbg !28 // CHECK:STDOUT: %c.var = alloca {}, align 8, !dbg !29 -// CHECK:STDOUT: %H.call.loc25 = call i32 @_CH.Main.b88d1103f417c6d4(i32 %x), !dbg !30 -// CHECK:STDOUT: %H.call.loc26 = call %type @_CH.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !31 -// CHECK:STDOUT: %H.call.loc27 = call %type @_CH.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !32 -// CHECK:STDOUT: %G.call = call i32 @_CG.Main.b88d1103f417c6d4(i32 %x), !dbg !33 -// CHECK:STDOUT: %H.call.loc28 = call i32 @_CH.Main.b88d1103f417c6d4(i32 %G.call), !dbg !34 +// CHECK:STDOUT: %.loc40_6.1.temp = alloca {}, align 8, !dbg !30 +// CHECK:STDOUT: %H.call.loc25 = call i32 @_CH.Main.b88d1103f417c6d4(i32 %x), !dbg !31 +// CHECK:STDOUT: %H.call.loc26 = call %type @_CH.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !32 +// CHECK:STDOUT: %H.call.loc27 = call %type @_CH.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !33 +// CHECK:STDOUT: %G.call = call i32 @_CG.Main.b88d1103f417c6d4(i32 %x), !dbg !34 +// CHECK:STDOUT: %H.call.loc28 = call i32 @_CH.Main.b88d1103f417c6d4(i32 %G.call), !dbg !35 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %var_f64.var), !dbg !25 -// CHECK:STDOUT: %.loc32 = load double, ptr %var_f64.var, align 8, !dbg !35 -// CHECK:STDOUT: %H.call.loc32 = call double @_CH.Main.66be507887ceee78(double %.loc32), !dbg !36 +// CHECK:STDOUT: %.loc32 = load double, ptr %var_f64.var, align 8, !dbg !36 +// CHECK:STDOUT: %H.call.loc32 = call double @_CH.Main.66be507887ceee78(double %.loc32), !dbg !37 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %ptr_i32.var), !dbg !26 -// CHECK:STDOUT: %.loc34 = load ptr, ptr %ptr_i32.var, align 8, !dbg !37 -// CHECK:STDOUT: %H.call.loc34 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc34), !dbg !38 +// CHECK:STDOUT: %.loc34 = load ptr, ptr %ptr_i32.var, align 8, !dbg !38 +// CHECK:STDOUT: %H.call.loc34 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc34), !dbg !39 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %ptr_f64.var), !dbg !27 -// CHECK:STDOUT: %.loc36 = load ptr, ptr %ptr_f64.var, align 8, !dbg !39 -// CHECK:STDOUT: %H.call.loc36 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc36), !dbg !40 +// CHECK:STDOUT: %.loc36 = load ptr, ptr %ptr_f64.var, align 8, !dbg !40 +// CHECK:STDOUT: %H.call.loc36 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc36), !dbg !41 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %ptr_i8.var), !dbg !28 -// CHECK:STDOUT: %.loc38 = load ptr, ptr %ptr_i8.var, align 8, !dbg !41 -// CHECK:STDOUT: %H.call.loc38 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc38), !dbg !42 +// CHECK:STDOUT: %.loc38 = load ptr, ptr %ptr_i8.var, align 8, !dbg !42 +// CHECK:STDOUT: %H.call.loc38 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc38), !dbg !43 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %c.var), !dbg !29 -// CHECK:STDOUT: %.loc40_6.1.temp = alloca {}, align 8, !dbg !43 -// CHECK:STDOUT: call void @_CH.Main.15b1f98bd9cc0c5b(ptr %.loc40_6.1.temp, ptr %c.var), !dbg !43 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc40_6.1.temp), !dbg !30 +// CHECK:STDOUT: call void @_CH.Main.15b1f98bd9cc0c5b(ptr %.loc40_6.1.temp, ptr %c.var), !dbg !30 // CHECK:STDOUT: ret i32 %x, !dbg !44 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -134,26 +135,27 @@ fn M() { // CHECK:STDOUT: %ptr_f64.var = alloca ptr, align 8, !dbg !50 // CHECK:STDOUT: %ptr_i8.var = alloca ptr, align 8, !dbg !51 // CHECK:STDOUT: %c.var = alloca {}, align 8, !dbg !52 -// CHECK:STDOUT: %H.call.loc25 = call double @_CH.Main.66be507887ceee78(double %x), !dbg !53 -// CHECK:STDOUT: %H.call.loc26 = call %type @_CH.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !54 -// CHECK:STDOUT: %H.call.loc27 = call %type @_CH.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !55 -// CHECK:STDOUT: %G.call = call double @_CG.Main.66be507887ceee78(double %x), !dbg !56 -// CHECK:STDOUT: %H.call.loc28 = call double @_CH.Main.66be507887ceee78(double %G.call), !dbg !57 +// CHECK:STDOUT: %.loc40_6.1.temp = alloca {}, align 8, !dbg !53 +// CHECK:STDOUT: %H.call.loc25 = call double @_CH.Main.66be507887ceee78(double %x), !dbg !54 +// CHECK:STDOUT: %H.call.loc26 = call %type @_CH.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !55 +// CHECK:STDOUT: %H.call.loc27 = call %type @_CH.Main.5754c7a55c7cbe4a(%type zeroinitializer), !dbg !56 +// CHECK:STDOUT: %G.call = call double @_CG.Main.66be507887ceee78(double %x), !dbg !57 +// CHECK:STDOUT: %H.call.loc28 = call double @_CH.Main.66be507887ceee78(double %G.call), !dbg !58 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %var_f64.var), !dbg !48 -// CHECK:STDOUT: %.loc32 = load double, ptr %var_f64.var, align 8, !dbg !58 -// CHECK:STDOUT: %H.call.loc32 = call double @_CH.Main.66be507887ceee78(double %.loc32), !dbg !59 +// CHECK:STDOUT: %.loc32 = load double, ptr %var_f64.var, align 8, !dbg !59 +// CHECK:STDOUT: %H.call.loc32 = call double @_CH.Main.66be507887ceee78(double %.loc32), !dbg !60 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %ptr_i32.var), !dbg !49 -// CHECK:STDOUT: %.loc34 = load ptr, ptr %ptr_i32.var, align 8, !dbg !60 -// CHECK:STDOUT: %H.call.loc34 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc34), !dbg !61 +// CHECK:STDOUT: %.loc34 = load ptr, ptr %ptr_i32.var, align 8, !dbg !61 +// CHECK:STDOUT: %H.call.loc34 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc34), !dbg !62 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %ptr_f64.var), !dbg !50 -// CHECK:STDOUT: %.loc36 = load ptr, ptr %ptr_f64.var, align 8, !dbg !62 -// CHECK:STDOUT: %H.call.loc36 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc36), !dbg !63 +// CHECK:STDOUT: %.loc36 = load ptr, ptr %ptr_f64.var, align 8, !dbg !63 +// CHECK:STDOUT: %H.call.loc36 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc36), !dbg !64 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %ptr_i8.var), !dbg !51 -// CHECK:STDOUT: %.loc38 = load ptr, ptr %ptr_i8.var, align 8, !dbg !64 -// CHECK:STDOUT: %H.call.loc38 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc38), !dbg !65 +// CHECK:STDOUT: %.loc38 = load ptr, ptr %ptr_i8.var, align 8, !dbg !65 +// CHECK:STDOUT: %H.call.loc38 = call ptr @_CH.Main.e8193710fd35b608(ptr %.loc38), !dbg !66 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %c.var), !dbg !52 -// CHECK:STDOUT: %.loc40_6.1.temp = alloca {}, align 8, !dbg !66 -// CHECK:STDOUT: call void @_CH.Main.15b1f98bd9cc0c5b(ptr %.loc40_6.1.temp, ptr %c.var), !dbg !66 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc40_6.1.temp), !dbg !53 +// CHECK:STDOUT: call void @_CH.Main.15b1f98bd9cc0c5b(ptr %.loc40_6.1.temp, ptr %c.var), !dbg !53 // CHECK:STDOUT: ret double %x, !dbg !67 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -183,7 +185,7 @@ fn M() { // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 13, 12, 11, 10 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 14, 13, 12 } // CHECK:STDOUT: uselistorder ptr @_CH.Main.b88d1103f417c6d4, { 1, 0 } // CHECK:STDOUT: uselistorder ptr @_CH.Main.5754c7a55c7cbe4a, { 3, 2, 1, 0 } // CHECK:STDOUT: uselistorder ptr @_CH.Main.66be507887ceee78, { 3, 2, 1, 0 } @@ -225,20 +227,20 @@ fn M() { // CHECK:STDOUT: !27 = !DILocation(line: 35, column: 3, scope: !24) // CHECK:STDOUT: !28 = !DILocation(line: 37, column: 3, scope: !24) // CHECK:STDOUT: !29 = !DILocation(line: 39, column: 3, scope: !24) -// CHECK:STDOUT: !30 = !DILocation(line: 25, column: 3, scope: !24) -// CHECK:STDOUT: !31 = !DILocation(line: 26, column: 3, scope: !24) -// CHECK:STDOUT: !32 = !DILocation(line: 27, column: 3, scope: !24) -// CHECK:STDOUT: !33 = !DILocation(line: 28, column: 5, scope: !24) -// CHECK:STDOUT: !34 = !DILocation(line: 28, column: 3, scope: !24) -// CHECK:STDOUT: !35 = !DILocation(line: 32, column: 5, scope: !24) -// CHECK:STDOUT: !36 = !DILocation(line: 32, column: 3, scope: !24) -// CHECK:STDOUT: !37 = !DILocation(line: 34, column: 5, scope: !24) -// CHECK:STDOUT: !38 = !DILocation(line: 34, column: 3, scope: !24) -// CHECK:STDOUT: !39 = !DILocation(line: 36, column: 5, scope: !24) -// CHECK:STDOUT: !40 = !DILocation(line: 36, column: 3, scope: !24) -// CHECK:STDOUT: !41 = !DILocation(line: 38, column: 5, scope: !24) -// CHECK:STDOUT: !42 = !DILocation(line: 38, column: 3, scope: !24) -// CHECK:STDOUT: !43 = !DILocation(line: 40, column: 3, scope: !24) +// CHECK:STDOUT: !30 = !DILocation(line: 40, column: 3, scope: !24) +// CHECK:STDOUT: !31 = !DILocation(line: 25, column: 3, scope: !24) +// CHECK:STDOUT: !32 = !DILocation(line: 26, column: 3, scope: !24) +// CHECK:STDOUT: !33 = !DILocation(line: 27, column: 3, scope: !24) +// CHECK:STDOUT: !34 = !DILocation(line: 28, column: 5, scope: !24) +// CHECK:STDOUT: !35 = !DILocation(line: 28, column: 3, scope: !24) +// CHECK:STDOUT: !36 = !DILocation(line: 32, column: 5, scope: !24) +// CHECK:STDOUT: !37 = !DILocation(line: 32, column: 3, scope: !24) +// CHECK:STDOUT: !38 = !DILocation(line: 34, column: 5, scope: !24) +// CHECK:STDOUT: !39 = !DILocation(line: 34, column: 3, scope: !24) +// CHECK:STDOUT: !40 = !DILocation(line: 36, column: 5, scope: !24) +// CHECK:STDOUT: !41 = !DILocation(line: 36, column: 3, scope: !24) +// CHECK:STDOUT: !42 = !DILocation(line: 38, column: 5, scope: !24) +// CHECK:STDOUT: !43 = !DILocation(line: 38, column: 3, scope: !24) // CHECK:STDOUT: !44 = !DILocation(line: 42, column: 3, scope: !24) // CHECK:STDOUT: !45 = distinct !DISubprogram(name: "F", linkageName: "_CF.Main.66be507887ceee78", scope: null, file: !3, line: 15, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !46 = !DILocation(line: 15, column: 1, scope: !45) @@ -248,20 +250,20 @@ fn M() { // CHECK:STDOUT: !50 = !DILocation(line: 35, column: 3, scope: !47) // CHECK:STDOUT: !51 = !DILocation(line: 37, column: 3, scope: !47) // CHECK:STDOUT: !52 = !DILocation(line: 39, column: 3, scope: !47) -// CHECK:STDOUT: !53 = !DILocation(line: 25, column: 3, scope: !47) -// CHECK:STDOUT: !54 = !DILocation(line: 26, column: 3, scope: !47) -// CHECK:STDOUT: !55 = !DILocation(line: 27, column: 3, scope: !47) -// CHECK:STDOUT: !56 = !DILocation(line: 28, column: 5, scope: !47) -// CHECK:STDOUT: !57 = !DILocation(line: 28, column: 3, scope: !47) -// CHECK:STDOUT: !58 = !DILocation(line: 32, column: 5, scope: !47) -// CHECK:STDOUT: !59 = !DILocation(line: 32, column: 3, scope: !47) -// CHECK:STDOUT: !60 = !DILocation(line: 34, column: 5, scope: !47) -// CHECK:STDOUT: !61 = !DILocation(line: 34, column: 3, scope: !47) -// CHECK:STDOUT: !62 = !DILocation(line: 36, column: 5, scope: !47) -// CHECK:STDOUT: !63 = !DILocation(line: 36, column: 3, scope: !47) -// CHECK:STDOUT: !64 = !DILocation(line: 38, column: 5, scope: !47) -// CHECK:STDOUT: !65 = !DILocation(line: 38, column: 3, scope: !47) -// CHECK:STDOUT: !66 = !DILocation(line: 40, column: 3, scope: !47) +// CHECK:STDOUT: !53 = !DILocation(line: 40, column: 3, scope: !47) +// CHECK:STDOUT: !54 = !DILocation(line: 25, column: 3, scope: !47) +// CHECK:STDOUT: !55 = !DILocation(line: 26, column: 3, scope: !47) +// CHECK:STDOUT: !56 = !DILocation(line: 27, column: 3, scope: !47) +// CHECK:STDOUT: !57 = !DILocation(line: 28, column: 5, scope: !47) +// CHECK:STDOUT: !58 = !DILocation(line: 28, column: 3, scope: !47) +// CHECK:STDOUT: !59 = !DILocation(line: 32, column: 5, scope: !47) +// CHECK:STDOUT: !60 = !DILocation(line: 32, column: 3, scope: !47) +// CHECK:STDOUT: !61 = !DILocation(line: 34, column: 5, scope: !47) +// CHECK:STDOUT: !62 = !DILocation(line: 34, column: 3, scope: !47) +// CHECK:STDOUT: !63 = !DILocation(line: 36, column: 5, scope: !47) +// CHECK:STDOUT: !64 = !DILocation(line: 36, column: 3, scope: !47) +// CHECK:STDOUT: !65 = !DILocation(line: 38, column: 5, scope: !47) +// CHECK:STDOUT: !66 = !DILocation(line: 38, column: 3, scope: !47) // CHECK:STDOUT: !67 = !DILocation(line: 42, column: 3, scope: !47) // CHECK:STDOUT: !68 = distinct !DISubprogram(name: "H", linkageName: "_CH.Main.b88d1103f417c6d4", scope: null, file: !3, line: 18, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !69 = !DILocation(line: 19, column: 3, scope: !68) diff --git a/toolchain/lower/testdata/impl/import_thunk.carbon b/toolchain/lower/testdata/impl/import_thunk.carbon index b3639e5d1063..38c8945f6f0d 100644 --- a/toolchain/lower/testdata/impl/import_thunk.carbon +++ b/toolchain/lower/testdata/impl/import_thunk.carbon @@ -100,13 +100,24 @@ fn Test(a: A) -> C { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc20_19.1.temp = alloca { i32 }, align 8, !dbg !19 // CHECK:STDOUT: %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !20 +// CHECK:STDOUT: %.loc20_19.2.temp = alloca { i32 }, align 8, !dbg !19 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc20_19.1.temp), !dbg !19 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc16_9.1.temp), !dbg !20 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !20 // CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !19 -// CHECK:STDOUT: %.loc20_19.2.temp = alloca { i32 }, align 8, !dbg !19 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc20_19.2.temp), !dbg !19 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc20_19.2.temp, ptr %.loc20_19.1.temp), !dbg !19 // CHECK:STDOUT: ret void, !dbg !19 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -139,9 +150,13 @@ fn Test(a: A) -> C { // CHECK:STDOUT: %.loc7_20.1.temp = alloca { i32 }, align 8, !dbg !7 // CHECK:STDOUT: %.loc7_20.2.temp = alloca { i32 }, align 8, !dbg !7 // CHECK:STDOUT: %.loc7_19.1.temp = alloca { i32 }, align 8, !dbg !8 +// CHECK:STDOUT: %.loc7_21.1.temp = alloca { i32 }, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc7_20.1.temp), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc7_20.2.temp), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc7_19.1.temp), !dbg !8 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc7_19.1.temp, ptr %a), !dbg !8 // CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc7_20.2.temp, ptr %.loc7_19.1.temp), !dbg !7 -// CHECK:STDOUT: %.loc7_21.1.temp = alloca { i32 }, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc7_21.1.temp), !dbg !9 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc7_21.1.temp, ptr %.loc7_20.2.temp), !dbg !9 // CHECK:STDOUT: ret void, !dbg !9 // CHECK:STDOUT: } @@ -154,6 +169,14 @@ fn Test(a: A) -> C { // CHECK:STDOUT: // CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr) // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 3, 2, 1, 0 } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -183,9 +206,12 @@ fn Test(a: A) -> C { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc9_19.1.temp = alloca { i32 }, align 8, !dbg !11 // CHECK:STDOUT: %.2.temp = alloca { i32 }, align 8 +// CHECK:STDOUT: %.loc9_19.2.temp = alloca { i32 }, align 8, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc9_19.1.temp), !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.2.temp) // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.2.temp, ptr %a) // CHECK:STDOUT: call void @"_CF.X.Main:I.Main"(ptr %.loc9_19.1.temp, ptr %.2.temp), !dbg !11 -// CHECK:STDOUT: %.loc9_19.2.temp = alloca { i32 }, align 8, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc9_19.2.temp), !dbg !11 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc9_19.2.temp, ptr %.loc9_19.1.temp), !dbg !11 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } @@ -194,6 +220,14 @@ fn Test(a: A) -> C { // CHECK:STDOUT: // CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr) // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -217,9 +251,13 @@ fn Test(a: A) -> C { // CHECK:STDOUT: %.loc8_19.1.temp = alloca { i32 }, align 8, !dbg !7 // CHECK:STDOUT: %.loc8_19.2.temp = alloca { i32 }, align 8, !dbg !7 // CHECK:STDOUT: %.loc8_18.1.temp = alloca { i32 }, align 8, !dbg !8 +// CHECK:STDOUT: %.loc8_20.1.temp = alloca { i32 }, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc8_19.1.temp), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc8_19.2.temp), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc8_18.1.temp), !dbg !8 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc8_18.1.temp, ptr %a), !dbg !8 // CHECK:STDOUT: call void @"_CF.X.Main:I.Main"(ptr %.loc8_19.2.temp, ptr %.loc8_18.1.temp), !dbg !7 -// CHECK:STDOUT: %.loc8_20.1.temp = alloca { i32 }, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc8_20.1.temp), !dbg !9 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc8_20.1.temp, ptr %.loc8_19.2.temp), !dbg !9 // CHECK:STDOUT: ret void, !dbg !9 // CHECK:STDOUT: } @@ -232,6 +270,14 @@ fn Test(a: A) -> C { // CHECK:STDOUT: // CHECK:STDOUT: declare void @"_CConvert.B.Main:ImplicitAs.Core"(ptr sret({ i32 }), ptr) // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 3, 2, 1, 0 } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: diff --git a/toolchain/lower/testdata/impl/thunk.carbon b/toolchain/lower/testdata/impl/thunk.carbon index 860bc810ceca..462e8ff77f9b 100644 --- a/toolchain/lower/testdata/impl/thunk.carbon +++ b/toolchain/lower/testdata/impl/thunk.carbon @@ -104,9 +104,12 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc20_19.1.temp = alloca { i32 }, align 8, !dbg !19 // CHECK:STDOUT: %.loc16_9.1.temp = alloca { i32 }, align 8, !dbg !20 +// CHECK:STDOUT: %.loc20_19.2.temp = alloca { i32 }, align 8, !dbg !19 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc20_19.1.temp), !dbg !19 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc16_9.1.temp), !dbg !20 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc16_9.1.temp, ptr %a), !dbg !20 // CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc20_19.1.temp, ptr %.loc16_9.1.temp), !dbg !19 -// CHECK:STDOUT: %.loc20_19.2.temp = alloca { i32 }, align 8, !dbg !19 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc20_19.2.temp), !dbg !19 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc20_19.2.temp, ptr %.loc20_19.1.temp), !dbg !19 // CHECK:STDOUT: ret void, !dbg !19 // CHECK:STDOUT: } @@ -116,13 +119,25 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: %.loc24_20.1.temp = alloca { i32 }, align 8, !dbg !22 // CHECK:STDOUT: %.loc24_20.2.temp = alloca { i32 }, align 8, !dbg !22 // CHECK:STDOUT: %.loc24_19.1.temp = alloca { i32 }, align 8, !dbg !23 +// CHECK:STDOUT: %.loc24_21.1.temp = alloca { i32 }, align 8, !dbg !24 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc24_20.1.temp), !dbg !22 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc24_20.2.temp), !dbg !22 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc24_19.1.temp), !dbg !23 // CHECK:STDOUT: call void @"_CConvert.A.Main:ImplicitAs.Core"(ptr %.loc24_19.1.temp, ptr %a), !dbg !23 // CHECK:STDOUT: call void @"_CF.61ea2aba74ab3bf1:I.Main"(ptr %.loc24_20.2.temp, ptr %.loc24_19.1.temp), !dbg !22 -// CHECK:STDOUT: %.loc24_21.1.temp = alloca { i32 }, align 8, !dbg !24 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %.loc24_21.1.temp), !dbg !24 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc24_21.1.temp, ptr %.loc24_20.2.temp), !dbg !24 // CHECK:STDOUT: ret void, !dbg !24 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 6, 5, 4, 3, 2, 1, 0 } +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -167,12 +182,17 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc22_23.1.temp = alloca {}, align 8, !dbg !9 // CHECK:STDOUT: %.loc22_23.3.temp = alloca {}, align 8, !dbg !9 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_23.3.temp, ptr %b), !dbg !9 // CHECK:STDOUT: %.loc22_23.7.temp = alloca {}, align 8, !dbg !9 // CHECK:STDOUT: %.loc22_22.1.temp = alloca {}, align 8, !dbg !10 +// CHECK:STDOUT: %.loc22_24.1.temp = alloca {}, align 8, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc22_23.1.temp), !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc22_23.3.temp), !dbg !9 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_23.3.temp, ptr %b), !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc22_23.7.temp), !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc22_22.1.temp), !dbg !10 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_22.1.temp, ptr %b), !dbg !10 // CHECK:STDOUT: call void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr %.loc22_23.7.temp, ptr %c, ptr %.loc22_22.1.temp), !dbg !9 -// CHECK:STDOUT: %.loc22_24.1.temp = alloca {}, align 8, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc22_24.1.temp), !dbg !11 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc22_24.1.temp, ptr %.loc22_23.7.temp), !dbg !11 // CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } @@ -186,6 +206,9 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #0 // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #1 +// CHECK:STDOUT: // CHECK:STDOUT: define linkonce_odr void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr sret({}) %return, ptr %self, ptr %x) !dbg !15 { // CHECK:STDOUT: entry: // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %return, ptr align 1 @B.val.loc18_42, i64 0, i1 false), !dbg !16 @@ -201,17 +224,25 @@ fn CallCallGeneric(c: C(()), b: B) -> A { // CHECK:STDOUT: define linkonce_odr void @"_CF:thunk.C.Main:I.Main.e43630e9a6c38c3f"(ptr sret({}) %return, ptr %self, ptr %x) !dbg !20 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc18_31.2.temp = alloca {}, align 8, !dbg !21 -// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc18_31.2.temp, ptr %x), !dbg !21 // CHECK:STDOUT: %.loc18_31.6.temp = alloca {}, align 8, !dbg !21 // CHECK:STDOUT: %.loc12_21.1.temp = alloca {}, align 8, !dbg !22 +// CHECK:STDOUT: %.loc18_31.7.temp = alloca {}, align 8, !dbg !21 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc18_31.2.temp), !dbg !21 +// CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc18_31.2.temp, ptr %x), !dbg !21 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc18_31.6.temp), !dbg !21 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc12_21.1.temp), !dbg !22 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc12_21.1.temp, ptr %x), !dbg !22 // CHECK:STDOUT: call void @"_CF.C.Main:I.Main.e43630e9a6c38c3f"(ptr %.loc18_31.6.temp, ptr %self, ptr %.loc12_21.1.temp), !dbg !21 -// CHECK:STDOUT: %.loc18_31.7.temp = alloca {}, align 8, !dbg !21 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %.loc18_31.7.temp), !dbg !21 // CHECK:STDOUT: call void @"_CConvert.B.Main:ImplicitAs.Core"(ptr %.loc18_31.7.temp, ptr %.loc18_31.6.temp), !dbg !21 // CHECK:STDOUT: ret void, !dbg !21 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 0, 1, 2, 3, 8, 7, 6, 5, 4 } +// CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} diff --git a/toolchain/lower/testdata/index/array_element_access.carbon b/toolchain/lower/testdata/index/array_element_access.carbon index 2ef4368e0d4b..cd0865bda910 100644 --- a/toolchain/lower/testdata/index/array_element_access.carbon +++ b/toolchain/lower/testdata/index/array_element_access.carbon @@ -45,33 +45,35 @@ fn Run() { // CHECK:STDOUT: define void @main() !dbg !12 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca [2 x i32], align 4, !dbg !13 -// CHECK:STDOUT: %b.var = alloca i32, align 4, !dbg !14 -// CHECK:STDOUT: %c.var = alloca i32, align 4, !dbg !15 -// CHECK:STDOUT: %d.var = alloca i32, align 4, !dbg !16 +// CHECK:STDOUT: %.loc17_28.1.temp = alloca { i32, i32 }, align 8, !dbg !14 +// CHECK:STDOUT: %b.var = alloca i32, align 4, !dbg !15 +// CHECK:STDOUT: %c.var = alloca i32, align 4, !dbg !16 +// CHECK:STDOUT: %d.var = alloca i32, align 4, !dbg !17 +// CHECK:STDOUT: %.loc20_18.1.temp = alloca [2 x i32], align 4, !dbg !18 // CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %a.var), !dbg !13 -// CHECK:STDOUT: %.loc17_28.1.temp = alloca { i32, i32 }, align 8, !dbg !17 -// CHECK:STDOUT: call void @_CA.Main(ptr %.loc17_28.1.temp), !dbg !17 -// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc17_28.1.temp, i32 0, i32 0, !dbg !17 -// CHECK:STDOUT: %.loc17_28.3 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !17 -// CHECK:STDOUT: %.loc17_28.4.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 0, !dbg !17 -// CHECK:STDOUT: store i32 %.loc17_28.3, ptr %.loc17_28.4.array.index, align 4, !dbg !17 -// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc17_28.1.temp, i32 0, i32 1, !dbg !17 -// CHECK:STDOUT: %.loc17_28.6 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !17 -// CHECK:STDOUT: %.loc17_28.7.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 1, !dbg !17 -// CHECK:STDOUT: store i32 %.loc17_28.6, ptr %.loc17_28.7.array.index, align 4, !dbg !17 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %b.var), !dbg !14 -// CHECK:STDOUT: store i32 1, ptr %b.var, align 4, !dbg !14 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %c.var), !dbg !15 -// CHECK:STDOUT: %.loc19_18 = load i32, ptr %b.var, align 4, !dbg !18 -// CHECK:STDOUT: %.loc19_19.1.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i32 %.loc19_18, !dbg !19 -// CHECK:STDOUT: %.loc19_19.2 = load i32, ptr %.loc19_19.1.array.index, align 4, !dbg !19 -// CHECK:STDOUT: store i32 %.loc19_19.2, ptr %c.var, align 4, !dbg !15 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %d.var), !dbg !16 -// CHECK:STDOUT: %.loc20_18.1.temp = alloca [2 x i32], align 4, !dbg !20 -// CHECK:STDOUT: call void @_CB.Main(ptr %.loc20_18.1.temp), !dbg !20 -// CHECK:STDOUT: %.loc20_21.1.array.index = getelementptr inbounds [2 x i32], ptr %.loc20_18.1.temp, i32 0, i32 1, !dbg !20 -// CHECK:STDOUT: %.loc20_21.2 = load i32, ptr %.loc20_21.1.array.index, align 4, !dbg !20 -// CHECK:STDOUT: store i32 %.loc20_21.2, ptr %d.var, align 4, !dbg !16 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %.loc17_28.1.temp), !dbg !14 +// CHECK:STDOUT: call void @_CA.Main(ptr %.loc17_28.1.temp), !dbg !14 +// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc17_28.1.temp, i32 0, i32 0, !dbg !14 +// CHECK:STDOUT: %.loc17_28.3 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !14 +// CHECK:STDOUT: %.loc17_28.4.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 0, !dbg !14 +// CHECK:STDOUT: store i32 %.loc17_28.3, ptr %.loc17_28.4.array.index, align 4, !dbg !14 +// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc17_28.1.temp, i32 0, i32 1, !dbg !14 +// CHECK:STDOUT: %.loc17_28.6 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !14 +// CHECK:STDOUT: %.loc17_28.7.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 1, !dbg !14 +// CHECK:STDOUT: store i32 %.loc17_28.6, ptr %.loc17_28.7.array.index, align 4, !dbg !14 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %b.var), !dbg !15 +// CHECK:STDOUT: store i32 1, ptr %b.var, align 4, !dbg !15 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %c.var), !dbg !16 +// CHECK:STDOUT: %.loc19_18 = load i32, ptr %b.var, align 4, !dbg !19 +// CHECK:STDOUT: %.loc19_19.1.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i32 %.loc19_18, !dbg !20 +// CHECK:STDOUT: %.loc19_19.2 = load i32, ptr %.loc19_19.1.array.index, align 4, !dbg !20 +// CHECK:STDOUT: store i32 %.loc19_19.2, ptr %c.var, align 4, !dbg !16 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %d.var), !dbg !17 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %.loc20_18.1.temp), !dbg !18 +// CHECK:STDOUT: call void @_CB.Main(ptr %.loc20_18.1.temp), !dbg !18 +// CHECK:STDOUT: %.loc20_21.1.array.index = getelementptr inbounds [2 x i32], ptr %.loc20_18.1.temp, i32 0, i32 1, !dbg !18 +// CHECK:STDOUT: %.loc20_21.2 = load i32, ptr %.loc20_21.1.array.index, align 4, !dbg !18 +// CHECK:STDOUT: store i32 %.loc20_21.2, ptr %d.var, align 4, !dbg !17 // CHECK:STDOUT: ret void, !dbg !21 // CHECK:STDOUT: } // CHECK:STDOUT: @@ -83,7 +85,7 @@ fn Run() { // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives // CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 1, 0 } -// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 3, 2, 1, 0 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 5, 4, 3, 2, 1, 0 } // CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } @@ -105,11 +107,11 @@ fn Run() { // CHECK:STDOUT: !11 = !DILocation(line: 14, column: 27, scope: !9) // CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Run", linkageName: "main", scope: null, file: !3, line: 16, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !13 = !DILocation(line: 17, column: 3, scope: !12) -// CHECK:STDOUT: !14 = !DILocation(line: 18, column: 3, scope: !12) -// CHECK:STDOUT: !15 = !DILocation(line: 19, column: 3, scope: !12) -// CHECK:STDOUT: !16 = !DILocation(line: 20, column: 3, scope: !12) -// CHECK:STDOUT: !17 = !DILocation(line: 17, column: 26, scope: !12) -// CHECK:STDOUT: !18 = !DILocation(line: 19, column: 18, scope: !12) -// CHECK:STDOUT: !19 = !DILocation(line: 19, column: 16, scope: !12) -// CHECK:STDOUT: !20 = !DILocation(line: 20, column: 16, scope: !12) +// CHECK:STDOUT: !14 = !DILocation(line: 17, column: 26, scope: !12) +// CHECK:STDOUT: !15 = !DILocation(line: 18, column: 3, scope: !12) +// CHECK:STDOUT: !16 = !DILocation(line: 19, column: 3, scope: !12) +// CHECK:STDOUT: !17 = !DILocation(line: 20, column: 3, scope: !12) +// CHECK:STDOUT: !18 = !DILocation(line: 20, column: 16, scope: !12) +// CHECK:STDOUT: !19 = !DILocation(line: 19, column: 18, scope: !12) +// CHECK:STDOUT: !20 = !DILocation(line: 19, column: 16, scope: !12) // CHECK:STDOUT: !21 = !DILocation(line: 16, column: 1, scope: !12) diff --git a/toolchain/lower/testdata/operators/overloaded.carbon b/toolchain/lower/testdata/operators/overloaded.carbon index ed886bd105cf..186c8707b29b 100644 --- a/toolchain/lower/testdata/operators/overloaded.carbon +++ b/toolchain/lower/testdata/operators/overloaded.carbon @@ -83,11 +83,17 @@ fn Calculate(a: Number, b: Number) -> Number { // CHECK:STDOUT: define void @_CCalculate.Main(ptr sret({ i1 }) %return, ptr %a, ptr %b) !dbg !21 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %.loc28_10.1.temp = alloca { i1 }, align 8, !dbg !22 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 1, ptr %.loc28_10.1.temp), !dbg !22 // CHECK:STDOUT: call void @"_COp.Number.Main:Negate.Core"(ptr %.loc28_10.1.temp, ptr %a), !dbg !22 // CHECK:STDOUT: call void @"_COp.Number.Main:MulWith.Core"(ptr %return, ptr %.loc28_10.1.temp, ptr %b), !dbg !22 // CHECK:STDOUT: ret void, !dbg !23 // CHECK:STDOUT: } // CHECK:STDOUT: +// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) +// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: attributes #0 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } +// CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: diff --git a/toolchain/lower/testdata/tuple/access/return_value_access.carbon b/toolchain/lower/testdata/tuple/access/return_value_access.carbon index 7a282fd7e2f2..fcf6b505b285 100644 --- a/toolchain/lower/testdata/tuple/access/return_value_access.carbon +++ b/toolchain/lower/testdata/tuple/access/return_value_access.carbon @@ -32,8 +32,9 @@ fn Run() { // CHECK:STDOUT: define void @main() !dbg !9 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %t.var = alloca i32, align 4, !dbg !10 -// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %t.var), !dbg !10 // CHECK:STDOUT: %.loc16_18.1.temp = alloca { i32, i32 }, align 8, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %t.var), !dbg !10 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %.loc16_18.1.temp), !dbg !11 // CHECK:STDOUT: call void @_CF.Main(ptr %.loc16_18.1.temp), !dbg !11 // CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc16_18.1.temp, i32 0, i32 1, !dbg !11 // CHECK:STDOUT: %.loc16_19 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !11 @@ -47,6 +48,9 @@ fn Run() { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.lifetime.start.p0(i64 immarg, ptr captures(none)) #1 // CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } +// CHECK:STDOUT: // CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: attributes #1 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: