[SLP] Add cost model for `llvm.powi.*` intrinsics
[llvm-project.git] / llvm / test / Transforms / InstCombine / or.ll
blobeb7c3a48ae809d86609647842ae3d70f4e7a0605
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s
4 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128-n32:64"
5 declare void @use(i32)
7 ; Should be eliminated
8 define i32 @test12(i32 %A) {
9 ; CHECK-LABEL: @test12(
10 ; CHECK-NEXT:    [[C:%.*]] = and i32 [[A:%.*]], 8
11 ; CHECK-NEXT:    ret i32 [[C]]
13   %B = or i32 %A, 4
14   %C = and i32 %B, 8
15   ret i32 %C
18 define i32 @test13(i32 %A) {
19 ; CHECK-LABEL: @test13(
20 ; CHECK-NEXT:    ret i32 8
22   %B = or i32 %A, 12
23   ; Always equal to 8
24   %C = and i32 %B, 8
25   ret i32 %C
28 define i1 @test14(i32 %A, i32 %B) {
29 ; CHECK-LABEL: @test14(
30 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
31 ; CHECK-NEXT:    ret i1 [[TMP1]]
33   %C1 = icmp ult i32 %A, %B
34   %C2 = icmp ugt i32 %A, %B
35   ; (A < B) | (A > B) === A != B
36   %D = or i1 %C1, %C2
37   ret i1 %D
40 define i1 @test14_commuted(i32 %A, i32 %B) {
41 ; CHECK-LABEL: @test14_commuted(
42 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[B:%.*]], [[A:%.*]]
43 ; CHECK-NEXT:    ret i1 [[TMP1]]
45   %C1 = icmp ult i32 %A, %B
46   %C2 = icmp ult i32 %B, %A
47   ; (A < B) | (A > B) === A != B
48   %D = or i1 %C1, %C2
49   ret i1 %D
52 define i1 @test14_logical(i32 %A, i32 %B) {
53 ; CHECK-LABEL: @test14_logical(
54 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
55 ; CHECK-NEXT:    ret i1 [[TMP1]]
57   %C1 = icmp ult i32 %A, %B
58   %C2 = icmp ugt i32 %A, %B
59   ; (A < B) | (A > B) === A != B
60   %D = select i1 %C1, i1 true, i1 %C2
61   ret i1 %D
64 define i1 @test15(i32 %A, i32 %B) {
65 ; CHECK-LABEL: @test15(
66 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
67 ; CHECK-NEXT:    ret i1 [[TMP1]]
69   %C1 = icmp ult i32 %A, %B
70   %C2 = icmp eq i32 %A, %B
71   ; (A < B) | (A == B) === A <= B
72   %D = or i1 %C1, %C2
73   ret i1 %D
76 define i1 @test15_logical(i32 %A, i32 %B) {
77 ; CHECK-LABEL: @test15_logical(
78 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
79 ; CHECK-NEXT:    ret i1 [[TMP1]]
81   %C1 = icmp ult i32 %A, %B
82   %C2 = icmp eq i32 %A, %B
83   ; (A < B) | (A == B) === A <= B
84   %D = select i1 %C1, i1 true, i1 %C2
85   ret i1 %D
88 define i32 @test16(i32 %A) {
89 ; CHECK-LABEL: @test16(
90 ; CHECK-NEXT:    ret i32 [[A:%.*]]
92   %B = and i32 %A, 1
93   ; -2 = ~1
94   %C = and i32 %A, -2
95   ; %D = and int %B, -1 == %B
96   %D = or i32 %B, %C
97   ret i32 %D
100 define i32 @test17(i32 %A) {
101 ; CHECK-LABEL: @test17(
102 ; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], 5
103 ; CHECK-NEXT:    ret i32 [[D]]
105   %B = and i32 %A, 1
106   %C = and i32 %A, 4
107   ; %D = and int %B, 5
108   %D = or i32 %B, %C
109   ret i32 %D
112 define i1 @test18(i32 %A) {
113 ; CHECK-LABEL: @test18(
114 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -100
115 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -50
116 ; CHECK-NEXT:    ret i1 [[TMP2]]
118   %B = icmp sge i32 %A, 100
119   %C = icmp slt i32 %A, 50
120   %D = or i1 %B, %C
121   ret i1 %D
124 define i1 @test18_logical(i32 %A) {
125 ; CHECK-LABEL: @test18_logical(
126 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -100
127 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -50
128 ; CHECK-NEXT:    ret i1 [[TMP2]]
130   %B = icmp sge i32 %A, 100
131   %C = icmp slt i32 %A, 50
132   %D = select i1 %B, i1 true, i1 %C
133   ret i1 %D
136 define <2 x i1> @test18vec(<2 x i32> %A) {
137 ; CHECK-LABEL: @test18vec(
138 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], <i32 -100, i32 -100>
139 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 -50, i32 -50>
140 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
142   %B = icmp sge <2 x i32> %A, <i32 100, i32 100>
143   %C = icmp slt <2 x i32> %A, <i32 50, i32 50>
144   %D = or <2 x i1> %B, %C
145   ret <2 x i1> %D
148 define i32 @test20(i32 %x) {
149 ; CHECK-LABEL: @test20(
150 ; CHECK-NEXT:    ret i32 [[X:%.*]]
152   %y = and i32 %x, 123
153   %z = or i32 %y, %x
154   ret i32 %z
157 define i32 @test21(i32 %t1) {
158 ; CHECK-LABEL: @test21(
159 ; CHECK-NEXT:    [[T1_MASK1:%.*]] = add i32 [[T1:%.*]], 2
160 ; CHECK-NEXT:    ret i32 [[T1_MASK1]]
162   %t1.mask1 = add i32 %t1, 2
163   %t3 = and i32 %t1.mask1, -2
164   %t5 = and i32 %t1, 1
165   ;; add tmp.1, 2
166   %t6 = or i32 %t5, %t3
167   ret i32 %t6
170 define i32 @test22(i32 %B) {
171 ; CHECK-LABEL: @test22(
172 ; CHECK-NEXT:    ret i32 [[B:%.*]]
174   %ELIM41 = and i32 %B, 1
175   %ELIM7 = and i32 %B, -2
176   %ELIM5 = or i32 %ELIM41, %ELIM7
177   ret i32 %ELIM5
180 define i16 @test23(i16 %A) {
181 ; CHECK-LABEL: @test23(
182 ; CHECK-NEXT:    [[B:%.*]] = lshr i16 [[A:%.*]], 1
183 ; CHECK-NEXT:    [[D:%.*]] = xor i16 [[B]], -24575
184 ; CHECK-NEXT:    ret i16 [[D]]
186   %B = lshr i16 %A, 1
187   ;; fold or into xor
188   %C = or i16 %B, -32768
189   %D = xor i16 %C, 8193
190   ret i16 %D
193 define <2 x i16> @test23vec(<2 x i16> %A) {
194 ; CHECK-LABEL: @test23vec(
195 ; CHECK-NEXT:    [[B:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 1, i16 1>
196 ; CHECK-NEXT:    [[D:%.*]] = xor <2 x i16> [[B]], <i16 -24575, i16 -24575>
197 ; CHECK-NEXT:    ret <2 x i16> [[D]]
199   %B = lshr <2 x i16> %A, <i16 1, i16 1>
200   ;; fold or into xor
201   %C = or <2 x i16> %B, <i16 -32768, i16 -32768>
202   %D = xor <2 x i16> %C, <i16 8193, i16 8193>
203   ret <2 x i16> %D
206 ; PR3266 & PR5276
207 define i1 @test25(i32 %A, i32 %B) {
208 ; CHECK-LABEL: @test25(
209 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
210 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
211 ; CHECK-NEXT:    [[F:%.*]] = and i1 [[C]], [[D]]
212 ; CHECK-NEXT:    ret i1 [[F]]
214   %C = icmp eq i32 %A, 0
215   %D = icmp eq i32 %B, 57
216   %E = or i1 %C, %D
217   %F = xor i1 %E, -1
218   ret i1 %F
221 define i1 @test25_logical(i32 %A, i32 %B) {
222 ; CHECK-LABEL: @test25_logical(
223 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
224 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
225 ; CHECK-NEXT:    [[E:%.*]] = select i1 [[C]], i1 [[D]], i1 false
226 ; CHECK-NEXT:    ret i1 [[E]]
228   %C = icmp eq i32 %A, 0
229   %D = icmp eq i32 %B, 57
230   %E = select i1 %C, i1 true, i1 %D
231   %F = xor i1 %E, -1
232   ret i1 %F
235 ; PR5634
236 define i1 @and_icmp_eq_0(i32 %A, i32 %B) {
237 ; CHECK-LABEL: @and_icmp_eq_0(
238 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
239 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
240 ; CHECK-NEXT:    ret i1 [[TMP2]]
242   %C1 = icmp eq i32 %A, 0
243   %C2 = icmp eq i32 %B, 0
244   ; (A == 0) & (A == 0)   -->   (A|B) == 0
245   %D = and i1 %C1, %C2
246   ret i1 %D
249 define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) {
250 ; CHECK-LABEL: @and_icmp_eq_0_vector(
251 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
252 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
253 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
255   %C1 = icmp eq <2 x i32> %A, zeroinitializer
256   %C2 = icmp eq <2 x i32> %B, zeroinitializer
257   %D = and <2 x i1> %C1, %C2
258   ret <2 x i1> %D
261 define <2 x i1> @and_icmp_eq_0_vector_undef1(<2 x i32> %A, <2 x i32> %B) {
262 ; CHECK-LABEL: @and_icmp_eq_0_vector_undef1(
263 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
264 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
265 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
267   %C1 = icmp eq <2 x i32> %A, <i32 0, i32 undef>
268   %C2 = icmp eq <2 x i32> %B, <i32 0, i32 undef>
269   %D = and <2 x i1> %C1, %C2
270   ret <2 x i1> %D
273 define <2 x i1> @and_icmp_eq_0_vector_undef2(<2 x i32> %A, <2 x i32> %B) {
274 ; CHECK-LABEL: @and_icmp_eq_0_vector_undef2(
275 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
276 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
277 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
279   %C1 = icmp eq <2 x i32> %A, <i32 0, i32 undef>
280   %C2 = icmp eq <2 x i32> %B, <i32 undef, i32 0>
281   %D = and <2 x i1> %C1, %C2
282   ret <2 x i1> %D
285 define i1 @and_icmp_eq_0_logical(i32 %A, i32 %B) {
286 ; CHECK-LABEL: @and_icmp_eq_0_logical(
287 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0
288 ; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0
289 ; CHECK-NEXT:    [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
290 ; CHECK-NEXT:    ret i1 [[D]]
292   %C1 = icmp eq i32 %A, 0
293   %C2 = icmp eq i32 %B, 0
294   ; (A == 0) & (A == 0)   -->   (A|B) == 0
295   %D = select i1 %C1, i1 %C2, i1 false
296   ret i1 %D
299 define i1 @test27(i32* %A, i32* %B) {
300 ; CHECK-LABEL: @test27(
301 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32* [[A:%.*]], null
302 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[B:%.*]], null
303 ; CHECK-NEXT:    [[E:%.*]] = and i1 [[TMP1]], [[TMP2]]
304 ; CHECK-NEXT:    ret i1 [[E]]
306   %C1 = ptrtoint i32* %A to i32
307   %C2 = ptrtoint i32* %B to i32
308   %D = or i32 %C1, %C2
309   %E = icmp eq i32 %D, 0
310   ret i1 %E
313 define <2 x i1> @test27vec(<2 x i32*> %A, <2 x i32*> %B) {
314 ; CHECK-LABEL: @test27vec(
315 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32*> [[A:%.*]], zeroinitializer
316 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32*> [[B:%.*]], zeroinitializer
317 ; CHECK-NEXT:    [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
318 ; CHECK-NEXT:    ret <2 x i1> [[E]]
320   %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
321   %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
322   %D = or <2 x i32> %C1, %C2
323   %E = icmp eq <2 x i32> %D, zeroinitializer
324   ret <2 x i1> %E
327 ; PR5634
328 define i1 @test28(i32 %A, i32 %B) {
329 ; CHECK-LABEL: @test28(
330 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
331 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
332 ; CHECK-NEXT:    ret i1 [[TMP2]]
334   %C1 = icmp ne i32 %A, 0
335   %C2 = icmp ne i32 %B, 0
336   ; (A != 0) | (A != 0)   -->   (A|B) != 0
337   %D = or i1 %C1, %C2
338   ret i1 %D
341 define i1 @test28_logical(i32 %A, i32 %B) {
342 ; CHECK-LABEL: @test28_logical(
343 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0
344 ; CHECK-NEXT:    [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0
345 ; CHECK-NEXT:    [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
346 ; CHECK-NEXT:    ret i1 [[D]]
348   %C1 = icmp ne i32 %A, 0
349   %C2 = icmp ne i32 %B, 0
350   ; (A != 0) | (A != 0)   -->   (A|B) != 0
351   %D = select i1 %C1, i1 true, i1 %C2
352   ret i1 %D
355 define i1 @test29(i32* %A, i32* %B) {
356 ; CHECK-LABEL: @test29(
357 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32* [[A:%.*]], null
358 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32* [[B:%.*]], null
359 ; CHECK-NEXT:    [[E:%.*]] = or i1 [[TMP1]], [[TMP2]]
360 ; CHECK-NEXT:    ret i1 [[E]]
362   %C1 = ptrtoint i32* %A to i32
363   %C2 = ptrtoint i32* %B to i32
364   %D = or i32 %C1, %C2
365   %E = icmp ne i32 %D, 0
366   ret i1 %E
369 define <2 x i1> @test29vec(<2 x i32*> %A, <2 x i32*> %B) {
370 ; CHECK-LABEL: @test29vec(
371 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i32*> [[A:%.*]], zeroinitializer
372 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32*> [[B:%.*]], zeroinitializer
373 ; CHECK-NEXT:    [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
374 ; CHECK-NEXT:    ret <2 x i1> [[E]]
376   %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
377   %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
378   %D = or <2 x i32> %C1, %C2
379   %E = icmp ne <2 x i32> %D, zeroinitializer
380   ret <2 x i1> %E
383 ; PR4216
384 define i32 @test30(i32 %A) {
385 ; CHECK-LABEL: @test30(
386 ; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], -58312
387 ; CHECK-NEXT:    [[E:%.*]] = or i32 [[D]], 32962
388 ; CHECK-NEXT:    ret i32 [[E]]
390   %B = or i32 %A, 32962   ; 0b1000_0000_1100_0010
391   %C = and i32 %A, -65536 ; 0xffff0000
392   %D = and i32 %B, 40186  ; 0b1001_1100_1111_1010
393   %E = or i32 %D, %C
394   ret i32 %E
397 define <2 x i32> @test30vec(<2 x i32> %A) {
398 ; CHECK-LABEL: @test30vec(
399 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], <i32 -58312, i32 -58312>
400 ; CHECK-NEXT:    [[E:%.*]] = or <2 x i32> [[TMP1]], <i32 32962, i32 32962>
401 ; CHECK-NEXT:    ret <2 x i32> [[E]]
403   %B = or <2 x i32> %A, <i32 32962, i32 32962>
404   %C = and <2 x i32> %A, <i32 -65536, i32 -65536>
405   %D = and <2 x i32> %B, <i32 40186, i32 40186>
406   %E = or <2 x i32> %D, %C
407   ret <2 x i32> %E
410 ; PR4216
411 define i64 @test31(i64 %A) {
412 ; CHECK-LABEL: @test31(
413 ; CHECK-NEXT:    [[E:%.*]] = and i64 [[A:%.*]], 4294908984
414 ; CHECK-NEXT:    [[F:%.*]] = or i64 [[E]], 32962
415 ; CHECK-NEXT:    ret i64 [[F]]
417   %B = or i64 %A, 194
418   %D = and i64 %B, 250
420   %C = or i64 %A, 32768
421   %E = and i64 %C, 4294941696
423   %F = or i64 %D, %E
424   ret i64 %F
427 define <2 x i64> @test31vec(<2 x i64> %A) {
428 ; CHECK-LABEL: @test31vec(
429 ; CHECK-NEXT:    [[E:%.*]] = and <2 x i64> [[A:%.*]], <i64 4294908984, i64 4294908984>
430 ; CHECK-NEXT:    [[F:%.*]] = or <2 x i64> [[E]], <i64 32962, i64 32962>
431 ; CHECK-NEXT:    ret <2 x i64> [[F]]
433   %B = or <2 x i64> %A, <i64 194, i64 194>
434   %D = and <2 x i64> %B, <i64 250, i64 250>
436   %C = or <2 x i64> %A, <i64 32768, i64 32768>
437   %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>
439   %F = or <2 x i64> %D, %E
440   ret <2 x i64> %F
443 ; codegen is mature enough to handle vector selects.
444 define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
445 ; CHECK-LABEL: @test32(
446 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]]
447 ; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
449   %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32>
450   %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135
451   %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1>
452   %and.i = and <4 x i32> %vecinit6.i191, %neg.i
453   %or.i = or <4 x i32> %and.i, %and.i129
454   ret <4 x i32> %or.i
457 define i1 @test33(i1 %X, i1 %Y) {
458 ; CHECK-LABEL: @test33(
459 ; CHECK-NEXT:    [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
460 ; CHECK-NEXT:    ret i1 [[A]]
462   %a = or i1 %X, %Y
463   %b = or i1 %a, %X
464   ret i1 %b
467 define i1 @test33_logical(i1 %X, i1 %Y) {
468 ; CHECK-LABEL: @test33_logical(
469 ; CHECK-NEXT:    [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
470 ; CHECK-NEXT:    ret i1 [[A]]
472   %a = select i1 %X, i1 true, i1 %Y
473   %b = select i1 %a, i1 true, i1 %X
474   ret i1 %b
477 define i32 @test34(i32 %X, i32 %Y) {
478 ; CHECK-LABEL: @test34(
479 ; CHECK-NEXT:    [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
480 ; CHECK-NEXT:    ret i32 [[A]]
482   %a = or i32 %X, %Y
483   %b = or i32 %Y, %a
484   ret i32 %b
487 define i32 @test35(i32 %a, i32 %b) {
488 ; CHECK-LABEL: @test35(
489 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
490 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], 1135
491 ; CHECK-NEXT:    ret i32 [[TMP2]]
493   %1 = or i32 %a, 1135
494   %2 = or i32 %1, %b
495   ret i32 %2
498 define i1 @test36(i32 %x) {
499 ; CHECK-LABEL: @test36(
500 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -23
501 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
502 ; CHECK-NEXT:    ret i1 [[TMP2]]
504   %cmp1 = icmp eq i32 %x, 23
505   %cmp2 = icmp eq i32 %x, 24
506   %ret1 = or i1 %cmp1, %cmp2
507   %cmp3 = icmp eq i32 %x, 25
508   %ret2 = or i1 %ret1, %cmp3
509   ret i1 %ret2
512 define i1 @test36_logical(i32 %x) {
513 ; CHECK-LABEL: @test36_logical(
514 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -23
515 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
516 ; CHECK-NEXT:    ret i1 [[TMP2]]
518   %cmp1 = icmp eq i32 %x, 23
519   %cmp2 = icmp eq i32 %x, 24
520   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
521   %cmp3 = icmp eq i32 %x, 25
522   %ret2 = select i1 %ret1, i1 true, i1 %cmp3
523   ret i1 %ret2
526 define i1 @test37(i32 %x) {
527 ; CHECK-LABEL: @test37(
528 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
529 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
530 ; CHECK-NEXT:    ret i1 [[TMP2]]
532   %add1 = add i32 %x, 7
533   %cmp1 = icmp ult i32 %add1, 30
534   %cmp2 = icmp eq i32 %x, 23
535   %ret1 = or i1 %cmp1, %cmp2
536   ret i1 %ret1
539 define i1 @test37_logical(i32 %x) {
540 ; CHECK-LABEL: @test37_logical(
541 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
542 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
543 ; CHECK-NEXT:    ret i1 [[TMP2]]
545   %add1 = add i32 %x, 7
546   %cmp1 = icmp ult i32 %add1, 30
547   %cmp2 = icmp eq i32 %x, 23
548   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
549   ret i1 %ret1
552 define <2 x i1> @test37_uniform(<2 x i32> %x) {
553 ; CHECK-LABEL: @test37_uniform(
554 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 7>
555 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 31, i32 31>
556 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
558   %add1 = add <2 x i32> %x, <i32 7, i32 7>
559   %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30>
560   %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23>
561   %ret1 = or <2 x i1> %cmp1, %cmp2
562   ret <2 x i1> %ret1
565 define <2 x i1> @test37_undef(<2 x i32> %x) {
566 ; CHECK-LABEL: @test37_undef(
567 ; CHECK-NEXT:    [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 undef>
568 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 undef>
569 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 undef>
570 ; CHECK-NEXT:    [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
571 ; CHECK-NEXT:    ret <2 x i1> [[RET1]]
573   %add1 = add <2 x i32> %x, <i32 7, i32 undef>
574   %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 undef>
575   %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 undef>
576   %ret1 = or <2 x i1> %cmp1, %cmp2
577   ret <2 x i1> %ret1
580 define i1 @test38(i32 %x) {
581 ; CHECK-LABEL: @test38(
582 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
583 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
584 ; CHECK-NEXT:    ret i1 [[TMP2]]
586   %add1 = add i32 %x, 7
587   %cmp1 = icmp eq i32 %x, 23
588   %cmp2 = icmp ult i32 %add1, 30
589   %ret1 = or i1 %cmp1, %cmp2
590   ret i1 %ret1
593 define i1 @test38_logical(i32 %x) {
594 ; CHECK-LABEL: @test38_logical(
595 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
596 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
597 ; CHECK-NEXT:    ret i1 [[TMP2]]
599   %add1 = add i32 %x, 7
600   %cmp1 = icmp eq i32 %x, 23
601   %cmp2 = icmp ult i32 %add1, 30
602   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
603   ret i1 %ret1
606 define <2 x i1> @test38_nonuniform(<2 x i32> %x) {
607 ; CHECK-LABEL: @test38_nonuniform(
608 ; CHECK-NEXT:    [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>
609 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8>
610 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32>
611 ; CHECK-NEXT:    [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
612 ; CHECK-NEXT:    ret <2 x i1> [[RET1]]
614   %add1 = add <2 x i32> %x, <i32 7, i32 24>
615   %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8>
616   %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32>
617   %ret1 = or <2 x i1> %cmp1, %cmp2
618   ret <2 x i1> %ret1
621 ; (~A & B) | A --> A | B
623 define i32 @test39a(i32 %a, float %b) {
624 ; CHECK-LABEL: @test39a(
625 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
626 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
627 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
628 ; CHECK-NEXT:    ret i32 [[OR]]
630   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
631   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
632   %nota = xor i32 %a1, -1
633   %and = and i32 %nota, %b1
634   %or = or i32 %and, %a1
635   ret i32 %or
638 ; Commute 'and' operands:
639 ; (B & ~A) | A --> A | B
641 define i32 @test39b(i32 %a, float %b) {
642 ; CHECK-LABEL: @test39b(
643 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
644 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
645 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
646 ; CHECK-NEXT:    ret i32 [[OR]]
648   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
649   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
650   %nota = xor i32 %a1, -1
651   %and = and i32 %b1, %nota
652   %or = or i32 %and, %a1
653   ret i32 %or
656 ; Commute 'or' operands:
657 ; A | (~A & B) --> A | B
659 define i32 @test39c(i32 %a, float %b) {
660 ; CHECK-LABEL: @test39c(
661 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
662 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
663 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
664 ; CHECK-NEXT:    ret i32 [[OR]]
666   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
667   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
668   %nota = xor i32 %a1, -1
669   %and = and i32 %nota, %b1
670   %or = or i32 %a1, %and
671   ret i32 %or
674 ; Commute 'and' operands:
675 ; A | (B & ~A) --> A | B
677 define i32 @test39d(i32 %a, float %b) {
678 ; CHECK-LABEL: @test39d(
679 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
680 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
681 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
682 ; CHECK-NEXT:    ret i32 [[OR]]
684   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
685   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
686   %nota = xor i32 %a1, -1
687   %and = and i32 %b1, %nota
688   %or = or i32 %a1, %and
689   ret i32 %or
692 define i32 @test40(i32 %a, i32 %b) {
693 ; CHECK-LABEL: @test40(
694 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
695 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
696 ; CHECK-NEXT:    ret i32 [[OR]]
698   %and = and i32 %a, %b
699   %xor = xor i32 %a, -1
700   %or = or i32 %and, %xor
701   ret i32 %or
704 define i32 @test40b(i32 %a, i32 %b) {
705 ; CHECK-LABEL: @test40b(
706 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
707 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
708 ; CHECK-NEXT:    ret i32 [[OR]]
710   %and = and i32 %b, %a
711   %xor = xor i32 %a, -1
712   %or = or i32 %and, %xor
713   ret i32 %or
716 define i32 @test40c(i32 %a, i32 %b) {
717 ; CHECK-LABEL: @test40c(
718 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
719 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
720 ; CHECK-NEXT:    ret i32 [[OR]]
722   %and = and i32 %b, %a
723   %xor = xor i32 %a, -1
724   %or = or i32 %xor, %and
725   ret i32 %or
728 define i32 @test40d(i32 %a, i32 %b) {
729 ; CHECK-LABEL: @test40d(
730 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
731 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
732 ; CHECK-NEXT:    ret i32 [[OR]]
734   %and = and i32 %a, %b
735   %xor = xor i32 %a, -1
736   %or = or i32 %xor, %and
737   ret i32 %or
740 define i32 @test45(i32 %x, i32 %y, i32 %z) {
741 ; CHECK-LABEL: @test45(
742 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
743 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
744 ; CHECK-NEXT:    ret i32 [[OR1]]
746   %or = or i32 %y, %z
747   %and = and i32 %x, %or
748   %or1 = or i32 %and, %y
749   ret i32 %or1
752 define i1 @test46(i8 signext %c)  {
753 ; CHECK-LABEL: @test46(
754 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
755 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
756 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
757 ; CHECK-NEXT:    ret i1 [[TMP3]]
759   %c.off = add i8 %c, -97
760   %cmp1 = icmp ult i8 %c.off, 26
761   %c.off17 = add i8 %c, -65
762   %cmp2 = icmp ult i8 %c.off17, 26
763   %or = or i1 %cmp1, %cmp2
764   ret i1 %or
767 define i1 @test46_logical(i8 signext %c)  {
768 ; CHECK-LABEL: @test46_logical(
769 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
770 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
771 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
772 ; CHECK-NEXT:    ret i1 [[TMP3]]
774   %c.off = add i8 %c, -97
775   %cmp1 = icmp ult i8 %c.off, 26
776   %c.off17 = add i8 %c, -65
777   %cmp2 = icmp ult i8 %c.off17, 26
778   %or = select i1 %cmp1, i1 true, i1 %cmp2
779   ret i1 %or
782 define <2 x i1> @test46_uniform(<2 x i8> %c)  {
783 ; CHECK-LABEL: @test46_uniform(
784 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[C:%.*]], <i8 -33, i8 -33>
785 ; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i8> [[TMP1]], <i8 -65, i8 -65>
786 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult <2 x i8> [[TMP2]], <i8 26, i8 26>
787 ; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
789   %c.off = add <2 x i8> %c, <i8 -97, i8 -97>
790   %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26>
791   %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65>
792   %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26>
793   %or = or <2 x i1> %cmp1, %cmp2
794   ret <2 x i1> %or
797 define <2 x i1> @test46_undef(<2 x i8> %c)  {
798 ; CHECK-LABEL: @test46_undef(
799 ; CHECK-NEXT:    [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 undef>
800 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 undef>
801 ; CHECK-NEXT:    [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 undef>
802 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 undef>
803 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
804 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
806   %c.off = add <2 x i8> %c, <i8 -97, i8 undef>
807   %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 undef>
808   %c.off17 = add <2 x i8> %c, <i8 -65, i8 undef>
809   %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 undef>
810   %or = or <2 x i1> %cmp1, %cmp2
811   ret <2 x i1> %or
814 ; This is the variant of the above pattern where one of the ranges is
815 ; represented with an add.
816 define i1 @two_ranges_to_mask_and_range_degenerate(i16 %x) {
817 ; CHECK-LABEL: @two_ranges_to_mask_and_range_degenerate(
818 ; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[X:%.*]], -20
819 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i16 [[TMP1]], 12
820 ; CHECK-NEXT:    ret i1 [[TMP2]]
822   %cmp1 = icmp ult i16 %x, 12
823   %cmp2 = icmp uge i16 %x, 16
824   %cmp3 = icmp ult i16 %x, 28
825   %and = and i1 %cmp2, %cmp3
826   %or = or i1 %cmp1, %and
827   ret i1 %or
830 define i1 @test47(i8 signext %c)  {
831 ; CHECK-LABEL: @test47(
832 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
833 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
834 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
835 ; CHECK-NEXT:    ret i1 [[TMP3]]
837   %c.off = add i8 %c, -65
838   %cmp1 = icmp ule i8 %c.off, 26
839   %c.off17 = add i8 %c, -97
840   %cmp2 = icmp ule i8 %c.off17, 26
841   %or = or i1 %cmp1, %cmp2
842   ret i1 %or
845 define i1 @test47_logical(i8 signext %c)  {
846 ; CHECK-LABEL: @test47_logical(
847 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
848 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
849 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
850 ; CHECK-NEXT:    ret i1 [[TMP3]]
852   %c.off = add i8 %c, -65
853   %cmp1 = icmp ule i8 %c.off, 26
854   %c.off17 = add i8 %c, -97
855   %cmp2 = icmp ule i8 %c.off17, 26
856   %or = select i1 %cmp1, i1 true, i1 %cmp2
857   ret i1 %or
860 define <2 x i1> @test47_nonuniform(<2 x i8> %c)  {
861 ; CHECK-LABEL: @test47_nonuniform(
862 ; CHECK-NEXT:    [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>
863 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 27, i8 27>
864 ; CHECK-NEXT:    [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65>
865 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 27, i8 27>
866 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
867 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
869   %c.off = add <2 x i8> %c, <i8 -65, i8 -97>
870   %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26>
871   %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65>
872   %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26>
873   %or = or <2 x i1> %cmp1, %cmp2
874   ret <2 x i1> %or
877 define i32 @test49(i1 %C) {
878 ; CHECK-LABEL: @test49(
879 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123
880 ; CHECK-NEXT:    ret i32 [[V]]
882   %A = select i1 %C, i32 1000, i32 10
883   %V = or i32 %A, 123
884   ret i32 %V
887 define <2 x i32> @test49vec(i1 %C) {
888 ; CHECK-LABEL: @test49vec(
889 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 1019>, <2 x i32> <i32 123, i32 123>
890 ; CHECK-NEXT:    ret <2 x i32> [[V]]
892   %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
893   %V = or <2 x i32> %A, <i32 123, i32 123>
894   ret <2 x i32> %V
897 define <2 x i32> @test49vec2(i1 %C) {
898 ; CHECK-LABEL: @test49vec2(
899 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351>
900 ; CHECK-NEXT:    ret <2 x i32> [[V]]
902   %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
903   %V = or <2 x i32> %A, <i32 123, i32 333>
904   ret <2 x i32> %V
907 define i32 @test50(i1 %which) {
908 ; CHECK-LABEL: @test50(
909 ; CHECK-NEXT:  entry:
910 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
911 ; CHECK:       delay:
912 ; CHECK-NEXT:    br label [[FINAL]]
913 ; CHECK:       final:
914 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ]
915 ; CHECK-NEXT:    ret i32 [[A]]
917 entry:
918   br i1 %which, label %final, label %delay
920 delay:
921   br label %final
923 final:
924   %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
925   %value = or i32 %A, 123
926   ret i32 %value
929 define <2 x i32> @test50vec(i1 %which) {
930 ; CHECK-LABEL: @test50vec(
931 ; CHECK-NEXT:  entry:
932 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
933 ; CHECK:       delay:
934 ; CHECK-NEXT:    br label [[FINAL]]
935 ; CHECK:       final:
936 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 1019>, [[ENTRY:%.*]] ], [ <i32 123, i32 123>, [[DELAY]] ]
937 ; CHECK-NEXT:    ret <2 x i32> [[A]]
939 entry:
940   br i1 %which, label %final, label %delay
942 delay:
943   br label %final
945 final:
946   %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
947   %value = or <2 x i32> %A, <i32 123, i32 123>
948   ret <2 x i32> %value
951 define <2 x i32> @test50vec2(i1 %which) {
952 ; CHECK-LABEL: @test50vec2(
953 ; CHECK-NEXT:  entry:
954 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
955 ; CHECK:       delay:
956 ; CHECK-NEXT:    br label [[FINAL]]
957 ; CHECK:       final:
958 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ]
959 ; CHECK-NEXT:    ret <2 x i32> [[A]]
961 entry:
962   br i1 %which, label %final, label %delay
964 delay:
965   br label %final
967 final:
968   %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
969   %value = or <2 x i32> %A, <i32 123, i32 333>
970   ret <2 x i32> %value
973 ; In the next 4 tests, vary the types and predicates for extra coverage.
974 ; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp
976 define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
977 ; CHECK-LABEL: @or_andn_cmp_1(
978 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
979 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
980 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X]], [[Y]]
981 ; CHECK-NEXT:    ret i1 [[OR]]
983   %x = icmp sgt i32 %a, %b
984   %x_inv = icmp sle i32 %a, %b
985   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
986   %and = and i1 %y, %x_inv
987   %or = or i1 %x, %and
988   ret i1 %or
991 define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
992 ; CHECK-LABEL: @or_andn_cmp_1_logical(
993 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
994 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
995 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
996 ; CHECK-NEXT:    ret i1 [[OR]]
998   %x = icmp sgt i32 %a, %b
999   %x_inv = icmp sle i32 %a, %b
1000   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1001   %and = select i1 %y, i1 %x_inv, i1 false
1002   %or = select i1 %x, i1 true, i1 %and
1003   ret i1 %or
1006 ; Commute the 'or':
1007 ; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
1009 define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
1010 ; CHECK-LABEL: @or_andn_cmp_2(
1011 ; CHECK-NEXT:    [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
1012 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
1013 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]
1014 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
1016   %x = icmp sge <2 x i32> %a, %b
1017   %x_inv = icmp slt <2 x i32> %a, %b
1018   %y = icmp ugt <2 x i32> %c, <i32 42, i32 47>      ; thwart complexity-based ordering
1019   %and = and <2 x i1> %y, %x_inv
1020   %or = or <2 x i1> %and, %x
1021   ret <2 x i1> %or
1024 ; Commute the 'and':
1025 ; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
1027 define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
1028 ; CHECK-LABEL: @or_andn_cmp_3(
1029 ; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1030 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1031 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X]], [[Y]]
1032 ; CHECK-NEXT:    ret i1 [[OR]]
1034   %x = icmp ugt i72 %a, %b
1035   %x_inv = icmp ule i72 %a, %b
1036   %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
1037   %and = and i1 %x_inv, %y
1038   %or = or i1 %x, %and
1039   ret i1 %or
1042 define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
1043 ; CHECK-LABEL: @or_andn_cmp_3_logical(
1044 ; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1045 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1046 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1047 ; CHECK-NEXT:    ret i1 [[OR]]
1049   %x = icmp ugt i72 %a, %b
1050   %x_inv = icmp ule i72 %a, %b
1051   %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
1052   %and = select i1 %x_inv, i1 %y, i1 false
1053   %or = select i1 %x, i1 true, i1 %and
1054   ret i1 %or
1057 ; Commute the 'or':
1058 ; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
1060 define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
1061 ; CHECK-LABEL: @or_andn_cmp_4(
1062 ; CHECK-NEXT:    [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
1063 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
1064 ; CHECK-NEXT:    [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]
1065 ; CHECK-NEXT:    ret <3 x i1> [[OR]]
1067   %x = icmp eq <3 x i32> %a, %b
1068   %x_inv = icmp ne <3 x i32> %a, %b
1069   %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1>      ; thwart complexity-based ordering
1070   %and = and <3 x i1> %x_inv, %y
1071   %or = or <3 x i1> %and, %x
1072   ret <3 x i1> %or
1075 ; In the next 4 tests, vary the types and predicates for extra coverage.
1076 ; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp
1078 define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
1079 ; CHECK-LABEL: @orn_and_cmp_1(
1080 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1081 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1082 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
1083 ; CHECK-NEXT:    ret i1 [[OR]]
1085   %x = icmp sgt i37 %a, %b
1086   %x_inv = icmp sle i37 %a, %b
1087   %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
1088   %and = and i1 %y, %x
1089   %or = or i1 %x_inv, %and
1090   ret i1 %or
1093 define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
1094 ; CHECK-LABEL: @orn_and_cmp_1_logical(
1095 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1096 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1097 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1098 ; CHECK-NEXT:    ret i1 [[OR]]
1100   %x = icmp sgt i37 %a, %b
1101   %x_inv = icmp sle i37 %a, %b
1102   %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
1103   %and = select i1 %y, i1 %x, i1 false
1104   %or = select i1 %x_inv, i1 true, i1 %and
1105   ret i1 %or
1108 ; Commute the 'or':
1109 ; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1111 define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
1112 ; CHECK-LABEL: @orn_and_cmp_2(
1113 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1114 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1115 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1116 ; CHECK-NEXT:    ret i1 [[OR]]
1118   %x = icmp sge i16 %a, %b
1119   %x_inv = icmp slt i16 %a, %b
1120   %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
1121   %and = and i1 %y, %x
1122   %or = or i1 %and, %x_inv
1123   ret i1 %or
1126 define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
1127 ; CHECK-LABEL: @orn_and_cmp_2_logical(
1128 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1129 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1130 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]]
1131 ; CHECK-NEXT:    ret i1 [[OR]]
1133   %x = icmp sge i16 %a, %b
1134   %x_inv = icmp slt i16 %a, %b
1135   %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
1136   %and = select i1 %y, i1 %x, i1 false
1137   %or = select i1 %and, i1 true, i1 %x_inv
1138   ret i1 %or
1141 ; Commute the 'and':
1142 ; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
1144 define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
1145 ; CHECK-LABEL: @orn_and_cmp_3(
1146 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
1147 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
1148 ; CHECK-NEXT:    [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]
1149 ; CHECK-NEXT:    ret <4 x i1> [[OR]]
1151   %x = icmp ugt <4 x i32> %a, %b
1152   %x_inv = icmp ule <4 x i32> %a, %b
1153   %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1>      ; thwart complexity-based ordering
1154   %and = and <4 x i1> %x, %y
1155   %or = or <4 x i1> %x_inv, %and
1156   ret <4 x i1> %or
1159 ; Commute the 'or':
1160 ; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1162 define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
1163 ; CHECK-LABEL: @orn_and_cmp_4(
1164 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1165 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1166 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1167 ; CHECK-NEXT:    ret i1 [[OR]]
1169   %x = icmp eq i32 %a, %b
1170   %x_inv = icmp ne i32 %a, %b
1171   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1172   %and = and i1 %x, %y
1173   %or = or i1 %and, %x_inv
1174   ret i1 %or
1177 define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
1178 ; CHECK-LABEL: @orn_and_cmp_4_logical(
1179 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1180 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1181 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1182 ; CHECK-NEXT:    ret i1 [[OR]]
1184   %x = icmp eq i32 %a, %b
1185   %x_inv = icmp ne i32 %a, %b
1186   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1187   %and = select i1 %x, i1 %y, i1 false
1188   %or = select i1 %and, i1 true, i1 %x_inv
1189   ret i1 %or
1192 ; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
1193 define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
1194 ; CHECK-LABEL: @test51(
1195 ; CHECK-NEXT:    [[TMP1:%.*]] = shufflevector <16 x i1> [[ARG:%.*]], <16 x i1> [[ARG1:%.*]], <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 20, i32 5, i32 6, i32 23, i32 24, i32 9, i32 10, i32 27, i32 28, i32 29, i32 30, i32 31>
1196 ; CHECK-NEXT:    ret <16 x i1> [[TMP1]]
1198   %tmp = and <16 x i1> %arg, <i1 true, i1 true, i1 true, i1 true, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false>
1199   %tmp2 = and <16 x i1> %arg1, <i1 false, i1 false, i1 false, i1 false, i1 true, i1 false, i1 false, i1 true, i1 true, i1 false, i1 false, i1 true, i1 true, i1 true, i1 true, i1 true>
1200   %tmp3 = or <16 x i1> %tmp, %tmp2
1201   ret <16 x i1> %tmp3
1204 ; This would infinite loop because it reaches a transform
1205 ; that was not expecting a constant-foldable value.
1207 define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
1208 ; CHECK-LABEL: @PR46712(
1209 ; CHECK-NEXT:  entry:
1210 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1211 ; CHECK:       true:
1212 ; CHECK-NEXT:    [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1213 ; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1214 ; CHECK-NEXT:    br label [[END]]
1215 ; CHECK:       end:
1216 ; CHECK-NEXT:    [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1217 ; CHECK-NEXT:    ret i32 [[T5]]
1219 entry:
1220   %t2 = or i1 %x, %y
1221   %conv = sext i1 %t2 to i32
1222   %cmp = icmp sge i32 %conv, 1
1223   %conv2 = zext i1 %cmp to i64
1224   br i1 %b, label %true, label %end
1226 true:
1227   %bool4 = icmp eq i64 %conv2, 0
1228   %bool5 = icmp ne i64 %z, 0
1229   %and = and i1 %bool4, %bool5
1230   %sel = select i1 %and, i1 false, i1 true
1231   br label %end
1233 end:
1234   %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1235   %conv8 = zext i1 %t5 to i32
1236   ret i32 %conv8
1239 define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
1240 ; CHECK-LABEL: @PR46712_logical(
1241 ; CHECK-NEXT:  entry:
1242 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1243 ; CHECK:       true:
1244 ; CHECK-NEXT:    [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1245 ; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1246 ; CHECK-NEXT:    br label [[END]]
1247 ; CHECK:       end:
1248 ; CHECK-NEXT:    [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1249 ; CHECK-NEXT:    ret i32 [[T5]]
1251 entry:
1252   %t2 = select i1 %x, i1 true, i1 %y
1253   %conv = sext i1 %t2 to i32
1254   %cmp = icmp sge i32 %conv, 1
1255   %conv2 = zext i1 %cmp to i64
1256   br i1 %b, label %true, label %end
1258 true:
1259   %bool4 = icmp eq i64 %conv2, 0
1260   %bool5 = icmp ne i64 %z, 0
1261   %and = select i1 %bool4, i1 %bool5, i1 false
1262   %sel = select i1 %and, i1 false, i1 true
1263   br label %end
1265 end:
1266   %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1267   %conv8 = zext i1 %t5 to i32
1268   ret i32 %conv8
1271 ; (~x & y) | ~(x | y) --> ~x
1272 define i32 @PR38929(i32 %0, i32 %1) {
1273 ; CHECK-LABEL: @PR38929(
1274 ; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1
1275 ; CHECK-NEXT:    ret i32 [[TMP3]]
1277   %3 = xor i32 %0, -1
1278   %4 = and i32 %3, %1
1279   %5 = or i32 %1, %0
1280   %6 = xor i32 %5, -1
1281   %7 = or i32 %4, %6
1282   ret i32 %7
1285 define i32 @test1(i32 %x, i32 %y) {
1286 ; CHECK-LABEL: @test1(
1287 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1288 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1289 ; CHECK-NEXT:    ret i32 [[OR1]]
1291   %xor = xor i32 %y, %x
1292   %or = or i32 %y, %x
1293   %neg = xor i32 %or, -1
1294   %or1 = or i32 %xor, %neg
1295   ret i32 %or1
1298 define i32 @test2(i32 %x, i32 %y) {
1299 ; CHECK-LABEL: @test2(
1300 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1301 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1302 ; CHECK-NEXT:    ret i32 [[OR1]]
1304   %or = or i32 %x, %y
1305   %neg = xor i32 %or, -1
1306   %xor = xor i32 %y, %x
1307   %or1 = or i32 %xor, %neg
1308   ret i32 %or1
1311 define i32 @test3(i32 %x, i32 %y) {
1312 ; CHECK-LABEL: @test3(
1313 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
1314 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1315 ; CHECK-NEXT:    ret i32 [[OR1]]
1317   %or = or i32 %y, %x
1318   %neg = xor i32 %or, -1
1319   %xor = xor i32 %x, %y
1320   %or1 = or i32 %xor, %neg
1321   ret i32 %or1
1324 define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
1325 ; CHECK-LABEL: @test4_vec(
1326 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
1327 ; CHECK-NEXT:    [[OR1:%.*]] = xor <2 x i32> [[TMP1]], <i32 -1, i32 -1>
1328 ; CHECK-NEXT:    ret <2 x i32> [[OR1]]
1330   %or = or <2 x i32> %y, %x
1331   %neg = xor <2 x i32> %or, <i32 -1, i32 -1>
1332   %xor = xor <2 x i32> %y, %x
1333   %or1 = or <2 x i32> %xor, %neg
1334   ret <2 x i32> %or1
1337 define i32 @test5_use(i32 %x, i32 %y) {
1338 ; CHECK-LABEL: @test5_use(
1339 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1340 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[OR]], -1
1341 ; CHECK-NEXT:    call void @use(i32 [[NEG]])
1342 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1343 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1344 ; CHECK-NEXT:    ret i32 [[OR1]]
1346   %or = or i32 %y, %x
1347   %neg = xor i32 %or, -1
1348   %xor = xor i32 %y, %x
1349   call void @use(i32 %neg)
1350   %or1 = or i32 %xor, %neg
1351   ret i32 %or1
1354 define i32 @test5_use2(i32 %x, i32 %y) {
1355 ; CHECK-LABEL: @test5_use2(
1356 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1357 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
1358 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1359 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1360 ; CHECK-NEXT:    ret i32 [[OR1]]
1362   %or = or i32 %y, %x
1363   %neg = xor i32 %or, -1
1364   %xor = xor i32 %y, %x
1365   call void @use(i32 %xor)
1366   %or1 = or i32 %xor, %neg
1367   ret i32 %or1
1369 define i32 @test5_use3(i32 %x, i32 %y) {
1370 ; CHECK-LABEL: @test5_use3(
1371 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1372 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[OR]], -1
1373 ; CHECK-NEXT:    call void @use(i32 [[NEG]])
1374 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
1375 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
1376 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
1377 ; CHECK-NEXT:    ret i32 [[OR1]]
1379   %or = or i32 %y, %x
1380   %neg = xor i32 %or, -1
1381   call void @use(i32 %neg)
1382   %xor = xor i32 %y, %x
1383   call void @use(i32 %xor)
1384   %or1 = or i32 %xor, %neg
1385   ret i32 %or1
1388 define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) {
1389 ; CHECK-LABEL: @ashr_bitwidth_mask(
1390 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1391 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1392 ; CHECK-NEXT:    ret i8 [[R]]
1394   %sign = ashr i8 %x, 7
1395   %r = or i8 %sign, %y
1396   ret i8 %r
1399 define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {
1400 ; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute(
1401 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>
1402 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr <2 x i8> [[X:%.*]], <i8 7, i8 7>
1403 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i8> [[Y]], [[SIGN]]
1404 ; CHECK-NEXT:    ret <2 x i8> [[R]]
1406   %y = mul <2 x i8> %py, <i8 42, i8 2>      ; thwart complexity-based ordering
1407   %sign = ashr <2 x i8> %x, <i8 7, i8 7>
1408   %r = or <2 x i8> %y, %sign
1409   ret <2 x i8> %r
1412 define i32 @ashr_bitwidth_mask_use(i32 %x, i32 %y) {
1413 ; CHECK-LABEL: @ashr_bitwidth_mask_use(
1414 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i32 [[X:%.*]], 7
1415 ; CHECK-NEXT:    call void @use(i32 [[SIGN]])
1416 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[SIGN]], [[Y:%.*]]
1417 ; CHECK-NEXT:    ret i32 [[R]]
1419   %sign = ashr i32 %x, 7
1420   call void @use(i32 %sign)
1421   %r = or i32 %sign, %y
1422   ret i32 %r
1425 define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) {
1426 ; CHECK-LABEL: @ashr_not_bitwidth_mask(
1427 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6
1428 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1429 ; CHECK-NEXT:    ret i8 [[R]]
1431   %sign = ashr i8 %x, 6
1432   %r = or i8 %sign, %y
1433   ret i8 %r
1436 define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {
1437 ; CHECK-LABEL: @lshr_bitwidth_mask(
1438 ; CHECK-NEXT:    [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7
1439 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1440 ; CHECK-NEXT:    ret i8 [[R]]
1442   %sign = lshr i8 %x, 7
1443   %r = or i8 %sign, %y
1444   ret i8 %r
1447 define i1 @cmp_overlap(i32 %x) {
1448 ; CHECK-LABEL: @cmp_overlap(
1449 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
1450 ; CHECK-NEXT:    ret i1 [[TMP1]]
1452   %isneg = icmp slt i32 %x, 0
1453   %negx = sub i32 0, %x
1454   %isnotneg = icmp sgt i32 %negx, -1
1455   %r = or i1 %isneg, %isnotneg
1456   ret i1 %r
1459 define <2 x i1> @cmp_overlap_splat(<2 x i5> %x) {
1460 ; CHECK-LABEL: @cmp_overlap_splat(
1461 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i5> [[X:%.*]], <i5 1, i5 1>
1462 ; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
1464   %isneg = icmp slt <2 x i5> %x, zeroinitializer
1465   %negx = sub <2 x i5> zeroinitializer, %x
1466   %isnotneg = icmp sgt <2 x i5> %negx, <i5 -1, i5 -1>
1467   %r = or <2 x i1> %isneg, %isnotneg
1468   ret <2 x i1> %r
1471 define i32 @mul_no_common_bits(i32 %p1, i32 %p2) {
1472 ; CHECK-LABEL: @mul_no_common_bits(
1473 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
1474 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1475 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[Y]], 1
1476 ; CHECK-NEXT:    [[R:%.*]] = mul i32 [[X]], [[TMP1]]
1477 ; CHECK-NEXT:    ret i32 [[R]]
1479   %x = and i32 %p1, 7
1480   %y = shl i32 %p2, 3
1481   %m = mul i32 %x, %y
1482   %r = or i32 %m, %x
1483   ret i32 %r
1486 define i32 @mul_no_common_bits_const_op(i32 %p) {
1487 ; CHECK-LABEL: @mul_no_common_bits_const_op(
1488 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1489 ; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[X]], 25
1490 ; CHECK-NEXT:    ret i32 [[R]]
1492   %x = and i32 %p, 7
1493   %m = mul i32 %x, 24
1494   %r = or i32 %m, %x
1495   ret i32 %r
1498 define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) {
1499 ; CHECK-LABEL: @mul_no_common_bits_commute(
1500 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i12> [[P:%.*]] to <2 x i1>
1501 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP1]], <2 x i12> <i12 15, i12 17>, <2 x i12> zeroinitializer
1502 ; CHECK-NEXT:    ret <2 x i12> [[R]]
1504   %x = and <2 x i12> %p, <i12 1, i12 1>
1505   %m = mul <2 x i12> %x, <i12 14, i12 16>
1506   %r = or <2 x i12> %x, %m
1507   ret <2 x i12> %r
1510 ; negative test - extra use requires extra instructions
1512 define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) {
1513 ; CHECK-LABEL: @mul_no_common_bits_uses(
1514 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
1515 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1516 ; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y]]
1517 ; CHECK-NEXT:    call void @use(i32 [[M]])
1518 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
1519 ; CHECK-NEXT:    ret i32 [[R]]
1521   %x = and i32 %p1, 7
1522   %y = shl i32 %p2, 3
1523   %m = mul i32 %x, %y
1524   call void @use(i32 %m)
1525   %r = or i32 %m, %x
1526   ret i32 %r
1529 ; negative test - probably not good to create an extra mul
1531 define i32 @mul_no_common_bits_const_op_uses(i32 %p) {
1532 ; CHECK-LABEL: @mul_no_common_bits_const_op_uses(
1533 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1534 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 24
1535 ; CHECK-NEXT:    call void @use(i32 [[M]])
1536 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
1537 ; CHECK-NEXT:    ret i32 [[R]]
1539   %x = and i32 %p, 7
1540   %m = mul i32 %x, 24
1541   call void @use(i32 %m)
1542   %r = or i32 %m, %x
1543   ret i32 %r
1546 ; negative test - %x and %m may have set 3rd bit
1548 define i32 @mul_common_bits(i32 %p) {
1549 ; CHECK-LABEL: @mul_common_bits(
1550 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1551 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 12
1552 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
1553 ; CHECK-NEXT:    ret i32 [[R]]
1555   %x = and i32 %p, 7
1556   %m = mul i32 %x, 12
1557   %r = or i32 %m, %x
1558   ret i32 %r