summaryrefslogtreecommitdiff
path: root/test/Transforms/FunctionImport
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2016-07-23 20:41:05 +0000
commit01095a5d43bbfde13731688ddcf6048ebb8b7721 (patch)
tree4def12e759965de927d963ac65840d663ef9d1ea /test/Transforms/FunctionImport
parentf0f4822ed4b66e3579e92a89f368f8fb860e218e (diff)
Diffstat (limited to 'test/Transforms/FunctionImport')
-rw-r--r--test/Transforms/FunctionImport/Inputs/adjustable_threshold.ll37
-rw-r--r--test/Transforms/FunctionImport/Inputs/funcimport.ll47
-rw-r--r--test/Transforms/FunctionImport/Inputs/funcimport_debug.ll5
-rw-r--r--test/Transforms/FunctionImport/Inputs/inlineasm.ll11
-rw-r--r--test/Transforms/FunctionImport/adjustable_threshold.ll31
-rw-r--r--test/Transforms/FunctionImport/funcimport.ll107
-rw-r--r--test/Transforms/FunctionImport/funcimport_alias.ll6
-rw-r--r--test/Transforms/FunctionImport/funcimport_debug.ll26
-rw-r--r--test/Transforms/FunctionImport/inlineasm.ll19
9 files changed, 248 insertions, 41 deletions
diff --git a/test/Transforms/FunctionImport/Inputs/adjustable_threshold.ll b/test/Transforms/FunctionImport/Inputs/adjustable_threshold.ll
new file mode 100644
index 0000000000000..fd4644d264a5e
--- /dev/null
+++ b/test/Transforms/FunctionImport/Inputs/adjustable_threshold.ll
@@ -0,0 +1,37 @@
+define void @globalfunc1() {
+entry:
+ call void @trampoline()
+ ret void
+}
+; Adds an artificial level in the call graph to reduce the importing threshold
+define void @trampoline() {
+entry:
+ call void @largefunction()
+ ret void
+}
+
+define void @globalfunc2() {
+entry:
+ call void @largefunction()
+ ret void
+}
+
+
+; Size is 5: if two layers below in the call graph the threshold will be 4,
+; but if only one layer below the threshold will be 7.
+define void @largefunction() {
+ entry:
+ call void @staticfunc2()
+ call void @staticfunc2()
+ call void @staticfunc2()
+ call void @staticfunc2()
+ call void @staticfunc2()
+ ret void
+}
+
+define internal void @staticfunc2() {
+entry:
+ ret void
+}
+
+
diff --git a/test/Transforms/FunctionImport/Inputs/funcimport.ll b/test/Transforms/FunctionImport/Inputs/funcimport.ll
index 79b766b386df3..fa96b8ea2663f 100644
--- a/test/Transforms/FunctionImport/Inputs/funcimport.ll
+++ b/test/Transforms/FunctionImport/Inputs/funcimport.ll
@@ -75,6 +75,11 @@ entry:
ret void
}
+define linkonce void @linkoncefunc2() #0 {
+entry:
+ ret void
+}
+
define internal i32 @staticfunc() #0 {
entry:
ret i32 1
@@ -99,4 +104,46 @@ entry:
ret void
}
+define void @referencelargelinkonce() #0 {
+entry:
+ call void @linkonceodr()
+ ret void
+}
+
+; A large enough linkonce_odr function that should never be imported
+define linkonce_odr void @linkonceodr() #0 {
+entry:
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ call void @globalfunc2()
+ ret void
+}
+
diff --git a/test/Transforms/FunctionImport/Inputs/funcimport_debug.ll b/test/Transforms/FunctionImport/Inputs/funcimport_debug.ll
index 35c62a2629033..0e75924cd3b63 100644
--- a/test/Transforms/FunctionImport/Inputs/funcimport_debug.ll
+++ b/test/Transforms/FunctionImport/Inputs/funcimport_debug.ll
@@ -14,11 +14,10 @@ attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fp
!llvm.module.flags = !{!7, !8}
!llvm.ident = !{!9}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 255685) (llvm/trunk 255682)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 255685) (llvm/trunk 255682)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "funcimport_debug.c", directory: ".")
!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, variables: !2)
+!4 = distinct !DISubprogram(name: "func", scope: !1, file: !1, line: 1, type: !5, isLocal: false, isDefinition: true, scopeLine: 1, isOptimized: false, unit: !0, variables: !2)
!5 = !DISubroutineType(types: !6)
!6 = !{null}
!7 = !{i32 2, !"Dwarf Version", i32 4}
diff --git a/test/Transforms/FunctionImport/Inputs/inlineasm.ll b/test/Transforms/FunctionImport/Inputs/inlineasm.ll
new file mode 100644
index 0000000000000..1ffc5db5f8b0d
--- /dev/null
+++ b/test/Transforms/FunctionImport/Inputs/inlineasm.ll
@@ -0,0 +1,11 @@
+@myvar = internal constant i8 1, align 1
+@llvm.used = appending global [1 x i8*] [i8* @myvar], section "llvm.metadata"
+
+define void @foo(i64* %v) #0 {
+entry:
+ %v.addr = alloca i64*, align 8
+ store i64* %v, i64** %v.addr, align 8
+ %0 = load i64*, i64** %v.addr, align 8
+ call void asm sideeffect "movzbl myvar(%rip), %eax\0A\09movq %rax, $0\0A\09", "=*m,~{eax},~{dirflag},~{fpsr},~{flags}"(i64* %0) #1
+ ret void
+}
diff --git a/test/Transforms/FunctionImport/adjustable_threshold.ll b/test/Transforms/FunctionImport/adjustable_threshold.ll
new file mode 100644
index 0000000000000..adb8b0dffb052
--- /dev/null
+++ b/test/Transforms/FunctionImport/adjustable_threshold.ll
@@ -0,0 +1,31 @@
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: opt -module-summary %s -o %t.bc
+; RUN: opt -module-summary %p/Inputs/adjustable_threshold.ll -o %t2.bc
+; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
+
+; Test import with default progressive instruction factor
+; RUN: opt -function-import -summary-file %t3.thinlto.bc %t.bc -import-instr-limit=10 -S | FileCheck %s --check-prefix=CHECK --check-prefix=INSTLIM-DEFAULT
+; INSTLIM-DEFAULT: call void @staticfunc2.llvm.
+
+; Test import with a reduced progressive instruction factor
+; RUN: opt -function-import -summary-file %t3.thinlto.bc %t.bc -import-instr-limit=10 -import-instr-evolution-factor=0.5 -S | FileCheck %s --check-prefix=CHECK --check-prefix=INSTLIM-PROGRESSIVE
+; INSTLIM-PROGRESSIVE-NOT: call void @staticfunc
+
+
+
+declare void @globalfunc1()
+declare void @globalfunc2()
+
+define void @entry() {
+entry:
+; Call site are processed in reversed order!
+
+; On the direct call, we reconsider @largefunction with a higher threshold and
+; import it
+ call void @globalfunc2()
+; When importing globalfunc1, the threshold was limited and @largefunction was
+; not imported.
+ call void @globalfunc1()
+ ret void
+}
+
diff --git a/test/Transforms/FunctionImport/funcimport.ll b/test/Transforms/FunctionImport/funcimport.ll
index 52fd53d3f31f2..7f7e57b357432 100644
--- a/test/Transforms/FunctionImport/funcimport.ll
+++ b/test/Transforms/FunctionImport/funcimport.ll
@@ -1,14 +1,21 @@
; Do setup work for all below tests: generate bitcode and combined index
-; RUN: llvm-as -function-summary %s -o %t.bc
-; RUN: llvm-as -function-summary %p/Inputs/funcimport.ll -o %t2.bc
-; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
+; RUN: opt -module-summary %s -o %t.bc
+; RUN: opt -module-summary %p/Inputs/funcimport.ll -o %t2.bc
+; RUN: llvm-lto -thinlto -print-summary-global-ids -o %t3 %t.bc %t2.bc 2>&1 | FileCheck %s --check-prefix=GUID
; Do the import now
-; RUN: opt -function-import -summary-file %t3.thinlto.bc %s -S | FileCheck %s --check-prefix=CHECK --check-prefix=INSTLIMDEF
+; RUN: opt -disable-force-link-odr -function-import -stats -print-imports -enable-import-metadata -summary-file %t3.thinlto.bc %t.bc -S 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=INSTLIMDEF
+; "-stats" requires +Asserts.
+; REQUIRES: asserts
; Test import with smaller instruction limit
-; RUN: opt -function-import -summary-file %t3.thinlto.bc %s -import-instr-limit=5 -S | FileCheck %s --check-prefix=CHECK --check-prefix=INSTLIM5
-; INSTLIM5-NOT: @staticfunc.llvm.2
+; RUN: opt -disable-force-link-odr -function-import -enable-import-metadata -summary-file %t3.thinlto.bc %t.bc -import-instr-limit=5 -S | FileCheck %s --check-prefix=CHECK --check-prefix=INSTLIM5
+; INSTLIM5-NOT: @staticfunc.llvm.
+
+; Test import with smaller instruction limit and without the -disable-force-link-odr
+; RUN: opt -function-import -summary-file %t3.thinlto.bc %t.bc -import-instr-limit=5 -S | FileCheck %s --check-prefix=INSTLIM5ODR
+; INSTLIM5ODR: define linkonce_odr void @linkonceodr() {
+
define i32 @main() #0 {
entry:
@@ -21,6 +28,8 @@ entry:
call void (...) @setfuncptr()
call void (...) @callfuncptr()
call void (...) @weakfunc()
+ call void (...) @linkoncefunc2()
+ call void (...) @referencelargelinkonce()
ret i32 0
}
@@ -32,46 +41,102 @@ declare void @weakalias(...) #1
; CHECK-DAG: declare void @analias
declare void @analias(...) #1
+; FIXME: Add this checking back when follow on fix to add alias summary
+; records is committed.
; Aliases import the aliasee function
declare void @linkoncealias(...) #1
-; CHECK-DAG: define linkonce_odr void @linkoncefunc()
-; CHECK-DAG: @linkoncealias = alias void (...), bitcast (void ()* @linkoncefunc to void (...)*
-; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i)
+; INSTLIMDEF-DAG: Import referencestatics
+; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i) !thinlto_src_module !0 {
; INSTLIM5-DAG: declare i32 @referencestatics(...)
declare i32 @referencestatics(...) #1
; The import of referencestatics will expose call to staticfunc that
; should in turn be imported as a promoted/renamed and hidden function.
; Ensure that the call is to the properly-renamed function.
-; INSTLIMDEF-DAG: %call = call i32 @staticfunc.llvm.2()
-; INSTLIMDEF-DAG: define available_externally hidden i32 @staticfunc.llvm.2()
+; INSTLIMDEF-DAG: Import staticfunc
+; INSTLIMDEF-DAG: %call = call i32 @staticfunc.llvm.
+; INSTLIMDEF-DAG: define available_externally hidden i32 @staticfunc.llvm.{{.*}} !thinlto_src_module !0 {
-; CHECK-DAG: define available_externally i32 @referenceglobals(i32 %i)
+; INSTLIMDEF-DAG: Import referenceglobals
+; CHECK-DAG: define available_externally i32 @referenceglobals(i32 %i) !thinlto_src_module !0 {
declare i32 @referenceglobals(...) #1
; The import of referenceglobals will expose call to globalfunc1 that
; should in turn be imported.
-; CHECK-DAG: define available_externally void @globalfunc1()
+; INSTLIMDEF-DAG: Import globalfunc1
+; CHECK-DAG: define available_externally void @globalfunc1() !thinlto_src_module !0
-; CHECK-DAG: define available_externally i32 @referencecommon(i32 %i)
+; INSTLIMDEF-DAG: Import referencecommon
+; CHECK-DAG: define available_externally i32 @referencecommon(i32 %i) !thinlto_src_module !0 {
declare i32 @referencecommon(...) #1
-; CHECK-DAG: define available_externally void @setfuncptr()
+; INSTLIMDEF-DAG: Import setfuncptr
+; CHECK-DAG: define available_externally void @setfuncptr() !thinlto_src_module !0 {
declare void @setfuncptr(...) #1
-; CHECK-DAG: define available_externally void @callfuncptr()
+; INSTLIMDEF-DAG: Import callfuncptr
+; CHECK-DAG: define available_externally void @callfuncptr() !thinlto_src_module !0 {
declare void @callfuncptr(...) #1
; Ensure that all uses of local variable @P which has used in setfuncptr
; and callfuncptr are to the same promoted/renamed global.
-; CHECK-DAG: @P.llvm.2 = available_externally hidden global void ()* null
-; CHECK-DAG: %0 = load void ()*, void ()** @P.llvm.2,
-; CHECK-DAG: store void ()* @staticfunc2.llvm.2, void ()** @P.llvm.2,
+; CHECK-DAG: @P.llvm.{{.*}} = external hidden global void ()*
+; CHECK-DAG: %0 = load void ()*, void ()** @P.llvm.
+; CHECK-DAG: store void ()* @staticfunc2.llvm.{{.*}}, void ()** @P.llvm.
+
+; Ensure that @referencelargelinkonce definition is pulled in, but later we
+; also check that the linkonceodr function is not.
+; CHECK-DAG: define available_externally void @referencelargelinkonce() !thinlto_src_module !0 {
+; INSTLIM5-DAG: declare void @linkonceodr()
+declare void @referencelargelinkonce(...)
; Won't import weak func
; CHECK-DAG: declare void @weakfunc(...)
declare void @weakfunc(...) #1
-; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.2() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.2()
+; Won't import linkonce func
+; CHECK-DAG: declare void @linkoncefunc2(...)
+declare void @linkoncefunc2(...) #1
+
+; INSTLIMDEF-DAG: Import funcwithpersonality
+; INSTLIMDEF-DAG: define available_externally hidden void @funcwithpersonality.llvm.{{.*}}() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !thinlto_src_module !0 {
+; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.{{.*}}()
+
+; INSTLIMDEF-DAG: Import globalfunc2
+; INSTLIMDEF-DAG: 13 function-import - Number of functions imported
+; CHECK-DAG: !0 = !{!"{{.*}}/Inputs/funcimport.ll"}
+
+; The actual GUID values will depend on path to test.
+; GUID-DAG: GUID {{.*}} is weakalias
+; GUID-DAG: GUID {{.*}} is referenceglobals
+; GUID-DAG: GUID {{.*}} is weakfunc
+; GUID-DAG: GUID {{.*}} is main
+; GUID-DAG: GUID {{.*}} is referencecommon
+; GUID-DAG: GUID {{.*}} is analias
+; GUID-DAG: GUID {{.*}} is referencestatics
+; GUID-DAG: GUID {{.*}} is linkoncealias
+; GUID-DAG: GUID {{.*}} is setfuncptr
+; GUID-DAG: GUID {{.*}} is callfuncptr
+; GUID-DAG: GUID {{.*}} is funcwithpersonality
+; GUID-DAG: GUID {{.*}} is setfuncptr
+; GUID-DAG: GUID {{.*}} is staticfunc2
+; GUID-DAG: GUID {{.*}} is __gxx_personality_v0
+; GUID-DAG: GUID {{.*}} is referencestatics
+; GUID-DAG: GUID {{.*}} is globalfunc1
+; GUID-DAG: GUID {{.*}} is globalfunc2
+; GUID-DAG: GUID {{.*}} is P
+; GUID-DAG: GUID {{.*}} is staticvar
+; GUID-DAG: GUID {{.*}} is commonvar
+; GUID-DAG: GUID {{.*}} is weakalias
+; GUID-DAG: GUID {{.*}} is staticfunc
+; GUID-DAG: GUID {{.*}} is weakfunc
+; GUID-DAG: GUID {{.*}} is referenceglobals
+; GUID-DAG: GUID {{.*}} is weakvar
+; GUID-DAG: GUID {{.*}} is staticconstvar
+; GUID-DAG: GUID {{.*}} is analias
+; GUID-DAG: GUID {{.*}} is globalvar
+; GUID-DAG: GUID {{.*}} is referencecommon
+; GUID-DAG: GUID {{.*}} is linkoncealias
+; GUID-DAG: GUID {{.*}} is callfuncptr
+; GUID-DAG: GUID {{.*}} is linkoncefunc
diff --git a/test/Transforms/FunctionImport/funcimport_alias.ll b/test/Transforms/FunctionImport/funcimport_alias.ll
index 8c7f00fe37b34..7868e08d32fd3 100644
--- a/test/Transforms/FunctionImport/funcimport_alias.ll
+++ b/test/Transforms/FunctionImport/funcimport_alias.ll
@@ -1,12 +1,12 @@
; Do setup work for all below tests: generate bitcode and combined index
-; RUN: llvm-as -function-summary %s -o %t.bc
-; RUN: llvm-as -function-summary %p/Inputs/funcimport_alias.ll -o %t2.bc
+; RUN: opt -module-summary %s -o %t.bc
+; RUN: opt -module-summary %p/Inputs/funcimport_alias.ll -o %t2.bc
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
; Do the import now. Ensures that the importer handles an external call
; from imported callanalias() to a function that is defined already in
; the dest module, but as an alias.
-; RUN: opt -function-import -summary-file %t3.thinlto.bc %s -S | FileCheck %s
+; RUN: opt -function-import -summary-file %t3.thinlto.bc %t.bc -S | FileCheck %s
define i32 @main() #0 {
entry:
diff --git a/test/Transforms/FunctionImport/funcimport_debug.ll b/test/Transforms/FunctionImport/funcimport_debug.ll
index 96b73a3f6bc76..e7c6389e90a5c 100644
--- a/test/Transforms/FunctionImport/funcimport_debug.ll
+++ b/test/Transforms/FunctionImport/funcimport_debug.ll
@@ -1,23 +1,22 @@
; Do setup work for all below tests: generate bitcode and combined index
-; RUN: llvm-as -function-summary %s -o %t.bc
-; RUN: llvm-as -function-summary %p/Inputs/funcimport_debug.ll -o %t2.bc
+; RUN: opt -module-summary %s -o %t.bc
+; RUN: opt -module-summary %p/Inputs/funcimport_debug.ll -o %t2.bc
; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
; Do the import now and confirm that metadata is linked for imported function.
-; RUN: opt -function-import -summary-file %t3.thinlto.bc %s -S | FileCheck %s
+; RUN: opt -function-import -summary-file %t3.thinlto.bc %t.bc -S | FileCheck %s
; CHECK: define available_externally void @func()
; Check that we have exactly two subprograms (that func's subprogram wasn't
; linked more than once for example), and that they are connected to
-; the subprogram list on a compute unit.
-; CHECK: !{{[0-9]+}} = distinct !DICompileUnit({{.*}} subprograms: ![[SPs1:[0-9]+]]
-; CHECK: ![[SPs1]] = !{![[MAINSP:[0-9]+]]}
-; CHECK: ![[MAINSP]] = distinct !DISubprogram(name: "main"
-; CHECK: !{{[0-9]+}} = distinct !DICompileUnit({{.*}} subprograms: ![[SPs2:[0-9]+]]
-; CHECK-NOT: ![[SPs2]] = !{{{.*}}null{{.*}}}
-; CHECK: ![[SPs2]] = !{![[FUNCSP:[0-9]+]]}
-; CHECK: ![[FUNCSP]] = distinct !DISubprogram(name: "func"
+; the correct compile unit.
+; CHECK: ![[CU1:[0-9]+]] = distinct !DICompileUnit(
+; CHECK: ![[CU2:[0-9]+]] = distinct !DICompileUnit(
+; CHECK: distinct !DISubprogram(name: "main"
+; CHECK-SAME: unit: ![[CU1]]
+; CHECK: distinct !DISubprogram(name: "func"
+; CHECK-SAME: unit: ![[CU2]]
; CHECK-NOT: distinct !DISubprogram
; ModuleID = 'funcimport_debug.o'
@@ -40,11 +39,10 @@ attributes #1 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-
!llvm.module.flags = !{!8, !9}
!llvm.ident = !{!10}
-!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 255685) (llvm/trunk 255682)", isOptimized: false, runtimeVersion: 0, emissionKind: 1, enums: !2, subprograms: !3)
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 3.8.0 (trunk 255685) (llvm/trunk 255682)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "funcimport_debug.c", directory: ".")
!2 = !{}
-!3 = !{!4}
-!4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, variables: !2)
+!4 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 2, type: !5, isLocal: false, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !0, variables: !2)
!5 = !DISubroutineType(types: !6)
!6 = !{!7}
!7 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
diff --git a/test/Transforms/FunctionImport/inlineasm.ll b/test/Transforms/FunctionImport/inlineasm.ll
new file mode 100644
index 0000000000000..d0516f1465341
--- /dev/null
+++ b/test/Transforms/FunctionImport/inlineasm.ll
@@ -0,0 +1,19 @@
+; Do setup work for all below tests: generate bitcode and combined index
+; RUN: opt -module-summary %s -o %t.bc
+; RUN: opt -module-summary %p/Inputs/inlineasm.ll -o %t2.bc
+; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc
+
+; Attempt the import now, ensure below that file containing inline assembly
+; is not imported from. Otherwise we would need to promote its local variable
+; used in the inline assembly, which would not see the rename.
+; RUN: opt -function-import -summary-file %t3.thinlto.bc %t.bc -S 2>&1 | FileCheck %s --check-prefix=CHECK
+
+define i32 @main() #0 {
+entry:
+ %f = alloca i64, align 8
+ call void @foo(i64* %f)
+ ret i32 0
+}
+
+; CHECK: declare void @foo(i64*)
+declare void @foo(i64*) #1