Home | History | Annotate | Download | only in Other
      1 ; Make sure that even without some external devirtualization iteration tool,
      2 ; the CGSCC pass manager correctly observes and re-visits SCCs that change
      3 ; structure due to devirtualization. We trigger devirtualization here with GVN
      4 ; which forwards a store through a load and to an indirect call.
      5 ;
      6 ; RUN: opt -aa-pipeline=basic-aa -passes='cgscc(function-attrs)' -S < %s | FileCheck %s --check-prefix=BEFORE
      7 ; RUN: opt -aa-pipeline=basic-aa -passes='cgscc(function-attrs,function(gvn))' -S < %s | FileCheck %s --check-prefix=AFTER
      8 ;
      9 ; Also check that adding an extra CGSCC pass after the function update but
     10 ; without requiring the outer manager to iterate doesn't break any invariant.
     11 ; RUN: opt -aa-pipeline=basic-aa -passes='cgscc(function-attrs,function(gvn),function-attrs)' -S < %s | FileCheck %s --check-prefix=AFTER
     12 
     13 declare void @readnone() readnone
     14 declare void @unknown()
     15 
     16 ; The @test1_* checks that if we refine an indirect call to a direct call and
     17 ; in the process change the very structure of the call graph we also revisit
     18 ; that component of the graph and do so in an up-to-date fashion.
     19 
     20 ; BEFORE: define void @test1_a1() {
     21 ; AFTER: define void @test1_a1() {
     22 define void @test1_a1() {
     23   %fptr = alloca void()*
     24   store void()* @test1_b2, void()** %fptr
     25   store void()* @test1_b1, void()** %fptr
     26   %f = load void()*, void()** %fptr
     27   call void %f()
     28   ret void
     29 }
     30 
     31 ; BEFORE: define void @test1_b1() {
     32 ; AFTER: define void @test1_b1() {
     33 define void @test1_b1() {
     34   call void @unknown()
     35   call void @test1_a1()
     36   ret void
     37 }
     38 
     39 ; BEFORE: define void @test1_a2() {
     40 ; AFTER: define void @test1_a2() #0 {
     41 define void @test1_a2() {
     42   %fptr = alloca void()*
     43   store void()* @test1_b1, void()** %fptr
     44   store void()* @test1_b2, void()** %fptr
     45   %f = load void()*, void()** %fptr
     46   call void %f()
     47   ret void
     48 }
     49 
     50 ; BEFORE: define void @test1_b2() {
     51 ; AFTER: define void @test1_b2() #0 {
     52 define void @test1_b2() {
     53   call void @readnone()
     54   call void @test1_a2()
     55   ret void
     56 }
     57 
     58 
     59 ; The @test2_* set of functions exercise a case where running function passes
     60 ; introduces a new post-order relationship that was not present originally and
     61 ; makes sure we walk across the SCCs in that order.
     62 
     63 ; CHECK: define void @test2_a() {
     64 define void @test2_a() {
     65   call void @test2_b1()
     66   call void @test2_b2()
     67   call void @test2_b3()
     68   call void @unknown()
     69   ret void
     70 }
     71 
     72 ; CHECK: define void @test2_b1() #0 {
     73 define void @test2_b1() {
     74   %fptr = alloca void()*
     75   store void()* @test2_a, void()** %fptr
     76   store void()* @readnone, void()** %fptr
     77   %f = load void()*, void()** %fptr
     78   call void %f()
     79   ret void
     80 }
     81 
     82 ; CHECK: define void @test2_b2() #0 {
     83 define void @test2_b2() {
     84   %fptr = alloca void()*
     85   store void()* @test2_a, void()** %fptr
     86   store void()* @test2_b2, void()** %fptr
     87   store void()* @test2_b3, void()** %fptr
     88   store void()* @test2_b1, void()** %fptr
     89   %f = load void()*, void()** %fptr
     90   call void %f()
     91   ret void
     92 }
     93 
     94 ; CHECK: define void @test2_b3() #0 {
     95 define void @test2_b3() {
     96   %fptr = alloca void()*
     97   store void()* @test2_a, void()** %fptr
     98   store void()* @test2_b2, void()** %fptr
     99   store void()* @test2_b3, void()** %fptr
    100   store void()* @test2_b1, void()** %fptr
    101   %f = load void()*, void()** %fptr
    102   call void %f()
    103   ret void
    104 }
    105 
    106 ; CHECK: attributes #0 = { readnone }
    107