diff options
author | Stephen Hines <srhines@google.com> | 2015-03-23 12:10:34 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2015-03-23 12:10:34 -0700 |
commit | ebe69fe11e48d322045d5949c83283927a0d790b (patch) | |
tree | c92f1907a6b8006628a4b01615f38264d29834ea /test/Instrumentation/MemorySanitizer | |
parent | b7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff) | |
download | external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.zip external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.gz external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.bz2 |
Update aosp/master LLVM for rebase to r230699.
Change-Id: I2b5be30509658cb8266be782de0ab24f9099f9b9
Diffstat (limited to 'test/Instrumentation/MemorySanitizer')
8 files changed, 242 insertions, 107 deletions
diff --git a/test/Instrumentation/MemorySanitizer/atomics.ll b/test/Instrumentation/MemorySanitizer/atomics.ll index c8f3b88..28736ad 100644 --- a/test/Instrumentation/MemorySanitizer/atomics.ll +++ b/test/Instrumentation/MemorySanitizer/atomics.ll @@ -1,4 +1,6 @@ ; RUN: opt < %s -msan -msan-check-access-address=0 -S | FileCheck %s +; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s +; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" diff --git a/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll b/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll index 11e4410..f147944 100644 --- a/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll +++ b/test/Instrumentation/MemorySanitizer/check-constant-shadow.ll @@ -1,10 +1,11 @@ -; RUN: opt < %s -msan -msan-check-constant-shadow=1 -S | FileCheck %s +; RUN: opt < %s -msan -msan-check-access-address=0 -msan-check-constant-shadow=1 -msan-track-origins=1 -S | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" ; Test that returning a literal undef from main() triggers an MSan warning. +; main() is special: it inserts check for the return value define i32 @main() nounwind uwtable sanitize_memory { entry: ret i32 undef @@ -13,3 +14,40 @@ entry: ; CHECK-LABEL: @main ; CHECK: call void @__msan_warning_noreturn ; CHECK: ret i32 undef + + +; This function stores known initialized value. +; Expect 2 stores: one for the shadow (0), one for the value (42), but no origin. +define void @StoreConstant(i32* nocapture %p) nounwind uwtable sanitize_memory { +entry: + store i32 42, i32* %p, align 4 + ret void +} + +; CHECK-LABEL: @StoreConstant +; CHECK-NOT: store i32 +; CHECK: store i32 0, +; CHECK-NOT: store i32 +; CHECK: store i32 42, +; CHECK-NOT: store i32 +; CHECK: ret void + + +; This function stores known uninitialized value. +; Expect 3 stores: shadow, value and origin. +; Expect no icmp(s): everything here is unconditional. +define void @StoreUndef(i32* nocapture %p) nounwind uwtable sanitize_memory { +entry: + store i32 undef, i32* %p, align 4 + ret void +} + +; CHECK-LABEL: @StoreUndef +; CHECK-NOT: icmp +; CHECK: store i32 +; CHECK-NOT: icmp +; CHECK: store i32 +; CHECK-NOT: icmp +; CHECK: store i32 +; CHECK-NOT: icmp +; CHECK: ret void diff --git a/test/Instrumentation/MemorySanitizer/do-not-emit-module-limits.ll b/test/Instrumentation/MemorySanitizer/do-not-emit-module-limits.ll deleted file mode 100644 index 7d0a62a..0000000 --- a/test/Instrumentation/MemorySanitizer/do-not-emit-module-limits.ll +++ /dev/null @@ -1,21 +0,0 @@ -; Test that MSan does not emit undefined symbol __executable_start when it is -; not needed (i.e. without -msan-wrap-indirect-calls). - -; RUN: opt < %s -msan -S | FileCheck %s - -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -; Function Attrs: nounwind uwtable -define void @_Z1fv() #0 { -entry: - ret void -} - -attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } - -!llvm.ident = !{!0} - -!0 = metadata !{metadata !"clang version 3.5.0 (208165)"} - -; CHECK-NOT: __executable_start diff --git a/test/Instrumentation/MemorySanitizer/missing_origin.ll b/test/Instrumentation/MemorySanitizer/missing_origin.ll index 673e853..f7385b9 100644 --- a/test/Instrumentation/MemorySanitizer/missing_origin.ll +++ b/test/Instrumentation/MemorySanitizer/missing_origin.ll @@ -17,3 +17,17 @@ entry: ; CHECK: [[A:%.*]] = load i32* {{.*}}@__msan_param_origin_tls, ; CHECK: store i32 [[A]], i32* @__msan_retval_origin_tls ; CHECK: ret <4 x i32> + + +; Regression test for origin propagation in "select i1, float, float". +; https://code.google.com/p/memory-sanitizer/issues/detail?id=78 + +define float @SelectFloat(i1 %b, float %x, float %y) nounwind uwtable sanitize_memory { +entry: + %z = select i1 %b, float %x, float %y + ret float %z +} + +; CHECK-LABEL: @SelectFloat( +; CHECK-NOT: select {{.*}} i32 0, i32 0 +; CHECK: ret float diff --git a/test/Instrumentation/MemorySanitizer/origin-alignment.ll b/test/Instrumentation/MemorySanitizer/origin-alignment.ll new file mode 100644 index 0000000..ce0dbfc --- /dev/null +++ b/test/Instrumentation/MemorySanitizer/origin-alignment.ll @@ -0,0 +1,73 @@ +; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS1 %s +; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=2 -S | FileCheck -check-prefix=CHECK -check-prefix=CHECK-ORIGINS2 %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + + +; Check origin instrumentation of stores. +; Check that debug info for origin propagation code is set correctly. + +@a8 = global i8 0, align 8 +@a4 = global i8 0, align 4 +@a2 = global i8 0, align 2 +@a1 = global i8 0, align 1 + +; 8-aligned store => 8-aligned origin store, origin address is not realigned +define void @Store8(i8 %x) sanitize_memory { +entry: + store i8 %x, i8* @a8, align 8 + ret void +} + +; CHECK-LABEL: @Store8 +; CHECK-ORIGINS1: [[ORIGIN:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls +; CHECK-ORIGINS2: [[ORIGIN0:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls +; CHECK-ORIGINS2: [[ORIGIN:%[01-9a-z]+]] = call i32 @__msan_chain_origin(i32 [[ORIGIN0]]) +; CHECK: store i32 [[ORIGIN]], i32* inttoptr (i64 add (i64 and (i64 ptrtoint {{.*}} to i32*), align 8 +; CHECK: ret void + + +; 4-aligned store => 4-aligned origin store, origin address is not realigned +define void @Store4(i8 %x) sanitize_memory { +entry: + store i8 %x, i8* @a4, align 4 + ret void +} + +; CHECK-LABEL: @Store4 +; CHECK-ORIGINS1: [[ORIGIN:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls +; CHECK-ORIGINS2: [[ORIGIN0:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls +; CHECK-ORIGINS2: [[ORIGIN:%[01-9a-z]+]] = call i32 @__msan_chain_origin(i32 [[ORIGIN0]]) +; CHECK: store i32 [[ORIGIN]], i32* inttoptr (i64 add (i64 and (i64 ptrtoint {{.*}} to i32*), align 4 +; CHECK: ret void + + +; 2-aligned store => 4-aligned origin store, origin address is realigned +define void @Store2(i8 %x) sanitize_memory { +entry: + store i8 %x, i8* @a2, align 2 + ret void +} + +; CHECK-LABEL: @Store2 +; CHECK-ORIGINS1: [[ORIGIN:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls +; CHECK-ORIGINS2: [[ORIGIN0:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls +; CHECK-ORIGINS2: [[ORIGIN:%[01-9a-z]+]] = call i32 @__msan_chain_origin(i32 [[ORIGIN0]]) +; CHECK: store i32 [[ORIGIN]], i32* inttoptr (i64 and (i64 add (i64 and (i64 ptrtoint {{.*}} i64 -4) to i32*), align 4 +; CHECK: ret void + + +; 1-aligned store => 4-aligned origin store, origin address is realigned +define void @Store1(i8 %x) sanitize_memory { +entry: + store i8 %x, i8* @a1, align 1 + ret void +} + +; CHECK-LABEL: @Store1 +; CHECK-ORIGINS1: [[ORIGIN:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls +; CHECK-ORIGINS2: [[ORIGIN0:%[01-9a-z]+]] = load {{.*}} @__msan_param_origin_tls +; CHECK-ORIGINS2: [[ORIGIN:%[01-9a-z]+]] = call i32 @__msan_chain_origin(i32 [[ORIGIN0]]) +; CHECK: store i32 [[ORIGIN]], i32* inttoptr (i64 and (i64 add (i64 and (i64 ptrtoint {{.*}} i64 -4) to i32*), align 4 +; CHECK: ret void diff --git a/test/Instrumentation/MemorySanitizer/store-long-origin.ll b/test/Instrumentation/MemorySanitizer/store-long-origin.ll new file mode 100644 index 0000000..128f810 --- /dev/null +++ b/test/Instrumentation/MemorySanitizer/store-long-origin.ll @@ -0,0 +1,89 @@ +; RUN: opt < %s -msan -msan-check-access-address=0 -msan-track-origins=1 -S | FileCheck %s + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + + +; Test origin for longer stores. + +define void @Store8(i64* nocapture %p, i64 %x) sanitize_memory { +entry: + store i64 %x, i64* %p, align 8 + ret void +} + +; Single 8-byte origin store +; CHECK-LABEL: define void @Store8( +; CHECK: store i64 {{.*}}, align 8 +; CHECK: store i64 {{.*}}, align 8 +; CHECK: store i64 {{.*}}, align 8 +; CHECK: ret void + +define void @Store8_align4(i64* nocapture %p, i64 %x) sanitize_memory { +entry: + store i64 %x, i64* %p, align 4 + ret void +} + +; Two 4-byte origin stores +; CHECK-LABEL: define void @Store8_align4( +; CHECK: store i64 {{.*}}, align 4 +; CHECK: store i32 {{.*}}, align 4 +; CHECK: getelementptr i32* {{.*}}, i32 1 +; CHECK: store i32 {{.*}}, align 4 +; CHECK: store i64 {{.*}}, align 4 +; CHECK: ret void + +%struct.S = type { i32, i32, i32 } + +define void @StoreAgg(%struct.S* nocapture %p, %struct.S %x) sanitize_memory { +entry: + store %struct.S %x, %struct.S* %p, align 4 + ret void +} + +; Three 4-byte origin stores +; CHECK-LABEL: define void @StoreAgg( +; CHECK: store { i32, i32, i32 } {{.*}}, align 4 +; CHECK: store i32 {{.*}}, align 4 +; CHECK: getelementptr i32* {{.*}}, i32 1 +; CHECK: store i32 {{.*}}, align 4 +; CHECK: getelementptr i32* {{.*}}, i32 2 +; CHECK: store i32 {{.*}}, align 4 +; CHECK: store %struct.S {{.*}}, align 4 +; CHECK: ret void + + +define void @StoreAgg8(%struct.S* nocapture %p, %struct.S %x) sanitize_memory { +entry: + store %struct.S %x, %struct.S* %p, align 8 + ret void +} + +; 8-byte + 4-byte origin stores +; CHECK-LABEL: define void @StoreAgg8( +; CHECK: store { i32, i32, i32 } {{.*}}, align 8 +; CHECK: store i64 {{.*}}, align 8 +; CHECK: getelementptr i32* {{.*}}, i32 2 +; CHECK: store i32 {{.*}}, align 8 +; CHECK: store %struct.S {{.*}}, align 8 +; CHECK: ret void + + +%struct.Q = type { i64, i64, i64 } +define void @StoreAgg24(%struct.Q* nocapture %p, %struct.Q %x) sanitize_memory { +entry: + store %struct.Q %x, %struct.Q* %p, align 8 + ret void +} + +; 3 8-byte origin stores +; CHECK-LABEL: define void @StoreAgg24( +; CHECK: store { i64, i64, i64 } {{.*}}, align 8 +; CHECK: store i64 {{.*}}, align 8 +; CHECK: getelementptr i64* {{.*}}, i32 1 +; CHECK: store i64 {{.*}}, align 8 +; CHECK: getelementptr i64* {{.*}}, i32 2 +; CHECK: store i64 {{.*}}, align 8 +; CHECK: store %struct.Q {{.*}}, align 8 +; CHECK: ret void diff --git a/test/Instrumentation/MemorySanitizer/store-origin.ll b/test/Instrumentation/MemorySanitizer/store-origin.ll index bde4e90..c2948b1 100644 --- a/test/Instrumentation/MemorySanitizer/store-origin.ll +++ b/test/Instrumentation/MemorySanitizer/store-origin.ll @@ -11,8 +11,8 @@ target triple = "x86_64-unknown-linux-gnu" ; Function Attrs: nounwind define void @Store(i32* nocapture %p, i32 %x) #0 { entry: - tail call void @llvm.dbg.value(metadata !{i32* %p}, i64 0, metadata !11, metadata !{metadata !"0x102"}), !dbg !16 - tail call void @llvm.dbg.value(metadata !{i32 %x}, i64 0, metadata !12, metadata !{metadata !"0x102"}), !dbg !16 + tail call void @llvm.dbg.value(metadata i32* %p, i64 0, metadata !11, metadata !{!"0x102"}), !dbg !16 + tail call void @llvm.dbg.value(metadata i32 %x, i64 0, metadata !12, metadata !{!"0x102"}), !dbg !16 store i32 %x, i32* %p, align 4, !dbg !17, !tbaa !18 ret void, !dbg !22 } @@ -27,29 +27,29 @@ attributes #1 = { nounwind readnone } !llvm.module.flags = !{!13, !14} !llvm.ident = !{!15} -!0 = metadata !{metadata !"0x11\0012\00clang version 3.5.0 (204220)\001\00\000\00\001", metadata !1, metadata !2, metadata !2, metadata !3, metadata !2, metadata !2} ; [ DW_TAG_compile_unit ] [/tmp/build0/../2.cc] [DW_LANG_C99] -!1 = metadata !{metadata !"../2.cc", metadata !"/tmp/build0"} -!2 = metadata !{} -!3 = metadata !{metadata !4} -!4 = metadata !{metadata !"0x2e\00Store\00Store\00\001\000\001\000\006\00256\001\001", metadata !1, metadata !5, metadata !6, null, void (i32*, i32)* @Store, null, null, metadata !10} ; [ DW_TAG_subprogram ] [line 1] [def] [Store] -!5 = metadata !{metadata !"0x29", metadata !1} ; [ DW_TAG_file_type ] [/tmp/build0/../2.cc] -!6 = metadata !{metadata !"0x15\00\000\000\000\000\000\000", i32 0, null, null, metadata !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] -!7 = metadata !{null, metadata !8, metadata !9} -!8 = metadata !{metadata !"0xf\00\000\0064\0064\000\000", null, null, metadata !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int] -!9 = metadata !{metadata !"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] -!10 = metadata !{metadata !11, metadata !12} -!11 = metadata !{metadata !"0x101\00p\0016777217\000", metadata !4, metadata !5, metadata !8} ; [ DW_TAG_arg_variable ] [p] [line 1] -!12 = metadata !{metadata !"0x101\00x\0033554433\000", metadata !4, metadata !5, metadata !9} ; [ DW_TAG_arg_variable ] [x] [line 1] -!13 = metadata !{i32 2, metadata !"Dwarf Version", i32 4} -!14 = metadata !{i32 1, metadata !"Debug Info Version", i32 2} -!15 = metadata !{metadata !"clang version 3.5.0 (204220)"} -!16 = metadata !{i32 1, i32 0, metadata !4, null} -!17 = metadata !{i32 2, i32 0, metadata !4, null} -!18 = metadata !{metadata !19, metadata !19, i64 0} -!19 = metadata !{metadata !"int", metadata !20, i64 0} -!20 = metadata !{metadata !"omnipotent char", metadata !21, i64 0} -!21 = metadata !{metadata !"Simple C/C++ TBAA"} -!22 = metadata !{i32 3, i32 0, metadata !4, null} +!0 = !{!"0x11\0012\00clang version 3.5.0 (204220)\001\00\000\00\001", !1, !2, !2, !3, !2, !2} ; [ DW_TAG_compile_unit ] [/tmp/build0/../2.cc] [DW_LANG_C99] +!1 = !{!"../2.cc", !"/tmp/build0"} +!2 = !{} +!3 = !{!4} +!4 = !{!"0x2e\00Store\00Store\00\001\000\001\000\006\00256\001\001", !1, !5, !6, null, void (i32*, i32)* @Store, null, null, !10} ; [ DW_TAG_subprogram ] [line 1] [def] [Store] +!5 = !{!"0x29", !1} ; [ DW_TAG_file_type ] [/tmp/build0/../2.cc] +!6 = !{!"0x15\00\000\000\000\000\000\000", i32 0, null, null, !7, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] +!7 = !{null, !8, !9} +!8 = !{!"0xf\00\000\0064\0064\000\000", null, null, !9} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from int] +!9 = !{!"0x24\00int\000\0032\0032\000\000\005", null, null} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] +!10 = !{!11, !12} +!11 = !{!"0x101\00p\0016777217\000", !4, !5, !8} ; [ DW_TAG_arg_variable ] [p] [line 1] +!12 = !{!"0x101\00x\0033554433\000", !4, !5, !9} ; [ DW_TAG_arg_variable ] [x] [line 1] +!13 = !{i32 2, !"Dwarf Version", i32 4} +!14 = !{i32 1, !"Debug Info Version", i32 2} +!15 = !{!"clang version 3.5.0 (204220)"} +!16 = !MDLocation(line: 1, scope: !4) +!17 = !MDLocation(line: 2, scope: !4) +!18 = !{!19, !19, i64 0} +!19 = !{!"int", !20, i64 0} +!20 = !{!"omnipotent char", !21, i64 0} +!21 = !{!"Simple C/C++ TBAA"} +!22 = !MDLocation(line: 3, scope: !4) ; CHECK: @Store diff --git a/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll b/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll deleted file mode 100644 index 65037cb..0000000 --- a/test/Instrumentation/MemorySanitizer/wrap_indirect_calls.ll +++ /dev/null @@ -1,60 +0,0 @@ -; RUN: opt < %s -msan -msan-check-access-address=0 -msan-wrap-indirect-calls=zzz -msan-wrap-indirect-calls-fast=0 -S | FileCheck %s -; RUN: opt < %s -msan -msan-check-access-address=0 -msan-wrap-indirect-calls=zzz -msan-wrap-indirect-calls-fast=1 -S | FileCheck -check-prefix=CHECK-FAST %s -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" -target triple = "x86_64-unknown-linux-gnu" - -; Test for -msan-wrap-indirect-calls functionality. -; Replaces indirect call to %f with a call to whatever is returned from the -; wrapper function. - -; This does not depend on the sanitize_memory attribute. -define i32 @func1(i32 (i32, i32)* nocapture %f, i32 %x, i32 %y) { -entry: - %call = tail call i32 %f(i32 %x, i32 %y) - ret i32 %call -} - -; CHECK: @func1 -; CHECK: bitcast i32 (i32, i32)* %f to void ()* -; CHECK: call void ()* (void ()*)* @zzz(void ()* -; CHECK: [[A:%[01-9a-z_.]+]] = bitcast void ()* {{.*}} to i32 (i32, i32)* -; CHECK: call i32 {{.*}}[[A]](i32 {{.*}}, i32 {{.*}}) -; CHECK: ret i32 - -; CHECK-FAST: @func1 -; CHECK-FAST: bitcast i32 (i32, i32)* %f to void ()* -; CHECK-FAST-DAG: icmp ult void ()* {{.*}}, bitcast (i32* @__executable_start to void ()*) -; CHECK-FAST-DAG: icmp uge void ()* {{.*}}, bitcast (i32* @_end to void ()*) -; CHECK-FAST: or i1 -; CHECK-FAST: br i1 -; CHECK-FAST: call void ()* (void ()*)* @zzz(void ()* -; CHECK-FAST: br label -; CHECK-FAST: [[A:%[01-9a-z_.]+]] = phi i32 (i32, i32)* [ %f, %entry ], [ {{.*}} ] -; CHECK-FAST: call i32 {{.*}}[[A]](i32 {{.*}}, i32 {{.*}}) -; CHECK-FAST: ret i32 - - -; The same test, but with a complex expression as the call target. - -declare i8* @callee(i32) - -define i8* @func2(i64 %x) #1 { -entry: - %call = tail call i8* bitcast (i8* (i32)* @callee to i8* (i64)*)(i64 %x) - ret i8* %call -} - -; CHECK: @func2 -; CHECK: call {{.*}} @zzz -; CHECK: [[A:%[01-9a-z_.]+]] = bitcast void ()* {{.*}} to i8* (i64)* -; CHECK: call i8* {{.*}}[[A]](i64 {{.*}}) -; CHECK: ret i8* - -; CHECK-FAST: @func2 -; CHECK-FAST: {{br i1 or .* icmp ult .* bitcast .* @callee .* @__executable_start.* icmp uge .* bitcast .* @callee .* @_end}} -; CHECK-FAST: {{call .* @zzz.* bitcast .*@callee}} -; CHECK-FAST: bitcast void ()* {{.*}} to i8* (i64)* -; CHECK-FAST: br label -; CHECK-FAST: [[A:%[01-9a-z_.]+]] = phi i8* (i64)* [{{.*bitcast .* @callee.*, %entry.*}}], [ {{.*}} ] -; CHECK-FAST: call i8* {{.*}}[[A]](i64 {{.*}}) -; CHECK-FAST: ret i8* |