[RISCV] emit .option directive for functions with target features which differ from...
[llvm-project.git] / llvm / test / Other / cgscc-observe-devirt.ll
blobf9af9ecb306b90b08785624364d466c7a5f30a68
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.
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
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
13 declare void @readnone() nofree nosync readnone
14 declare void @unknown()
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.
20 ; BEFORE: define void @test1_a1() {
21 ; AFTER: define void @test1_a1() {
22 define void @test1_a1() {
23   %fptr = alloca ptr
24   store ptr @test1_b2, ptr %fptr
25   store ptr @test1_b1, ptr %fptr
26   %f = load ptr, ptr %fptr
27   call void %f()
28   ret void
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
39 ; BEFORE: define void @test1_a2() {
40 ; AFTER: define void @test1_a2() #0 {
41 define void @test1_a2() {
42   %fptr = alloca ptr
43   store ptr @test1_b1, ptr %fptr
44   store ptr @test1_b2, ptr %fptr
45   %f = load ptr, ptr %fptr
46   call void %f()
47   ret void
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
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.
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
72 ; CHECK: define void @test2_b1() #0 {
73 define void @test2_b1() {
74   %fptr = alloca ptr
75   store ptr @test2_a, ptr %fptr
76   store ptr @readnone, ptr %fptr
77   %f = load ptr, ptr %fptr
78   call void %f()
79   ret void
82 ; CHECK: define void @test2_b2() #0 {
83 define void @test2_b2() {
84   %fptr = alloca ptr
85   store ptr @test2_a, ptr %fptr
86   store ptr @test2_b2, ptr %fptr
87   store ptr @test2_b3, ptr %fptr
88   store ptr @test2_b1, ptr %fptr
89   %f = load ptr, ptr %fptr
90   call void %f()
91   ret void
94 ; CHECK: define void @test2_b3() #0 {
95 define void @test2_b3() {
96   %fptr = alloca ptr
97   store ptr @test2_a, ptr %fptr
98   store ptr @test2_b2, ptr %fptr
99   store ptr @test2_b3, ptr %fptr
100   store ptr @test2_b1, ptr %fptr
101   %f = load ptr, ptr %fptr
102   call void %f()
103   ret void
106 ; CHECK: attributes #0 = { nofree nosync readnone }