diff --git a/toolchain/lower/function_context.h b/toolchain/lower/function_context.h index 8a52b7743612..eef1a7370cac 100644 --- a/toolchain/lower/function_context.h +++ b/toolchain/lower/function_context.h @@ -89,6 +89,19 @@ class FunctionContext { return file_context_->GetTypeAsValue(); } + // 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) { + 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 @@ -111,6 +124,7 @@ class FunctionContext { return file_context_->llvm_context(); } auto llvm_module() -> llvm::Module& { return file_context_->llvm_module(); } + auto llvm_function() -> llvm::Function& { return *function_; } auto builder() -> llvm::IRBuilderBase& { return builder_; } auto sem_ir() -> const SemIR::File& { return file_context_->sem_ir(); } @@ -155,8 +169,14 @@ class FunctionContext { // The IR function we're generating. llvm::Function* function_; + // Builder for creating code in this function. The insertion point is held at + // the location of the current SemIR instruction. llvm::IRBuilder builder_; + // The instruction after all allocas. This is used as the insert point for new + // allocas. + llvm::Instruction* after_allocas_ = nullptr; + llvm::DISubprogram* di_subprogram_; // The optional vlog stream. diff --git a/toolchain/lower/handle.cpp b/toolchain/lower/handle.cpp index a52ecae1af22..7ac2b72f488c 100644 --- a/toolchain/lower/handle.cpp +++ b/toolchain/lower/handle.cpp @@ -264,9 +264,41 @@ auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, SemIR::VarStorage inst) -> void { - context.SetLocal(inst_id, - context.builder().CreateAlloca(context.GetType(inst.type_id), - /*ArraySize=*/nullptr)); + auto* type = context.GetType(inst.type_id); + + // Position the first alloca right before the start of the executable code in + // the function. + auto saved_ip = context.builder().saveIP(); + if (auto* after_allocas = context.GetInstructionAfterAllocas()) { + context.builder().SetInsertPoint(after_allocas); + } else { + context.builder().SetInsertPointPastAllocas(&context.llvm_function()); + } + + // Create an alloca for this variable in the entry block. + auto* alloca = context.builder().CreateAlloca(type); + context.builder().restoreIP(saved_ip); + + // 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); } auto HandleInst(FunctionContext& context, SemIR::InstId inst_id, diff --git a/toolchain/lower/testdata/alias/local.carbon b/toolchain/lower/testdata/alias/local.carbon index 357d7d157db0..665a745679dd 100644 --- a/toolchain/lower/testdata/alias/local.carbon +++ b/toolchain/lower/testdata/alias/local.carbon @@ -20,11 +20,17 @@ fn F() -> i32 { // CHECK:STDOUT: define i32 @_CF.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %a.var), !dbg !7 // CHECK:STDOUT: store i32 0, ptr %a.var, align 4, !dbg !8 // CHECK:STDOUT: %.loc14 = load i32, ptr %a.var, align 4, !dbg !9 // CHECK:STDOUT: ret i32 %.loc14, !dbg !10 // 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 nocapture) #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/array/array_in_place.carbon b/toolchain/lower/testdata/array/array_in_place.carbon index dd443433fff1..08c3a10c7158 100644 --- a/toolchain/lower/testdata/array/array_in_place.carbon +++ b/toolchain/lower/testdata/array/array_in_place.carbon @@ -22,6 +22,7 @@ fn G() { // CHECK:STDOUT: define void @_CG.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %v.var = alloca [2 x { i32, i32, i32 }], align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 24, ptr %v.var), !dbg !7 // CHECK:STDOUT: %.loc14_42.1.array.index = getelementptr inbounds [2 x { i32, i32, i32 }], ptr %v.var, i32 0, i64 0, !dbg !8 // CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_42.1.array.index), !dbg !9 // CHECK:STDOUT: %.loc14_42.3.array.index = getelementptr inbounds [2 x { i32, i32, i32 }], ptr %v.var, i32 0, i64 1, !dbg !8 @@ -29,6 +30,11 @@ fn G() { // CHECK:STDOUT: ret void, !dbg !11 // 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 nocapture) #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/array/assign_return_value.carbon b/toolchain/lower/testdata/array/assign_return_value.carbon index 3413e29af391..d821bf737a44 100644 --- a/toolchain/lower/testdata/array/assign_return_value.carbon +++ b/toolchain/lower/testdata/array/assign_return_value.carbon @@ -30,6 +30,7 @@ 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: %.loc14_23.1.temp = alloca { i32, i32 }, align 8, !dbg !11 // CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_23.1.temp), !dbg !11 // CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc14_23.1.temp, i32 0, i32 0, !dbg !11 @@ -46,7 +47,11 @@ fn Run() { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #1 +// 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/array/base.carbon b/toolchain/lower/testdata/array/base.carbon index 6dc7a6d60c4f..4d3ce6ed87f3 100644 --- a/toolchain/lower/testdata/array/base.carbon +++ b/toolchain/lower/testdata/array/base.carbon @@ -27,47 +27,58 @@ fn Run() { // CHECK:STDOUT: define void @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca [1 x i32], align 4, !dbg !7 +// CHECK:STDOUT: %b.var = alloca [2 x double], align 8, !dbg !7 +// CHECK:STDOUT: %c.var = alloca [5 x {}], align 8, !dbg !7 +// CHECK:STDOUT: %d.var = alloca { i32, i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: %e.var = alloca [3 x i32], align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %a.var), !dbg !7 // CHECK:STDOUT: %.loc12_24.3.array.index = getelementptr inbounds [1 x i32], ptr %a.var, i32 0, i64 0, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a.var, ptr align 4 @array.1.loc12_25, i64 4, i1 false), !dbg !9 -// CHECK:STDOUT: %b.var = alloca [2 x double], align 8, !dbg !10 -// CHECK:STDOUT: %.loc13_32.2.array.index = getelementptr inbounds [2 x double], ptr %b.var, i32 0, i64 0, !dbg !11 -// CHECK:STDOUT: %.loc13_32.4.array.index = getelementptr inbounds [2 x double], ptr %b.var, i32 0, i64 1, !dbg !11 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %b.var, ptr align 8 @array.2.loc13_33, i64 16, i1 false), !dbg !12 -// CHECK:STDOUT: %c.var = alloca [5 x {}], align 8, !dbg !13 -// CHECK:STDOUT: %.loc14_40.2.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 0, !dbg !14 -// CHECK:STDOUT: %.loc14_40.4.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 1, !dbg !14 -// CHECK:STDOUT: %.loc14_40.6.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 2, !dbg !14 -// CHECK:STDOUT: %.loc14_40.8.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 3, !dbg !14 -// CHECK:STDOUT: %.loc14_40.10.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 4, !dbg !14 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %c.var, ptr align 1 @array.3.loc14_41, i64 0, i1 false), !dbg !15 -// CHECK:STDOUT: %d.var = alloca { i32, i32, i32 }, align 8, !dbg !16 -// CHECK:STDOUT: %tuple.elem0.loc15.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 0, !dbg !17 -// CHECK:STDOUT: %tuple.elem1.loc15.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 1, !dbg !17 -// CHECK:STDOUT: %tuple.elem2.loc15.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 2, !dbg !17 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %d.var, ptr align 4 @tuple.loc15_37, i64 12, i1 false), !dbg !18 -// CHECK:STDOUT: %e.var = alloca [3 x i32], align 4, !dbg !19 -// CHECK:STDOUT: %tuple.elem0.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 0, !dbg !20 -// CHECK:STDOUT: %.loc16_21.1 = load i32, ptr %tuple.elem0.loc16.tuple.elem, align 4, !dbg !20 -// CHECK:STDOUT: %.loc16_21.2.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 0, !dbg !20 -// CHECK:STDOUT: store i32 %.loc16_21.1, ptr %.loc16_21.2.array.index, align 4, !dbg !20 -// CHECK:STDOUT: %tuple.elem1.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 1, !dbg !20 -// CHECK:STDOUT: %.loc16_21.4 = load i32, ptr %tuple.elem1.loc16.tuple.elem, align 4, !dbg !20 -// CHECK:STDOUT: %.loc16_21.5.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 1, !dbg !20 -// CHECK:STDOUT: store i32 %.loc16_21.4, ptr %.loc16_21.5.array.index, align 4, !dbg !20 -// CHECK:STDOUT: %tuple.elem2.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 2, !dbg !20 -// CHECK:STDOUT: %.loc16_21.7 = load i32, ptr %tuple.elem2.loc16.tuple.elem, align 4, !dbg !20 -// CHECK:STDOUT: %.loc16_21.8.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 2, !dbg !20 -// CHECK:STDOUT: store i32 %.loc16_21.7, ptr %.loc16_21.8.array.index, align 4, !dbg !20 -// CHECK:STDOUT: ret void, !dbg !21 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %b.var), !dbg !7 +// CHECK:STDOUT: %.loc13_32.2.array.index = getelementptr inbounds [2 x double], ptr %b.var, i32 0, i64 0, !dbg !10 +// CHECK:STDOUT: %.loc13_32.4.array.index = getelementptr inbounds [2 x double], ptr %b.var, i32 0, i64 1, !dbg !10 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %b.var, ptr align 8 @array.2.loc13_33, i64 16, i1 false), !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %c.var), !dbg !7 +// CHECK:STDOUT: %.loc14_40.2.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 0, !dbg !12 +// CHECK:STDOUT: %.loc14_40.4.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 1, !dbg !12 +// CHECK:STDOUT: %.loc14_40.6.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 2, !dbg !12 +// CHECK:STDOUT: %.loc14_40.8.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 3, !dbg !12 +// CHECK:STDOUT: %.loc14_40.10.array.index = getelementptr inbounds [5 x {}], ptr %c.var, i32 0, i64 4, !dbg !12 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %c.var, ptr align 1 @array.3.loc14_41, i64 0, i1 false), !dbg !13 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %d.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem0.loc15.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 0, !dbg !14 +// CHECK:STDOUT: %tuple.elem1.loc15.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 1, !dbg !14 +// CHECK:STDOUT: %tuple.elem2.loc15.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 2, !dbg !14 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %d.var, ptr align 4 @tuple.loc15_37, i64 12, i1 false), !dbg !15 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %e.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem0.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 0, !dbg !16 +// CHECK:STDOUT: %.loc16_21.1 = load i32, ptr %tuple.elem0.loc16.tuple.elem, align 4, !dbg !16 +// CHECK:STDOUT: %.loc16_21.2.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 0, !dbg !16 +// CHECK:STDOUT: store i32 %.loc16_21.1, ptr %.loc16_21.2.array.index, align 4, !dbg !16 +// CHECK:STDOUT: %tuple.elem1.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 1, !dbg !16 +// CHECK:STDOUT: %.loc16_21.4 = load i32, ptr %tuple.elem1.loc16.tuple.elem, align 4, !dbg !16 +// CHECK:STDOUT: %.loc16_21.5.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 1, !dbg !16 +// CHECK:STDOUT: store i32 %.loc16_21.4, ptr %.loc16_21.5.array.index, align 4, !dbg !16 +// CHECK:STDOUT: %tuple.elem2.loc16.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %d.var, i32 0, i32 2, !dbg !16 +// CHECK:STDOUT: %.loc16_21.7 = load i32, ptr %tuple.elem2.loc16.tuple.elem, align 4, !dbg !16 +// CHECK:STDOUT: %.loc16_21.8.array.index = getelementptr inbounds [3 x i32], ptr %e.var, i32 0, i64 2, !dbg !16 +// CHECK:STDOUT: store i32 %.loc16_21.7, ptr %.loc16_21.8.array.index, align 4, !dbg !16 +// CHECK:STDOUT: ret void, !dbg !17 // 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 nocapture) #0 +// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0 +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder i32 1, { 0, 2, 1, 3, 4, 5, 6, 7 } +// 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 nounwind willreturn memory(argmem: readwrite) } +// 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} @@ -82,15 +93,11 @@ fn Run() { // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 21, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 21, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 7, scope: !4) -// CHECK:STDOUT: !14 = !DILocation(line: 14, column: 20, scope: !4) -// CHECK:STDOUT: !15 = !DILocation(line: 14, column: 3, scope: !4) -// CHECK:STDOUT: !16 = !DILocation(line: 15, column: 7, scope: !4) -// CHECK:STDOUT: !17 = !DILocation(line: 15, column: 28, scope: !4) -// CHECK:STDOUT: !18 = !DILocation(line: 15, column: 3, scope: !4) -// CHECK:STDOUT: !19 = !DILocation(line: 16, column: 7, scope: !4) -// CHECK:STDOUT: !20 = !DILocation(line: 16, column: 21, scope: !4) -// CHECK:STDOUT: !21 = !DILocation(line: 11, column: 1, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 21, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 20, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !14 = !DILocation(line: 15, column: 28, scope: !4) +// CHECK:STDOUT: !15 = !DILocation(line: 15, column: 3, scope: !4) +// CHECK:STDOUT: !16 = !DILocation(line: 16, column: 21, scope: !4) +// CHECK:STDOUT: !17 = !DILocation(line: 11, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/basics/numeric_literals.carbon b/toolchain/lower/testdata/basics/numeric_literals.carbon index e630627b3974..ee9d8c92778f 100644 --- a/toolchain/lower/testdata/basics/numeric_literals.carbon +++ b/toolchain/lower/testdata/basics/numeric_literals.carbon @@ -36,29 +36,36 @@ fn F() { // CHECK:STDOUT: define void @_CF.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %ints.var = alloca [4 x i32], align 4, !dbg !7 +// CHECK:STDOUT: %floats.var = alloca [6 x double], align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %ints.var), !dbg !7 // CHECK:STDOUT: %.loc19_3.3.array.index = getelementptr inbounds [4 x i32], ptr %ints.var, i32 0, i64 0, !dbg !8 // CHECK:STDOUT: %.loc19_3.6.array.index = getelementptr inbounds [4 x i32], ptr %ints.var, i32 0, i64 1, !dbg !8 // CHECK:STDOUT: %.loc19_3.9.array.index = getelementptr inbounds [4 x i32], ptr %ints.var, i32 0, i64 2, !dbg !8 // CHECK:STDOUT: %.loc19_3.12.array.index = getelementptr inbounds [4 x i32], ptr %ints.var, i32 0, i64 3, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %ints.var, ptr align 4 @array.1.loc19_4, i64 16, i1 false), !dbg !9 -// CHECK:STDOUT: %floats.var = alloca [6 x double], align 8, !dbg !10 -// CHECK:STDOUT: %.loc27_3.2.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 0, !dbg !11 -// CHECK:STDOUT: %.loc27_3.4.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 1, !dbg !11 -// CHECK:STDOUT: %.loc27_3.6.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 2, !dbg !11 -// CHECK:STDOUT: %.loc27_3.8.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 3, !dbg !11 -// CHECK:STDOUT: %.loc27_3.10.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 4, !dbg !11 -// CHECK:STDOUT: %.loc27_3.12.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 5, !dbg !11 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %floats.var, ptr align 8 @array.2.loc27_4, i64 48, i1 false), !dbg !12 -// CHECK:STDOUT: ret void, !dbg !13 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 48, ptr %floats.var), !dbg !7 +// CHECK:STDOUT: %.loc27_3.2.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 0, !dbg !10 +// CHECK:STDOUT: %.loc27_3.4.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 1, !dbg !10 +// CHECK:STDOUT: %.loc27_3.6.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 2, !dbg !10 +// CHECK:STDOUT: %.loc27_3.8.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 3, !dbg !10 +// CHECK:STDOUT: %.loc27_3.10.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 4, !dbg !10 +// CHECK:STDOUT: %.loc27_3.12.array.index = getelementptr inbounds [6 x double], ptr %floats.var, i32 0, i64 5, !dbg !10 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %floats.var, ptr align 8 @array.2.loc27_4, i64 48, i1 false), !dbg !11 +// CHECK:STDOUT: ret void, !dbg !12 // 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 nocapture) #0 +// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0 +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } // CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 1, 0 } // CHECK:STDOUT: -// CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// 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} @@ -73,7 +80,6 @@ fn F() { // CHECK:STDOUT: !7 = !DILocation(line: 14, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 14, column: 24, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 14, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 20, column: 7, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 20, column: 26, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 20, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 11, column: 1, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 20, column: 26, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 20, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 11, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/builtins/no_prelude/types.carbon b/toolchain/lower/testdata/builtins/no_prelude/types.carbon index 539f67f01978..4c1f2d5f4d9c 100644 --- a/toolchain/lower/testdata/builtins/no_prelude/types.carbon +++ b/toolchain/lower/testdata/builtins/no_prelude/types.carbon @@ -26,14 +26,25 @@ fn F() { // CHECK:STDOUT: define void @_CF.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %i.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %f.var = alloca double, align 8, !dbg !7 +// CHECK:STDOUT: %b.var = alloca i1, align 1, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %i.var), !dbg !7 // CHECK:STDOUT: store i32 0, ptr %i.var, align 4, !dbg !8 -// CHECK:STDOUT: %f.var = alloca double, align 8, !dbg !9 -// CHECK:STDOUT: store double 0.000000e+00, ptr %f.var, align 8, !dbg !10 -// CHECK:STDOUT: %b.var = alloca i1, align 1, !dbg !11 -// CHECK:STDOUT: store i1 false, ptr %b.var, align 1, !dbg !12 -// CHECK:STDOUT: ret void, !dbg !13 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %f.var), !dbg !7 +// CHECK:STDOUT: store double 0.000000e+00, ptr %f.var, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 1, ptr %b.var), !dbg !7 +// CHECK:STDOUT: store i1 false, ptr %b.var, align 1, !dbg !10 +// CHECK:STDOUT: ret void, !dbg !11 // 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 nocapture) #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: @@ -46,8 +57,6 @@ fn F() { // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 18, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 18, column: 3, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 19, column: 7, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 19, column: 3, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 20, column: 7, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 20, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 17, column: 1, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 19, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 20, column: 3, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 17, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/class/adapt.carbon b/toolchain/lower/testdata/class/adapt.carbon index 996cfb1a043f..14b616e3efbb 100644 --- a/toolchain/lower/testdata/class/adapt.carbon +++ b/toolchain/lower/testdata/class/adapt.carbon @@ -80,6 +80,7 @@ fn DoStuff(a: Int) -> Int { // CHECK:STDOUT: define i32 @_CUse.Main() !dbg !15 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %pa.var = alloca { i32, i32 }, align 8, !dbg !16 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %pa.var), !dbg !16 // CHECK:STDOUT: call void @_CMake.PairAdapter.Main(ptr %pa.var), !dbg !17 // CHECK:STDOUT: %GetB.call = call i32 @_CGetB.PairAdapter.Main(ptr %pa.var), !dbg !18 // CHECK:STDOUT: ret i32 %GetB.call, !dbg !19 @@ -88,7 +89,11 @@ fn DoStuff(a: Int) -> Int { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #1 +// 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/class/basic.carbon b/toolchain/lower/testdata/class/basic.carbon index 97a1858eecb7..cbd22bcad30b 100644 --- a/toolchain/lower/testdata/class/basic.carbon +++ b/toolchain/lower/testdata/class/basic.carbon @@ -28,11 +28,21 @@ fn Run() { // CHECK:STDOUT: define void @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %c.var = alloca { i32, ptr }, align 8, !dbg !7 -// CHECK:STDOUT: %d.var = alloca { i32, ptr }, align 8, !dbg !8 -// CHECK:STDOUT: call void @_CF.Main(ptr %d.var, ptr %c.var), !dbg !9 -// CHECK:STDOUT: ret void, !dbg !10 +// CHECK:STDOUT: %d.var = alloca { i32, ptr }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %c.var), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %d.var), !dbg !7 +// CHECK:STDOUT: call void @_CF.Main(ptr %d.var, ptr %c.var), !dbg !8 +// CHECK:STDOUT: ret void, !dbg !9 // 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 nocapture) #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} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -44,6 +54,5 @@ fn Run() { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 19, column: 7, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 20, column: 7, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 20, column: 14, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 18, column: 1, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 20, column: 14, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 18, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/class/convert.carbon b/toolchain/lower/testdata/class/convert.carbon index f76d1d609e16..61d2b4046bd0 100644 --- a/toolchain/lower/testdata/class/convert.carbon +++ b/toolchain/lower/testdata/class/convert.carbon @@ -43,6 +43,7 @@ fn DoIt() { // CHECK:STDOUT: define void @_CDoIt.Main() !dbg !11 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %w.var = alloca { i32 }, align 8, !dbg !12 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %w.var), !dbg !12 // CHECK:STDOUT: %.loc22_31.3.n = getelementptr inbounds nuw { i32 }, ptr %w.var, i32 0, i32 0, !dbg !13 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %w.var, ptr align 4 @IntWrapper.val.loc22_32, i64 4, i1 false), !dbg !14 // CHECK:STDOUT: %Convert.call = call i32 @"_CConvert.IntWrapper.Main:ImplicitAs.Core"(ptr %w.var), !dbg !15 @@ -50,10 +51,14 @@ fn DoIt() { // CHECK:STDOUT: ret void, !dbg !17 // 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 nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #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 nocapture writeonly, ptr noalias nocapture readonly, 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/class/field.carbon b/toolchain/lower/testdata/class/field.carbon index 1eee8359db20..741b13c64af5 100644 --- a/toolchain/lower/testdata/class/field.carbon +++ b/toolchain/lower/testdata/class/field.carbon @@ -39,6 +39,7 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !10 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %c.var = alloca { i32, ptr }, align 8, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %c.var), !dbg !11 // CHECK:STDOUT: %.loc22_4.a = getelementptr inbounds nuw { i32, ptr }, ptr %c.var, i32 0, i32 0, !dbg !12 // CHECK:STDOUT: store i32 1, ptr %.loc22_4.a, align 4, !dbg !12 // CHECK:STDOUT: %.loc23.b = getelementptr inbounds nuw { i32, ptr }, ptr %c.var, i32 0, i32 1, !dbg !13 @@ -47,6 +48,11 @@ fn Run() -> i32 { // CHECK:STDOUT: ret i32 %F.call, !dbg !15 // 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 nocapture) #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/class/virtual.carbon b/toolchain/lower/testdata/class/virtual.carbon index a7b57135dd86..82e37a764c47 100644 --- a/toolchain/lower/testdata/class/virtual.carbon +++ b/toolchain/lower/testdata/class/virtual.carbon @@ -79,19 +79,30 @@ fn Fn() { // CHECK:STDOUT: define void @_CCreate.Create() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %b.var = alloca {}, align 8, !dbg !7 -// CHECK:STDOUT: %i.var = alloca { ptr, {} }, align 8, !dbg !8 -// CHECK:STDOUT: %d.var = alloca { { ptr, {} } }, align 8, !dbg !9 -// CHECK:STDOUT: ret void, !dbg !10 +// CHECK:STDOUT: %i.var = alloca { ptr, {} }, align 8, !dbg !7 +// CHECK:STDOUT: %d.var = alloca { { ptr, {} } }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %b.var), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %i.var), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %d.var), !dbg !7 +// CHECK:STDOUT: ret void, !dbg !8 // CHECK:STDOUT: } // CHECK:STDOUT: -// CHECK:STDOUT: define void @_CUse.Create(ptr %v) !dbg !11 { +// CHECK:STDOUT: define void @_CUse.Create(ptr %v) !dbg !9 { // CHECK:STDOUT: entry: -// CHECK:STDOUT: call void @_CFn.Intermediate.Classes(), !dbg !12 -// CHECK:STDOUT: ret void, !dbg !13 +// CHECK:STDOUT: call void @_CFn.Intermediate.Classes(), !dbg !10 +// CHECK:STDOUT: ret void, !dbg !11 // CHECK:STDOUT: } // CHECK:STDOUT: // CHECK:STDOUT: declare void @_CFn.Intermediate.Classes() // 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 nocapture) #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: @@ -103,12 +114,10 @@ fn Fn() { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 7, column: 7, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 8, column: 7, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 9, column: 7, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 6, column: 1, scope: !4) -// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "Use", linkageName: "_CUse.Create", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2) -// CHECK:STDOUT: !12 = !DILocation(line: 13, column: 3, scope: !11) -// CHECK:STDOUT: !13 = !DILocation(line: 12, column: 1, scope: !11) +// CHECK:STDOUT: !8 = !DILocation(line: 6, column: 1, scope: !4) +// CHECK:STDOUT: !9 = distinct !DISubprogram(name: "Use", linkageName: "_CUse.Create", scope: null, file: !3, line: 12, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 3, scope: !9) +// CHECK:STDOUT: !11 = !DILocation(line: 12, column: 1, scope: !9) // CHECK:STDOUT: ; ModuleID = 'member_init.carbon' // CHECK:STDOUT: source_filename = "member_init.carbon" // CHECK:STDOUT: @@ -117,18 +126,28 @@ fn Fn() { // CHECK:STDOUT: define void @_CFn.MemberInit() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %i.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %v.var = alloca { ptr, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %i.var), !dbg !7 // CHECK:STDOUT: store i32 3, ptr %i.var, align 4, !dbg !8 -// CHECK:STDOUT: %v.var = alloca { ptr, i32 }, align 8, !dbg !9 -// CHECK:STDOUT: %.loc12_24.2.vptr = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 0, !dbg !10 -// CHECK:STDOUT: store ptr null, ptr %.loc12_24.2.vptr, align 8, !dbg !10 -// CHECK:STDOUT: %.loc12_23 = load i32, ptr %i.var, align 4, !dbg !11 -// CHECK:STDOUT: %.loc12_24.5.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !10 -// CHECK:STDOUT: store i32 %.loc12_23, ptr %.loc12_24.5.m, align 4, !dbg !10 -// CHECK:STDOUT: %.loc15_4.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !12 -// CHECK:STDOUT: store i32 5, ptr %.loc15_4.m, align 4, !dbg !12 -// CHECK:STDOUT: ret void, !dbg !13 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %v.var), !dbg !7 +// CHECK:STDOUT: %.loc12_24.2.vptr = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 0, !dbg !9 +// CHECK:STDOUT: store ptr null, ptr %.loc12_24.2.vptr, align 8, !dbg !9 +// CHECK:STDOUT: %.loc12_23 = load i32, ptr %i.var, align 4, !dbg !10 +// CHECK:STDOUT: %.loc12_24.5.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !9 +// CHECK:STDOUT: store i32 %.loc12_23, ptr %.loc12_24.5.m, align 4, !dbg !9 +// CHECK:STDOUT: %.loc15_4.m = getelementptr inbounds nuw { ptr, i32 }, ptr %v.var, i32 0, i32 1, !dbg !11 +// CHECK:STDOUT: store i32 5, ptr %.loc15_4.m, align 4, !dbg !11 +// CHECK:STDOUT: ret void, !dbg !12 // 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 nocapture) #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} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -141,8 +160,7 @@ fn Fn() { // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 10, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 10, column: 3, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 12, column: 7, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 12, column: 17, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 12, column: 23, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 15, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 9, column: 1, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 12, column: 17, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 12, column: 23, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 15, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 9, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/function/call/empty_struct.carbon b/toolchain/lower/testdata/function/call/empty_struct.carbon index c320614ff2da..99e62bb29767 100644 --- a/toolchain/lower/testdata/function/call/empty_struct.carbon +++ b/toolchain/lower/testdata/function/call/empty_struct.carbon @@ -27,10 +27,16 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !8 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %b.var = alloca {}, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %b.var), !dbg !9 // CHECK:STDOUT: call void @_CEcho.Main(), !dbg !10 // CHECK:STDOUT: ret void, !dbg !11 // 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 nocapture) #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/call/empty_tuple.carbon b/toolchain/lower/testdata/function/call/empty_tuple.carbon index c05c94f1d634..4775599234b2 100644 --- a/toolchain/lower/testdata/function/call/empty_tuple.carbon +++ b/toolchain/lower/testdata/function/call/empty_tuple.carbon @@ -27,10 +27,16 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !8 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %b.var = alloca {}, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %b.var), !dbg !9 // CHECK:STDOUT: call void @_CEcho.Main(), !dbg !10 // CHECK:STDOUT: ret void, !dbg !11 // 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 nocapture) #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/call/i32.carbon b/toolchain/lower/testdata/function/call/i32.carbon index 3e4a9e4914a2..8457c4375463 100644 --- a/toolchain/lower/testdata/function/call/i32.carbon +++ b/toolchain/lower/testdata/function/call/i32.carbon @@ -27,11 +27,17 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !8 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %b.var = alloca i32, align 4, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %b.var), !dbg !9 // CHECK:STDOUT: %Echo.call = call i32 @_CEcho.Main(i32 1), !dbg !10 // CHECK:STDOUT: store i32 %Echo.call, ptr %b.var, align 4, !dbg !11 // CHECK:STDOUT: ret void, !dbg !12 // 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 nocapture) #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/call/implicit_empty_tuple_as_arg.carbon b/toolchain/lower/testdata/function/call/implicit_empty_tuple_as_arg.carbon index 2f0e16773a8c..18f7ed1931a0 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 @@ -33,12 +33,18 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !10 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca {}, align 8, !dbg !11 +// 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: %.loc17_23.1.temp = alloca {}, align 8, !dbg !12 // CHECK:STDOUT: call void @_CBar.Main(), !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 nocapture) #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/call/return_implicit.carbon b/toolchain/lower/testdata/function/call/return_implicit.carbon index a1e3c1a51126..2fba16122b3d 100644 --- a/toolchain/lower/testdata/function/call/return_implicit.carbon +++ b/toolchain/lower/testdata/function/call/return_implicit.carbon @@ -27,10 +27,16 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !8 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %b.var = alloca {}, align 8, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %b.var), !dbg !9 // CHECK:STDOUT: call void @_CMakeImplicitEmptyTuple.Main(), !dbg !10 // CHECK:STDOUT: ret void, !dbg !11 // 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 nocapture) #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/call/var_param.carbon b/toolchain/lower/testdata/function/call/var_param.carbon index 0ebccd348889..1790ca4befc3 100644 --- a/toolchain/lower/testdata/function/call/var_param.carbon +++ b/toolchain/lower/testdata/function/call/var_param.carbon @@ -26,12 +26,18 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !8 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca i32, align 4, !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %a.var), !dbg !9 // CHECK:STDOUT: store i32 0, ptr %a.var, align 4, !dbg !10 // CHECK:STDOUT: %.loc15 = load i32, ptr %a.var, align 4, !dbg !11 // CHECK:STDOUT: call void @_CDoNothing.Main(i32 %.loc15), !dbg !12 // CHECK:STDOUT: ret void, !dbg !13 // 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 nocapture) #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.carbon b/toolchain/lower/testdata/function/generic/call.carbon index cd9db70a609d..d6d39409ac43 100644 --- a/toolchain/lower/testdata/function/generic/call.carbon +++ b/toolchain/lower/testdata/function/generic/call.carbon @@ -36,21 +36,27 @@ fn G() { // CHECK:STDOUT: define void @_CG.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %c.var = alloca {}, align 8, !dbg !7 +// CHECK:STDOUT: %d.var = alloca {}, align 8, !dbg !7 +// CHECK:STDOUT: %n.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %c.var), !dbg !7 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %c.var, ptr align 1 @C.val.loc18_16, i64 0, i1 false), !dbg !8 -// CHECK:STDOUT: %d.var = alloca {}, align 8, !dbg !9 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %d.var, ptr align 1 @D.val.loc19_16, i64 0, i1 false), !dbg !10 -// CHECK:STDOUT: %n.var = alloca i32, align 4, !dbg !11 -// CHECK:STDOUT: store i32 0, ptr %n.var, align 4, !dbg !12 -// CHECK:STDOUT: call void @_CF.Main.40(ptr %c.var), !dbg !13 -// CHECK:STDOUT: call void @_CF.Main.41(ptr %d.var), !dbg !14 -// CHECK:STDOUT: %.loc24 = load i32, ptr %n.var, align 4, !dbg !15 -// CHECK:STDOUT: call void @_CF.Main.42(i32 %.loc24), !dbg !16 -// CHECK:STDOUT: call void @_CF.Main.43(%type zeroinitializer), !dbg !17 -// CHECK:STDOUT: ret void, !dbg !18 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %d.var), !dbg !7 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %d.var, ptr align 1 @D.val.loc19_16, i64 0, i1 false), !dbg !9 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %n.var), !dbg !7 +// CHECK:STDOUT: store i32 0, ptr %n.var, align 4, !dbg !10 +// CHECK:STDOUT: call void @_CF.Main.40(ptr %c.var), !dbg !11 +// CHECK:STDOUT: call void @_CF.Main.41(ptr %d.var), !dbg !12 +// CHECK:STDOUT: %.loc24 = load i32, ptr %n.var, align 4, !dbg !13 +// CHECK:STDOUT: call void @_CF.Main.42(i32 %.loc24), !dbg !14 +// CHECK:STDOUT: call void @_CF.Main.43(%type zeroinitializer), !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 nocapture) #0 +// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0 +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 // CHECK:STDOUT: // CHECK:STDOUT: declare void @_CF.Main.40(ptr) // CHECK:STDOUT: @@ -61,9 +67,11 @@ fn G() { // CHECK:STDOUT: declare void @_CF.Main.43(%type) // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 } // CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 1, 0 } // CHECK:STDOUT: -// CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// 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} @@ -77,13 +85,11 @@ fn G() { // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 18, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 18, column: 3, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 19, column: 7, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 19, column: 3, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 20, column: 7, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 20, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 22, column: 3, scope: !4) -// CHECK:STDOUT: !14 = !DILocation(line: 23, column: 3, scope: !4) -// CHECK:STDOUT: !15 = !DILocation(line: 24, column: 5, scope: !4) -// CHECK:STDOUT: !16 = !DILocation(line: 24, column: 3, scope: !4) -// CHECK:STDOUT: !17 = !DILocation(line: 25, column: 3, scope: !4) -// CHECK:STDOUT: !18 = !DILocation(line: 17, column: 1, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 19, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 20, column: 3, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 22, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 23, column: 3, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 24, column: 5, scope: !4) +// CHECK:STDOUT: !14 = !DILocation(line: 24, column: 3, scope: !4) +// CHECK:STDOUT: !15 = !DILocation(line: 25, column: 3, scope: !4) +// CHECK:STDOUT: !16 = !DILocation(line: 17, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/function/generic/call_method.carbon b/toolchain/lower/testdata/function/generic/call_method.carbon index 74fd79f9ef03..f8cd4c132ecd 100644 --- a/toolchain/lower/testdata/function/generic/call_method.carbon +++ b/toolchain/lower/testdata/function/generic/call_method.carbon @@ -28,20 +28,29 @@ fn CallF() -> i32 { // CHECK:STDOUT: define i32 @_CCallF.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %c.var = alloca {}, align 8, !dbg !7 +// CHECK:STDOUT: %n.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %c.var), !dbg !7 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %c.var, ptr align 1 @C.val.loc18_16, i64 0, i1 false), !dbg !8 -// CHECK:STDOUT: %n.var = alloca i32, align 4, !dbg !9 -// CHECK:STDOUT: store i32 0, ptr %n.var, align 4, !dbg !10 -// CHECK:STDOUT: %.loc20_14 = load i32, ptr %n.var, align 4, !dbg !11 -// CHECK:STDOUT: %F.call = call i32 @_CF.C.Main.40(ptr %c.var, i32 %.loc20_14), !dbg !12 -// CHECK:STDOUT: ret i32 %F.call, !dbg !13 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %n.var), !dbg !7 +// CHECK:STDOUT: store i32 0, ptr %n.var, align 4, !dbg !9 +// CHECK:STDOUT: %.loc20_14 = load i32, ptr %n.var, align 4, !dbg !10 +// CHECK:STDOUT: %F.call = call i32 @_CF.C.Main.40(ptr %c.var, i32 %.loc20_14), !dbg !11 +// CHECK:STDOUT: ret i32 %F.call, !dbg !12 // 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 nocapture) #0 +// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0 +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 // CHECK:STDOUT: // CHECK:STDOUT: declare i32 @_CF.C.Main.40(ptr, i32) // CHECK:STDOUT: -// CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// 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: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} @@ -55,8 +64,7 @@ fn CallF() -> i32 { // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 18, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 18, column: 3, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 19, column: 7, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 19, column: 3, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 20, column: 14, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 20, column: 10, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 20, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 19, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 20, column: 14, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 20, column: 10, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 20, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/index/array_element_access.carbon b/toolchain/lower/testdata/index/array_element_access.carbon index e1c7ae7c38c4..7f05b2a1b7ef 100644 --- a/toolchain/lower/testdata/index/array_element_access.carbon +++ b/toolchain/lower/testdata/index/array_element_access.carbon @@ -43,6 +43,10 @@ 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 !13 +// CHECK:STDOUT: %c.var = alloca i32, align 4, !dbg !13 +// CHECK:STDOUT: %d.var = alloca i32, align 4, !dbg !13 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %a.var), !dbg !13 // CHECK:STDOUT: %.loc15_23.1.temp = alloca { i32, i32 }, align 8, !dbg !14 // CHECK:STDOUT: call void @_CA.Main(ptr %.loc15_23.1.temp), !dbg !14 // CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc15_23.1.temp, i32 0, i32 0, !dbg !14 @@ -53,29 +57,35 @@ fn Run() { // CHECK:STDOUT: %.loc15_23.6 = load i32, ptr %tuple.elem1.tuple.elem, align 4, !dbg !14 // CHECK:STDOUT: %.loc15_23.7.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i64 1, !dbg !14 // CHECK:STDOUT: store i32 %.loc15_23.6, ptr %.loc15_23.7.array.index, align 4, !dbg !14 -// CHECK:STDOUT: %b.var = alloca i32, align 4, !dbg !15 -// CHECK:STDOUT: store i32 1, ptr %b.var, align 4, !dbg !16 -// CHECK:STDOUT: %c.var = alloca i32, align 4, !dbg !17 -// CHECK:STDOUT: %.loc17_18 = load i32, ptr %b.var, align 4, !dbg !18 -// CHECK:STDOUT: %.loc17_19.1.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i32 %.loc17_18, !dbg !19 -// CHECK:STDOUT: %.loc17_19.2 = load i32, ptr %.loc17_19.1.array.index, align 4, !dbg !19 -// CHECK:STDOUT: store i32 %.loc17_19.2, ptr %c.var, align 4, !dbg !20 -// CHECK:STDOUT: %d.var = alloca i32, align 4, !dbg !21 -// CHECK:STDOUT: %.loc18_18.1.temp = alloca [2 x i32], align 4, !dbg !22 -// CHECK:STDOUT: call void @_CB.Main(ptr %.loc18_18.1.temp), !dbg !22 -// CHECK:STDOUT: %.loc18_21.1.array.index = getelementptr inbounds [2 x i32], ptr %.loc18_18.1.temp, i32 0, i32 1, !dbg !22 -// CHECK:STDOUT: %.loc18_21.2 = load i32, ptr %.loc18_21.1.array.index, align 4, !dbg !22 -// CHECK:STDOUT: store i32 %.loc18_21.2, ptr %d.var, align 4, !dbg !23 -// CHECK:STDOUT: ret void, !dbg !24 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %b.var), !dbg !13 +// 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 !13 +// CHECK:STDOUT: %.loc17_18 = load i32, ptr %b.var, align 4, !dbg !16 +// CHECK:STDOUT: %.loc17_19.1.array.index = getelementptr inbounds [2 x i32], ptr %a.var, i32 0, i32 %.loc17_18, !dbg !17 +// CHECK:STDOUT: %.loc17_19.2 = load i32, ptr %.loc17_19.1.array.index, align 4, !dbg !17 +// CHECK:STDOUT: store i32 %.loc17_19.2, ptr %c.var, align 4, !dbg !18 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %d.var), !dbg !13 +// CHECK:STDOUT: %.loc18_18.1.temp = alloca [2 x i32], align 4, !dbg !19 +// CHECK:STDOUT: call void @_CB.Main(ptr %.loc18_18.1.temp), !dbg !19 +// CHECK:STDOUT: %.loc18_21.1.array.index = getelementptr inbounds [2 x i32], ptr %.loc18_18.1.temp, i32 0, i32 1, !dbg !19 +// CHECK:STDOUT: %.loc18_21.2 = load i32, ptr %.loc18_21.1.array.index, align 4, !dbg !19 +// CHECK:STDOUT: store i32 %.loc18_21.2, ptr %d.var, align 4, !dbg !20 +// CHECK:STDOUT: ret void, !dbg !21 // 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 nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #1 +// CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder i32 1, { 0, 1, 4, 6, 7, 2, 3, 5, 8, 9, 10 } // 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: // 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} @@ -95,13 +105,10 @@ fn Run() { // CHECK:STDOUT: !12 = distinct !DISubprogram(name: "Run", linkageName: "main", scope: null, file: !3, line: 14, type: !5, spFlags: DISPFlagDefinition, unit: !2) // CHECK:STDOUT: !13 = !DILocation(line: 15, column: 7, scope: !12) // CHECK:STDOUT: !14 = !DILocation(line: 15, column: 21, scope: !12) -// CHECK:STDOUT: !15 = !DILocation(line: 16, column: 7, scope: !12) -// CHECK:STDOUT: !16 = !DILocation(line: 16, column: 3, scope: !12) -// CHECK:STDOUT: !17 = !DILocation(line: 17, column: 7, scope: !12) -// CHECK:STDOUT: !18 = !DILocation(line: 17, column: 18, scope: !12) -// CHECK:STDOUT: !19 = !DILocation(line: 17, column: 16, scope: !12) -// CHECK:STDOUT: !20 = !DILocation(line: 17, column: 3, scope: !12) -// CHECK:STDOUT: !21 = !DILocation(line: 18, column: 7, scope: !12) -// CHECK:STDOUT: !22 = !DILocation(line: 18, column: 16, scope: !12) -// CHECK:STDOUT: !23 = !DILocation(line: 18, column: 3, scope: !12) -// CHECK:STDOUT: !24 = !DILocation(line: 14, column: 1, scope: !12) +// CHECK:STDOUT: !15 = !DILocation(line: 16, column: 3, scope: !12) +// CHECK:STDOUT: !16 = !DILocation(line: 17, column: 18, scope: !12) +// CHECK:STDOUT: !17 = !DILocation(line: 17, column: 16, scope: !12) +// CHECK:STDOUT: !18 = !DILocation(line: 17, column: 3, scope: !12) +// CHECK:STDOUT: !19 = !DILocation(line: 18, column: 16, scope: !12) +// CHECK:STDOUT: !20 = !DILocation(line: 18, column: 3, scope: !12) +// CHECK:STDOUT: !21 = !DILocation(line: 14, column: 1, scope: !12) diff --git a/toolchain/lower/testdata/let/tuple.carbon b/toolchain/lower/testdata/let/tuple.carbon index d3bc14c2814f..2828aa23e094 100644 --- a/toolchain/lower/testdata/let/tuple.carbon +++ b/toolchain/lower/testdata/let/tuple.carbon @@ -24,55 +24,63 @@ fn F() -> i32 { // CHECK:STDOUT: define i32 @_CF.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca { i32, i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: %b.var = alloca { i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %a.var), !dbg !7 // CHECK:STDOUT: %tuple.elem0.loc12.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: %tuple.elem1.loc12.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 1, !dbg !8 // CHECK:STDOUT: %tuple.elem2.loc12.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 2, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a.var, ptr align 4 @tuple.1.loc12_37, i64 12, i1 false), !dbg !9 -// CHECK:STDOUT: %b.var = alloca { i32, i32 }, align 8, !dbg !10 -// CHECK:STDOUT: %tuple.elem0.loc13.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: %tuple.elem1.loc13.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %b.var, ptr align 4 @tuple.2.loc13_29, i64 8, i1 false), !dbg !12 -// CHECK:STDOUT: %tuple.elem0.loc14_43.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 0, !dbg !13 -// CHECK:STDOUT: %.loc14_43.1 = load i32, ptr %tuple.elem0.loc14_43.tuple.elem, align 4, !dbg !13 -// CHECK:STDOUT: %tuple.elem1.loc14_43.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 1, !dbg !13 -// CHECK:STDOUT: %.loc14_43.2 = load i32, ptr %tuple.elem1.loc14_43.tuple.elem, align 4, !dbg !13 -// CHECK:STDOUT: %tuple.elem2.loc14.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 2, !dbg !13 -// CHECK:STDOUT: %.loc14_43.3 = load i32, ptr %tuple.elem2.loc14.tuple.elem, align 4, !dbg !13 -// CHECK:STDOUT: %tuple.loc14_43 = alloca { i32, i32, i32 }, align 8, !dbg !13 -// CHECK:STDOUT: %tuple.loc14_431 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc14_43, i32 0, i32 0, !dbg !13 -// CHECK:STDOUT: store i32 %.loc14_43.1, ptr %tuple.loc14_431, align 4, !dbg !13 -// CHECK:STDOUT: %tuple.loc14_432 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc14_43, i32 0, i32 1, !dbg !13 -// CHECK:STDOUT: store i32 %.loc14_43.2, ptr %tuple.loc14_432, align 4, !dbg !13 -// CHECK:STDOUT: %tuple.loc14_433 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc14_43, i32 0, i32 2, !dbg !13 -// CHECK:STDOUT: store i32 %.loc14_43.3, ptr %tuple.loc14_433, align 4, !dbg !13 -// CHECK:STDOUT: %tuple.elem0.loc14_46.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 0, !dbg !14 -// CHECK:STDOUT: %.loc14_46.1 = load i32, ptr %tuple.elem0.loc14_46.tuple.elem, align 4, !dbg !14 -// CHECK:STDOUT: %tuple.elem1.loc14_46.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 1, !dbg !14 -// CHECK:STDOUT: %.loc14_46.2 = load i32, ptr %tuple.elem1.loc14_46.tuple.elem, align 4, !dbg !14 -// CHECK:STDOUT: %tuple.loc14_46 = alloca { i32, i32 }, align 8, !dbg !14 -// CHECK:STDOUT: %tuple.loc14_464 = getelementptr inbounds nuw { i32, i32 }, ptr %tuple.loc14_46, i32 0, i32 0, !dbg !14 -// CHECK:STDOUT: store i32 %.loc14_46.1, ptr %tuple.loc14_464, align 4, !dbg !14 -// CHECK:STDOUT: %tuple.loc14_465 = getelementptr inbounds nuw { i32, i32 }, ptr %tuple.loc14_46, i32 0, i32 1, !dbg !14 -// CHECK:STDOUT: store i32 %.loc14_46.2, ptr %tuple.loc14_465, align 4, !dbg !14 -// CHECK:STDOUT: %tuple.loc14_47 = alloca { ptr, ptr }, align 8, !dbg !15 -// CHECK:STDOUT: %tuple.loc14_476 = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc14_47, i32 0, i32 0, !dbg !15 -// CHECK:STDOUT: store ptr %tuple.loc14_43, ptr %tuple.loc14_476, align 8, !dbg !15 -// CHECK:STDOUT: %tuple.loc14_477 = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc14_47, i32 0, i32 1, !dbg !15 -// CHECK:STDOUT: store ptr %tuple.loc14_46, ptr %tuple.loc14_477, align 8, !dbg !15 -// CHECK:STDOUT: %tuple.elem1.loc15_11.tuple.elem = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc14_47, i32 0, i32 1, !dbg !16 -// CHECK:STDOUT: %tuple.elem1.loc15_11.tuple.elem.load = load ptr, ptr %tuple.elem1.loc15_11.tuple.elem, align 8, !dbg !16 -// CHECK:STDOUT: %tuple.elem1.loc15_13.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %tuple.elem1.loc15_11.tuple.elem.load, i32 0, i32 1, !dbg !16 -// CHECK:STDOUT: %tuple.elem1.loc15_13.tuple.elem.load = load i32, ptr %tuple.elem1.loc15_13.tuple.elem, align 4, !dbg !16 -// CHECK:STDOUT: ret i32 %tuple.elem1.loc15_13.tuple.elem.load, !dbg !17 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %b.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem0.loc13.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: %tuple.elem1.loc13.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %b.var, ptr align 4 @tuple.2.loc13_29, i64 8, i1 false), !dbg !11 +// CHECK:STDOUT: %tuple.elem0.loc14_43.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 0, !dbg !12 +// CHECK:STDOUT: %.loc14_43.1 = load i32, ptr %tuple.elem0.loc14_43.tuple.elem, align 4, !dbg !12 +// CHECK:STDOUT: %tuple.elem1.loc14_43.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 1, !dbg !12 +// CHECK:STDOUT: %.loc14_43.2 = load i32, ptr %tuple.elem1.loc14_43.tuple.elem, align 4, !dbg !12 +// CHECK:STDOUT: %tuple.elem2.loc14.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 2, !dbg !12 +// CHECK:STDOUT: %.loc14_43.3 = load i32, ptr %tuple.elem2.loc14.tuple.elem, align 4, !dbg !12 +// CHECK:STDOUT: %tuple.loc14_43 = alloca { i32, i32, i32 }, align 8, !dbg !12 +// CHECK:STDOUT: %tuple.loc14_431 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc14_43, i32 0, i32 0, !dbg !12 +// CHECK:STDOUT: store i32 %.loc14_43.1, ptr %tuple.loc14_431, align 4, !dbg !12 +// CHECK:STDOUT: %tuple.loc14_432 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc14_43, i32 0, i32 1, !dbg !12 +// CHECK:STDOUT: store i32 %.loc14_43.2, ptr %tuple.loc14_432, align 4, !dbg !12 +// CHECK:STDOUT: %tuple.loc14_433 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc14_43, i32 0, i32 2, !dbg !12 +// CHECK:STDOUT: store i32 %.loc14_43.3, ptr %tuple.loc14_433, align 4, !dbg !12 +// CHECK:STDOUT: %tuple.elem0.loc14_46.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 0, !dbg !13 +// CHECK:STDOUT: %.loc14_46.1 = load i32, ptr %tuple.elem0.loc14_46.tuple.elem, align 4, !dbg !13 +// CHECK:STDOUT: %tuple.elem1.loc14_46.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 1, !dbg !13 +// CHECK:STDOUT: %.loc14_46.2 = load i32, ptr %tuple.elem1.loc14_46.tuple.elem, align 4, !dbg !13 +// CHECK:STDOUT: %tuple.loc14_46 = alloca { i32, i32 }, align 8, !dbg !13 +// CHECK:STDOUT: %tuple.loc14_464 = getelementptr inbounds nuw { i32, i32 }, ptr %tuple.loc14_46, i32 0, i32 0, !dbg !13 +// CHECK:STDOUT: store i32 %.loc14_46.1, ptr %tuple.loc14_464, align 4, !dbg !13 +// CHECK:STDOUT: %tuple.loc14_465 = getelementptr inbounds nuw { i32, i32 }, ptr %tuple.loc14_46, i32 0, i32 1, !dbg !13 +// CHECK:STDOUT: store i32 %.loc14_46.2, ptr %tuple.loc14_465, align 4, !dbg !13 +// CHECK:STDOUT: %tuple.loc14_47 = alloca { ptr, ptr }, align 8, !dbg !14 +// CHECK:STDOUT: %tuple.loc14_476 = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc14_47, i32 0, i32 0, !dbg !14 +// CHECK:STDOUT: store ptr %tuple.loc14_43, ptr %tuple.loc14_476, align 8, !dbg !14 +// CHECK:STDOUT: %tuple.loc14_477 = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc14_47, i32 0, i32 1, !dbg !14 +// CHECK:STDOUT: store ptr %tuple.loc14_46, ptr %tuple.loc14_477, align 8, !dbg !14 +// CHECK:STDOUT: %tuple.elem1.loc15_11.tuple.elem = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc14_47, i32 0, i32 1, !dbg !15 +// CHECK:STDOUT: %tuple.elem1.loc15_11.tuple.elem.load = load ptr, ptr %tuple.elem1.loc15_11.tuple.elem, align 8, !dbg !15 +// CHECK:STDOUT: %tuple.elem1.loc15_13.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %tuple.elem1.loc15_11.tuple.elem.load, i32 0, i32 1, !dbg !15 +// CHECK:STDOUT: %tuple.elem1.loc15_13.tuple.elem.load = load i32, ptr %tuple.elem1.loc15_13.tuple.elem, align 4, !dbg !15 +// CHECK:STDOUT: ret i32 %tuple.elem1.loc15_13.tuple.elem.load, !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 nocapture) #0 +// CHECK:STDOUT: // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) -// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0 +// CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 // CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder i32 1, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 11, 13, 14 } +// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 1, 0 } // CHECK:STDOUT: uselistorder ptr @llvm.memcpy.p0.p0.i64, { 1, 0 } // CHECK:STDOUT: -// CHECK:STDOUT: attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } +// 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} @@ -87,11 +95,10 @@ fn F() -> i32 { // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 28, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 23, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 43, scope: !4) -// CHECK:STDOUT: !14 = !DILocation(line: 14, column: 46, scope: !4) -// CHECK:STDOUT: !15 = !DILocation(line: 14, column: 42, scope: !4) -// CHECK:STDOUT: !16 = !DILocation(line: 15, column: 10, scope: !4) -// CHECK:STDOUT: !17 = !DILocation(line: 15, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 23, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 43, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 46, scope: !4) +// CHECK:STDOUT: !14 = !DILocation(line: 14, column: 42, scope: !4) +// CHECK:STDOUT: !15 = !DILocation(line: 15, column: 10, scope: !4) +// CHECK:STDOUT: !16 = !DILocation(line: 15, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/operators/assignment.carbon b/toolchain/lower/testdata/operators/assignment.carbon index 9bf90cd976df..c2939c144318 100644 --- a/toolchain/lower/testdata/operators/assignment.carbon +++ b/toolchain/lower/testdata/operators/assignment.carbon @@ -23,19 +23,28 @@ fn Main() { // CHECK:STDOUT: define void @_CMain.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %b.var = alloca { i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %a.var), !dbg !7 // CHECK:STDOUT: store i32 12, ptr %a.var, align 4, !dbg !8 // CHECK:STDOUT: store i32 9, ptr %a.var, align 4, !dbg !9 -// CHECK:STDOUT: %b.var = alloca { i32, i32 }, align 8, !dbg !10 -// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %b.var, ptr align 4 @tuple.loc15_5, i64 8, i1 false), !dbg !12 -// CHECK:STDOUT: ret void, !dbg !13 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %b.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %b.var, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %b.var, ptr align 4 @tuple.loc15_5, i64 8, i1 false), !dbg !11 +// CHECK:STDOUT: ret void, !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 nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #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 nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #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 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} @@ -50,7 +59,6 @@ fn Main() { // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 3, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 14, column: 7, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 15, column: 7, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 15, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 11, column: 1, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 15, column: 7, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 15, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 11, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/pointer/address_of_field.carbon b/toolchain/lower/testdata/pointer/address_of_field.carbon index 9603bb98412e..9867c7bb6319 100644 --- a/toolchain/lower/testdata/pointer/address_of_field.carbon +++ b/toolchain/lower/testdata/pointer/address_of_field.carbon @@ -25,6 +25,7 @@ fn F() { // CHECK:STDOUT: define void @_CF.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %s.var = alloca { i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %s.var), !dbg !7 // CHECK:STDOUT: %.loc14_46.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %s.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: %.loc14_46.6.b = getelementptr inbounds nuw { i32, i32 }, ptr %s.var, i32 0, i32 1, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %s.var, ptr align 4 @struct.loc14_47, i64 8, i1 false), !dbg !9 @@ -33,10 +34,14 @@ fn F() { // CHECK:STDOUT: ret void, !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 nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #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 nocapture writeonly, ptr noalias nocapture readonly, 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/pointer/address_of_unused.carbon b/toolchain/lower/testdata/pointer/address_of_unused.carbon index 0b0f94d4fee0..11ac24b16adc 100644 --- a/toolchain/lower/testdata/pointer/address_of_unused.carbon +++ b/toolchain/lower/testdata/pointer/address_of_unused.carbon @@ -19,10 +19,16 @@ fn F() { // CHECK:STDOUT: define void @_CF.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %n.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %n.var), !dbg !7 // CHECK:STDOUT: store i32 0, ptr %n.var, align 4, !dbg !8 // CHECK:STDOUT: ret void, !dbg !9 // 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 nocapture) #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/pointer/basic.carbon b/toolchain/lower/testdata/pointer/basic.carbon index 3b3aade1fd60..e4b4048ace4a 100644 --- a/toolchain/lower/testdata/pointer/basic.carbon +++ b/toolchain/lower/testdata/pointer/basic.carbon @@ -29,11 +29,17 @@ fn F() -> i32 { // CHECK:STDOUT: define i32 @_CF.Main() !dbg !9 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %n.var = alloca i32, align 4, !dbg !10 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %n.var), !dbg !10 // CHECK:STDOUT: store i32 0, ptr %n.var, align 4, !dbg !11 // CHECK:STDOUT: %G.call = call i32 @_CG.Main(ptr %n.var), !dbg !12 // CHECK:STDOUT: ret i32 %G.call, !dbg !13 // 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 nocapture) #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/pointer/pointer_to_pointer.carbon b/toolchain/lower/testdata/pointer/pointer_to_pointer.carbon index e68f2c18f7c7..436b6775b4ce 100644 --- a/toolchain/lower/testdata/pointer/pointer_to_pointer.carbon +++ b/toolchain/lower/testdata/pointer/pointer_to_pointer.carbon @@ -21,18 +21,29 @@ fn F(p: i32**) -> i32 { // CHECK:STDOUT: define i32 @_CF.Main(ptr %p) !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca ptr, align 8, !dbg !7 +// CHECK:STDOUT: %b.var = alloca ptr, align 8, !dbg !7 +// CHECK:STDOUT: %c.var = alloca ptr, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %a.var), !dbg !7 // CHECK:STDOUT: store ptr %p, ptr %a.var, align 8, !dbg !8 -// CHECK:STDOUT: %b.var = alloca ptr, align 8, !dbg !9 -// CHECK:STDOUT: %.loc13_17.2 = load ptr, ptr %p, align 8, !dbg !10 -// CHECK:STDOUT: store ptr %.loc13_17.2, ptr %b.var, align 8, !dbg !11 -// CHECK:STDOUT: %c.var = alloca ptr, align 8, !dbg !12 -// CHECK:STDOUT: store ptr %b.var, ptr %c.var, align 8, !dbg !13 -// CHECK:STDOUT: %.loc15_12 = load ptr, ptr %c.var, align 8, !dbg !14 -// CHECK:STDOUT: %.loc15_11.2 = load ptr, ptr %.loc15_12, align 8, !dbg !15 -// CHECK:STDOUT: %.loc15_10.2 = load i32, ptr %.loc15_11.2, align 4, !dbg !16 -// CHECK:STDOUT: ret i32 %.loc15_10.2, !dbg !17 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %b.var), !dbg !7 +// CHECK:STDOUT: %.loc13_17.2 = load ptr, ptr %p, align 8, !dbg !9 +// CHECK:STDOUT: store ptr %.loc13_17.2, ptr %b.var, align 8, !dbg !10 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %c.var), !dbg !7 +// CHECK:STDOUT: store ptr %b.var, ptr %c.var, align 8, !dbg !11 +// CHECK:STDOUT: %.loc15_12 = load ptr, ptr %c.var, align 8, !dbg !12 +// CHECK:STDOUT: %.loc15_11.2 = load ptr, ptr %.loc15_12, align 8, !dbg !13 +// CHECK:STDOUT: %.loc15_10.2 = load i32, ptr %.loc15_11.2, align 4, !dbg !14 +// CHECK:STDOUT: ret i32 %.loc15_10.2, !dbg !15 // 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 nocapture) #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: @@ -45,12 +56,10 @@ fn F(p: i32**) -> i32 { // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 17, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 7, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 3, scope: !4) -// CHECK:STDOUT: !14 = !DILocation(line: 15, column: 12, scope: !4) -// CHECK:STDOUT: !15 = !DILocation(line: 15, column: 11, scope: !4) -// CHECK:STDOUT: !16 = !DILocation(line: 15, column: 10, scope: !4) -// CHECK:STDOUT: !17 = !DILocation(line: 15, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 17, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 3, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 15, column: 12, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 15, column: 11, scope: !4) +// CHECK:STDOUT: !14 = !DILocation(line: 15, column: 10, scope: !4) +// CHECK:STDOUT: !15 = !DILocation(line: 15, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/return/return_var_byval.carbon b/toolchain/lower/testdata/return/return_var_byval.carbon index 55c420829238..f869897c2e9b 100644 --- a/toolchain/lower/testdata/return/return_var_byval.carbon +++ b/toolchain/lower/testdata/return/return_var_byval.carbon @@ -19,11 +19,17 @@ fn Main() -> i32 { // CHECK:STDOUT: define i32 @_CMain.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %x.var), !dbg !7 // CHECK:STDOUT: store i32 0, ptr %x.var, align 4, !dbg !8 // CHECK:STDOUT: %.loc12_16 = load i32, ptr %x.var, align 4, !dbg !7 // CHECK:STDOUT: ret i32 %.loc12_16, !dbg !9 // 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 nocapture) #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/return/var.carbon b/toolchain/lower/testdata/return/var.carbon index 271544d634ef..5b420fa421c6 100644 --- a/toolchain/lower/testdata/return/var.carbon +++ b/toolchain/lower/testdata/return/var.carbon @@ -19,11 +19,17 @@ fn Main() -> i32 { // CHECK:STDOUT: define i32 @_CMain.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %x.var), !dbg !7 // CHECK:STDOUT: store i32 0, ptr %x.var, align 4, !dbg !8 // CHECK:STDOUT: %.loc13 = load i32, ptr %x.var, align 4, !dbg !9 // CHECK:STDOUT: ret i32 %.loc13, !dbg !10 // 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 nocapture) #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/struct/empty.carbon b/toolchain/lower/testdata/struct/empty.carbon index 3cc6457fc6c0..0f158717de21 100644 --- a/toolchain/lower/testdata/struct/empty.carbon +++ b/toolchain/lower/testdata/struct/empty.carbon @@ -20,10 +20,20 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca {}, align 8, !dbg !7 -// CHECK:STDOUT: %y.var = alloca {}, align 8, !dbg !8 -// CHECK:STDOUT: ret i32 0, !dbg !9 +// CHECK:STDOUT: %y.var = alloca {}, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %x.var), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %y.var), !dbg !7 +// CHECK:STDOUT: ret i32 0, !dbg !8 // 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 nocapture) #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} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -35,5 +45,4 @@ fn Run() -> i32 { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 14, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/struct/member_access.carbon b/toolchain/lower/testdata/struct/member_access.carbon index 4a476f38ee8b..d5e6b9bdc7dd 100644 --- a/toolchain/lower/testdata/struct/member_access.carbon +++ b/toolchain/lower/testdata/struct/member_access.carbon @@ -23,23 +23,34 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca { double, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: %y.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %z.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 16, ptr %x.var), !dbg !7 // CHECK:STDOUT: %.loc12_48.2.a = getelementptr inbounds nuw { double, i32 }, ptr %x.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: %.loc12_48.5.b = getelementptr inbounds nuw { double, i32 }, ptr %x.var, i32 0, i32 1, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 %x.var, ptr align 8 @struct.loc12_49, i64 16, i1 false), !dbg !9 -// CHECK:STDOUT: %y.var = alloca i32, align 4, !dbg !10 -// CHECK:STDOUT: %.loc13_17.1.b = getelementptr inbounds nuw { double, i32 }, ptr %x.var, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: %.loc13_17.2 = load i32, ptr %.loc13_17.1.b, align 4, !dbg !11 -// CHECK:STDOUT: store i32 %.loc13_17.2, ptr %y.var, align 4, !dbg !12 -// CHECK:STDOUT: %z.var = alloca i32, align 4, !dbg !13 -// CHECK:STDOUT: %.loc14 = load i32, ptr %y.var, align 4, !dbg !14 -// CHECK:STDOUT: store i32 %.loc14, ptr %z.var, align 4, !dbg !15 -// CHECK:STDOUT: ret i32 0, !dbg !16 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %y.var), !dbg !7 +// CHECK:STDOUT: %.loc13_17.1.b = getelementptr inbounds nuw { double, i32 }, ptr %x.var, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: %.loc13_17.2 = load i32, ptr %.loc13_17.1.b, align 4, !dbg !10 +// CHECK:STDOUT: store i32 %.loc13_17.2, ptr %y.var, align 4, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %z.var), !dbg !7 +// CHECK:STDOUT: %.loc14 = load i32, ptr %y.var, align 4, !dbg !12 +// CHECK:STDOUT: store i32 %.loc14, ptr %z.var, align 4, !dbg !13 +// CHECK:STDOUT: ret i32 0, !dbg !14 // 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 nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #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 nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder i32 1, { 1, 3, 0, 2, 4, 5 } +// 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: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} @@ -54,10 +65,8 @@ fn Run() -> i32 { // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 31, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 16, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 7, scope: !4) -// CHECK:STDOUT: !14 = !DILocation(line: 14, column: 16, scope: !4) -// CHECK:STDOUT: !15 = !DILocation(line: 14, column: 3, scope: !4) -// CHECK:STDOUT: !16 = !DILocation(line: 15, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 16, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 16, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !14 = !DILocation(line: 15, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/struct/nested_struct_in_place.carbon b/toolchain/lower/testdata/struct/nested_struct_in_place.carbon index b110ded86f14..3221d60ec410 100644 --- a/toolchain/lower/testdata/struct/nested_struct_in_place.carbon +++ b/toolchain/lower/testdata/struct/nested_struct_in_place.carbon @@ -22,6 +22,7 @@ fn G() { // CHECK:STDOUT: define void @_CG.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %v.var = alloca { { i32, i32, i32 }, { i32, i32, i32 } }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 24, ptr %v.var), !dbg !7 // CHECK:STDOUT: %.loc14_74.1.a = getelementptr inbounds nuw { { i32, i32, i32 }, { i32, i32, i32 } }, ptr %v.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_74.1.a), !dbg !9 // CHECK:STDOUT: %.loc14_74.2.b = getelementptr inbounds nuw { { i32, i32, i32 }, { i32, i32, i32 } }, ptr %v.var, i32 0, i32 1, !dbg !8 @@ -29,6 +30,11 @@ fn G() { // CHECK:STDOUT: ret void, !dbg !11 // 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 nocapture) #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/struct/one_entry.carbon b/toolchain/lower/testdata/struct/one_entry.carbon index b55ed350498c..f9c6251eedfa 100644 --- a/toolchain/lower/testdata/struct/one_entry.carbon +++ b/toolchain/lower/testdata/struct/one_entry.carbon @@ -20,15 +20,25 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca { i32 }, align 8, !dbg !7 +// CHECK:STDOUT: %y.var = alloca { i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %x.var), !dbg !7 // CHECK:STDOUT: store { i32 } { i32 4 }, ptr %x.var, align 4, !dbg !8 -// CHECK:STDOUT: %y.var = alloca { i32 }, align 8, !dbg !9 -// CHECK:STDOUT: %.loc13_22.1.a = getelementptr inbounds nuw { i32 }, ptr %x.var, i32 0, i32 0, !dbg !10 -// CHECK:STDOUT: %.loc13_22.2 = load i32, ptr %.loc13_22.1.a, align 4, !dbg !10 -// CHECK:STDOUT: %.loc13_22.3.struct.init = insertvalue { i32 } poison, i32 %.loc13_22.2, 0, !dbg !10 -// CHECK:STDOUT: store { i32 } %.loc13_22.3.struct.init, ptr %y.var, align 4, !dbg !11 -// CHECK:STDOUT: ret i32 0, !dbg !12 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %y.var), !dbg !7 +// CHECK:STDOUT: %.loc13_22.1.a = getelementptr inbounds nuw { i32 }, ptr %x.var, i32 0, i32 0, !dbg !9 +// CHECK:STDOUT: %.loc13_22.2 = load i32, ptr %.loc13_22.1.a, align 4, !dbg !9 +// CHECK:STDOUT: %.loc13_22.3.struct.init = insertvalue { i32 } poison, i32 %.loc13_22.2, 0, !dbg !9 +// CHECK:STDOUT: store { i32 } %.loc13_22.3.struct.init, ptr %y.var, align 4, !dbg !10 +// CHECK:STDOUT: ret i32 0, !dbg !11 // 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 nocapture) #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} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -41,7 +51,6 @@ fn Run() -> i32 { // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 22, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 22, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 3, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/struct/two_entries.carbon b/toolchain/lower/testdata/struct/two_entries.carbon index 7a0e4b48aa85..7de730c09152 100644 --- a/toolchain/lower/testdata/struct/two_entries.carbon +++ b/toolchain/lower/testdata/struct/two_entries.carbon @@ -22,25 +22,35 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca { i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: %y.var = alloca { i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %x.var), !dbg !7 // CHECK:STDOUT: %.loc12_46.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: %.loc12_46.6.b = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 1, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x.var, ptr align 4 @struct.loc12_47, i64 8, i1 false), !dbg !9 -// CHECK:STDOUT: %y.var = alloca { i32, i32 }, align 8, !dbg !10 -// CHECK:STDOUT: %.loc13_31.1.a = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: %.loc13_31.2 = load i32, ptr %.loc13_31.1.a, align 4, !dbg !11 -// CHECK:STDOUT: %.loc13_31.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %y.var, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: store i32 %.loc13_31.2, ptr %.loc13_31.3.a, align 4, !dbg !11 -// CHECK:STDOUT: %.loc13_31.5.b = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: %.loc13_31.6 = load i32, ptr %.loc13_31.5.b, align 4, !dbg !11 -// CHECK:STDOUT: %.loc13_31.7.b = getelementptr inbounds nuw { i32, i32 }, ptr %y.var, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: store i32 %.loc13_31.6, ptr %.loc13_31.7.b, align 4, !dbg !11 -// CHECK:STDOUT: ret i32 0, !dbg !12 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %y.var), !dbg !7 +// CHECK:STDOUT: %.loc13_31.1.a = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: %.loc13_31.2 = load i32, ptr %.loc13_31.1.a, align 4, !dbg !10 +// CHECK:STDOUT: %.loc13_31.3.a = getelementptr inbounds nuw { i32, i32 }, ptr %y.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: store i32 %.loc13_31.2, ptr %.loc13_31.3.a, align 4, !dbg !10 +// CHECK:STDOUT: %.loc13_31.5.b = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: %.loc13_31.6 = load i32, ptr %.loc13_31.5.b, align 4, !dbg !10 +// CHECK:STDOUT: %.loc13_31.7.b = getelementptr inbounds nuw { i32, i32 }, ptr %y.var, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: store i32 %.loc13_31.6, ptr %.loc13_31.7.b, align 4, !dbg !10 +// CHECK:STDOUT: ret i32 0, !dbg !11 // 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 nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #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 nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder i32 1, { 0, 1, 3, 2, 4, 5 } +// 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: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} @@ -55,6 +65,5 @@ fn Run() -> i32 { // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 31, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 31, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 31, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/tuple/access/element_access.carbon b/toolchain/lower/testdata/tuple/access/element_access.carbon index e8258eab2f31..0abbe868e86b 100644 --- a/toolchain/lower/testdata/tuple/access/element_access.carbon +++ b/toolchain/lower/testdata/tuple/access/element_access.carbon @@ -23,25 +23,36 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca { i32, i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: %b.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %c.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %a.var), !dbg !7 // CHECK:STDOUT: %tuple.elem0.loc12.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 1, !dbg !8 // CHECK:STDOUT: %tuple.elem2.loc12.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 2, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %a.var, ptr align 4 @tuple.loc12_37, i64 12, i1 false), !dbg !9 -// CHECK:STDOUT: %b.var = alloca i32, align 4, !dbg !10 -// CHECK:STDOUT: %tuple.elem0.loc13.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: %.loc13 = load i32, ptr %tuple.elem0.loc13.tuple.elem, align 4, !dbg !11 -// CHECK:STDOUT: store i32 %.loc13, ptr %b.var, align 4, !dbg !12 -// CHECK:STDOUT: %c.var = alloca i32, align 4, !dbg !13 -// CHECK:STDOUT: %tuple.elem2.loc14.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 2, !dbg !14 -// CHECK:STDOUT: %.loc14 = load i32, ptr %tuple.elem2.loc14.tuple.elem, align 4, !dbg !14 -// CHECK:STDOUT: store i32 %.loc14, ptr %c.var, align 4, !dbg !15 -// CHECK:STDOUT: ret i32 0, !dbg !16 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %b.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem0.loc13.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: %.loc13 = load i32, ptr %tuple.elem0.loc13.tuple.elem, align 4, !dbg !10 +// CHECK:STDOUT: store i32 %.loc13, ptr %b.var, align 4, !dbg !11 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %c.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem2.loc14.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 2, !dbg !12 +// CHECK:STDOUT: %.loc14 = load i32, ptr %tuple.elem2.loc14.tuple.elem, align 4, !dbg !12 +// CHECK:STDOUT: store i32 %.loc14, ptr %c.var, align 4, !dbg !13 +// CHECK:STDOUT: ret i32 0, !dbg !14 // 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 nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #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 nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder i32 1, { 2, 0, 1, 3, 4 } +// 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: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} @@ -56,10 +67,8 @@ fn Run() -> i32 { // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 28, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 16, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 7, scope: !4) -// CHECK:STDOUT: !14 = !DILocation(line: 14, column: 16, scope: !4) -// CHECK:STDOUT: !15 = !DILocation(line: 14, column: 3, scope: !4) -// CHECK:STDOUT: !16 = !DILocation(line: 15, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 16, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 16, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !14 = !DILocation(line: 15, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/tuple/access/return_value_access.carbon b/toolchain/lower/testdata/tuple/access/return_value_access.carbon index a3fece7f8240..c2b1f7851204 100644 --- a/toolchain/lower/testdata/tuple/access/return_value_access.carbon +++ b/toolchain/lower/testdata/tuple/access/return_value_access.carbon @@ -30,6 +30,7 @@ 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: %.loc14_18.1.temp = alloca { i32, i32 }, align 8, !dbg !11 // CHECK:STDOUT: call void @_CF.Main(ptr %.loc14_18.1.temp), !dbg !11 // CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %.loc14_18.1.temp, i32 0, i32 1, !dbg !11 @@ -41,7 +42,11 @@ fn Run() { // CHECK:STDOUT: ; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite) // CHECK:STDOUT: declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #1 +// 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/tuple/empty.carbon b/toolchain/lower/testdata/tuple/empty.carbon index 8a2ddfb3a323..c534e2319106 100644 --- a/toolchain/lower/testdata/tuple/empty.carbon +++ b/toolchain/lower/testdata/tuple/empty.carbon @@ -20,10 +20,20 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca {}, align 8, !dbg !7 -// CHECK:STDOUT: %y.var = alloca {}, align 8, !dbg !8 -// CHECK:STDOUT: ret i32 0, !dbg !9 +// CHECK:STDOUT: %y.var = alloca {}, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %x.var), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 0, ptr %y.var), !dbg !7 +// CHECK:STDOUT: ret i32 0, !dbg !8 // 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 nocapture) #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} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -35,5 +45,4 @@ fn Run() -> i32 { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 14, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/tuple/nested_tuple_in_place.carbon b/toolchain/lower/testdata/tuple/nested_tuple_in_place.carbon index 2f51438d5571..421aeafca671 100644 --- a/toolchain/lower/testdata/tuple/nested_tuple_in_place.carbon +++ b/toolchain/lower/testdata/tuple/nested_tuple_in_place.carbon @@ -22,6 +22,7 @@ fn G() { // CHECK:STDOUT: define void @_CG.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %v.var = alloca { { i32, i32, i32 }, { i32, i32, i32 } }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 24, ptr %v.var), !dbg !7 // CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { { i32, i32, i32 }, { i32, i32, i32 } }, ptr %v.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: call void @_CF.Main(ptr %tuple.elem0.tuple.elem), !dbg !9 // CHECK:STDOUT: %tuple.elem1.tuple.elem = getelementptr inbounds nuw { { i32, i32, i32 }, { i32, i32, i32 } }, ptr %v.var, i32 0, i32 1, !dbg !8 @@ -29,6 +30,11 @@ fn G() { // CHECK:STDOUT: ret void, !dbg !11 // 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 nocapture) #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/one_entry.carbon b/toolchain/lower/testdata/tuple/one_entry.carbon index 48bfa2b06b99..1bf5b1b525cc 100644 --- a/toolchain/lower/testdata/tuple/one_entry.carbon +++ b/toolchain/lower/testdata/tuple/one_entry.carbon @@ -20,17 +20,25 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca { i32 }, align 8, !dbg !7 +// CHECK:STDOUT: %y.var = alloca { i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %x.var), !dbg !7 // CHECK:STDOUT: store { i32 } { i32 1 }, ptr %x.var, align 4, !dbg !8 -// CHECK:STDOUT: %y.var = alloca { i32 }, align 8, !dbg !9 -// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32 }, ptr %x.var, i32 0, i32 0, !dbg !10 -// CHECK:STDOUT: %.loc13_20.1 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !10 -// CHECK:STDOUT: %.loc13_20.2.tuple.init = insertvalue { i32 } poison, i32 %.loc13_20.1, 0, !dbg !10 -// CHECK:STDOUT: store { i32 } %.loc13_20.2.tuple.init, ptr %y.var, align 4, !dbg !11 -// CHECK:STDOUT: ret i32 0, !dbg !12 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %y.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem0.tuple.elem = getelementptr inbounds nuw { i32 }, ptr %x.var, i32 0, i32 0, !dbg !9 +// CHECK:STDOUT: %.loc13_20.1 = load i32, ptr %tuple.elem0.tuple.elem, align 4, !dbg !9 +// CHECK:STDOUT: %.loc13_20.2.tuple.init = insertvalue { i32 } poison, i32 %.loc13_20.1, 0, !dbg !9 +// CHECK:STDOUT: store { i32 } %.loc13_20.2.tuple.init, ptr %y.var, align 4, !dbg !10 +// CHECK:STDOUT: ret i32 0, !dbg !11 // 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 nocapture) #0 +// CHECK:STDOUT: // CHECK:STDOUT: ; uselistorder directives -// CHECK:STDOUT: uselistorder i32 1, { 0, 2, 1 } +// CHECK:STDOUT: uselistorder i32 1, { 2, 0, 1 } +// 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} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} @@ -44,7 +52,6 @@ fn Run() -> i32 { // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 20, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 3, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 20, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 3, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/tuple/two_entries.carbon b/toolchain/lower/testdata/tuple/two_entries.carbon index bd6597f81b37..d600d4855d3e 100644 --- a/toolchain/lower/testdata/tuple/two_entries.carbon +++ b/toolchain/lower/testdata/tuple/two_entries.carbon @@ -22,25 +22,35 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca { i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: %y.var = alloca { i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %x.var), !dbg !7 // CHECK:STDOUT: %tuple.elem0.loc12.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 0, !dbg !8 // CHECK:STDOUT: %tuple.elem1.loc12.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 1, !dbg !8 // CHECK:STDOUT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %x.var, ptr align 4 @tuple.loc12_30, i64 8, i1 false), !dbg !9 -// CHECK:STDOUT: %y.var = alloca { i32, i32 }, align 8, !dbg !10 -// CHECK:STDOUT: %tuple.elem0.loc13_23.1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: %.loc13_23.1 = load i32, ptr %tuple.elem0.loc13_23.1.tuple.elem, align 4, !dbg !11 -// CHECK:STDOUT: %tuple.elem0.loc13_23.2.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %y.var, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: store i32 %.loc13_23.1, ptr %tuple.elem0.loc13_23.2.tuple.elem, align 4, !dbg !11 -// CHECK:STDOUT: %tuple.elem1.loc13_23.1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: %.loc13_23.3 = load i32, ptr %tuple.elem1.loc13_23.1.tuple.elem, align 4, !dbg !11 -// CHECK:STDOUT: %tuple.elem1.loc13_23.2.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %y.var, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: store i32 %.loc13_23.3, ptr %tuple.elem1.loc13_23.2.tuple.elem, align 4, !dbg !11 -// CHECK:STDOUT: ret i32 0, !dbg !12 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 8, ptr %y.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem0.loc13_23.1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: %.loc13_23.1 = load i32, ptr %tuple.elem0.loc13_23.1.tuple.elem, align 4, !dbg !10 +// CHECK:STDOUT: %tuple.elem0.loc13_23.2.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %y.var, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: store i32 %.loc13_23.1, ptr %tuple.elem0.loc13_23.2.tuple.elem, align 4, !dbg !10 +// CHECK:STDOUT: %tuple.elem1.loc13_23.1.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %x.var, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: %.loc13_23.3 = load i32, ptr %tuple.elem1.loc13_23.1.tuple.elem, align 4, !dbg !10 +// CHECK:STDOUT: %tuple.elem1.loc13_23.2.tuple.elem = getelementptr inbounds nuw { i32, i32 }, ptr %y.var, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: store i32 %.loc13_23.3, ptr %tuple.elem1.loc13_23.2.tuple.elem, align 4, !dbg !10 +// CHECK:STDOUT: ret i32 0, !dbg !11 // 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 nocapture writeonly, ptr noalias nocapture readonly, 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 nocapture) #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 nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #1 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder i32 1, { 0, 1, 3, 2, 4 } +// 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: attributes #1 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } // CHECK:STDOUT: // CHECK:STDOUT: !llvm.module.flags = !{!0, !1} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} @@ -55,6 +65,5 @@ fn Run() -> i32 { // CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) // CHECK:STDOUT: !8 = !DILocation(line: 12, column: 23, scope: !4) // CHECK:STDOUT: !9 = !DILocation(line: 12, column: 3, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 7, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 13, column: 23, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 14, column: 3, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 13, column: 23, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 3, scope: !4) diff --git a/toolchain/lower/testdata/tuple/value_formation.carbon b/toolchain/lower/testdata/tuple/value_formation.carbon index bf6cc885e54c..1779b7573712 100644 --- a/toolchain/lower/testdata/tuple/value_formation.carbon +++ b/toolchain/lower/testdata/tuple/value_formation.carbon @@ -24,42 +24,52 @@ fn F() { // CHECK:STDOUT: define void @_CF.Main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %a.var = alloca { i32, i32, i32 }, align 8, !dbg !7 -// CHECK:STDOUT: %b.var = alloca { i32, i32, i32 }, align 8, !dbg !8 -// CHECK:STDOUT: %tuple.elem0.loc16_6.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 0, !dbg !9 -// CHECK:STDOUT: %.loc16_6.1 = load i32, ptr %tuple.elem0.loc16_6.tuple.elem, align 4, !dbg !9 -// CHECK:STDOUT: %tuple.elem1.loc16_6.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 1, !dbg !9 -// CHECK:STDOUT: %.loc16_6.2 = load i32, ptr %tuple.elem1.loc16_6.tuple.elem, align 4, !dbg !9 -// CHECK:STDOUT: %tuple.elem2.loc16_6.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 2, !dbg !9 -// CHECK:STDOUT: %.loc16_6.3 = load i32, ptr %tuple.elem2.loc16_6.tuple.elem, align 4, !dbg !9 -// CHECK:STDOUT: %tuple.loc16_6 = alloca { i32, i32, i32 }, align 8, !dbg !9 -// CHECK:STDOUT: %tuple.loc16_61 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_6, i32 0, i32 0, !dbg !9 -// CHECK:STDOUT: store i32 %.loc16_6.1, ptr %tuple.loc16_61, align 4, !dbg !9 -// CHECK:STDOUT: %tuple.loc16_62 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_6, i32 0, i32 1, !dbg !9 -// CHECK:STDOUT: store i32 %.loc16_6.2, ptr %tuple.loc16_62, align 4, !dbg !9 -// CHECK:STDOUT: %tuple.loc16_63 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_6, i32 0, i32 2, !dbg !9 -// CHECK:STDOUT: store i32 %.loc16_6.3, ptr %tuple.loc16_63, align 4, !dbg !9 -// CHECK:STDOUT: %tuple.elem0.loc16_9.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %b.var, i32 0, i32 0, !dbg !10 -// CHECK:STDOUT: %.loc16_9.1 = load i32, ptr %tuple.elem0.loc16_9.tuple.elem, align 4, !dbg !10 -// CHECK:STDOUT: %tuple.elem1.loc16_9.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %b.var, i32 0, i32 1, !dbg !10 -// CHECK:STDOUT: %.loc16_9.2 = load i32, ptr %tuple.elem1.loc16_9.tuple.elem, align 4, !dbg !10 -// CHECK:STDOUT: %tuple.elem2.loc16_9.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %b.var, i32 0, i32 2, !dbg !10 -// CHECK:STDOUT: %.loc16_9.3 = load i32, ptr %tuple.elem2.loc16_9.tuple.elem, align 4, !dbg !10 -// CHECK:STDOUT: %tuple.loc16_9 = alloca { i32, i32, i32 }, align 8, !dbg !10 -// CHECK:STDOUT: %tuple.loc16_94 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_9, i32 0, i32 0, !dbg !10 -// CHECK:STDOUT: store i32 %.loc16_9.1, ptr %tuple.loc16_94, align 4, !dbg !10 -// CHECK:STDOUT: %tuple.loc16_95 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_9, i32 0, i32 1, !dbg !10 -// CHECK:STDOUT: store i32 %.loc16_9.2, ptr %tuple.loc16_95, align 4, !dbg !10 -// CHECK:STDOUT: %tuple.loc16_96 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_9, i32 0, i32 2, !dbg !10 -// CHECK:STDOUT: store i32 %.loc16_9.3, ptr %tuple.loc16_96, align 4, !dbg !10 -// CHECK:STDOUT: %tuple.loc16_10 = alloca { ptr, ptr }, align 8, !dbg !11 -// CHECK:STDOUT: %tuple.loc16_107 = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc16_10, i32 0, i32 0, !dbg !11 -// CHECK:STDOUT: store ptr %tuple.loc16_6, ptr %tuple.loc16_107, align 8, !dbg !11 -// CHECK:STDOUT: %tuple.loc16_108 = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc16_10, i32 0, i32 1, !dbg !11 -// CHECK:STDOUT: store ptr %tuple.loc16_9, ptr %tuple.loc16_108, align 8, !dbg !11 -// CHECK:STDOUT: call void @_CG.Main(ptr %tuple.loc16_10), !dbg !12 -// CHECK:STDOUT: ret void, !dbg !13 +// CHECK:STDOUT: %b.var = alloca { i32, i32, i32 }, align 8, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %a.var), !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 12, ptr %b.var), !dbg !7 +// CHECK:STDOUT: %tuple.elem0.loc16_6.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 0, !dbg !8 +// CHECK:STDOUT: %.loc16_6.1 = load i32, ptr %tuple.elem0.loc16_6.tuple.elem, align 4, !dbg !8 +// CHECK:STDOUT: %tuple.elem1.loc16_6.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 1, !dbg !8 +// CHECK:STDOUT: %.loc16_6.2 = load i32, ptr %tuple.elem1.loc16_6.tuple.elem, align 4, !dbg !8 +// CHECK:STDOUT: %tuple.elem2.loc16_6.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %a.var, i32 0, i32 2, !dbg !8 +// CHECK:STDOUT: %.loc16_6.3 = load i32, ptr %tuple.elem2.loc16_6.tuple.elem, align 4, !dbg !8 +// CHECK:STDOUT: %tuple.loc16_6 = alloca { i32, i32, i32 }, align 8, !dbg !8 +// CHECK:STDOUT: %tuple.loc16_61 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_6, i32 0, i32 0, !dbg !8 +// CHECK:STDOUT: store i32 %.loc16_6.1, ptr %tuple.loc16_61, align 4, !dbg !8 +// CHECK:STDOUT: %tuple.loc16_62 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_6, i32 0, i32 1, !dbg !8 +// CHECK:STDOUT: store i32 %.loc16_6.2, ptr %tuple.loc16_62, align 4, !dbg !8 +// CHECK:STDOUT: %tuple.loc16_63 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_6, i32 0, i32 2, !dbg !8 +// CHECK:STDOUT: store i32 %.loc16_6.3, ptr %tuple.loc16_63, align 4, !dbg !8 +// CHECK:STDOUT: %tuple.elem0.loc16_9.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %b.var, i32 0, i32 0, !dbg !9 +// CHECK:STDOUT: %.loc16_9.1 = load i32, ptr %tuple.elem0.loc16_9.tuple.elem, align 4, !dbg !9 +// CHECK:STDOUT: %tuple.elem1.loc16_9.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %b.var, i32 0, i32 1, !dbg !9 +// CHECK:STDOUT: %.loc16_9.2 = load i32, ptr %tuple.elem1.loc16_9.tuple.elem, align 4, !dbg !9 +// CHECK:STDOUT: %tuple.elem2.loc16_9.tuple.elem = getelementptr inbounds nuw { i32, i32, i32 }, ptr %b.var, i32 0, i32 2, !dbg !9 +// CHECK:STDOUT: %.loc16_9.3 = load i32, ptr %tuple.elem2.loc16_9.tuple.elem, align 4, !dbg !9 +// CHECK:STDOUT: %tuple.loc16_9 = alloca { i32, i32, i32 }, align 8, !dbg !9 +// CHECK:STDOUT: %tuple.loc16_94 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_9, i32 0, i32 0, !dbg !9 +// CHECK:STDOUT: store i32 %.loc16_9.1, ptr %tuple.loc16_94, align 4, !dbg !9 +// CHECK:STDOUT: %tuple.loc16_95 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_9, i32 0, i32 1, !dbg !9 +// CHECK:STDOUT: store i32 %.loc16_9.2, ptr %tuple.loc16_95, align 4, !dbg !9 +// CHECK:STDOUT: %tuple.loc16_96 = getelementptr inbounds nuw { i32, i32, i32 }, ptr %tuple.loc16_9, i32 0, i32 2, !dbg !9 +// CHECK:STDOUT: store i32 %.loc16_9.3, ptr %tuple.loc16_96, align 4, !dbg !9 +// CHECK:STDOUT: %tuple.loc16_10 = alloca { ptr, ptr }, align 8, !dbg !10 +// CHECK:STDOUT: %tuple.loc16_107 = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc16_10, i32 0, i32 0, !dbg !10 +// CHECK:STDOUT: store ptr %tuple.loc16_6, ptr %tuple.loc16_107, align 8, !dbg !10 +// CHECK:STDOUT: %tuple.loc16_108 = getelementptr inbounds nuw { ptr, ptr }, ptr %tuple.loc16_10, i32 0, i32 1, !dbg !10 +// CHECK:STDOUT: store ptr %tuple.loc16_9, ptr %tuple.loc16_108, align 8, !dbg !10 +// CHECK:STDOUT: call void @_CG.Main(ptr %tuple.loc16_10), !dbg !11 +// CHECK:STDOUT: ret void, !dbg !12 // 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 nocapture) #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} // CHECK:STDOUT: !llvm.dbg.cu = !{!2} // CHECK:STDOUT: @@ -71,9 +81,8 @@ fn F() { // CHECK:STDOUT: !5 = !DISubroutineType(types: !6) // CHECK:STDOUT: !6 = !{} // CHECK:STDOUT: !7 = !DILocation(line: 14, column: 7, scope: !4) -// CHECK:STDOUT: !8 = !DILocation(line: 15, column: 7, scope: !4) -// CHECK:STDOUT: !9 = !DILocation(line: 16, column: 6, scope: !4) -// CHECK:STDOUT: !10 = !DILocation(line: 16, column: 9, scope: !4) -// CHECK:STDOUT: !11 = !DILocation(line: 16, column: 5, scope: !4) -// CHECK:STDOUT: !12 = !DILocation(line: 16, column: 3, scope: !4) -// CHECK:STDOUT: !13 = !DILocation(line: 13, column: 1, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 16, column: 6, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 16, column: 9, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 16, column: 5, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 16, column: 3, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 13, column: 1, scope: !4) diff --git a/toolchain/lower/testdata/var/local.carbon b/toolchain/lower/testdata/var/local.carbon index 6ceb441c60fc..a8396960bdff 100644 --- a/toolchain/lower/testdata/var/local.carbon +++ b/toolchain/lower/testdata/var/local.carbon @@ -19,11 +19,17 @@ fn Run() -> i32 { // CHECK:STDOUT: define i32 @main() !dbg !4 { // CHECK:STDOUT: entry: // CHECK:STDOUT: %x.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %x.var), !dbg !7 // CHECK:STDOUT: store i32 1, ptr %x.var, align 4, !dbg !8 // CHECK:STDOUT: %.loc13 = load i32, ptr %x.var, align 4, !dbg !9 // CHECK:STDOUT: ret i32 %.loc13, !dbg !10 // 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 nocapture) #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/var/nested.carbon b/toolchain/lower/testdata/var/nested.carbon new file mode 100644 index 000000000000..38d5778089d4 --- /dev/null +++ b/toolchain/lower/testdata/var/nested.carbon @@ -0,0 +1,75 @@ +// Part of the Carbon Language project, under the Apache License v2.0 with LLVM +// Exceptions. See /LICENSE for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// AUTOUPDATE +// TIP: To test this file alone, run: +// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/var/nested.carbon +// TIP: To dump output, run: +// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/var/nested.carbon + +fn Run() -> i32 { + var a: i32 = 1; + while (true) { + var b: i32 = a; + a = b; + } + return a; +} + +// CHECK:STDOUT: ; ModuleID = 'nested.carbon' +// CHECK:STDOUT: source_filename = "nested.carbon" +// CHECK:STDOUT: +// CHECK:STDOUT: define i32 @main() !dbg !4 { +// CHECK:STDOUT: entry: +// CHECK:STDOUT: %a.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: %b.var = alloca i32, align 4, !dbg !7 +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %a.var), !dbg !7 +// CHECK:STDOUT: store i32 1, ptr %a.var, align 4, !dbg !8 +// CHECK:STDOUT: br label %while.cond, !dbg !9 +// CHECK:STDOUT: +// CHECK:STDOUT: while.cond: ; preds = %while.body, %entry +// CHECK:STDOUT: br i1 true, label %while.body, label %while.done, !dbg !9 +// CHECK:STDOUT: +// CHECK:STDOUT: while.body: ; preds = %while.cond +// CHECK:STDOUT: call void @llvm.lifetime.start.p0(i64 4, ptr %b.var), !dbg !7 +// CHECK:STDOUT: %.loc14 = load i32, ptr %a.var, align 4, !dbg !10 +// CHECK:STDOUT: store i32 %.loc14, ptr %b.var, align 4, !dbg !11 +// CHECK:STDOUT: %.loc15 = load i32, ptr %b.var, align 4, !dbg !12 +// CHECK:STDOUT: store i32 %.loc15, ptr %a.var, align 4, !dbg !13 +// CHECK:STDOUT: br label %while.cond, !dbg !14 +// CHECK:STDOUT: +// CHECK:STDOUT: while.done: ; preds = %while.cond +// CHECK:STDOUT: %.loc17 = load i32, ptr %a.var, align 4, !dbg !15 +// CHECK:STDOUT: ret i32 %.loc17, !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 nocapture) #0 +// CHECK:STDOUT: +// CHECK:STDOUT: ; uselistorder directives +// CHECK:STDOUT: uselistorder i32 1, { 1, 0, 2 } +// 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} +// CHECK:STDOUT: !llvm.dbg.cu = !{!2} +// CHECK:STDOUT: +// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5} +// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3} +// CHECK:STDOUT: !2 = distinct !DICompileUnit(language: DW_LANG_C, file: !3, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug) +// CHECK:STDOUT: !3 = !DIFile(filename: "nested.carbon", directory: "") +// CHECK:STDOUT: !4 = distinct !DISubprogram(name: "Run", linkageName: "main", scope: null, file: !3, line: 11, type: !5, spFlags: DISPFlagDefinition, unit: !2) +// CHECK:STDOUT: !5 = !DISubroutineType(types: !6) +// CHECK:STDOUT: !6 = !{} +// CHECK:STDOUT: !7 = !DILocation(line: 12, column: 7, scope: !4) +// CHECK:STDOUT: !8 = !DILocation(line: 12, column: 3, scope: !4) +// CHECK:STDOUT: !9 = !DILocation(line: 13, column: 9, scope: !4) +// CHECK:STDOUT: !10 = !DILocation(line: 14, column: 18, scope: !4) +// CHECK:STDOUT: !11 = !DILocation(line: 14, column: 5, scope: !4) +// CHECK:STDOUT: !12 = !DILocation(line: 15, column: 9, scope: !4) +// CHECK:STDOUT: !13 = !DILocation(line: 15, column: 5, scope: !4) +// CHECK:STDOUT: !14 = !DILocation(line: 13, column: 3, scope: !4) +// CHECK:STDOUT: !15 = !DILocation(line: 17, column: 10, scope: !4) +// CHECK:STDOUT: !16 = !DILocation(line: 17, column: 3, scope: !4)