152 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes="function(ee-instrument),cgscc(inline),function(ee-instrument<post-inline>)" -S < %s | FileCheck %s3 4; Running the passes twice should not result in more instrumentation.5; RUN: opt -passes="function(ee-instrument),function(ee-instrument),cgscc(inline),function(ee-instrument<post-inline>),function(ee-instrument<post-inline>)" -S < %s | FileCheck %s6 7target datalayout = "E-m:e-i64:64-n32:64"8target triple = "powerpc64le-unknown-linux"9 10define void @leaf_function() #0 {11; CHECK-LABEL: define void @leaf_function() {12; CHECK-NEXT: call void @mcount()13; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0)14; CHECK-NEXT: call void @__cyg_profile_func_enter(ptr @leaf_function, ptr [[TMP1]])15; CHECK-NEXT: [[TMP2:%.*]] = call ptr @llvm.returnaddress(i32 0)16; CHECK-NEXT: call void @__cyg_profile_func_exit(ptr @leaf_function, ptr [[TMP2]])17; CHECK-NEXT: ret void18;19 ret void20}21 22 23define void @root_function() #0 {24; CHECK-LABEL: define void @root_function() {25; CHECK-NEXT: call void @mcount()26; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0)27; CHECK-NEXT: call void @__cyg_profile_func_enter(ptr @root_function, ptr [[TMP1]])28; CHECK-NEXT: [[TMP2:%.*]] = call ptr @llvm.returnaddress(i32 0)29; CHECK-NEXT: call void @__cyg_profile_func_enter(ptr @leaf_function, ptr [[TMP2]])30; CHECK-NEXT: [[TMP3:%.*]] = call ptr @llvm.returnaddress(i32 0)31; CHECK-NEXT: call void @__cyg_profile_func_exit(ptr @leaf_function, ptr [[TMP3]])32; CHECK-NEXT: [[TMP4:%.*]] = call ptr @llvm.returnaddress(i32 0)33; CHECK-NEXT: call void @__cyg_profile_func_exit(ptr @root_function, ptr [[TMP4]])34; CHECK-NEXT: ret void35;36 call void @leaf_function()37 ret void38}39 40; The mcount function has many different names.41 42define void @f1() #1 {43; CHECK-LABEL: define void @f1() {44; CHECK-NEXT: call void @.mcount()45; CHECK-NEXT: ret void46;47 ret void48}49 50define void @f2() #2 {51; CHECK-LABEL: define void @f2() {52; CHECK-NEXT: call void @llvm.arm.gnu.eabi.mcount()53; CHECK-NEXT: ret void54;55 ret void56}57 58define void @f3() #3 {59; CHECK-LABEL: define void @f3() {60; CHECK-NEXT: call void @"\01_mcount"()61; CHECK-NEXT: ret void62;63 ret void64}65 66define void @f4() #4 {67; CHECK-LABEL: define void @f4() {68; CHECK-NEXT: call void @"\01mcount"()69; CHECK-NEXT: ret void70;71 ret void72}73 74define void @f5() #5 {75; CHECK-LABEL: define void @f5() {76; CHECK-NEXT: call void @__mcount()77; CHECK-NEXT: ret void78;79 ret void80}81 82define void @f6() #6 {83; CHECK-LABEL: define void @f6() {84; CHECK-NEXT: call void @_mcount()85; CHECK-NEXT: ret void86;87 ret void88}89 90define void @f7() #7 {91; CHECK-LABEL: define void @f7() {92; CHECK-NEXT: call void @__cyg_profile_func_enter_bare()93; CHECK-NEXT: ret void94;95 ret void96}97 98; Treat musttail calls as terminators; inserting between the musttail call and99; ret is not allowed.100declare ptr @tailcallee()101define ptr @tailcaller() #8 {102; CHECK-LABEL: define ptr @tailcaller() {103; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0)104; CHECK-NEXT: call void @__cyg_profile_func_exit(ptr @tailcaller, ptr [[TMP1]])105; CHECK-NEXT: [[TMP2:%.*]] = musttail call ptr @tailcallee()106; CHECK-NEXT: ret ptr [[TMP2]]107;108 %1 = musttail call ptr @tailcallee()109 ret ptr %1110}111define ptr @tailcaller2() #8 {112; CHECK-LABEL: define ptr @tailcaller2() {113; CHECK-NEXT: [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0)114; CHECK-NEXT: call void @__cyg_profile_func_exit(ptr @tailcaller2, ptr [[TMP1]])115; CHECK-NEXT: [[TMP2:%.*]] = musttail call ptr @tailcallee()116; CHECK-NEXT: ret ptr [[TMP2]]117;118 %1 = musttail call ptr @tailcallee()119 ret ptr %1120}121 122;; naked functions are not instrumented, otherwise the argument registers123;; and the return address register (if present) would be clobbered.124define void @naked() naked {125; CHECK-LABEL: define void @naked(126; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {127; CHECK-NEXT: ret void128;129 ret void130}131 132define available_externally void @always_inline() {133; CHECK-LABEL: define available_externally void @always_inline() {134; CHECK-NEXT: ret void135;136 ret void137}138 139; The attributes are "consumed" when the instrumentation is inserted.140; CHECK: attributes141; CHECK-NOT: instrument-function142 143attributes #0 = { "instrument-function-entry-inlined"="mcount" "instrument-function-entry"="__cyg_profile_func_enter" "instrument-function-exit"="__cyg_profile_func_exit" }144attributes #1 = { "instrument-function-entry-inlined"=".mcount" }145attributes #2 = { "instrument-function-entry-inlined"="llvm.arm.gnu.eabi.mcount" }146attributes #3 = { "instrument-function-entry-inlined"="\01_mcount" }147attributes #4 = { "instrument-function-entry-inlined"="\01mcount" }148attributes #5 = { "instrument-function-entry-inlined"="__mcount" }149attributes #6 = { "instrument-function-entry-inlined"="_mcount" }150attributes #7 = { "instrument-function-entry-inlined"="__cyg_profile_func_enter_bare" }151attributes #8 = { "instrument-function-exit"="__cyg_profile_func_exit" }152