mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-02 11:45:49 +01:00
Use the Carbon-computed alignment for allocas, loads, stores, and memcpys. Previously we used whatever LLVM felt like giving us, which would result in ABI mismatches and runtime crashes due to misalignment when creating objects of imported C++ class types, as well as resulting in some surprising choices like `(i32, i32)` and `()` having 8-byte alignment instead of 4 and 1, respectively.
387 lines
19 KiB
Plaintext
387 lines
19 KiB
Plaintext
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/int.carbon
|
|
//
|
|
// AUTOUPDATE
|
|
// TIP: To test this file alone, run:
|
|
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/lower/testdata/interop/cpp/template.carbon
|
|
// TIP: To dump output, run:
|
|
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/lower/testdata/interop/cpp/template.carbon
|
|
|
|
// --- function_template.h
|
|
|
|
template<typename T> T identity(T x) { return x; }
|
|
|
|
class Class {};
|
|
|
|
// --- call.carbon
|
|
|
|
library "[[@TEST_NAME]]";
|
|
|
|
import Cpp library "function_template.h";
|
|
|
|
fn PassI32(a: i32) -> i32 {
|
|
return Cpp.identity(a);
|
|
}
|
|
|
|
fn PassI32Explicitly(a: i32) -> i32 {
|
|
return Cpp.identity(i32, a);
|
|
}
|
|
|
|
fn PassClass(a: Cpp.Class) -> Cpp.Class {
|
|
return Cpp.identity(a);
|
|
}
|
|
|
|
// --- variadic.carbon
|
|
|
|
library "[[@TEST_NAME]]";
|
|
|
|
import Cpp inline '''
|
|
template<typename ...T>
|
|
auto foo(int, T...) -> void;
|
|
''';
|
|
|
|
fn Call1() {
|
|
//@dump-sem-ir-begin
|
|
Cpp.foo(1);
|
|
//@dump-sem-ir-end
|
|
}
|
|
|
|
fn Call2() {
|
|
//@dump-sem-ir-begin
|
|
Cpp.foo(1, 2);
|
|
//@dump-sem-ir-end
|
|
}
|
|
|
|
fn Call3() {
|
|
//@dump-sem-ir-begin
|
|
Cpp.foo(1, 2, 3);
|
|
//@dump-sem-ir-end
|
|
}
|
|
|
|
// --- variadic_thunk.carbon
|
|
|
|
library "[[@TEST_NAME]]";
|
|
|
|
import Cpp inline '''
|
|
class X {};
|
|
template<typename ...T>
|
|
auto foo(X, T...) -> void;
|
|
''';
|
|
|
|
fn Call1() {
|
|
//@dump-sem-ir-begin
|
|
Cpp.foo({} as Cpp.X);
|
|
//@dump-sem-ir-end
|
|
}
|
|
|
|
fn Call2() {
|
|
//@dump-sem-ir-begin
|
|
Cpp.foo({} as Cpp.X, 2);
|
|
//@dump-sem-ir-end
|
|
}
|
|
|
|
fn Call3() {
|
|
//@dump-sem-ir-begin
|
|
Cpp.foo({} as Cpp.X, 2, 3);
|
|
//@dump-sem-ir-end
|
|
}
|
|
|
|
// CHECK:STDOUT: ; ModuleID = 'call.carbon'
|
|
// CHECK:STDOUT: source_filename = "call.carbon"
|
|
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
|
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: %class.Class = type { i8 }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: $_Z8identityIiET_S0_ = comdat any
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: $_Z8identityI5ClassET_S1_ = comdat any
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define i32 @_CPassI32.Main(i32 %a) #0 !dbg !11 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %identity.call = call i32 @_Z8identityIiET_S0_(i32 %a), !dbg !17
|
|
// CHECK:STDOUT: ret i32 %identity.call, !dbg !18
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
|
|
// CHECK:STDOUT: define linkonce_odr dso_local noundef i32 @_Z8identityIiET_S0_(i32 noundef %x) #1 comdat {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %x.addr = alloca i32, align 4
|
|
// CHECK:STDOUT: store i32 %x, ptr %x.addr, align 4, !tbaa !7
|
|
// CHECK:STDOUT: %0 = load i32, ptr %x.addr, align 4, !tbaa !7
|
|
// CHECK:STDOUT: ret i32 %0
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define i32 @_CPassI32Explicitly.Main(i32 %a) #0 !dbg !19 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %identity.call = call i32 @_Z8identityIiET_S0_(i32 %a), !dbg !22
|
|
// CHECK:STDOUT: ret i32 %identity.call, !dbg !23
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define void @_CPassClass.Main(ptr sret({}) %return, ptr %a) #0 !dbg !24 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: call void @_Z8identityI5ClassET_S1_.carbon_thunk._(ptr %a, ptr %return), !dbg !30
|
|
// CHECK:STDOUT: ret void, !dbg !31
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
|
|
// CHECK:STDOUT: define internal void @_Z8identityI5ClassET_S1_.carbon_thunk._(ptr noundef %x, ptr noundef %return) #2 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %x.addr = alloca ptr, align 8
|
|
// CHECK:STDOUT: %return.addr = alloca ptr, align 8
|
|
// CHECK:STDOUT: %agg.tmp = alloca %class.Class, align 1
|
|
// CHECK:STDOUT: %undef.agg.tmp = alloca %class.Class, align 1
|
|
// CHECK:STDOUT: store ptr %x, ptr %x.addr, align 8, !tbaa !32
|
|
// CHECK:STDOUT: store ptr %return, ptr %return.addr, align 8, !tbaa !32
|
|
// CHECK:STDOUT: %0 = load ptr, ptr %return.addr, align 8, !tbaa !32
|
|
// CHECK:STDOUT: %1 = load ptr, ptr %x.addr, align 8, !tbaa !32
|
|
// CHECK:STDOUT: call void @_Z8identityI5ClassET_S1_()
|
|
// CHECK:STDOUT: ret void
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: mustprogress nounwind uwtable
|
|
// CHECK:STDOUT: define linkonce_odr dso_local void @_Z8identityI5ClassET_S1_() #1 comdat {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %x = alloca %class.Class, align 1
|
|
// CHECK:STDOUT: ret void
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: attributes #0 = { nounwind }
|
|
// CHECK:STDOUT: attributes #1 = { mustprogress nounwind uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
// CHECK:STDOUT: attributes #2 = { alwaysinline mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
|
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
|
// CHECK:STDOUT: !llvm.errno.tbaa = !{!7}
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
|
|
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
|
|
// CHECK:STDOUT: !2 = !{i32 8, !"PIC Level", i32 2}
|
|
// CHECK:STDOUT: !3 = !{i32 7, !"PIE Level", i32 2}
|
|
// CHECK:STDOUT: !4 = !{i32 7, !"uwtable", i32 2}
|
|
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
|
// CHECK:STDOUT: !6 = !DIFile(filename: "call.carbon", directory: "")
|
|
// CHECK:STDOUT: !7 = !{!8, !8, i64 0}
|
|
// CHECK:STDOUT: !8 = !{!"int", !9, i64 0}
|
|
// CHECK:STDOUT: !9 = !{!"omnipotent char", !10, i64 0}
|
|
// CHECK:STDOUT: !10 = !{!"Simple C++ TBAA"}
|
|
// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "PassI32", linkageName: "_CPassI32.Main", scope: null, file: !6, line: 6, type: !12, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !15)
|
|
// CHECK:STDOUT: !12 = !DISubroutineType(types: !13)
|
|
// CHECK:STDOUT: !13 = !{!14, !14}
|
|
// CHECK:STDOUT: !14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
|
|
// CHECK:STDOUT: !15 = !{!16}
|
|
// CHECK:STDOUT: !16 = !DILocalVariable(arg: 1, scope: !11, type: !14)
|
|
// CHECK:STDOUT: !17 = !DILocation(line: 7, column: 10, scope: !11)
|
|
// CHECK:STDOUT: !18 = !DILocation(line: 7, column: 3, scope: !11)
|
|
// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "PassI32Explicitly", linkageName: "_CPassI32Explicitly.Main", scope: null, file: !6, line: 10, type: !12, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !20)
|
|
// CHECK:STDOUT: !20 = !{!21}
|
|
// CHECK:STDOUT: !21 = !DILocalVariable(arg: 1, scope: !19, type: !14)
|
|
// CHECK:STDOUT: !22 = !DILocation(line: 11, column: 10, scope: !19)
|
|
// CHECK:STDOUT: !23 = !DILocation(line: 11, column: 3, scope: !19)
|
|
// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "PassClass", linkageName: "_CPassClass.Main", scope: null, file: !6, line: 14, type: !25, spFlags: DISPFlagDefinition, unit: !5, retainedNodes: !28)
|
|
// CHECK:STDOUT: !25 = !DISubroutineType(types: !26)
|
|
// CHECK:STDOUT: !26 = !{!27, !27}
|
|
// CHECK:STDOUT: !27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: null, size: 64)
|
|
// CHECK:STDOUT: !28 = !{!29}
|
|
// CHECK:STDOUT: !29 = !DILocalVariable(arg: 1, scope: !24, type: !27)
|
|
// CHECK:STDOUT: !30 = !DILocation(line: 15, column: 10, scope: !24)
|
|
// CHECK:STDOUT: !31 = !DILocation(line: 15, column: 3, scope: !24)
|
|
// CHECK:STDOUT: !32 = !{!33, !33, i64 0}
|
|
// CHECK:STDOUT: !33 = !{!"p1 _ZTS5Class", !34, i64 0}
|
|
// CHECK:STDOUT: !34 = !{!"any pointer", !9, i64 0}
|
|
// CHECK:STDOUT: ; ModuleID = 'variadic.carbon'
|
|
// CHECK:STDOUT: source_filename = "variadic.carbon"
|
|
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
|
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define void @_CCall1.Main() #0 !dbg !11 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: call void @_Z3fooIJEEviDpT_(i32 1), !dbg !14
|
|
// CHECK:STDOUT: ret void, !dbg !15
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: declare void @_Z3fooIJEEviDpT_(i32 noundef) #1
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define void @_CCall2.Main() #0 !dbg !16 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: call void @_Z3fooIJiEEviDpT_(i32 1, i32 2), !dbg !17
|
|
// CHECK:STDOUT: ret void, !dbg !18
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: declare void @_Z3fooIJiEEviDpT_(i32 noundef, i32 noundef) #1
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define void @_CCall3.Main() #0 !dbg !19 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: call void @_Z3fooIJiiEEviDpT_(i32 1, i32 2, i32 3), !dbg !20
|
|
// CHECK:STDOUT: ret void, !dbg !21
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: declare void @_Z3fooIJiiEEviDpT_(i32 noundef, i32 noundef, i32 noundef) #1
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: attributes #0 = { nounwind }
|
|
// CHECK:STDOUT: attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
|
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
|
// CHECK:STDOUT: !llvm.errno.tbaa = !{!7}
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
|
|
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
|
|
// CHECK:STDOUT: !2 = !{i32 8, !"PIC Level", i32 2}
|
|
// CHECK:STDOUT: !3 = !{i32 7, !"PIE Level", i32 2}
|
|
// CHECK:STDOUT: !4 = !{i32 7, !"uwtable", i32 2}
|
|
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
|
// CHECK:STDOUT: !6 = !DIFile(filename: "variadic.carbon", directory: "")
|
|
// CHECK:STDOUT: !7 = !{!8, !8, i64 0}
|
|
// CHECK:STDOUT: !8 = !{!"int", !9, i64 0}
|
|
// CHECK:STDOUT: !9 = !{!"omnipotent char", !10, i64 0}
|
|
// CHECK:STDOUT: !10 = !{!"Simple C++ TBAA"}
|
|
// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "Call1", linkageName: "_CCall1.Main", scope: null, file: !6, line: 9, type: !12, spFlags: DISPFlagDefinition, unit: !5)
|
|
// CHECK:STDOUT: !12 = !DISubroutineType(types: !13)
|
|
// CHECK:STDOUT: !13 = !{null}
|
|
// CHECK:STDOUT: !14 = !DILocation(line: 11, column: 3, scope: !11)
|
|
// CHECK:STDOUT: !15 = !DILocation(line: 9, column: 1, scope: !11)
|
|
// CHECK:STDOUT: !16 = distinct !DISubprogram(name: "Call2", linkageName: "_CCall2.Main", scope: null, file: !6, line: 15, type: !12, spFlags: DISPFlagDefinition, unit: !5)
|
|
// CHECK:STDOUT: !17 = !DILocation(line: 17, column: 3, scope: !16)
|
|
// CHECK:STDOUT: !18 = !DILocation(line: 15, column: 1, scope: !16)
|
|
// CHECK:STDOUT: !19 = distinct !DISubprogram(name: "Call3", linkageName: "_CCall3.Main", scope: null, file: !6, line: 21, type: !12, spFlags: DISPFlagDefinition, unit: !5)
|
|
// CHECK:STDOUT: !20 = !DILocation(line: 23, column: 3, scope: !19)
|
|
// CHECK:STDOUT: !21 = !DILocation(line: 21, column: 1, scope: !19)
|
|
// CHECK:STDOUT: ; ModuleID = 'variadic_thunk.carbon'
|
|
// CHECK:STDOUT: source_filename = "variadic_thunk.carbon"
|
|
// CHECK:STDOUT: target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
|
|
// CHECK:STDOUT: target triple = "x86_64-unknown-linux-gnu"
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: %class.X = type { i8 }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: @X.val = internal constant {} zeroinitializer
|
|
// CHECK:STDOUT: @X.val.loc12_14.3 = internal constant {} zeroinitializer
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define void @_CCall1.Main() #0 !dbg !11 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %.loc12_12.2.temp = alloca {}, align 1, !dbg !14
|
|
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc12_12.2.temp), !dbg !14
|
|
// CHECK:STDOUT: call void @_Z3fooIJEEv1XDpT_.carbon_thunk._(ptr @X.val.loc12_14.3), !dbg !15
|
|
// CHECK:STDOUT: ret void, !dbg !16
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
|
|
// CHECK:STDOUT: define internal void @_Z3fooIJEEv1XDpT_.carbon_thunk._(ptr noundef %0) #1 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %.addr = alloca ptr, align 8
|
|
// CHECK:STDOUT: %agg.tmp = alloca %class.X, align 1
|
|
// CHECK:STDOUT: store ptr %0, ptr %.addr, align 8, !tbaa !17
|
|
// CHECK:STDOUT: %1 = load ptr, ptr %.addr, align 8, !tbaa !17
|
|
// CHECK:STDOUT: call void @_Z3fooIJEEv1XDpT_()
|
|
// CHECK:STDOUT: ret void
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define void @_CCall2.Main() #0 !dbg !20 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %.loc18_12.2.temp = alloca {}, align 1, !dbg !21
|
|
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc18_12.2.temp), !dbg !21
|
|
// CHECK:STDOUT: call void @_Z3fooIJiEEv1XDpT_.carbon_thunk.__(ptr @X.val.loc12_14.3, i32 2), !dbg !22
|
|
// CHECK:STDOUT: ret void, !dbg !23
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
|
|
// CHECK:STDOUT: define internal void @_Z3fooIJiEEv1XDpT_.carbon_thunk.__(ptr noundef %0, i32 noundef %1) #1 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %.addr = alloca ptr, align 8
|
|
// CHECK:STDOUT: %.addr1 = alloca i32, align 4
|
|
// CHECK:STDOUT: %agg.tmp = alloca %class.X, align 1
|
|
// CHECK:STDOUT: store ptr %0, ptr %.addr, align 8, !tbaa !17
|
|
// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !7
|
|
// CHECK:STDOUT: %2 = load ptr, ptr %.addr, align 8, !tbaa !17
|
|
// CHECK:STDOUT: %3 = load i32, ptr %.addr1, align 4, !tbaa !7
|
|
// CHECK:STDOUT: call void @_Z3fooIJiEEv1XDpT_(i32 noundef %3)
|
|
// CHECK:STDOUT: ret void
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nounwind
|
|
// CHECK:STDOUT: define void @_CCall3.Main() #0 !dbg !24 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %.loc24_12.2.temp = alloca {}, align 1, !dbg !25
|
|
// CHECK:STDOUT: call void @llvm.lifetime.start.p0(ptr %.loc24_12.2.temp), !dbg !25
|
|
// CHECK:STDOUT: call void @_Z3fooIJiiEEv1XDpT_.carbon_thunk.___(ptr @X.val.loc12_14.3, i32 2, i32 3), !dbg !26
|
|
// CHECK:STDOUT: ret void, !dbg !27
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: alwaysinline mustprogress uwtable
|
|
// CHECK:STDOUT: define internal void @_Z3fooIJiiEEv1XDpT_.carbon_thunk.___(ptr noundef %0, i32 noundef %1, i32 noundef %2) #1 {
|
|
// CHECK:STDOUT: entry:
|
|
// CHECK:STDOUT: %.addr = alloca ptr, align 8
|
|
// CHECK:STDOUT: %.addr1 = alloca i32, align 4
|
|
// CHECK:STDOUT: %.addr2 = alloca i32, align 4
|
|
// CHECK:STDOUT: %agg.tmp = alloca %class.X, align 1
|
|
// CHECK:STDOUT: store ptr %0, ptr %.addr, align 8, !tbaa !17
|
|
// CHECK:STDOUT: store i32 %1, ptr %.addr1, align 4, !tbaa !7
|
|
// CHECK:STDOUT: store i32 %2, ptr %.addr2, align 4, !tbaa !7
|
|
// CHECK:STDOUT: %3 = load ptr, ptr %.addr, align 8, !tbaa !17
|
|
// CHECK:STDOUT: %4 = load i32, ptr %.addr1, align 4, !tbaa !7
|
|
// CHECK:STDOUT: %5 = load i32, ptr %.addr2, align 4, !tbaa !7
|
|
// CHECK:STDOUT: call void @_Z3fooIJiiEEv1XDpT_(i32 noundef %4, i32 noundef %5)
|
|
// CHECK:STDOUT: ret void
|
|
// CHECK:STDOUT: }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; Function Attrs: nocallback nofree nosync nounwind willreturn memory(argmem: readwrite)
|
|
// CHECK:STDOUT: declare void @llvm.lifetime.start.p0(ptr captures(none)) #2
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: declare void @_Z3fooIJEEv1XDpT_() #3
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: declare void @_Z3fooIJiEEv1XDpT_(i32 noundef) #3
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: declare void @_Z3fooIJiiEEv1XDpT_(i32 noundef, i32 noundef) #3
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: ; uselistorder directives
|
|
// CHECK:STDOUT: uselistorder ptr @llvm.lifetime.start.p0, { 2, 1, 0 }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: attributes #0 = { nounwind }
|
|
// CHECK:STDOUT: attributes #1 = { alwaysinline mustprogress uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
// CHECK:STDOUT: attributes #2 = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
|
|
// CHECK:STDOUT: attributes #3 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: !llvm.module.flags = !{!0, !1, !2, !3, !4}
|
|
// CHECK:STDOUT: !llvm.dbg.cu = !{!5}
|
|
// CHECK:STDOUT: !llvm.errno.tbaa = !{!7}
|
|
// CHECK:STDOUT:
|
|
// CHECK:STDOUT: !0 = !{i32 7, !"Dwarf Version", i32 5}
|
|
// CHECK:STDOUT: !1 = !{i32 2, !"Debug Info Version", i32 3}
|
|
// CHECK:STDOUT: !2 = !{i32 8, !"PIC Level", i32 2}
|
|
// CHECK:STDOUT: !3 = !{i32 7, !"PIE Level", i32 2}
|
|
// CHECK:STDOUT: !4 = !{i32 7, !"uwtable", i32 2}
|
|
// CHECK:STDOUT: !5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !6, producer: "carbon", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
|
|
// CHECK:STDOUT: !6 = !DIFile(filename: "variadic_thunk.carbon", directory: "")
|
|
// CHECK:STDOUT: !7 = !{!8, !8, i64 0}
|
|
// CHECK:STDOUT: !8 = !{!"int", !9, i64 0}
|
|
// CHECK:STDOUT: !9 = !{!"omnipotent char", !10, i64 0}
|
|
// CHECK:STDOUT: !10 = !{!"Simple C++ TBAA"}
|
|
// CHECK:STDOUT: !11 = distinct !DISubprogram(name: "Call1", linkageName: "_CCall1.Main", scope: null, file: !6, line: 10, type: !12, spFlags: DISPFlagDefinition, unit: !5)
|
|
// CHECK:STDOUT: !12 = !DISubroutineType(types: !13)
|
|
// CHECK:STDOUT: !13 = !{null}
|
|
// CHECK:STDOUT: !14 = !DILocation(line: 12, column: 11, scope: !11)
|
|
// CHECK:STDOUT: !15 = !DILocation(line: 12, column: 3, scope: !11)
|
|
// CHECK:STDOUT: !16 = !DILocation(line: 10, column: 1, scope: !11)
|
|
// CHECK:STDOUT: !17 = !{!18, !18, i64 0}
|
|
// CHECK:STDOUT: !18 = !{!"p1 _ZTS1X", !19, i64 0}
|
|
// CHECK:STDOUT: !19 = !{!"any pointer", !9, i64 0}
|
|
// CHECK:STDOUT: !20 = distinct !DISubprogram(name: "Call2", linkageName: "_CCall2.Main", scope: null, file: !6, line: 16, type: !12, spFlags: DISPFlagDefinition, unit: !5)
|
|
// CHECK:STDOUT: !21 = !DILocation(line: 18, column: 11, scope: !20)
|
|
// CHECK:STDOUT: !22 = !DILocation(line: 18, column: 3, scope: !20)
|
|
// CHECK:STDOUT: !23 = !DILocation(line: 16, column: 1, scope: !20)
|
|
// CHECK:STDOUT: !24 = distinct !DISubprogram(name: "Call3", linkageName: "_CCall3.Main", scope: null, file: !6, line: 22, type: !12, spFlags: DISPFlagDefinition, unit: !5)
|
|
// CHECK:STDOUT: !25 = !DILocation(line: 24, column: 11, scope: !24)
|
|
// CHECK:STDOUT: !26 = !DILocation(line: 24, column: 3, scope: !24)
|
|
// CHECK:STDOUT: !27 = !DILocation(line: 22, column: 1, scope: !24)
|