Home | History | Annotate | Download | only in Inline
      1 ; This test tries to ensure that the inliner successfully invalidates function
      2 ; analyses after inlining into the function body.
      3 ;
      4 ; The strategy for these tests is to compute domtree over all the functions,
      5 ; then run the inliner, and then verify the domtree. Then we can arrange the
      6 ; inline to disturb the domtree (easy) and detect any stale cached entries in
      7 ; the verifier. We do the initial computation both *inside* the CGSCC walk and
      8 ; in a pre-step to make sure both work.
      9 ;
     10 ; RUN: opt < %s -passes='function(require<domtree>),cgscc(inline,function(verify<domtree>))' -S | FileCheck %s
     11 ; RUN: opt < %s -passes='cgscc(function(require<domtree>),inline,function(verify<domtree>))' -S | FileCheck %s
     12 
     13 ; An external function used to control branches.
     14 declare i1 @flag()
     15 ; CHECK-LABEL: declare i1 @flag()
     16 
     17 ; The utility function with interesting control flow that gets inlined below to
     18 ; perturb the dominator tree.
     19 define internal void @callee() {
     20 ; CHECK-LABEL: @callee
     21 entry:
     22   %ptr = alloca i8
     23   %flag = call i1 @flag()
     24   br i1 %flag, label %then, label %else
     25 
     26 then:
     27   store volatile i8 42, i8* %ptr
     28   br label %return
     29 
     30 else:
     31   store volatile i8 -42, i8* %ptr
     32   br label %return
     33 
     34 return:
     35   ret void
     36 }
     37 
     38 
     39 ; The 'test1_' prefixed functions test the basic scenario of inlining
     40 ; destroying dominator tree.
     41 
     42 define void @test1_caller() {
     43 ; CHECK-LABEL: define void @test1_caller()
     44 entry:
     45   call void @callee()
     46 ; CHECK-NOT: @callee
     47   ret void
     48 ; CHECK: ret void
     49 }
     50 
     51 
     52 ; The 'test2_' prefixed functions test the scenario of not inlining preserving
     53 ; dominators.
     54 
     55 define void @test2_caller() {
     56 ; CHECK-LABEL: define void @test2_caller()
     57 entry:
     58   call void @callee() noinline
     59 ; CHECK: call void @callee
     60   ret void
     61 ; CHECK: ret void
     62 }
     63 
     64 
     65 ; The 'test3_' prefixed functions test the scenario of not inlining preserving
     66 ; dominators after splitting an SCC into two smaller SCCs.
     67 
     68 ; This function ends up split into a separate SCC, which can cause its analyses
     69 ; to become stale if the splitting doesn't properly invalidate things. Also, as
     70 ; a consequence of being split out, test3_f is too large to inline by the time
     71 ; we get here.
     72 define void @test3_g() {
     73 ; CHECK-LABEL: define void @test3_g()
     74 entry:
     75   ; Create the second edge in the SCC cycle.
     76   call void @test3_f()
     77 ; CHECK: call void @test3_f()
     78 
     79   ; Pull interesting CFG into this function.
     80   call void @callee()
     81 ; CHECK-NOT: call void @callee()
     82 
     83   ret void
     84 ; CHECK: ret void
     85 }
     86 
     87 ; The second function gets visited first and we end up inlining everything we
     88 ; can into this routine. That splits test3_g into a separate SCC that is enqued
     89 ; for later processing.
     90 define void @test3_f() {
     91 ; CHECK-LABEL: define void @test3_f()
     92 entry:
     93   ; Create the first edge in the SCC cycle.
     94   call void @test3_g()
     95 ; CHECK-NOT: @test3_g()
     96 ; CHECK: call void @test3_f()
     97 
     98   ; Pull interesting CFG into this function.
     99   call void @callee()
    100 ; CHECK-NOT: call void @callee()
    101 
    102   ret void
    103 ; CHECK: ret void
    104 }
    105