• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; RUN: opt < %s -gvn -enable-pre -S | FileCheck %s
2; RUN: opt < %s -passes="gvn<pre>" -enable-pre=false -S | FileCheck %s
3
4declare void @may_exit() nounwind
5
6declare void @may_exit_1(i32) nounwind
7
8define i32 @main(i32 %p, i32 %q) {
9
10; CHECK-LABEL: @main(
11
12block1:
13    %cmp = icmp eq i32 %p, %q
14	br i1 %cmp, label %block2, label %block3
15
16block2:
17 %a = add i32 %p, 1
18 br label %block4
19
20block3:
21  br label %block4
22; CHECK: %.pre = add i32 %p, 1
23; CHECK-NEXT: br label %block4
24
25block4:
26  %b = add i32 %p, 1
27  ret i32 %b
28; CHECK: %b.pre-phi = phi i32 [ %.pre, %block3 ], [ %a, %block2 ]
29; CHECK-NEXT: ret i32 %b.pre-phi
30}
31
32; Don't PRE across implicit control flow.
33define i32 @test2(i32 %p, i32 %q) {
34
35; CHECK-LABEL: @test2
36; CHECK: block1:
37
38block1:
39  %cmp = icmp eq i32 %p, %q
40  br i1 %cmp, label %block2, label %block3
41
42block2:
43 %a = sdiv i32 %p, %q
44 br label %block4
45
46block3:
47  br label %block4
48
49; CHECK: block4:
50; CHECK-NEXT: call void @may_exit(
51; CHECK-NEXT: %b = sdiv
52; CHECK-NEXT: ret i32 %b
53
54block4:
55  call void @may_exit() nounwind
56  %b = sdiv i32 %p, %q
57  ret i32 %b
58}
59
60; Don't PRE across implicit control flow.
61define i32 @test3(i32 %p, i32 %q, i1 %r) {
62
63; CHECK-LABEL: @test3
64; CHECK: block1:
65
66block1:
67  br i1 %r, label %block2, label %block3
68
69block2:
70 %a = sdiv i32 %p, %q
71 br label %block4
72
73block3:
74  br label %block4
75
76block4:
77
78; CHECK: block4:
79; CHECK-NEXT: phi i32
80; CHECK-NEXT: call void @may_exit_1(
81; CHECK-NEXT: %b = sdiv
82; CHECK-NEXT: ret i32 %b
83
84  %phi = phi i32 [ 0, %block3 ], [ %a, %block2 ]
85  call void @may_exit_1(i32 %phi) nounwind
86  %b = sdiv i32 %p, %q
87  ret i32 %b
88
89}
90
91; It's OK to PRE an instruction that is guaranteed to be safe to execute
92; speculatively.
93; TODO: Does it make any sense in this case?
94define i32 @test4(i32 %p, i32 %q) {
95
96; CHECK-LABEL: @test4
97; CHECK: block1:
98
99block1:
100  %cmp = icmp eq i32 %p, %q
101  br i1 %cmp, label %block2, label %block3
102
103block2:
104 %a = sdiv i32 %p, 6
105 br label %block4
106
107block3:
108  br label %block4
109
110; CHECK: block4:
111; CHECK-NEXT: %b.pre-phi = phi i32
112; CHECK-NEXT: call void @may_exit(
113; CHECK-NEXT: ret i32 %b
114
115block4:
116  call void @may_exit() nounwind
117  %b = sdiv i32 %p, 6
118  ret i32 %b
119}
120
121; It is OK to PRE across implicit control flow if we don't insert new
122; instructions.
123define i32 @test5(i1 %cond, i32 %p, i32 %q) {
124
125; CHECK-LABEL: @test5
126; CHECK: block1:
127
128block1:
129  br i1 %cond, label %block2, label %block3
130
131block2:
132 %a = sdiv i32 %p, %q
133 br label %block4
134
135block3:
136  %b = sdiv i32 %p, %q
137  br label %block4
138
139; CHECK: block4:
140; CHECK-NEXT: %c.pre-phi = phi i32 [ %b, %block3 ], [ %a, %block2 ]
141; CHECK-NEXT: call void @may_exit()
142; CHECK-NEXT: ret i32 %c.pre-phi
143
144block4:
145  call void @may_exit() nounwind
146  %c = sdiv i32 %p, %q
147  ret i32 %c
148}
149