1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4; rdar://11748024
5
6define i32 @a(i1 zeroext %x, i1 zeroext %y) {
7; CHECK-LABEL: @a(
8; CHECK-NEXT:    [[CONV3_NEG1:%.*]] = sext i1 [[Y:%.*]] to i32
9; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[X:%.*]], i32 2, i32 1
10; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[SUB]], [[CONV3_NEG1]]
11; CHECK-NEXT:    ret i32 [[ADD]]
12;
13  %conv = zext i1 %x to i32
14  %conv3 = zext i1 %y to i32
15  %conv3.neg = sub i32 0, %conv3
16  %sub = add i32 %conv, 1
17  %add = add i32 %sub, %conv3.neg
18  ret i32 %add
19}
20
21define i32 @PR30273_select(i1 %a, i1 %b) {
22; CHECK-LABEL: @PR30273_select(
23; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[A:%.*]] to i32
24; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[A]], i32 2, i32 1
25; CHECK-NEXT:    [[SEL2:%.*]] = select i1 [[B:%.*]], i32 [[SEL1]], i32 [[ZEXT]]
26; CHECK-NEXT:    ret i32 [[SEL2]]
27;
28  %zext = zext i1 %a to i32
29  %sel1 = select i1 %a, i32 2, i32 1
30  %sel2 = select i1 %b, i32 %sel1, i32 %zext
31  ret i32 %sel2
32}
33
34define i32 @PR30273_zext_add(i1 %a, i1 %b) {
35; CHECK-LABEL: @PR30273_zext_add(
36; CHECK-NEXT:    [[CONV:%.*]] = zext i1 [[A:%.*]] to i32
37; CHECK-NEXT:    [[CONV3:%.*]] = zext i1 [[B:%.*]] to i32
38; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i32 [[CONV3]], [[CONV]]
39; CHECK-NEXT:    ret i32 [[ADD]]
40;
41  %conv = zext i1 %a to i32
42  %conv3 = zext i1 %b to i32
43  %add = add nuw nsw i32 %conv3, %conv
44  ret i32 %add
45}
46
47define i32 @PR30273_three_bools(i1 %x, i1 %y, i1 %z) {
48; CHECK-LABEL: @PR30273_three_bools(
49; CHECK-NEXT:    [[FROMBOOL:%.*]] = zext i1 [[X:%.*]] to i32
50; CHECK-NEXT:    [[ADD1:%.*]] = select i1 [[X]], i32 2, i32 1
51; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[Y:%.*]], i32 [[ADD1]], i32 [[FROMBOOL]]
52; CHECK-NEXT:    [[ADD2:%.*]] = zext i1 [[Z:%.*]] to i32
53; CHECK-NEXT:    [[SEL2:%.*]] = add nuw nsw i32 [[SEL1]], [[ADD2]]
54; CHECK-NEXT:    ret i32 [[SEL2]]
55;
56  %frombool = zext i1 %x to i32
57  %add1 = add nsw i32 %frombool, 1
58  %sel1 = select i1 %y, i32 %add1, i32 %frombool
59  %add2 = add nsw i32 %sel1, 1
60  %sel2 = select i1 %z, i32 %add2, i32 %sel1
61  ret i32 %sel2
62}
63
64define i32 @zext_add_scalar(i1 %x) {
65; CHECK-LABEL: @zext_add_scalar(
66; CHECK-NEXT:    [[ADD:%.*]] = select i1 [[X:%.*]], i32 43, i32 42
67; CHECK-NEXT:    ret i32 [[ADD]]
68;
69  %zext = zext i1 %x to i32
70  %add = add i32 %zext, 42
71  ret i32 %add
72}
73
74define <2 x i32> @zext_add_vec_splat(<2 x i1> %x) {
75; CHECK-LABEL: @zext_add_vec_splat(
76; CHECK-NEXT:    [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 43, i32 43>, <2 x i32> <i32 42, i32 42>
77; CHECK-NEXT:    ret <2 x i32> [[ADD]]
78;
79  %zext = zext <2 x i1> %x to <2 x i32>
80  %add = add <2 x i32> %zext, <i32 42, i32 42>
81  ret <2 x i32> %add
82}
83
84define <2 x i32> @zext_add_vec(<2 x i1> %x) {
85; CHECK-LABEL: @zext_add_vec(
86; CHECK-NEXT:    [[ADD:%.*]] = select <2 x i1> [[X:%.*]], <2 x i32> <i32 43, i32 24>, <2 x i32> <i32 42, i32 23>
87; CHECK-NEXT:    ret <2 x i32> [[ADD]]
88;
89  %zext = zext <2 x i1> %x to <2 x i32>
90  %add = add <2 x i32> %zext, <i32 42, i32 23>
91  ret <2 x i32> %add
92}
93
94declare void @use(i64)
95
96define i64 @zext_negate(i1 %A) {
97; CHECK-LABEL: @zext_negate(
98; CHECK-NEXT:    [[EXT_NEG:%.*]] = sext i1 [[A:%.*]] to i64
99; CHECK-NEXT:    ret i64 [[EXT_NEG]]
100;
101  %ext = zext i1 %A to i64
102  %sub = sub i64 0, %ext
103  ret i64 %sub
104}
105
106define i64 @zext_negate_extra_use(i1 %A) {
107; CHECK-LABEL: @zext_negate_extra_use(
108; CHECK-NEXT:    [[EXT_NEG:%.*]] = sext i1 [[A:%.*]] to i64
109; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[A]] to i64
110; CHECK-NEXT:    call void @use(i64 [[EXT]])
111; CHECK-NEXT:    ret i64 [[EXT_NEG]]
112;
113  %ext = zext i1 %A to i64
114  %sub = sub i64 0, %ext
115  call void @use(i64 %ext)
116  ret i64 %sub
117}
118
119define <2 x i64> @zext_negate_vec(<2 x i1> %A) {
120; CHECK-LABEL: @zext_negate_vec(
121; CHECK-NEXT:    [[EXT_NEG:%.*]] = sext <2 x i1> [[A:%.*]] to <2 x i64>
122; CHECK-NEXT:    ret <2 x i64> [[EXT_NEG]]
123;
124  %ext = zext <2 x i1> %A to <2 x i64>
125  %sub = sub <2 x i64> zeroinitializer, %ext
126  ret <2 x i64> %sub
127}
128
129define <2 x i64> @zext_negate_vec_undef_elt(<2 x i1> %A) {
130; CHECK-LABEL: @zext_negate_vec_undef_elt(
131; CHECK-NEXT:    [[EXT_NEG:%.*]] = sext <2 x i1> [[A:%.*]] to <2 x i64>
132; CHECK-NEXT:    ret <2 x i64> [[EXT_NEG]]
133;
134  %ext = zext <2 x i1> %A to <2 x i64>
135  %sub = sub <2 x i64> <i64 0, i64 undef>, %ext
136  ret <2 x i64> %sub
137}
138
139define i64 @zext_sub_const(i1 %A) {
140; CHECK-LABEL: @zext_sub_const(
141; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[A:%.*]], i64 41, i64 42
142; CHECK-NEXT:    ret i64 [[SUB]]
143;
144  %ext = zext i1 %A to i64
145  %sub = sub i64 42, %ext
146  ret i64 %sub
147}
148
149define i64 @zext_sub_const_extra_use(i1 %A) {
150; CHECK-LABEL: @zext_sub_const_extra_use(
151; CHECK-NEXT:    [[EXT:%.*]] = zext i1 [[A:%.*]] to i64
152; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[A]], i64 41, i64 42
153; CHECK-NEXT:    call void @use(i64 [[EXT]])
154; CHECK-NEXT:    ret i64 [[SUB]]
155;
156  %ext = zext i1 %A to i64
157  %sub = sub i64 42, %ext
158  call void @use(i64 %ext)
159  ret i64 %sub
160}
161
162define <2 x i64> @zext_sub_const_vec(<2 x i1> %A) {
163; CHECK-LABEL: @zext_sub_const_vec(
164; CHECK-NEXT:    [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 41, i64 2>, <2 x i64> <i64 42, i64 3>
165; CHECK-NEXT:    ret <2 x i64> [[SUB]]
166;
167  %ext = zext <2 x i1> %A to <2 x i64>
168  %sub = sub <2 x i64> <i64 42, i64 3>, %ext
169  ret <2 x i64> %sub
170}
171
172define <2 x i64> @zext_sub_const_vec_undef_elt(<2 x i1> %A) {
173; CHECK-LABEL: @zext_sub_const_vec_undef_elt(
174; CHECK-NEXT:    [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 41, i64 undef>, <2 x i64> <i64 42, i64 undef>
175; CHECK-NEXT:    ret <2 x i64> [[SUB]]
176;
177  %ext = zext <2 x i1> %A to <2 x i64>
178  %sub = sub <2 x i64> <i64 42, i64 undef>, %ext
179  ret <2 x i64> %sub
180}
181
182define i64 @sext_negate(i1 %A) {
183; CHECK-LABEL: @sext_negate(
184; CHECK-NEXT:    [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64
185; CHECK-NEXT:    ret i64 [[EXT_NEG]]
186;
187  %ext = sext i1 %A to i64
188  %sub = sub i64 0, %ext
189  ret i64 %sub
190}
191
192define i64 @sext_negate_extra_use(i1 %A) {
193; CHECK-LABEL: @sext_negate_extra_use(
194; CHECK-NEXT:    [[EXT_NEG:%.*]] = zext i1 [[A:%.*]] to i64
195; CHECK-NEXT:    [[EXT:%.*]] = sext i1 [[A]] to i64
196; CHECK-NEXT:    call void @use(i64 [[EXT]])
197; CHECK-NEXT:    ret i64 [[EXT_NEG]]
198;
199  %ext = sext i1 %A to i64
200  %sub = sub i64 0, %ext
201  call void @use(i64 %ext)
202  ret i64 %sub
203}
204
205define <2 x i64> @sext_negate_vec(<2 x i1> %A) {
206; CHECK-LABEL: @sext_negate_vec(
207; CHECK-NEXT:    [[EXT_NEG:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i64>
208; CHECK-NEXT:    ret <2 x i64> [[EXT_NEG]]
209;
210  %ext = sext <2 x i1> %A to <2 x i64>
211  %sub = sub <2 x i64> zeroinitializer, %ext
212  ret <2 x i64> %sub
213}
214
215define <2 x i64> @sext_negate_vec_undef_elt(<2 x i1> %A) {
216; CHECK-LABEL: @sext_negate_vec_undef_elt(
217; CHECK-NEXT:    [[EXT_NEG:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i64>
218; CHECK-NEXT:    ret <2 x i64> [[EXT_NEG]]
219;
220  %ext = sext <2 x i1> %A to <2 x i64>
221  %sub = sub <2 x i64> <i64 0, i64 undef>, %ext
222  ret <2 x i64> %sub
223}
224
225define i64 @sext_sub_const(i1 %A) {
226; CHECK-LABEL: @sext_sub_const(
227; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[A:%.*]], i64 43, i64 42
228; CHECK-NEXT:    ret i64 [[SUB]]
229;
230  %ext = sext i1 %A to i64
231  %sub = sub i64 42, %ext
232  ret i64 %sub
233}
234
235define i64 @sext_sub_const_extra_use(i1 %A) {
236; CHECK-LABEL: @sext_sub_const_extra_use(
237; CHECK-NEXT:    [[EXT:%.*]] = sext i1 [[A:%.*]] to i64
238; CHECK-NEXT:    [[SUB:%.*]] = select i1 [[A]], i64 43, i64 42
239; CHECK-NEXT:    call void @use(i64 [[EXT]])
240; CHECK-NEXT:    ret i64 [[SUB]]
241;
242  %ext = sext i1 %A to i64
243  %sub = sub i64 42, %ext
244  call void @use(i64 %ext)
245  ret i64 %sub
246}
247
248define <2 x i64> @sext_sub_const_vec(<2 x i1> %A) {
249; CHECK-LABEL: @sext_sub_const_vec(
250; CHECK-NEXT:    [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 43, i64 4>, <2 x i64> <i64 42, i64 3>
251; CHECK-NEXT:    ret <2 x i64> [[SUB]]
252;
253  %ext = sext <2 x i1> %A to <2 x i64>
254  %sub = sub <2 x i64> <i64 42, i64 3>, %ext
255  ret <2 x i64> %sub
256}
257
258define <2 x i64> @sext_sub_const_vec_undef_elt(<2 x i1> %A) {
259; CHECK-LABEL: @sext_sub_const_vec_undef_elt(
260; CHECK-NEXT:    [[SUB:%.*]] = select <2 x i1> [[A:%.*]], <2 x i64> <i64 undef, i64 43>, <2 x i64> <i64 undef, i64 42>
261; CHECK-NEXT:    ret <2 x i64> [[SUB]]
262;
263  %ext = sext <2 x i1> %A to <2 x i64>
264  %sub = sub <2 x i64> <i64 undef, i64 42>, %ext
265  ret <2 x i64> %sub
266}
267
268define i8 @sext_sub(i8 %x, i1 %y) {
269; CHECK-LABEL: @sext_sub(
270; CHECK-NEXT:    [[SEXT_NEG:%.*]] = zext i1 [[Y:%.*]] to i8
271; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[SEXT_NEG]], [[X:%.*]]
272; CHECK-NEXT:    ret i8 [[SUB]]
273;
274  %sext = sext i1 %y to i8
275  %sub = sub i8 %x, %sext
276  ret i8 %sub
277}
278
279; Vectors get the same transform.
280
281define <2 x i8> @sext_sub_vec(<2 x i8> %x, <2 x i1> %y) {
282; CHECK-LABEL: @sext_sub_vec(
283; CHECK-NEXT:    [[SEXT_NEG:%.*]] = zext <2 x i1> [[Y:%.*]] to <2 x i8>
284; CHECK-NEXT:    [[SUB:%.*]] = add <2 x i8> [[SEXT_NEG]], [[X:%.*]]
285; CHECK-NEXT:    ret <2 x i8> [[SUB]]
286;
287  %sext = sext <2 x i1> %y to <2 x i8>
288  %sub = sub <2 x i8> %x, %sext
289  ret <2 x i8> %sub
290}
291
292; NSW is preserved.
293
294define <2 x i8> @sext_sub_vec_nsw(<2 x i8> %x, <2 x i1> %y) {
295; CHECK-LABEL: @sext_sub_vec_nsw(
296; CHECK-NEXT:    [[SEXT_NEG:%.*]] = zext <2 x i1> [[Y:%.*]] to <2 x i8>
297; CHECK-NEXT:    [[SUB:%.*]] = add <2 x i8> [[SEXT_NEG]], [[X:%.*]]
298; CHECK-NEXT:    ret <2 x i8> [[SUB]]
299;
300  %sext = sext <2 x i1> %y to <2 x i8>
301  %sub = sub nsw <2 x i8> %x, %sext
302  ret <2 x i8> %sub
303}
304
305; We favor the canonical zext+add over keeping the NUW.
306
307define i8 @sext_sub_nuw(i8 %x, i1 %y) {
308; CHECK-LABEL: @sext_sub_nuw(
309; CHECK-NEXT:    [[SEXT_NEG:%.*]] = zext i1 [[Y:%.*]] to i8
310; CHECK-NEXT:    [[SUB:%.*]] = add i8 [[SEXT_NEG]], [[X:%.*]]
311; CHECK-NEXT:    ret i8 [[SUB]]
312;
313  %sext = sext i1 %y to i8
314  %sub = sub nuw i8 %x, %sext
315  ret i8 %sub
316}
317
318define i32 @sextbool_add(i1 %c, i32 %x) {
319; CHECK-LABEL: @sextbool_add(
320; CHECK-NEXT:    [[B:%.*]] = sext i1 [[C:%.*]] to i32
321; CHECK-NEXT:    [[S:%.*]] = add i32 [[B]], [[X:%.*]]
322; CHECK-NEXT:    ret i32 [[S]]
323;
324  %b = sext i1 %c to i32
325  %s = add i32 %b, %x
326  ret i32 %s
327}
328
329define i32 @sextbool_add_commute(i1 %c, i32 %px) {
330; CHECK-LABEL: @sextbool_add_commute(
331; CHECK-NEXT:    [[X:%.*]] = urem i32 [[PX:%.*]], 42
332; CHECK-NEXT:    [[B:%.*]] = sext i1 [[C:%.*]] to i32
333; CHECK-NEXT:    [[S:%.*]] = add nsw i32 [[X]], [[B]]
334; CHECK-NEXT:    ret i32 [[S]]
335;
336  %x = urem i32 %px, 42 ; thwart complexity-based canonicalization
337  %b = sext i1 %c to i32
338  %s = add i32 %x, %b
339  ret i32 %s
340}
341
342; Negative test - extra use prevents canonicalization.
343
344declare void @use32(i32)
345
346define i32 @sextbool_add_uses(i1 %c, i32 %x) {
347; CHECK-LABEL: @sextbool_add_uses(
348; CHECK-NEXT:    [[B:%.*]] = sext i1 [[C:%.*]] to i32
349; CHECK-NEXT:    call void @use32(i32 [[B]])
350; CHECK-NEXT:    [[S:%.*]] = add i32 [[B]], [[X:%.*]]
351; CHECK-NEXT:    ret i32 [[S]]
352;
353  %b = sext i1 %c to i32
354  call void @use32(i32 %b)
355  %s = add i32 %b, %x
356  ret i32 %s
357}
358
359define <4 x i32> @sextbool_add_vector(<4 x i1> %c, <4 x i32> %x) {
360; CHECK-LABEL: @sextbool_add_vector(
361; CHECK-NEXT:    [[B:%.*]] = sext <4 x i1> [[C:%.*]] to <4 x i32>
362; CHECK-NEXT:    [[S:%.*]] = add <4 x i32> [[B]], [[X:%.*]]
363; CHECK-NEXT:    ret <4 x i32> [[S]]
364;
365  %b = sext <4 x i1> %c to <4 x i32>
366  %s = add <4 x i32> %x, %b
367  ret <4 x i32> %s
368}
369
370define i32 @zextbool_sub(i1 %c, i32 %x) {
371; CHECK-LABEL: @zextbool_sub(
372; CHECK-NEXT:    [[B:%.*]] = zext i1 [[C:%.*]] to i32
373; CHECK-NEXT:    [[S:%.*]] = sub i32 [[B]], [[X:%.*]]
374; CHECK-NEXT:    ret i32 [[S]]
375;
376  %b = zext i1 %c to i32
377  %s = sub i32 %b, %x
378  ret i32 %s
379}
380
381define i32 @zextbool_sub_uses(i1 %c, i32 %x) {
382; CHECK-LABEL: @zextbool_sub_uses(
383; CHECK-NEXT:    [[B:%.*]] = zext i1 [[C:%.*]] to i32
384; CHECK-NEXT:    call void @use32(i32 [[B]])
385; CHECK-NEXT:    [[S:%.*]] = sub i32 [[X:%.*]], [[B]]
386; CHECK-NEXT:    ret i32 [[S]]
387;
388  %b = zext i1 %c to i32
389  call void @use32(i32 %b)
390  %s = sub i32 %x, %b
391  ret i32 %s
392}
393
394define <4 x i32> @zextbool_sub_vector(<4 x i1> %c, <4 x i32> %x) {
395; CHECK-LABEL: @zextbool_sub_vector(
396; CHECK-NEXT:    [[B_NEG:%.*]] = sext <4 x i1> [[C:%.*]] to <4 x i32>
397; CHECK-NEXT:    [[S:%.*]] = add <4 x i32> [[B_NEG]], [[X:%.*]]
398; CHECK-NEXT:    ret <4 x i32> [[S]]
399;
400  %b = zext <4 x i1> %c to <4 x i32>
401  %s = sub <4 x i32> %x, %b
402  ret <4 x i32> %s
403}
404
405