blob: 82d321ccf225c2e1b2993b37e32198273d3bfc54 [file] [log] [blame]
Chandler Carruthb698d592017-01-22 10:34:01 +00001; Test for a subtle bug when computing analyses during inlining and mutating
2; the SCC structure. Without care, this can fail to invalidate analyses.
3;
4; RUN: opt < %s -passes='cgscc(inline,function(verify<domtree>))' -debug-pass-manager -S 2>&1 | FileCheck %s
5
6; First we check that the passes run in the way we expect. Otherwise this test
7; may stop testing anything.
8;
9; CHECK-LABEL: Starting llvm::Module pass manager run.
Chandler Carruth20e588e2017-03-09 11:35:40 +000010; CHECK: Running pass: InlinerPass on (test1_f, test1_g, test1_h)
11; CHECK: Running analysis: FunctionAnalysisManagerCGSCCProxy on (test1_f, test1_g, test1_h)
Chandler Carruthb698d592017-01-22 10:34:01 +000012; CHECK: Running analysis: DominatorTreeAnalysis on test1_f
13; CHECK: Running analysis: DominatorTreeAnalysis on test1_g
Chandler Carruth20e588e2017-03-09 11:35:40 +000014; CHECK: Invalidating all non-preserved analyses for: (test1_f, test1_g, test1_h)
Chandler Carruthb698d592017-01-22 10:34:01 +000015; CHECK: Invalidating all non-preserved analyses for: test1_f
16; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_f
Chandler Carruth20e588e2017-03-09 11:35:40 +000017; CHECK: Invalidating all non-preserved analyses for: test1_g
18; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_g
19; CHECK: Invalidating all non-preserved analyses for: test1_h
20; CHECK-NOT: Invalidating anaylsis:
Chandler Carruthb698d592017-01-22 10:34:01 +000021; CHECK: Running analysis: DominatorTreeAnalysis on test1_h
Chandler Carruth20e588e2017-03-09 11:35:40 +000022; CHECK: Invalidating all non-preserved analyses for: (test1_g, test1_h)
Chandler Carruthb698d592017-01-22 10:34:01 +000023; CHECK: Invalidating all non-preserved analyses for: test1_h
24; CHECK: Invalidating analysis: DominatorTreeAnalysis on test1_h
25
26; An external function used to control branches.
27declare i1 @flag()
28; CHECK-LABEL: declare i1 @flag()
29
30; The utility function with interesting control flow that gets inlined below to
31; perturb the dominator tree.
32define internal void @callee() {
33entry:
34 %ptr = alloca i8
35 %flag = call i1 @flag()
36 br i1 %flag, label %then, label %else
37
38then:
39 store volatile i8 42, i8* %ptr
40 br label %return
41
42else:
43 store volatile i8 -42, i8* %ptr
44 br label %return
45
46return:
47 ret void
48}
49
50; The 'test1_' prefixed functions work to carefully test that incrementally
51; reducing an SCC in the inliner cannot accidentially leave stale function
52; analysis results due to failing to invalidate them for all the functions.
53
Chandler Carruth20e588e2017-03-09 11:35:40 +000054; The inliner visits this last function. It can't actually break any cycles
55; here, but because we visit this function we compute fresh analyses for it.
56; These analyses are then invalidated when we inline callee disrupting the
57; CFG, and it is important that they be freed.
58define void @test1_h() {
59; CHECK-LABEL: define void @test1_h()
Chandler Carruthb698d592017-01-22 10:34:01 +000060entry:
Chandler Carruth20e588e2017-03-09 11:35:40 +000061 call void @test1_g()
Chandler Carruthb698d592017-01-22 10:34:01 +000062; CHECK: call void @test1_g()
63
64 ; Pull interesting CFG into this function.
65 call void @callee()
66; CHECK-NOT: call void @callee()
67
68 ret void
69; CHECK: ret void
70}
71
Chandler Carruth20e588e2017-03-09 11:35:40 +000072; We visit this function second and here we inline the edge to 'test1_f'
Chandler Carruthb698d592017-01-22 10:34:01 +000073; separating it into its own SCC. The current SCC is now just 'test1_g' and
74; 'test1_h'.
75define void @test1_g() {
76; CHECK-LABEL: define void @test1_g()
77entry:
78 ; This edge gets inlined away.
79 call void @test1_f()
80; CHECK-NOT: call void @test1_f()
81; CHECK: call void @test1_g()
82
83 ; We force this edge to survive inlining.
84 call void @test1_h() noinline
85; CHECK: call void @test1_h()
86
87 ; Pull interesting CFG into this function.
88 call void @callee()
89; CHECK-NOT: call void @callee()
90
91 ret void
92; CHECK: ret void
93}
94
Chandler Carruth20e588e2017-03-09 11:35:40 +000095; We visit this function first in the inliner, and while we inline callee
96; perturbing the CFG, we don't inline anything else and the SCC structure
97; remains in tact.
98define void @test1_f() {
99; CHECK-LABEL: define void @test1_f()
Chandler Carruthb698d592017-01-22 10:34:01 +0000100entry:
Chandler Carruth20e588e2017-03-09 11:35:40 +0000101 ; We force this edge to survive inlining.
102 call void @test1_g() noinline
Chandler Carruthb698d592017-01-22 10:34:01 +0000103; CHECK: call void @test1_g()
104
105 ; Pull interesting CFG into this function.
106 call void @callee()
107; CHECK-NOT: call void @callee()
108
109 ret void
110; CHECK: ret void
111}