[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / Inline / cgscc-incremental-invalidate.ll
blob5a429bc3a4f02677a745de8bea5e852e98c29d7b
1 ; Test for a subtle bug when computing analyses during inlining and mutating
2 ; the SCC structure. Without care, this can fail to invalidate analyses.
4 ; RUN: opt < %s -passes='cgscc(inline,function(verify<domtree>))' -debug-pass-manager -S 2>&1 | FileCheck %s
6 ; First we check that the passes run in the way we expect. Otherwise this test
7 ; may stop testing anything.
9 ; CHECK-LABEL: Starting llvm::Module pass manager run.
10 ; CHECK: Running pass: InlinerPass on (test1_f, test1_g, test1_h)
11 ; CHECK: Running analysis: DominatorTreeAnalysis on test1_f
12 ; CHECK: Running analysis: DominatorTreeAnalysis on test1_g
13 ; CHECK: Invalidating all non-preserved analyses for: (test1_f)
14 ; CHECK: Invalidating all non-preserved analyses for: test1_f
15 ; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_f
16 ; CHECK: Invalidating analysis: LoopAnalysis on test1_f
17 ; CHECK: Invalidating analysis: BranchProbabilityAnalysis on test1_f
18 ; CHECK: Invalidating analysis: BlockFrequencyAnalysis on test1_f
19 ; CHECK: Invalidating all non-preserved analyses for: (test1_g, test1_h)
20 ; CHECK: Invalidating all non-preserved analyses for: test1_g
21 ; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_g
22 ; CHECK: Invalidating analysis: LoopAnalysis on test1_g
23 ; CHECK: Invalidating analysis: BranchProbabilityAnalysis on test1_g
24 ; CHECK: Invalidating analysis: BlockFrequencyAnalysis on test1_g
25 ; CHECK: Invalidating all non-preserved analyses for: test1_h
26 ; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_h
27 ; CHECK: Invalidating analysis: LoopAnalysis on test1_h
28 ; CHECK: Invalidating analysis: BranchProbabilityAnalysis on test1_h
29 ; CHECK: Invalidating analysis: BlockFrequencyAnalysis on test1_h
30 ; CHECK-NOT: Invalidating analysis:
31 ; CHECK: Starting llvm::Function pass manager run.
32 ; CHECK-NEXT: Running pass: DominatorTreeVerifierPass on test1_g
33 ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_g
34 ; CHECK-NEXT: Finished llvm::Function pass manager run.
35 ; CHECK-NOT: Invalidating analysis:
36 ; CHECK: Starting llvm::Function pass manager run.
37 ; CHECK-NEXT: Running pass: DominatorTreeVerifierPass on test1_h
38 ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_h
39 ; CHECK-NEXT: Finished llvm::Function pass manager run.
40 ; CHECK-NOT: Invalidating analysis:
41 ; CHECK: Running pass: DominatorTreeVerifierPass on test1_f
42 ; CHECK-NEXT: Running analysis: DominatorTreeAnalysis on test1_f
44 ; An external function used to control branches.
45 declare i1 @flag()
46 ; CHECK-LABEL: declare i1 @flag()
48 ; The utility function with interesting control flow that gets inlined below to
49 ; perturb the dominator tree.
50 define internal void @callee() {
51 entry:
52   %ptr = alloca i8
53   %flag = call i1 @flag()
54   br i1 %flag, label %then, label %else
56 then:
57   store volatile i8 42, i8* %ptr
58   br label %return
60 else:
61   store volatile i8 -42, i8* %ptr
62   br label %return
64 return:
65   ret void
68 ; The 'test1_' prefixed functions work to carefully test that incrementally
69 ; reducing an SCC in the inliner cannot accidentially leave stale function
70 ; analysis results due to failing to invalidate them for all the functions.
72 ; The inliner visits this last function. It can't actually break any cycles
73 ; here, but because we visit this function we compute fresh analyses for it.
74 ; These analyses are then invalidated when we inline callee disrupting the
75 ; CFG, and it is important that they be freed.
76 define void @test1_h() {
77 ; CHECK-LABEL: define void @test1_h()
78 entry:
79   call void @test1_g()
80 ; CHECK: call void @test1_g()
82   ; Pull interesting CFG into this function.
83   call void @callee()
84 ; CHECK-NOT: call void @callee()
86   ret void
87 ; CHECK: ret void
90 ; We visit this function second and here we inline the edge to 'test1_f'
91 ; separating it into its own SCC. The current SCC is now just 'test1_g' and
92 ; 'test1_h'.
93 define void @test1_g() {
94 ; CHECK-LABEL: define void @test1_g()
95 entry:
96   ; This edge gets inlined away.
97   call void @test1_f()
98 ; CHECK-NOT: call void @test1_f()
99 ; CHECK: call void @test1_g()
101   ; We force this edge to survive inlining.
102   call void @test1_h() noinline
103 ; CHECK: call void @test1_h()
105   ; Pull interesting CFG into this function.
106   call void @callee()
107 ; CHECK-NOT: call void @callee()
109   ret void
110 ; CHECK: ret void
113 ; We visit this function first in the inliner, and while we inline callee
114 ; perturbing the CFG, we don't inline anything else and the SCC structure
115 ; remains in tact.
116 define void @test1_f() {
117 ; CHECK-LABEL: define void @test1_f()
118 entry:
119   ; We force this edge to survive inlining.
120   call void @test1_g() noinline
121 ; CHECK: call void @test1_g()
123   ; Pull interesting CFG into this function.
124   call void @callee()
125 ; CHECK-NOT: call void @callee()
127   ret void
128 ; CHECK: ret void
131 ; The 'test2_' prefixed code works to carefully trigger forming an SCC with
132 ; a dominator tree for one of the functions but not the other and without even
133 ; a function analysis manager proxy for the SCC that things get merged into.
134 ; Without proper handling when updating the call graph this will find a stale
135 ; dominator tree.
137 @test2_global = external global i32, align 4
139 define void @test2_hoge(i1 (i32*)* %arg) {
140 ; CHECK-LABEL: define void @test2_hoge(
142   %tmp2 = call zeroext i1 %arg(i32* @test2_global)
143 ; CHECK: call zeroext i1 %arg(
144   br label %bb3
146 bb3:
147   %tmp5 = call zeroext i1 %arg(i32* @test2_global)
148 ; CHECK: call zeroext i1 %arg(
149   br i1 %tmp5, label %bb3, label %bb6
151 bb6:
152   ret void
155 define zeroext i1 @test2_widget(i32* %arg) {
156 ; CHECK-LABEL: define zeroext i1 @test2_widget(
158   %tmp1 = alloca i8, align 1
159   %tmp2 = alloca i32, align 4
160   call void @test2_quux()
161 ; CHECK-NOT:     call
163 ; CHECK:         call zeroext i1 @test2_widget(i32* @test2_global)
164 ; CHECK-NEXT:    br label %[[NEW_BB:.*]]
166 ; CHECK:       [[NEW_BB]]:
167 ; CHECK-NEXT:    call zeroext i1 @test2_widget(i32* @test2_global)
169 ; CHECK:       {{.*}}:
171   call void @test2_hoge.1(i32* %arg)
172 ; CHECK-NEXT:    call void @test2_hoge.1(
174   %tmp4 = call zeroext i1 @test2_barney(i32* %tmp2)
175   %tmp5 = zext i1 %tmp4 to i32
176   store i32 %tmp5, i32* %tmp2, align 4
177   %tmp6 = call zeroext i1 @test2_barney(i32* null)
178   call void @test2_ham(i8* %tmp1)
179 ; CHECK:         call void @test2_ham(
181   call void @test2_quux()
182 ; CHECK-NOT:     call
184 ; CHECK:         call zeroext i1 @test2_widget(i32* @test2_global)
185 ; CHECK-NEXT:    br label %[[NEW_BB:.*]]
187 ; CHECK:       [[NEW_BB]]:
188 ; CHECK-NEXT:    call zeroext i1 @test2_widget(i32* @test2_global)
190 ; CHECK:       {{.*}}:
191   ret i1 true
192 ; CHECK-NEXT:    ret i1 true
195 define internal void @test2_quux() {
196 ; CHECK-NOT: @test2_quux
198   call void @test2_hoge(i1 (i32*)* @test2_widget)
199   ret void
202 declare void @test2_hoge.1(i32*)
204 declare zeroext i1 @test2_barney(i32*)
206 declare void @test2_ham(i8*)