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 [[MERGE_THREAD:%.*]], label [[MERGE:%.*]]
46; CHECK:       Merge.thread:
47; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
48; CHECK-NEXT:    br label [[T2:%.*]]
49; CHECK:       Merge:
50; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
51; CHECK-NEXT:    [[A:%.*]] = trunc i32 0 to i1
52; CHECK-NEXT:    [[A_FR:%.*]] = freeze i1 [[A]]
53; CHECK-NEXT:    br i1 [[A_FR]], label [[T2]], label [[F2:%.*]]
54; CHECK:       T2:
55; CHECK-NEXT:    [[B5:%.*]] = phi i32 [ [[V1]], [[MERGE_THREAD]] ], [ [[V2]], [[MERGE]] ]
56; CHECK-NEXT:    call void @f3()
57; CHECK-NEXT:    ret i32 [[B5]]
58; CHECK:       F2:
59; CHECK-NEXT:    ret i32 [[V2]]
60;
61  br i1 %cond, label %T1, label %F1
62
63T1:
64  %v1 = call i32 @f1()
65  br label %Merge
66
67F1:
68  %v2 = call i32 @f2()
69  br label %Merge
70
71Merge:
72  %A0 = phi i32 [1, %T1], [0, %F1]
73  %B = phi i32 [%v1, %T1], [%v2, %F1]
74  %A = trunc i32 %A0 to i1
75  %A.fr = freeze i1 %A
76  br i1 %A.fr, label %T2, label %F2
77
78T2:
79  call void @f3()
80  ret i32 %B
81
82F2:
83  ret i32 %B
84}
85
86define i32 @test1_cast2(i1 %cond) {
87; CHECK-LABEL: @test1_cast2(
88; CHECK-NEXT:    br i1 [[COND:%.*]], label [[MERGE_THREAD:%.*]], label [[MERGE:%.*]]
89; CHECK:       Merge.thread:
90; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
91; CHECK-NEXT:    br label [[T2:%.*]]
92; CHECK:       Merge:
93; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
94; CHECK-NEXT:    [[A0_FR:%.*]] = freeze i32 0
95; CHECK-NEXT:    [[A_FR:%.*]] = trunc i32 [[A0_FR]] to i1
96; CHECK-NEXT:    br i1 [[A_FR]], label [[T2]], label [[F2:%.*]]
97; CHECK:       T2:
98; CHECK-NEXT:    [[B5:%.*]] = phi i32 [ [[V1]], [[MERGE_THREAD]] ], [ [[V2]], [[MERGE]] ]
99; CHECK-NEXT:    call void @f3()
100; CHECK-NEXT:    ret i32 [[B5]]
101; CHECK:       F2:
102; CHECK-NEXT:    ret i32 [[V2]]
103;
104  br i1 %cond, label %T1, label %F1
105
106T1:
107  %v1 = call i32 @f1()
108  br label %Merge
109
110F1:
111  %v2 = call i32 @f2()
112  br label %Merge
113
114Merge:
115  %A0 = phi i32 [1, %T1], [0, %F1]
116  %B = phi i32 [%v1, %T1], [%v2, %F1]
117  %A0.fr = freeze i32 %A0
118  %A.fr = trunc i32 %A0.fr to i1
119  br i1 %A.fr, label %T2, label %F2
120
121T2:
122  call void @f3()
123  ret i32 %B
124
125F2:
126  ret i32 %B
127}
128
129define i32 @test1_undef(i1 %cond) {
130; CHECK-LABEL: @test1_undef(
131; CHECK-NEXT:    br i1 [[COND:%.*]], label [[T2:%.*]], label [[F2:%.*]]
132; CHECK:       T2:
133; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
134; CHECK-NEXT:    call void @f3()
135; CHECK-NEXT:    ret i32 [[V1]]
136; CHECK:       F2:
137; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
138; CHECK-NEXT:    ret i32 [[V2]]
139;
140  br i1 %cond, label %T1, label %F1
141
142T1:
143  %v1 = call i32 @f1()
144  br label %Merge
145
146F1:
147  %v2 = call i32 @f2()
148  br label %Merge
149
150Merge:
151  %A = phi i1 [true, %T1], [undef, %F1]
152  %B = phi i32 [%v1, %T1], [%v2, %F1]
153  %A.fr = freeze i1 %A
154  br i1 %A.fr, label %T2, label %F2
155
156T2:
157  call void @f3()
158  ret i32 %B
159
160F2:
161  ret i32 %B
162}
163
164define i32 @test2(i1 %cond, i1 %cond2) {
165; CHECK-LABEL: @test2(
166; CHECK-NEXT:    br i1 [[COND:%.*]], label [[MERGE_THREAD:%.*]], label [[MERGE:%.*]]
167; CHECK:       Merge.thread:
168; CHECK-NEXT:    [[V1:%.*]] = call i32 @f1()
169; CHECK-NEXT:    br label [[T2:%.*]]
170; CHECK:       Merge:
171; CHECK-NEXT:    [[V2:%.*]] = call i32 @f2()
172; CHECK-NEXT:    [[A_FR:%.*]] = freeze i1 [[COND2:%.*]]
173; CHECK-NEXT:    br i1 [[A_FR]], label [[T2]], label [[F2:%.*]]
174; CHECK:       T2:
175; CHECK-NEXT:    [[B4:%.*]] = phi i32 [ [[V1]], [[MERGE_THREAD]] ], [ [[V2]], [[MERGE]] ]
176; CHECK-NEXT:    call void @f3()
177; CHECK-NEXT:    ret i32 [[B4]]
178; CHECK:       F2:
179; CHECK-NEXT:    ret i32 [[V2]]
180;
181  br i1 %cond, label %T1, label %F1
182
183T1:
184  %v1 = call i32 @f1()
185  br label %Merge
186
187F1:
188  %v2 = call i32 @f2()
189  br label %Merge
190
191Merge:
192  %A = phi i1 [true, %T1], [%cond2, %F1]
193  %B = phi i32 [%v1, %T1], [%v2, %F1]
194  %A.fr = freeze i1 %A
195  br i1 %A.fr, label %T2, label %F2
196
197T2:
198  call void @f3()
199  ret i32 %B
200
201F2:
202  ret i32 %B
203}
204