Home | History | Annotate | Download | only in Inline
      1 ; RUN: opt -S -always-inline < %s | FileCheck %s
      2 
      3 declare void @f()
      4 declare i32 @g()
      5 declare fastcc i32 @g.fastcc()
      6 
      7 define i32 @callee_0() alwaysinline {
      8  entry:
      9   call void @f()
     10   ret i32 2
     11 }
     12 
     13 define i32 @caller_0() {
     14 ; CHECK-LABEL: @caller_0(
     15  entry:
     16 ; CHECK: entry:
     17 ; CHECK-NEXT: call void @f()
     18 ; CHECK-NEXT: ret i32 2
     19   %x = call i32 @callee_0() [ "deopt"(i32 5) ]
     20   ret i32 %x
     21 }
     22 
     23 define i32 @callee_1() alwaysinline {
     24  entry:
     25   call void @f() [ "deopt"() ]
     26   call void @f() [ "deopt"(i32 0, i32 1) ]
     27   call void @f() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
     28   ret i32 2
     29 }
     30 
     31 define i32 @caller_1() {
     32 ; CHECK-LABEL: @caller_1(
     33  entry:
     34 ; CHECK: entry:
     35 ; CHECK-NEXT:  call void @f() [ "deopt"(i32 5) ]
     36 ; CHECK-NEXT:  call void @f() [ "deopt"(i32 5, i32 0, i32 1) ]
     37 ; CHECK-NEXT:  call void @f() [ "deopt"(i32 5, i32 0, i32 1), "foo"(double 0.000000e+00) ]
     38 ; CHECK-NEXT:  ret i32 2
     39 
     40   %x = call i32 @callee_1() [ "deopt"(i32 5) ]
     41   ret i32 %x
     42 }
     43 
     44 define i32 @callee_2() alwaysinline {
     45  entry:
     46   %v = call i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
     47   ret i32 %v
     48 }
     49 
     50 define i32 @caller_2(i32 %val) {
     51 ; CHECK-LABEL: @caller_2(
     52  entry:
     53 ; CHECK: entry:
     54 ; CHECK-NEXT:   [[RVAL:%[^ ]+]] = call i32 @g() [ "deopt"(i32 %val, i32 0, i32 1), "foo"(double 0.000000e+00) ]
     55 ; CHECK-NEXT:   ret i32 [[RVAL]]
     56   %x = call i32 @callee_2() [ "deopt"(i32 %val) ]
     57   ret i32 %x
     58 }
     59 
     60 define i32 @callee_3() alwaysinline {
     61  entry:
     62   %v = call i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
     63   ret i32 %v
     64 }
     65 
     66 define i32 @caller_3() personality i8 3 {
     67 ; CHECK-LABEL: @caller_3(
     68  entry:
     69   %x = invoke i32 @callee_3() [ "deopt"(i32 7) ] to label %normal unwind label %unwind
     70 ; CHECK: invoke i32 @g() [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
     71 
     72  normal:
     73   ret i32 %x
     74 
     75  unwind:
     76   %cleanup = landingpad i8 cleanup
     77   ret i32 101
     78 }
     79 
     80 define i32 @callee_4() alwaysinline personality i8 3 {
     81  entry:
     82   %v = invoke i32 @g() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] to label %normal unwind label %unwind
     83 
     84  normal:
     85   ret i32 %v
     86 
     87  unwind:
     88   %cleanup = landingpad i8 cleanup
     89   ret i32 100
     90 }
     91 
     92 define i32 @caller_4() {
     93 ; CHECK-LABEL: @caller_4(
     94  entry:
     95 ; CHECK: invoke i32 @g() [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
     96   %x = call i32 @callee_4() [ "deopt"(i32 7) ]
     97   ret i32 %x
     98 }
     99 
    100 define i32 @callee_5() alwaysinline personality i8 3 {
    101  entry:
    102   %v = invoke fastcc i32 @g.fastcc() #0 [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ] to label %normal unwind label %unwind
    103 
    104  normal:
    105   ret i32 %v
    106 
    107  unwind:
    108   %cleanup = landingpad i8 cleanup
    109   ret i32 100
    110 }
    111 
    112 define i32 @caller_5() {
    113 ; CHECK-LABEL: @caller_5(
    114  entry:
    115 ; CHECK:  invoke fastcc i32 @g.fastcc() #[[FOO_BAR_ATTR_IDX:[0-9]+]] [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
    116   %x = call i32 @callee_5() [ "deopt"(i32 7) ]
    117   ret i32 %x
    118 }
    119 
    120 define i32 @callee_6() alwaysinline personality i8 3 {
    121  entry:
    122   %v = call fastcc i32 @g.fastcc() #0 [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
    123   ret i32 %v
    124 }
    125 
    126 define i32 @caller_6() {
    127 ; CHECK-LABEL: @caller_6(
    128  entry:
    129 ; CHECK: call fastcc i32 @g.fastcc() #[[FOO_BAR_ATTR_IDX]] [ "deopt"(i32 7, i32 0, i32 1), "foo"(double 0.000000e+00) ]
    130   %x = call i32 @callee_6() [ "deopt"(i32 7) ]
    131   ret i32 %x
    132 }
    133 
    134 define i32 @callee_7(i1 %val) alwaysinline personality i8 3 {
    135 ; We want something that PruningFunctionCloner is not smart enough to
    136 ; recognize, but can be recognized by recursivelySimplifyInstruction.
    137 
    138  entry:
    139   br i1 %val, label %check, label %precheck
    140 
    141  precheck:
    142   br label %check
    143 
    144  check:
    145   %p = phi i1 [ %val, %entry ], [ true, %precheck ]
    146   br i1 %p, label %do.not, label %do
    147 
    148  do.not:
    149   ret i32 0
    150 
    151  do:
    152   %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
    153   ret i32 %v
    154 }
    155 
    156 define i32 @caller_7() {
    157 ; CHECK-LABEL: @caller_7(
    158  entry:
    159 ; CHECK-NOT: call fastcc i32 @g.fastcc()
    160 ; CHECK: ret i32 0
    161   %x = call i32 @callee_7(i1 true) [ "deopt"(i32 7) ]
    162   ret i32 %x
    163 }
    164 
    165 define i32 @callee_8(i1 %val) alwaysinline personality i8 3 {
    166 ; We want something that PruningFunctionCloner is not smart enough to
    167 ; recognize, but can be recognized by recursivelySimplifyInstruction.
    168 
    169  entry:
    170   br i1 %val, label %check, label %precheck
    171 
    172  precheck:
    173   br label %check
    174 
    175  check:
    176   %p = phi i1 [ %val, %entry ], [ true, %precheck ]
    177   br i1 %p, label %do.not, label %do
    178 
    179  do.not:
    180   ret i32 0
    181 
    182  do:
    183   %phi = phi i32 [ 0, %check ], [ %v, %do ]
    184   %v = call fastcc i32 @g.fastcc() [ "deopt"(i32 0, i32 1), "foo"(double 0.0) ]
    185   %ic = icmp eq i32 %v, 42
    186   br i1 %ic, label %do, label %done
    187 
    188  done:
    189   ret i32 %phi
    190 }
    191 
    192 define i32 @caller_8() {
    193 ; CHECK-LABEL: @caller_8(
    194  entry:
    195 ; CHECK-NOT: call fastcc i32 @g.fastcc()
    196 ; CHECK: ret i32 0
    197   %x = call i32 @callee_8(i1 true) [ "deopt"(i32 7) ]
    198   ret i32 %x
    199 }
    200 
    201 attributes #0 = { "foo"="bar" }
    202 
    203 ; CHECK: attributes #[[FOO_BAR_ATTR_IDX]] = { "foo"="bar" }
    204