Home | History | Annotate | Download | only in Inline
      1 ; RUN: opt < %s -inline -inline-threshold=20 -S | FileCheck %s
      2 
      3 define internal i32 @callee1(i32 %A, i32 %B) {
      4   %C = sdiv i32 %A, %B
      5   ret i32 %C
      6 }
      7 
      8 define i32 @caller1() {
      9 ; CHECK-LABEL: define i32 @caller1(
     10 ; CHECK-NEXT: ret i32 3
     11 
     12   %X = call i32 @callee1( i32 10, i32 3 )
     13   ret i32 %X
     14 }
     15 
     16 define i32 @caller2() {
     17 ; Check that we can constant-prop through instructions after inlining callee21
     18 ; to get constants in the inlined callsite to callee22.
     19 ; FIXME: Currently, the threshold is fixed at 20 because we don't perform
     20 ; *recursive* cost analysis to realize that the nested call site will definitely
     21 ; inline and be cheap. We should eventually do that and lower the threshold here
     22 ; to 1.
     23 ;
     24 ; CHECK-LABEL: @caller2(
     25 ; CHECK-NOT: call void @callee2
     26 ; CHECK: ret
     27 
     28   %x = call i32 @callee21(i32 42, i32 48)
     29   ret i32 %x
     30 }
     31 
     32 define i32 @callee21(i32 %x, i32 %y) {
     33   %sub = sub i32 %y, %x
     34   %result = call i32 @callee22(i32 %sub)
     35   ret i32 %result
     36 }
     37 
     38 declare i8* @getptr()
     39 
     40 define i32 @callee22(i32 %x) {
     41   %icmp = icmp ugt i32 %x, 42
     42   br i1 %icmp, label %bb.true, label %bb.false
     43 bb.true:
     44   ; This block musn't be counted in the inline cost.
     45   %x1 = add i32 %x, 1
     46   %x2 = add i32 %x1, 1
     47   %x3 = add i32 %x2, 1
     48   %x4 = add i32 %x3, 1
     49   %x5 = add i32 %x4, 1
     50   %x6 = add i32 %x5, 1
     51   %x7 = add i32 %x6, 1
     52   %x8 = add i32 %x7, 1
     53 
     54   ret i32 %x8
     55 bb.false:
     56   ret i32 %x
     57 }
     58 
     59 define i32 @caller3() {
     60 ; Check that even if the expensive path is hidden behind several basic blocks,
     61 ; it doesn't count toward the inline cost when constant-prop proves those paths
     62 ; dead.
     63 ;
     64 ; CHECK-LABEL: @caller3(
     65 ; CHECK-NOT: call
     66 ; CHECK: ret i32 6
     67 
     68 entry:
     69   %x = call i32 @callee3(i32 42, i32 48)
     70   ret i32 %x
     71 }
     72 
     73 define i32 @callee3(i32 %x, i32 %y) {
     74   %sub = sub i32 %y, %x
     75   %icmp = icmp ugt i32 %sub, 42
     76   br i1 %icmp, label %bb.true, label %bb.false
     77 
     78 bb.true:
     79   %icmp2 = icmp ult i32 %sub, 64
     80   br i1 %icmp2, label %bb.true.true, label %bb.true.false
     81 
     82 bb.true.true:
     83   ; This block musn't be counted in the inline cost.
     84   %x1 = add i32 %x, 1
     85   %x2 = add i32 %x1, 1
     86   %x3 = add i32 %x2, 1
     87   %x4 = add i32 %x3, 1
     88   %x5 = add i32 %x4, 1
     89   %x6 = add i32 %x5, 1
     90   %x7 = add i32 %x6, 1
     91   %x8 = add i32 %x7, 1
     92   br label %bb.merge
     93 
     94 bb.true.false:
     95   ; This block musn't be counted in the inline cost.
     96   %y1 = add i32 %y, 1
     97   %y2 = add i32 %y1, 1
     98   %y3 = add i32 %y2, 1
     99   %y4 = add i32 %y3, 1
    100   %y5 = add i32 %y4, 1
    101   %y6 = add i32 %y5, 1
    102   %y7 = add i32 %y6, 1
    103   %y8 = add i32 %y7, 1
    104   br label %bb.merge
    105 
    106 bb.merge:
    107   %result = phi i32 [ %x8, %bb.true.true ], [ %y8, %bb.true.false ]
    108   ret i32 %result
    109 
    110 bb.false:
    111   ret i32 %sub
    112 }
    113 
    114 declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
    115 
    116 define i8 @caller4(i8 %z) {
    117 ; Check that we can constant fold through intrinsics such as the
    118 ; overflow-detecting arithmetic instrinsics. These are particularly important
    119 ; as they are used heavily in standard library code and generic C++ code where
    120 ; the arguments are oftent constant but complete generality is required.
    121 ;
    122 ; CHECK-LABEL: @caller4(
    123 ; CHECK-NOT: call
    124 ; CHECK: ret i8 -1
    125 
    126 entry:
    127   %x = call i8 @callee4(i8 254, i8 14, i8 %z)
    128   ret i8 %x
    129 }
    130 
    131 define i8 @callee4(i8 %x, i8 %y, i8 %z) {
    132   %uadd = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %x, i8 %y)
    133   %o = extractvalue {i8, i1} %uadd, 1
    134   br i1 %o, label %bb.true, label %bb.false
    135 
    136 bb.true:
    137   ret i8 -1
    138 
    139 bb.false:
    140   ; This block musn't be counted in the inline cost.
    141   %z1 = add i8 %z, 1
    142   %z2 = add i8 %z1, 1
    143   %z3 = add i8 %z2, 1
    144   %z4 = add i8 %z3, 1
    145   %z5 = add i8 %z4, 1
    146   %z6 = add i8 %z5, 1
    147   %z7 = add i8 %z6, 1
    148   %z8 = add i8 %z7, 1
    149   ret i8 %z8
    150 }
    151 
    152 define i64 @caller5(i64 %y) {
    153 ; Check that we can round trip constants through various kinds of casts etc w/o
    154 ; losing track of the constant prop in the inline cost analysis.
    155 ;
    156 ; CHECK-LABEL: @caller5(
    157 ; CHECK-NOT: call
    158 ; CHECK: ret i64 -1
    159 
    160 entry:
    161   %x = call i64 @callee5(i64 42, i64 %y)
    162   ret i64 %x
    163 }
    164 
    165 define i64 @callee5(i64 %x, i64 %y) {
    166   %inttoptr = inttoptr i64 %x to i8*
    167   %bitcast = bitcast i8* %inttoptr to i32*
    168   %ptrtoint = ptrtoint i32* %bitcast to i64
    169   %trunc = trunc i64 %ptrtoint to i32
    170   %zext = zext i32 %trunc to i64
    171   %cmp = icmp eq i64 %zext, 42
    172   br i1 %cmp, label %bb.true, label %bb.false
    173 
    174 bb.true:
    175   ret i64 -1
    176 
    177 bb.false:
    178   ; This block musn't be counted in the inline cost.
    179   %y1 = add i64 %y, 1
    180   %y2 = add i64 %y1, 1
    181   %y3 = add i64 %y2, 1
    182   %y4 = add i64 %y3, 1
    183   %y5 = add i64 %y4, 1
    184   %y6 = add i64 %y5, 1
    185   %y7 = add i64 %y6, 1
    186   %y8 = add i64 %y7, 1
    187   ret i64 %y8
    188 }
    189 
    190 define float @caller6() {
    191 ; Check that we can constant-prop through fcmp instructions
    192 ;
    193 ; CHECK-LABEL: @caller6(
    194 ; CHECK-NOT: call
    195 ; CHECK: ret
    196   %x = call float @callee6(float 42.0)
    197   ret float %x
    198 }
    199 
    200 define float @callee6(float %x) {
    201   %icmp = fcmp ugt float %x, 42.0
    202   br i1 %icmp, label %bb.true, label %bb.false
    203 
    204 bb.true:
    205   ; This block musn't be counted in the inline cost.
    206   %x1 = fadd float %x, 1.0
    207   %x2 = fadd float %x1, 1.0
    208   %x3 = fadd float %x2, 1.0
    209   %x4 = fadd float %x3, 1.0
    210   %x5 = fadd float %x4, 1.0
    211   %x6 = fadd float %x5, 1.0
    212   %x7 = fadd float %x6, 1.0
    213   %x8 = fadd float %x7, 1.0
    214   ret float %x8
    215 
    216 bb.false:
    217   ret float %x
    218 }
    219 
    220 
    221 
    222 define i32 @PR13412.main() {
    223 ; This is a somewhat complicated three layer subprogram that was reported to
    224 ; compute the wrong value for a branch due to assuming that an argument
    225 ; mid-inline couldn't be equal to another pointer.
    226 ;
    227 ; After inlining, the branch should point directly to the exit block, not to
    228 ; the intermediate block.
    229 ; CHECK: @PR13412.main
    230 ; CHECK: br i1 true, label %[[TRUE_DEST:.*]], label %[[FALSE_DEST:.*]]
    231 ; CHECK: [[FALSE_DEST]]:
    232 ; CHECK-NEXT: call void @PR13412.fail()
    233 ; CHECK: [[TRUE_DEST]]:
    234 ; CHECK-NEXT: ret i32 0
    235 
    236 entry:
    237   %i1 = alloca i64
    238   store i64 0, i64* %i1
    239   %arraydecay = bitcast i64* %i1 to i32*
    240   %call = call i1 @PR13412.first(i32* %arraydecay, i32* %arraydecay)
    241   br i1 %call, label %cond.end, label %cond.false
    242 
    243 cond.false:
    244   call void @PR13412.fail()
    245   br label %cond.end
    246 
    247 cond.end:
    248   ret i32 0
    249 }
    250 
    251 define internal i1 @PR13412.first(i32* %a, i32* %b) {
    252 entry:
    253   %call = call i32* @PR13412.second(i32* %a, i32* %b)
    254   %cmp = icmp eq i32* %call, %b
    255   ret i1 %cmp
    256 }
    257 
    258 declare void @PR13412.fail()
    259 
    260 define internal i32* @PR13412.second(i32* %a, i32* %b) {
    261 entry:
    262   %sub.ptr.lhs.cast = ptrtoint i32* %b to i64
    263   %sub.ptr.rhs.cast = ptrtoint i32* %a to i64
    264   %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
    265   %sub.ptr.div = ashr exact i64 %sub.ptr.sub, 2
    266   %cmp = icmp ugt i64 %sub.ptr.div, 1
    267   br i1 %cmp, label %if.then, label %if.end3
    268 
    269 if.then:
    270   %0 = load i32* %a
    271   %1 = load i32* %b
    272   %cmp1 = icmp eq i32 %0, %1
    273   br i1 %cmp1, label %return, label %if.end3
    274 
    275 if.end3:
    276   br label %return
    277 
    278 return:
    279   %retval.0 = phi i32* [ %b, %if.end3 ], [ %a, %if.then ]
    280   ret i32* %retval.0
    281 }
    282