1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -jump-threading -S < %s | FileCheck %s
3
4declare i32 @f1()
5declare i32 @f2()
6declare void @f3()
7
8define i32 @test1(i1 %cond) {
9; CHECK-LABEL: @test1(
10; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
11; CHECK:       T2:
12; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
13; CHECK-NEXT:    call void @f3()
14; CHECK-NEXT:    ret i32 [[V1]]
15; CHECK:       F2:
16; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
17; CHECK-NEXT:    ret i32 [[V2]]
18;
19  br i1 %cond, label %T1, label %F1
20
21T1:
22  %v1 = call i32 @f1()
23  br label %Merge
24
25F1:
26  %v2 = call i32 @f2()
27  br label %Merge
28
29Merge:
30  %A = phi i1 [true, %T1], [false, %F1]
31  %B = phi i32 [%v1, %T1], [%v2, %F1]
32  %A.fr = freeze i1 %A
33  br i1 %A.fr, label %T2, label %F2
34
35T2:
36  call void @f3()
37  ret i32 %B
38
39F2:
40  ret i32 %B
41}
42
43define i32 @test1_cast(i1 %cond) {
44; CHECK-LABEL: @test1_cast(
45; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
46; CHECK:       T2:
47; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
48; CHECK-NEXT:    call void @f3()
49; CHECK-NEXT:    ret i32 [[V1]]
50; CHECK:       F2:
51; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
52; CHECK-NEXT:    [[A:%.*]] = trunc i32 0 to i1
53; CHECK-NEXT:    ret i32 [[V2]]
54;
55  br i1 %cond, label %T1, label %F1
56
57T1:
58  %v1 = call i32 @f1()
59  br label %Merge
60
61F1:
62  %v2 = call i32 @f2()
63  br label %Merge
64
65Merge:
66  %A0 = phi i32 [1, %T1], [0, %F1]
67  %B = phi i32 [%v1, %T1], [%v2, %F1]
68  %A = trunc i32 %A0 to i1
69  %A.fr = freeze i1 %A
70  br i1 %A.fr, label %T2, label %F2
71
72T2:
73  call void @f3()
74  ret i32 %B
75
76F2:
77  ret i32 %B
78}
79
80define i32 @test1_cast2(i1 %cond) {
81; CHECK-LABEL: @test1_cast2(
82; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
83; CHECK:       T2:
84; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
85; CHECK-NEXT:    call void @f3()
86; CHECK-NEXT:    ret i32 [[V1]]
87; CHECK:       F2:
88; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
89; CHECK-NEXT:    [[A0_FR:%.*]] = freeze i32 0
90; CHECK-NEXT:    ret i32 [[V2]]
91;
92  br i1 %cond, label %T1, label %F1
93
94T1:
95  %v1 = call i32 @f1()
96  br label %Merge
97
98F1:
99  %v2 = call i32 @f2()
100  br label %Merge
101
102Merge:
103  %A0 = phi i32 [1, %T1], [0, %F1]
104  %B = phi i32 [%v1, %T1], [%v2, %F1]
105  %A0.fr = freeze i32 %A0
106  %A.fr = trunc i32 %A0.fr to i1
107  br i1 %A.fr, label %T2, label %F2
108
109T2:
110  call void @f3()
111  ret i32 %B
112
113F2:
114  ret i32 %B
115}
116
117define i32 @test1_undef(i1 %cond) {
118; CHECK-LABEL: @test1_undef(
119; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
120; CHECK:       T2:
121; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
122; CHECK-NEXT:    call void @f3()
123; CHECK-NEXT:    ret i32 [[V1]]
124; CHECK:       F2:
125; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
126; CHECK-NEXT:    ret i32 [[V2]]
127;
128  br i1 %cond, label %T1, label %F1
129
130T1:
131  %v1 = call i32 @f1()
132  br label %Merge
133
134F1:
135  %v2 = call i32 @f2()
136  br label %Merge
137
138Merge:
139  %A = phi i1 [true, %T1], [undef, %F1]
140  %B = phi i32 [%v1, %T1], [%v2, %F1]
141  %A.fr = freeze i1 %A
142  br i1 %A.fr, label %T2, label %F2
143
144T2:
145  call void @f3()
146  ret i32 %B
147
148F2:
149  ret i32 %B
150}
151
152define i32 @test2(i1 %cond, i1 %cond2) {
153; CHECK-LABEL: @test2(
154; CHECK-NEXT:    br i1 [[COND:%.*]], label [[MERGE_THREAD:%.*]], label [[MERGE:%.*]]
155; CHECK:       Merge.thread:
156; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
157; CHECK-NEXT:    br label [[T2:%.*]]
158; CHECK:       Merge:
159; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
160; CHECK-NEXT:    [[A_FR:%.*]] = freeze i1 [[COND2:%.*]]
161; CHECK-NEXT:    br i1 [[A_FR]], label [[T2]], label [[F2:%.*]]
162; CHECK:       T2:
163; CHECK-NEXT:    [[B4:%.*]] = phi i32 [ [[V1]], [[MERGE_THREAD]] ], [ [[V2]], [[MERGE]] ]
164; CHECK-NEXT:    call void @f3()
165; CHECK-NEXT:    ret i32 [[B4]]
166; CHECK:       F2:
167; CHECK-NEXT:    ret i32 [[V2]]
168;
169  br i1 %cond, label %T1, label %F1
170
171T1:
172  %v1 = call i32 @f1()
173  br label %Merge
174
175F1:
176  %v2 = call i32 @f2()
177  br label %Merge
178
179Merge:
180  %A = phi i1 [true, %T1], [%cond2, %F1]
181  %B = phi i32 [%v1, %T1], [%v2, %F1]
182  %A.fr = freeze i1 %A
183  br i1 %A.fr, label %T2, label %F2
184
185T2:
186  call void @f3()
187  ret i32 %B
188
189F2:
190  ret i32 %B
191}
192