1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux-gnu"
6
7define i1 @test1(i1 %a, i1 %b) {
8; CHECK-LABEL: @test1(
9; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
10; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]]
11; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]]
12; CHECK-NEXT:    ret i1 [[AND]]
13;
14  %wc = call i1 @llvm.experimental.widenable.condition()
15  %lhs = and i1 %b, %wc
16  %and = and i1 %lhs, %a
17  ret i1 %and
18}
19
20define i1 @test1_logical(i1 %a, i1 %b) {
21; CHECK-LABEL: @test1_logical(
22; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
23; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[B:%.*]], i1 [[WC]], i1 false
24; CHECK-NEXT:    [[AND:%.*]] = select i1 [[LHS]], i1 [[A:%.*]], i1 false
25; CHECK-NEXT:    ret i1 [[AND]]
26;
27  %wc = call i1 @llvm.experimental.widenable.condition()
28  %lhs = select i1 %b, i1 %wc, i1 false
29  %and = select i1 %lhs, i1 %a, i1 false
30  ret i1 %and
31}
32
33; Negative test - profitability of dropping WC from first use unclear
34define i1 @test1b(i1 %a, i1 %b) {
35; CHECK-LABEL: @test1b(
36; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
37; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]]
38; CHECK-NEXT:    call void @use(i1 [[LHS]])
39; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]]
40; CHECK-NEXT:    ret i1 [[AND]]
41;
42  %wc = call i1 @llvm.experimental.widenable.condition()
43  %lhs = and i1 %b, %wc
44  call void @use(i1 %lhs)
45  %and = and i1 %lhs, %a
46  ret i1 %and
47}
48
49define i1 @test1b_logical(i1 %a, i1 %b) {
50; CHECK-LABEL: @test1b_logical(
51; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
52; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[B:%.*]], i1 [[WC]], i1 false
53; CHECK-NEXT:    call void @use(i1 [[LHS]])
54; CHECK-NEXT:    [[AND:%.*]] = select i1 [[LHS]], i1 [[A:%.*]], i1 false
55; CHECK-NEXT:    ret i1 [[AND]]
56;
57  %wc = call i1 @llvm.experimental.widenable.condition()
58  %lhs = select i1 %b, i1 %wc, i1 false
59  call void @use(i1 %lhs)
60  %and = select i1 %lhs, i1 %a, i1 false
61  ret i1 %and
62}
63
64; multiple uses of A, B, WC doesn't change result
65define i1 @test1c(i1 %a, i1 %b) {
66; CHECK-LABEL: @test1c(
67; CHECK-NEXT:    call void @use(i1 [[A:%.*]])
68; CHECK-NEXT:    call void @use(i1 [[B:%.*]])
69; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
70; CHECK-NEXT:    call void @use(i1 [[WC]])
71; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[WC]], [[B]]
72; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[A]]
73; CHECK-NEXT:    ret i1 [[AND]]
74;
75  call void @use(i1 %a)
76  call void @use(i1 %b)
77  %wc = call i1 @llvm.experimental.widenable.condition()
78  call void @use(i1 %wc)
79  %lhs = and i1 %b, %wc
80  %and = and i1 %lhs, %a
81  ret i1 %and
82}
83
84define i1 @test1c_logical(i1 %a, i1 %b) {
85; CHECK-LABEL: @test1c_logical(
86; CHECK-NEXT:    call void @use(i1 [[A:%.*]])
87; CHECK-NEXT:    call void @use(i1 [[B:%.*]])
88; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
89; CHECK-NEXT:    call void @use(i1 [[WC]])
90; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[B]], i1 [[WC]], i1 false
91; CHECK-NEXT:    [[AND:%.*]] = select i1 [[LHS]], i1 [[A]], i1 false
92; CHECK-NEXT:    ret i1 [[AND]]
93;
94  call void @use(i1 %a)
95  call void @use(i1 %b)
96  %wc = call i1 @llvm.experimental.widenable.condition()
97  call void @use(i1 %wc)
98  %lhs = select i1 %b, i1 %wc, i1 false
99  %and = select i1 %lhs, i1 %a, i1 false
100  ret i1 %and
101}
102
103define i1 @test2(i1 %a, i1 %b) {
104; CHECK-LABEL: @test2(
105; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
106; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[WC]], [[B:%.*]]
107; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[A:%.*]]
108; CHECK-NEXT:    ret i1 [[AND]]
109;
110  %wc = call i1 @llvm.experimental.widenable.condition()
111  %lhs = and i1 %wc, %b
112  %and = and i1 %lhs, %a
113  ret i1 %and
114}
115
116define i1 @test2_logical(i1 %a, i1 %b) {
117; CHECK-LABEL: @test2_logical(
118; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
119; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[WC]], i1 [[B:%.*]], i1 false
120; CHECK-NEXT:    [[AND:%.*]] = select i1 [[LHS]], i1 [[A:%.*]], i1 false
121; CHECK-NEXT:    ret i1 [[AND]]
122;
123  %wc = call i1 @llvm.experimental.widenable.condition()
124  %lhs = select i1 %wc, i1 %b, i1 false
125  %and = select i1 %lhs, i1 %a, i1 false
126  ret i1 %and
127}
128
129; To test the rhs side, an instruction on lhs to prevent complexity
130; canonicalization reducing to above.
131define i1 @test3(i1 %a, i1 %b, i1 %c) {
132; CHECK-LABEL: @test3(
133; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
134; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
135; CHECK-NEXT:    [[RHS:%.*]] = and i1 [[WC]], [[C:%.*]]
136; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[RHS]]
137; CHECK-NEXT:    ret i1 [[AND]]
138;
139  %wc = call i1 @llvm.experimental.widenable.condition()
140  %lhs = and i1 %a, %b
141  %rhs = and i1 %c, %wc
142  %and = and i1 %lhs, %rhs
143  ret i1 %and
144}
145
146define i1 @test3_logical(i1 %a, i1 %b, i1 %c) {
147; CHECK-LABEL: @test3_logical(
148; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
149; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
150; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[LHS]], i1 [[C:%.*]], i1 false
151; CHECK-NEXT:    [[AND:%.*]] = select i1 [[TMP1]], i1 [[WC]], i1 false
152; CHECK-NEXT:    ret i1 [[AND]]
153;
154  %wc = call i1 @llvm.experimental.widenable.condition()
155  %lhs = select i1 %a, i1 %b, i1 false
156  %rhs = select i1 %c, i1 %wc, i1 false
157  %and = select i1 %lhs, i1 %rhs, i1 false
158  ret i1 %and
159}
160
161define i1 @test4(i1 %a, i1 %b, i1 %c) {
162; CHECK-LABEL: @test4(
163; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
164; CHECK-NEXT:    [[LHS:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
165; CHECK-NEXT:    [[RHS:%.*]] = and i1 [[WC]], [[C:%.*]]
166; CHECK-NEXT:    [[AND:%.*]] = and i1 [[LHS]], [[RHS]]
167; CHECK-NEXT:    ret i1 [[AND]]
168;
169  %wc = call i1 @llvm.experimental.widenable.condition()
170  %lhs = and i1 %a, %b
171  %rhs = and i1 %wc, %c
172  %and = and i1 %lhs, %rhs
173  ret i1 %and
174}
175
176define i1 @test4_logical(i1 %a, i1 %b, i1 %c) {
177; CHECK-LABEL: @test4_logical(
178; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
179; CHECK-NEXT:    [[LHS:%.*]] = select i1 [[A:%.*]], i1 [[B:%.*]], i1 false
180; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[LHS]], i1 [[WC]], i1 false
181; CHECK-NEXT:    [[AND:%.*]] = select i1 [[TMP1]], i1 [[C:%.*]], i1 false
182; CHECK-NEXT:    ret i1 [[AND]]
183;
184  %wc = call i1 @llvm.experimental.widenable.condition()
185  %lhs = select i1 %a, i1 %b, i1 false
186  %rhs = select i1 %wc, i1 %c, i1 false
187  %and = select i1 %lhs, i1 %rhs, i1 false
188  ret i1 %and
189}
190
191define i1 @test5(i1 %a, i1 %b) {
192; CHECK-LABEL: @test5(
193; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
194; CHECK-NEXT:    ret i1 [[WC]]
195;
196  %wc = call i1 @llvm.experimental.widenable.condition()
197  %and = and i1 %wc, %wc
198  ret i1 %and
199}
200
201define i1 @test5_logical(i1 %a, i1 %b) {
202; CHECK-LABEL: @test5_logical(
203; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
204; CHECK-NEXT:    ret i1 [[WC]]
205;
206  %wc = call i1 @llvm.experimental.widenable.condition()
207  %and = select i1 %wc, i1 %wc, i1 false
208  ret i1 %and
209}
210
211define i1 @test6(i1 %a, i1 %b) {
212; CHECK-LABEL: @test6(
213; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
214; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
215; CHECK-NEXT:    [[AND:%.*]] = and i1 [[WC]], [[WC2]]
216; CHECK-NEXT:    ret i1 [[AND]]
217;
218  %wc = call i1 @llvm.experimental.widenable.condition()
219  %wc2 = call i1 @llvm.experimental.widenable.condition()
220  %and = and i1 %wc, %wc2
221  ret i1 %and
222}
223
224define i1 @test6_logical(i1 %a, i1 %b) {
225; CHECK-LABEL: @test6_logical(
226; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
227; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
228; CHECK-NEXT:    [[AND:%.*]] = select i1 [[WC]], i1 [[WC2]], i1 false
229; CHECK-NEXT:    ret i1 [[AND]]
230;
231  %wc = call i1 @llvm.experimental.widenable.condition()
232  %wc2 = call i1 @llvm.experimental.widenable.condition()
233  %and = select i1 %wc, i1 %wc2, i1 false
234  ret i1 %and
235}
236
237define i1 @test7(i1 %a, i1 %b) {
238; CHECK-LABEL: @test7(
239; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
240; CHECK-NEXT:    call void @use(i1 [[WC]])
241; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
242; CHECK-NEXT:    [[AND:%.*]] = and i1 [[WC]], [[WC2]]
243; CHECK-NEXT:    ret i1 [[AND]]
244;
245  %wc = call i1 @llvm.experimental.widenable.condition()
246  call void @use(i1 %wc)
247  %wc2 = call i1 @llvm.experimental.widenable.condition()
248  %and = and i1 %wc, %wc2
249  ret i1 %and
250}
251
252define i1 @test7_logical(i1 %a, i1 %b) {
253; CHECK-LABEL: @test7_logical(
254; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
255; CHECK-NEXT:    call void @use(i1 [[WC]])
256; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
257; CHECK-NEXT:    [[AND:%.*]] = select i1 [[WC]], i1 [[WC2]], i1 false
258; CHECK-NEXT:    ret i1 [[AND]]
259;
260  %wc = call i1 @llvm.experimental.widenable.condition()
261  call void @use(i1 %wc)
262  %wc2 = call i1 @llvm.experimental.widenable.condition()
263  %and = select i1 %wc, i1 %wc2, i1 false
264  ret i1 %and
265}
266
267define i1 @test8(i1 %a, i1 %b) {
268; CHECK-LABEL: @test8(
269; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
270; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
271; CHECK-NEXT:    call void @use(i1 [[WC2]])
272; CHECK-NEXT:    [[AND:%.*]] = and i1 [[WC]], [[WC2]]
273; CHECK-NEXT:    ret i1 [[AND]]
274;
275  %wc = call i1 @llvm.experimental.widenable.condition()
276  %wc2 = call i1 @llvm.experimental.widenable.condition()
277  call void @use(i1 %wc2)
278  %and = and i1 %wc, %wc2
279  ret i1 %and
280}
281
282define i1 @test8_logical(i1 %a, i1 %b) {
283; CHECK-LABEL: @test8_logical(
284; CHECK-NEXT:    [[WC:%.*]] = call i1 @llvm.experimental.widenable.condition()
285; CHECK-NEXT:    [[WC2:%.*]] = call i1 @llvm.experimental.widenable.condition()
286; CHECK-NEXT:    call void @use(i1 [[WC2]])
287; CHECK-NEXT:    [[AND:%.*]] = select i1 [[WC]], i1 [[WC2]], i1 false
288; CHECK-NEXT:    ret i1 [[AND]]
289;
290  %wc = call i1 @llvm.experimental.widenable.condition()
291  %wc2 = call i1 @llvm.experimental.widenable.condition()
292  call void @use(i1 %wc2)
293  %and = select i1 %wc, i1 %wc2, i1 false
294  ret i1 %and
295}
296
297
298declare void @use(i1)
299declare i1 @llvm.experimental.widenable.condition()
300