1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -S -gvn < %s | FileCheck %s
3
4
5define i64 @test1(i1 %c, i64 %a, i64 %b) {
6; CHECK-LABEL: @test1(
7; CHECK-NEXT:    br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
8; CHECK:       taken:
9; CHECK-NEXT:    br label [[MERGE:%.*]]
10; CHECK:       untaken:
11; CHECK-NEXT:    br label [[MERGE]]
12; CHECK:       merge:
13; CHECK-NEXT:    [[PHI1:%.*]] = phi i64 [ [[A:%.*]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ]
14; CHECK-NEXT:    ret i64 0
15;
16  br i1 %c, label %taken, label %untaken
17taken:
18  br label %merge
19untaken:
20  br label %merge
21merge:
22  %phi1 = phi i64 [%a, %taken], [%b, %untaken]
23  %phi2 = phi i64 [%a, %taken], [%b, %untaken]
24  %ret = sub i64 %phi1, %phi2
25  ret i64 %ret
26}
27
28declare void @llvm.assume(i1)
29
30define i64 @test2(i1 %c, i64 %a, i64 %b) {
31; CHECK-LABEL: @test2(
32; CHECK-NEXT:    br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
33; CHECK:       taken:
34; CHECK-NEXT:    [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0
35; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUMPTION]])
36; CHECK-NEXT:    br label [[MERGE:%.*]]
37; CHECK:       untaken:
38; CHECK-NEXT:    br label [[MERGE]]
39; CHECK:       merge:
40; CHECK-NEXT:    [[PHI1:%.*]] = phi i64 [ [[A]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ]
41; CHECK-NEXT:    [[PHI2:%.*]] = phi i64 [ 0, [[TAKEN]] ], [ [[B]], [[UNTAKEN]] ]
42; CHECK-NEXT:    [[RET:%.*]] = sub i64 [[PHI1]], [[PHI2]]
43; CHECK-NEXT:    ret i64 [[RET]]
44;
45  br i1 %c, label %taken, label %untaken
46taken:
47  %assumption = icmp eq i64 %a, 0
48  call void @llvm.assume(i1 %assumption)
49  br label %merge
50untaken:
51  br label %merge
52merge:
53  %phi1 = phi i64 [%a, %taken], [%b, %untaken]
54  %phi2 = phi i64 [0, %taken], [%b, %untaken]
55  %ret = sub i64 %phi1, %phi2
56  ret i64 %ret
57}
58
59
60define i64 @test3(i1 %c, i64 %a, i64 %b) {
61; CHECK-LABEL: @test3(
62; CHECK-NEXT:    br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
63; CHECK:       taken:
64; CHECK-NEXT:    [[ADD1:%.*]] = add i64 [[A:%.*]], 5
65; CHECK-NEXT:    br label [[MERGE:%.*]]
66; CHECK:       untaken:
67; CHECK-NEXT:    br label [[MERGE]]
68; CHECK:       merge:
69; CHECK-NEXT:    [[PHI1:%.*]] = phi i64 [ [[ADD1]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ]
70; CHECK-NEXT:    ret i64 0
71;
72  br i1 %c, label %taken, label %untaken
73taken:
74  %add1 = add i64 %a, 5
75  %add2 = add i64 %a, 5
76  br label %merge
77untaken:
78  br label %merge
79merge:
80  %phi1 = phi i64 [%add1, %taken], [%b, %untaken]
81  %phi2 = phi i64 [%add2, %taken], [%b, %untaken]
82  %ret = sub i64 %phi1, %phi2
83  ret i64 %ret
84}
85
86define i64 @test4(i1 %c, i64 %a, i64 %b) {
87; CHECK-LABEL: @test4(
88; CHECK-NEXT:    br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
89; CHECK:       taken:
90; CHECK-NEXT:    br label [[MERGE:%.*]]
91; CHECK:       untaken:
92; CHECK-NEXT:    br label [[MERGE]]
93; CHECK:       merge:
94; CHECK-NEXT:    [[PHI1:%.*]] = phi i64 [ [[A:%.*]], [[TAKEN]] ], [ [[B:%.*]], [[UNTAKEN]] ]
95; CHECK-NEXT:    br i1 [[C]], label [[TAKEN2:%.*]], label [[UNTAKEN2:%.*]]
96; CHECK:       taken2:
97; CHECK-NEXT:    [[ADD1:%.*]] = add i64 [[PHI1]], 5
98; CHECK-NEXT:    br label [[MERGE2:%.*]]
99; CHECK:       untaken2:
100; CHECK-NEXT:    br label [[MERGE2]]
101; CHECK:       merge2:
102; CHECK-NEXT:    [[PHI3:%.*]] = phi i64 [ [[ADD1]], [[TAKEN2]] ], [ [[PHI1]], [[UNTAKEN2]] ]
103; CHECK-NEXT:    ret i64 0
104;
105  br i1 %c, label %taken, label %untaken
106taken:
107  br label %merge
108untaken:
109  br label %merge
110merge:
111  %phi1 = phi i64 [%a, %taken], [%b, %untaken]
112  %phi2 = phi i64 [%a, %taken], [%b, %untaken]
113  br i1 %c, label %taken2, label %untaken2
114taken2:
115  %add1 = add i64 %phi1, 5
116  %add2 = add i64 %phi2, 5
117  br label %merge2
118untaken2:
119  br label %merge2
120merge2:
121  %phi3 = phi i64 [%add1, %taken2], [%phi2, %untaken2]
122  %phi4 = phi i64 [%add2, %taken2], [%phi2, %untaken2]
123  %ret = sub i64 %phi4, %phi3
124  ret i64 %ret
125}
126
127define i64 @test5(i1 %c, i64 %a) {
128; CHECK-LABEL: @test5(
129; CHECK-NEXT:    br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
130; CHECK:       taken:
131; CHECK-NEXT:    [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0
132; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUMPTION]])
133; CHECK-NEXT:    br label [[MERGE:%.*]]
134; CHECK:       untaken:
135; CHECK-NEXT:    br label [[MERGE]]
136; CHECK:       merge:
137; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ [[A]], [[TAKEN]] ], [ 0, [[UNTAKEN]] ]
138; CHECK-NEXT:    ret i64 [[PHI]]
139;
140  br i1 %c, label %taken, label %untaken
141taken:
142  %assumption = icmp eq i64 %a, 0
143  call void @llvm.assume(i1 %assumption)
144  br label %merge
145untaken:
146  br label %merge
147merge:
148  %phi = phi i64 [%a, %taken], [0, %untaken]
149  ret i64 %phi
150}
151
152define i64 @test6(i1 %c, i64 %a) {
153; CHECK-LABEL: @test6(
154; CHECK-NEXT:    br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
155; CHECK:       taken:
156; CHECK-NEXT:    [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0
157; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUMPTION]])
158; CHECK-NEXT:    br label [[MERGE:%.*]]
159; CHECK:       untaken:
160; CHECK-NEXT:    br label [[MERGE]]
161; CHECK:       merge:
162; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ [[A]], [[TAKEN]] ], [ 0, [[UNTAKEN]] ]
163; CHECK-NEXT:    ret i64 [[PHI]]
164;
165  br i1 %c, label %taken, label %untaken
166taken:
167  %assumption = icmp eq i64 %a, 0
168  call void @llvm.assume(i1 %assumption)
169  br label %next
170next:
171  br label %merge
172untaken:
173  br label %merge
174merge:
175  %phi = phi i64 [%a, %next], [0, %untaken]
176  ret i64 %phi
177}
178
179; negative test, phi use is NOT dominated by assume
180define i64 @test7(i1 %c, i64 %a) {
181; CHECK-LABEL: @test7(
182; CHECK-NEXT:    br i1 [[C:%.*]], label [[TAKEN:%.*]], label [[UNTAKEN:%.*]]
183; CHECK:       taken:
184; CHECK-NEXT:    [[ASSUMPTION:%.*]] = icmp eq i64 [[A:%.*]], 0
185; CHECK-NEXT:    call void @llvm.assume(i1 [[ASSUMPTION]])
186; CHECK-NEXT:    br label [[MERGE:%.*]]
187; CHECK:       untaken:
188; CHECK-NEXT:    br label [[MERGE]]
189; CHECK:       merge:
190; CHECK-NEXT:    ret i64 [[A]]
191;
192  br i1 %c, label %taken, label %untaken
193taken:
194  %assumption = icmp eq i64 %a, 0
195  call void @llvm.assume(i1 %assumption)
196  br label %merge
197untaken:
198  br label %merge
199merge:
200  br label %next
201next:
202  %phi = phi i64 [%a, %merge]
203  ret i64 %phi
204}
205