[sanitizer] Improve FreeBSD ASLR detection
[llvm-project.git] / llvm / test / Transforms / InstCombine / or.ll
blob869c17a3ccf9d0f083b35948a13b859378944b96
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -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_logical(i32 %A, i32 %B) {
41 ; CHECK-LABEL: @test14_logical(
42 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
43 ; CHECK-NEXT:    ret i1 [[TMP1]]
45   %C1 = icmp ult i32 %A, %B
46   %C2 = icmp ugt i32 %A, %B
47   ; (A < B) | (A > B) === A != B
48   %D = select i1 %C1, i1 true, i1 %C2
49   ret i1 %D
52 define i1 @test15(i32 %A, i32 %B) {
53 ; CHECK-LABEL: @test15(
54 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
55 ; CHECK-NEXT:    ret i1 [[TMP1]]
57   %C1 = icmp ult i32 %A, %B
58   %C2 = icmp eq i32 %A, %B
59   ; (A < B) | (A == B) === A <= B
60   %D = or i1 %C1, %C2
61   ret i1 %D
64 define i1 @test15_logical(i32 %A, i32 %B) {
65 ; CHECK-LABEL: @test15_logical(
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 = select i1 %C1, i1 true, i1 %C2
73   ret i1 %D
76 define i32 @test16(i32 %A) {
77 ; CHECK-LABEL: @test16(
78 ; CHECK-NEXT:    ret i32 [[A:%.*]]
80   %B = and i32 %A, 1
81   ; -2 = ~1
82   %C = and i32 %A, -2
83   ; %D = and int %B, -1 == %B
84   %D = or i32 %B, %C
85   ret i32 %D
88 define i32 @test17(i32 %A) {
89 ; CHECK-LABEL: @test17(
90 ; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], 5
91 ; CHECK-NEXT:    ret i32 [[D]]
93   %B = and i32 %A, 1
94   %C = and i32 %A, 4
95   ; %D = and int %B, 5
96   %D = or i32 %B, %C
97   ret i32 %D
100 define i1 @test18(i32 %A) {
101 ; CHECK-LABEL: @test18(
102 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -100
103 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], -50
104 ; CHECK-NEXT:    ret i1 [[TMP2]]
106   %B = icmp sge i32 %A, 100
107   %C = icmp slt i32 %A, 50
108   %D = or i1 %B, %C
109   ret i1 %D
112 define i1 @test18_logical(i32 %A) {
113 ; CHECK-LABEL: @test18_logical(
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 = select i1 %B, i1 true, i1 %C
121   ret i1 %D
124 define <2 x i1> @test18vec(<2 x i32> %A) {
125 ; CHECK-LABEL: @test18vec(
126 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], <i32 -100, i32 -100>
127 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 -50, i32 -50>
128 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
130   %B = icmp sge <2 x i32> %A, <i32 100, i32 100>
131   %C = icmp slt <2 x i32> %A, <i32 50, i32 50>
132   %D = or <2 x i1> %B, %C
133   ret <2 x i1> %D
136 define i32 @test20(i32 %x) {
137 ; CHECK-LABEL: @test20(
138 ; CHECK-NEXT:    ret i32 [[X:%.*]]
140   %y = and i32 %x, 123
141   %z = or i32 %y, %x
142   ret i32 %z
145 define i32 @test21(i32 %t1) {
146 ; CHECK-LABEL: @test21(
147 ; CHECK-NEXT:    [[T1_MASK1:%.*]] = add i32 [[T1:%.*]], 2
148 ; CHECK-NEXT:    ret i32 [[T1_MASK1]]
150   %t1.mask1 = add i32 %t1, 2
151   %t3 = and i32 %t1.mask1, -2
152   %t5 = and i32 %t1, 1
153   ;; add tmp.1, 2
154   %t6 = or i32 %t5, %t3
155   ret i32 %t6
158 define i32 @test22(i32 %B) {
159 ; CHECK-LABEL: @test22(
160 ; CHECK-NEXT:    ret i32 [[B:%.*]]
162   %ELIM41 = and i32 %B, 1
163   %ELIM7 = and i32 %B, -2
164   %ELIM5 = or i32 %ELIM41, %ELIM7
165   ret i32 %ELIM5
168 define i16 @test23(i16 %A) {
169 ; CHECK-LABEL: @test23(
170 ; CHECK-NEXT:    [[B:%.*]] = lshr i16 [[A:%.*]], 1
171 ; CHECK-NEXT:    [[D:%.*]] = xor i16 [[B]], -24575
172 ; CHECK-NEXT:    ret i16 [[D]]
174   %B = lshr i16 %A, 1
175   ;; fold or into xor
176   %C = or i16 %B, -32768
177   %D = xor i16 %C, 8193
178   ret i16 %D
181 define <2 x i16> @test23vec(<2 x i16> %A) {
182 ; CHECK-LABEL: @test23vec(
183 ; CHECK-NEXT:    [[B:%.*]] = lshr <2 x i16> [[A:%.*]], <i16 1, i16 1>
184 ; CHECK-NEXT:    [[D:%.*]] = xor <2 x i16> [[B]], <i16 -24575, i16 -24575>
185 ; CHECK-NEXT:    ret <2 x i16> [[D]]
187   %B = lshr <2 x i16> %A, <i16 1, i16 1>
188   ;; fold or into xor
189   %C = or <2 x i16> %B, <i16 -32768, i16 -32768>
190   %D = xor <2 x i16> %C, <i16 8193, i16 8193>
191   ret <2 x i16> %D
194 ; PR3266 & PR5276
195 define i1 @test25(i32 %A, i32 %B) {
196 ; CHECK-LABEL: @test25(
197 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
198 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
199 ; CHECK-NEXT:    [[F:%.*]] = and i1 [[C]], [[D]]
200 ; CHECK-NEXT:    ret i1 [[F]]
202   %C = icmp eq i32 %A, 0
203   %D = icmp eq i32 %B, 57
204   %E = or i1 %C, %D
205   %F = xor i1 %E, -1
206   ret i1 %F
209 define i1 @test25_logical(i32 %A, i32 %B) {
210 ; CHECK-LABEL: @test25_logical(
211 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
212 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
213 ; CHECK-NEXT:    [[E:%.*]] = select i1 [[C]], i1 [[D]], i1 false
214 ; CHECK-NEXT:    ret i1 [[E]]
216   %C = icmp eq i32 %A, 0
217   %D = icmp eq i32 %B, 57
218   %E = select i1 %C, i1 true, i1 %D
219   %F = xor i1 %E, -1
220   ret i1 %F
223 ; PR5634
224 define i1 @and_icmp_eq_0(i32 %A, i32 %B) {
225 ; CHECK-LABEL: @and_icmp_eq_0(
226 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
227 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
228 ; CHECK-NEXT:    ret i1 [[TMP2]]
230   %C1 = icmp eq i32 %A, 0
231   %C2 = icmp eq i32 %B, 0
232   ; (A == 0) & (A == 0)   -->   (A|B) == 0
233   %D = and i1 %C1, %C2
234   ret i1 %D
237 define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) {
238 ; CHECK-LABEL: @and_icmp_eq_0_vector(
239 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
240 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
241 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
243   %C1 = icmp eq <2 x i32> %A, zeroinitializer
244   %C2 = icmp eq <2 x i32> %B, zeroinitializer
245   %D = and <2 x i1> %C1, %C2
246   ret <2 x i1> %D
249 define <2 x i1> @and_icmp_eq_0_vector_undef1(<2 x i32> %A, <2 x i32> %B) {
250 ; CHECK-LABEL: @and_icmp_eq_0_vector_undef1(
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, <i32 0, i32 undef>
256   %C2 = icmp eq <2 x i32> %B, <i32 0, i32 undef>
257   %D = and <2 x i1> %C1, %C2
258   ret <2 x i1> %D
261 define <2 x i1> @and_icmp_eq_0_vector_undef2(<2 x i32> %A, <2 x i32> %B) {
262 ; CHECK-LABEL: @and_icmp_eq_0_vector_undef2(
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 undef, i32 0>
269   %D = and <2 x i1> %C1, %C2
270   ret <2 x i1> %D
273 define i1 @and_icmp_eq_0_logical(i32 %A, i32 %B) {
274 ; CHECK-LABEL: @and_icmp_eq_0_logical(
275 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0
276 ; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0
277 ; CHECK-NEXT:    [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
278 ; CHECK-NEXT:    ret i1 [[D]]
280   %C1 = icmp eq i32 %A, 0
281   %C2 = icmp eq i32 %B, 0
282   ; (A == 0) & (A == 0)   -->   (A|B) == 0
283   %D = select i1 %C1, i1 %C2, i1 false
284   ret i1 %D
287 define i1 @test27(i32* %A, i32* %B) {
288 ; CHECK-LABEL: @test27(
289 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i32* [[A:%.*]], null
290 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32* [[B:%.*]], null
291 ; CHECK-NEXT:    [[E:%.*]] = and i1 [[TMP1]], [[TMP2]]
292 ; CHECK-NEXT:    ret i1 [[E]]
294   %C1 = ptrtoint i32* %A to i32
295   %C2 = ptrtoint i32* %B to i32
296   %D = or i32 %C1, %C2
297   %E = icmp eq i32 %D, 0
298   ret i1 %E
301 define <2 x i1> @test27vec(<2 x i32*> %A, <2 x i32*> %B) {
302 ; CHECK-LABEL: @test27vec(
303 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i32*> [[A:%.*]], zeroinitializer
304 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32*> [[B:%.*]], zeroinitializer
305 ; CHECK-NEXT:    [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
306 ; CHECK-NEXT:    ret <2 x i1> [[E]]
308   %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
309   %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
310   %D = or <2 x i32> %C1, %C2
311   %E = icmp eq <2 x i32> %D, zeroinitializer
312   ret <2 x i1> %E
315 ; PR5634
316 define i1 @test28(i32 %A, i32 %B) {
317 ; CHECK-LABEL: @test28(
318 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
319 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
320 ; CHECK-NEXT:    ret i1 [[TMP2]]
322   %C1 = icmp ne i32 %A, 0
323   %C2 = icmp ne i32 %B, 0
324   ; (A != 0) | (A != 0)   -->   (A|B) != 0
325   %D = or i1 %C1, %C2
326   ret i1 %D
329 define i1 @test28_logical(i32 %A, i32 %B) {
330 ; CHECK-LABEL: @test28_logical(
331 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0
332 ; CHECK-NEXT:    [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0
333 ; CHECK-NEXT:    [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
334 ; CHECK-NEXT:    ret i1 [[D]]
336   %C1 = icmp ne i32 %A, 0
337   %C2 = icmp ne i32 %B, 0
338   ; (A != 0) | (A != 0)   -->   (A|B) != 0
339   %D = select i1 %C1, i1 true, i1 %C2
340   ret i1 %D
343 define i1 @test29(i32* %A, i32* %B) {
344 ; CHECK-LABEL: @test29(
345 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i32* [[A:%.*]], null
346 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32* [[B:%.*]], null
347 ; CHECK-NEXT:    [[E:%.*]] = or i1 [[TMP1]], [[TMP2]]
348 ; CHECK-NEXT:    ret i1 [[E]]
350   %C1 = ptrtoint i32* %A to i32
351   %C2 = ptrtoint i32* %B to i32
352   %D = or i32 %C1, %C2
353   %E = icmp ne i32 %D, 0
354   ret i1 %E
357 define <2 x i1> @test29vec(<2 x i32*> %A, <2 x i32*> %B) {
358 ; CHECK-LABEL: @test29vec(
359 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i32*> [[A:%.*]], zeroinitializer
360 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x i32*> [[B:%.*]], zeroinitializer
361 ; CHECK-NEXT:    [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
362 ; CHECK-NEXT:    ret <2 x i1> [[E]]
364   %C1 = ptrtoint <2 x i32*> %A to <2 x i32>
365   %C2 = ptrtoint <2 x i32*> %B to <2 x i32>
366   %D = or <2 x i32> %C1, %C2
367   %E = icmp ne <2 x i32> %D, zeroinitializer
368   ret <2 x i1> %E
371 ; PR4216
372 define i32 @test30(i32 %A) {
373 ; CHECK-LABEL: @test30(
374 ; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], -58312
375 ; CHECK-NEXT:    [[E:%.*]] = or i32 [[D]], 32962
376 ; CHECK-NEXT:    ret i32 [[E]]
378   %B = or i32 %A, 32962   ; 0b1000_0000_1100_0010
379   %C = and i32 %A, -65536 ; 0xffff0000
380   %D = and i32 %B, 40186  ; 0b1001_1100_1111_1010
381   %E = or i32 %D, %C
382   ret i32 %E
385 define <2 x i32> @test30vec(<2 x i32> %A) {
386 ; CHECK-LABEL: @test30vec(
387 ; CHECK-NEXT:    [[C:%.*]] = and <2 x i32> [[A:%.*]], <i32 -65536, i32 -65536>
388 ; CHECK-NEXT:    [[B:%.*]] = and <2 x i32> [[A]], <i32 7224, i32 7224>
389 ; CHECK-NEXT:    [[D:%.*]] = or <2 x i32> [[B]], <i32 32962, i32 32962>
390 ; CHECK-NEXT:    [[E:%.*]] = or <2 x i32> [[D]], [[C]]
391 ; CHECK-NEXT:    ret <2 x i32> [[E]]
393   %B = or <2 x i32> %A, <i32 32962, i32 32962>
394   %C = and <2 x i32> %A, <i32 -65536, i32 -65536>
395   %D = and <2 x i32> %B, <i32 40186, i32 40186>
396   %E = or <2 x i32> %D, %C
397   ret <2 x i32> %E
400 ; PR4216
401 define i64 @test31(i64 %A) {
402 ; CHECK-LABEL: @test31(
403 ; CHECK-NEXT:    [[E:%.*]] = and i64 [[A:%.*]], 4294908984
404 ; CHECK-NEXT:    [[F:%.*]] = or i64 [[E]], 32962
405 ; CHECK-NEXT:    ret i64 [[F]]
407   %B = or i64 %A, 194
408   %D = and i64 %B, 250
410   %C = or i64 %A, 32768
411   %E = and i64 %C, 4294941696
413   %F = or i64 %D, %E
414   ret i64 %F
417 define <2 x i64> @test31vec(<2 x i64> %A) {
418 ; CHECK-LABEL: @test31vec(
419 ; CHECK-NEXT:    [[E:%.*]] = and <2 x i64> [[A:%.*]], <i64 4294908984, i64 4294908984>
420 ; CHECK-NEXT:    [[F:%.*]] = or <2 x i64> [[E]], <i64 32962, i64 32962>
421 ; CHECK-NEXT:    ret <2 x i64> [[F]]
423   %B = or <2 x i64> %A, <i64 194, i64 194>
424   %D = and <2 x i64> %B, <i64 250, i64 250>
426   %C = or <2 x i64> %A, <i64 32768, i64 32768>
427   %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>
429   %F = or <2 x i64> %D, %E
430   ret <2 x i64> %F
433 ; codegen is mature enough to handle vector selects.
434 define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
435 ; CHECK-LABEL: @test32(
436 ; CHECK-NEXT:    [[TMP1:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]]
437 ; CHECK-NEXT:    ret <4 x i32> [[TMP1]]
439   %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32>
440   %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135
441   %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1>
442   %and.i = and <4 x i32> %vecinit6.i191, %neg.i
443   %or.i = or <4 x i32> %and.i, %and.i129
444   ret <4 x i32> %or.i
447 define i1 @test33(i1 %X, i1 %Y) {
448 ; CHECK-LABEL: @test33(
449 ; CHECK-NEXT:    [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
450 ; CHECK-NEXT:    ret i1 [[A]]
452   %a = or i1 %X, %Y
453   %b = or i1 %a, %X
454   ret i1 %b
457 define i1 @test33_logical(i1 %X, i1 %Y) {
458 ; CHECK-LABEL: @test33_logical(
459 ; CHECK-NEXT:    [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
460 ; CHECK-NEXT:    ret i1 [[A]]
462   %a = select i1 %X, i1 true, i1 %Y
463   %b = select i1 %a, i1 true, i1 %X
464   ret i1 %b
467 define i32 @test34(i32 %X, i32 %Y) {
468 ; CHECK-LABEL: @test34(
469 ; CHECK-NEXT:    [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
470 ; CHECK-NEXT:    ret i32 [[A]]
472   %a = or i32 %X, %Y
473   %b = or i32 %Y, %a
474   ret i32 %b
477 define i32 @test35(i32 %a, i32 %b) {
478 ; CHECK-LABEL: @test35(
479 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
480 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], 1135
481 ; CHECK-NEXT:    ret i32 [[TMP2]]
483   %1 = or i32 %a, 1135
484   %2 = or i32 %1, %b
485   ret i32 %2
488 define i1 @test36(i32 %x) {
489 ; CHECK-LABEL: @test36(
490 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -23
491 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
492 ; CHECK-NEXT:    ret i1 [[TMP2]]
494   %cmp1 = icmp eq i32 %x, 23
495   %cmp2 = icmp eq i32 %x, 24
496   %ret1 = or i1 %cmp1, %cmp2
497   %cmp3 = icmp eq i32 %x, 25
498   %ret2 = or i1 %ret1, %cmp3
499   ret i1 %ret2
502 define i1 @test36_logical(i32 %x) {
503 ; CHECK-LABEL: @test36_logical(
504 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -23
505 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 3
506 ; CHECK-NEXT:    ret i1 [[TMP2]]
508   %cmp1 = icmp eq i32 %x, 23
509   %cmp2 = icmp eq i32 %x, 24
510   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
511   %cmp3 = icmp eq i32 %x, 25
512   %ret2 = select i1 %ret1, i1 true, i1 %cmp3
513   ret i1 %ret2
516 define i1 @test37(i32 %x) {
517 ; CHECK-LABEL: @test37(
518 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
519 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
520 ; CHECK-NEXT:    ret i1 [[TMP2]]
522   %add1 = add i32 %x, 7
523   %cmp1 = icmp ult i32 %add1, 30
524   %cmp2 = icmp eq i32 %x, 23
525   %ret1 = or i1 %cmp1, %cmp2
526   ret i1 %ret1
529 define i1 @test37_logical(i32 %x) {
530 ; CHECK-LABEL: @test37_logical(
531 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
532 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
533 ; CHECK-NEXT:    ret i1 [[TMP2]]
535   %add1 = add i32 %x, 7
536   %cmp1 = icmp ult i32 %add1, 30
537   %cmp2 = icmp eq i32 %x, 23
538   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
539   ret i1 %ret1
542 define <2 x i1> @test37_uniform(<2 x i32> %x) {
543 ; CHECK-LABEL: @test37_uniform(
544 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 7>
545 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult <2 x i32> [[TMP1]], <i32 31, i32 31>
546 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
548   %add1 = add <2 x i32> %x, <i32 7, i32 7>
549   %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30>
550   %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23>
551   %ret1 = or <2 x i1> %cmp1, %cmp2
552   ret <2 x i1> %ret1
555 define <2 x i1> @test37_undef(<2 x i32> %x) {
556 ; CHECK-LABEL: @test37_undef(
557 ; CHECK-NEXT:    [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 undef>
558 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 undef>
559 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 undef>
560 ; CHECK-NEXT:    [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
561 ; CHECK-NEXT:    ret <2 x i1> [[RET1]]
563   %add1 = add <2 x i32> %x, <i32 7, i32 undef>
564   %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 undef>
565   %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 undef>
566   %ret1 = or <2 x i1> %cmp1, %cmp2
567   ret <2 x i1> %ret1
570 define i1 @test38(i32 %x) {
571 ; CHECK-LABEL: @test38(
572 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
573 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
574 ; CHECK-NEXT:    ret i1 [[TMP2]]
576   %add1 = add i32 %x, 7
577   %cmp1 = icmp eq i32 %x, 23
578   %cmp2 = icmp ult i32 %add1, 30
579   %ret1 = or i1 %cmp1, %cmp2
580   ret i1 %ret1
583 define i1 @test38_logical(i32 %x) {
584 ; CHECK-LABEL: @test38_logical(
585 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
586 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 31
587 ; CHECK-NEXT:    ret i1 [[TMP2]]
589   %add1 = add i32 %x, 7
590   %cmp1 = icmp eq i32 %x, 23
591   %cmp2 = icmp ult i32 %add1, 30
592   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
593   ret i1 %ret1
596 define <2 x i1> @test38_nonuniform(<2 x i32> %x) {
597 ; CHECK-LABEL: @test38_nonuniform(
598 ; CHECK-NEXT:    [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>
599 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8>
600 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32>
601 ; CHECK-NEXT:    [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
602 ; CHECK-NEXT:    ret <2 x i1> [[RET1]]
604   %add1 = add <2 x i32> %x, <i32 7, i32 24>
605   %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8>
606   %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32>
607   %ret1 = or <2 x i1> %cmp1, %cmp2
608   ret <2 x i1> %ret1
611 ; (~A & B) | A --> A | B
613 define i32 @test39a(i32 %a, float %b) {
614 ; CHECK-LABEL: @test39a(
615 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
616 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
617 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
618 ; CHECK-NEXT:    ret i32 [[OR]]
620   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
621   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
622   %nota = xor i32 %a1, -1
623   %and = and i32 %nota, %b1
624   %or = or i32 %and, %a1
625   ret i32 %or
628 ; Commute 'and' operands:
629 ; (B & ~A) | A --> A | B
631 define i32 @test39b(i32 %a, float %b) {
632 ; CHECK-LABEL: @test39b(
633 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
634 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
635 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
636 ; CHECK-NEXT:    ret i32 [[OR]]
638   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
639   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
640   %nota = xor i32 %a1, -1
641   %and = and i32 %b1, %nota
642   %or = or i32 %and, %a1
643   ret i32 %or
646 ; Commute 'or' operands:
647 ; A | (~A & B) --> A | B
649 define i32 @test39c(i32 %a, float %b) {
650 ; CHECK-LABEL: @test39c(
651 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
652 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
653 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
654 ; CHECK-NEXT:    ret i32 [[OR]]
656   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
657   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
658   %nota = xor i32 %a1, -1
659   %and = and i32 %nota, %b1
660   %or = or i32 %a1, %and
661   ret i32 %or
664 ; Commute 'and' operands:
665 ; A | (B & ~A) --> A | B
667 define i32 @test39d(i32 %a, float %b) {
668 ; CHECK-LABEL: @test39d(
669 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
670 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
671 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
672 ; CHECK-NEXT:    ret i32 [[OR]]
674   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
675   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
676   %nota = xor i32 %a1, -1
677   %and = and i32 %b1, %nota
678   %or = or i32 %a1, %and
679   ret i32 %or
682 define i32 @test40(i32 %a, i32 %b) {
683 ; CHECK-LABEL: @test40(
684 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
685 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
686 ; CHECK-NEXT:    ret i32 [[OR]]
688   %and = and i32 %a, %b
689   %xor = xor i32 %a, -1
690   %or = or i32 %and, %xor
691   ret i32 %or
694 define i32 @test40b(i32 %a, i32 %b) {
695 ; CHECK-LABEL: @test40b(
696 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
697 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
698 ; CHECK-NEXT:    ret i32 [[OR]]
700   %and = and i32 %b, %a
701   %xor = xor i32 %a, -1
702   %or = or i32 %and, %xor
703   ret i32 %or
706 define i32 @test40c(i32 %a, i32 %b) {
707 ; CHECK-LABEL: @test40c(
708 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
709 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
710 ; CHECK-NEXT:    ret i32 [[OR]]
712   %and = and i32 %b, %a
713   %xor = xor i32 %a, -1
714   %or = or i32 %xor, %and
715   ret i32 %or
718 define i32 @test40d(i32 %a, i32 %b) {
719 ; CHECK-LABEL: @test40d(
720 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
721 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[XOR]], [[B:%.*]]
722 ; CHECK-NEXT:    ret i32 [[OR]]
724   %and = and i32 %a, %b
725   %xor = xor i32 %a, -1
726   %or = or i32 %xor, %and
727   ret i32 %or
730 define i32 @test45(i32 %x, i32 %y, i32 %z) {
731 ; CHECK-LABEL: @test45(
732 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
733 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
734 ; CHECK-NEXT:    ret i32 [[OR1]]
736   %or = or i32 %y, %z
737   %and = and i32 %x, %or
738   %or1 = or i32 %and, %y
739   ret i32 %or1
742 define i1 @test46(i8 signext %c)  {
743 ; CHECK-LABEL: @test46(
744 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
745 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
746 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
747 ; CHECK-NEXT:    ret i1 [[TMP3]]
749   %c.off = add i8 %c, -97
750   %cmp1 = icmp ult i8 %c.off, 26
751   %c.off17 = add i8 %c, -65
752   %cmp2 = icmp ult i8 %c.off17, 26
753   %or = or i1 %cmp1, %cmp2
754   ret i1 %or
757 define i1 @test46_logical(i8 signext %c)  {
758 ; CHECK-LABEL: @test46_logical(
759 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
760 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
761 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 26
762 ; CHECK-NEXT:    ret i1 [[TMP3]]
764   %c.off = add i8 %c, -97
765   %cmp1 = icmp ult i8 %c.off, 26
766   %c.off17 = add i8 %c, -65
767   %cmp2 = icmp ult i8 %c.off17, 26
768   %or = select i1 %cmp1, i1 true, i1 %cmp2
769   ret i1 %or
772 define <2 x i1> @test46_uniform(<2 x i8> %c)  {
773 ; CHECK-LABEL: @test46_uniform(
774 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[C:%.*]], <i8 -33, i8 -33>
775 ; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i8> [[TMP1]], <i8 -65, i8 -65>
776 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult <2 x i8> [[TMP2]], <i8 26, i8 26>
777 ; CHECK-NEXT:    ret <2 x i1> [[TMP3]]
779   %c.off = add <2 x i8> %c, <i8 -97, i8 -97>
780   %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26>
781   %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65>
782   %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26>
783   %or = or <2 x i1> %cmp1, %cmp2
784   ret <2 x i1> %or
787 define <2 x i1> @test46_undef(<2 x i8> %c)  {
788 ; CHECK-LABEL: @test46_undef(
789 ; CHECK-NEXT:    [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 undef>
790 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 undef>
791 ; CHECK-NEXT:    [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 undef>
792 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 undef>
793 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
794 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
796   %c.off = add <2 x i8> %c, <i8 -97, i8 undef>
797   %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 undef>
798   %c.off17 = add <2 x i8> %c, <i8 -65, i8 undef>
799   %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 undef>
800   %or = or <2 x i1> %cmp1, %cmp2
801   ret <2 x i1> %or
804 define i1 @test47(i8 signext %c)  {
805 ; CHECK-LABEL: @test47(
806 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
807 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
808 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
809 ; CHECK-NEXT:    ret i1 [[TMP3]]
811   %c.off = add i8 %c, -65
812   %cmp1 = icmp ule i8 %c.off, 26
813   %c.off17 = add i8 %c, -97
814   %cmp2 = icmp ule i8 %c.off17, 26
815   %or = or i1 %cmp1, %cmp2
816   ret i1 %or
819 define i1 @test47_logical(i8 signext %c)  {
820 ; CHECK-LABEL: @test47_logical(
821 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
822 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
823 ; CHECK-NEXT:    [[TMP3:%.*]] = icmp ult i8 [[TMP2]], 27
824 ; CHECK-NEXT:    ret i1 [[TMP3]]
826   %c.off = add i8 %c, -65
827   %cmp1 = icmp ule i8 %c.off, 26
828   %c.off17 = add i8 %c, -97
829   %cmp2 = icmp ule i8 %c.off17, 26
830   %or = select i1 %cmp1, i1 true, i1 %cmp2
831   ret i1 %or
834 define <2 x i1> @test47_nonuniform(<2 x i8> %c)  {
835 ; CHECK-LABEL: @test47_nonuniform(
836 ; CHECK-NEXT:    [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>
837 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 27, i8 27>
838 ; CHECK-NEXT:    [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65>
839 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 27, i8 27>
840 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
841 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
843   %c.off = add <2 x i8> %c, <i8 -65, i8 -97>
844   %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26>
845   %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65>
846   %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26>
847   %or = or <2 x i1> %cmp1, %cmp2
848   ret <2 x i1> %or
851 define i32 @test49(i1 %C) {
852 ; CHECK-LABEL: @test49(
853 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123
854 ; CHECK-NEXT:    ret i32 [[V]]
856   %A = select i1 %C, i32 1000, i32 10
857   %V = or i32 %A, 123
858   ret i32 %V
861 define <2 x i32> @test49vec(i1 %C) {
862 ; CHECK-LABEL: @test49vec(
863 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 1019>, <2 x i32> <i32 123, i32 123>
864 ; CHECK-NEXT:    ret <2 x i32> [[V]]
866   %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
867   %V = or <2 x i32> %A, <i32 123, i32 123>
868   ret <2 x i32> %V
871 define <2 x i32> @test49vec2(i1 %C) {
872 ; CHECK-LABEL: @test49vec2(
873 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351>
874 ; CHECK-NEXT:    ret <2 x i32> [[V]]
876   %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
877   %V = or <2 x i32> %A, <i32 123, i32 333>
878   ret <2 x i32> %V
881 define i32 @test50(i1 %which) {
882 ; CHECK-LABEL: @test50(
883 ; CHECK-NEXT:  entry:
884 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
885 ; CHECK:       delay:
886 ; CHECK-NEXT:    br label [[FINAL]]
887 ; CHECK:       final:
888 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ]
889 ; CHECK-NEXT:    ret i32 [[A]]
891 entry:
892   br i1 %which, label %final, label %delay
894 delay:
895   br label %final
897 final:
898   %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
899   %value = or i32 %A, 123
900   ret i32 %value
903 define <2 x i32> @test50vec(i1 %which) {
904 ; CHECK-LABEL: @test50vec(
905 ; CHECK-NEXT:  entry:
906 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
907 ; CHECK:       delay:
908 ; CHECK-NEXT:    br label [[FINAL]]
909 ; CHECK:       final:
910 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 1019>, [[ENTRY:%.*]] ], [ <i32 123, i32 123>, [[DELAY]] ]
911 ; CHECK-NEXT:    ret <2 x i32> [[A]]
913 entry:
914   br i1 %which, label %final, label %delay
916 delay:
917   br label %final
919 final:
920   %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
921   %value = or <2 x i32> %A, <i32 123, i32 123>
922   ret <2 x i32> %value
925 define <2 x i32> @test50vec2(i1 %which) {
926 ; CHECK-LABEL: @test50vec2(
927 ; CHECK-NEXT:  entry:
928 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
929 ; CHECK:       delay:
930 ; CHECK-NEXT:    br label [[FINAL]]
931 ; CHECK:       final:
932 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ]
933 ; CHECK-NEXT:    ret <2 x i32> [[A]]
935 entry:
936   br i1 %which, label %final, label %delay
938 delay:
939   br label %final
941 final:
942   %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
943   %value = or <2 x i32> %A, <i32 123, i32 333>
944   ret <2 x i32> %value
947 ; In the next 4 tests, vary the types and predicates for extra coverage.
948 ; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp
950 define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
951 ; CHECK-LABEL: @or_andn_cmp_1(
952 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
953 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
954 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X]], [[Y]]
955 ; CHECK-NEXT:    ret i1 [[OR]]
957   %x = icmp sgt i32 %a, %b
958   %x_inv = icmp sle i32 %a, %b
959   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
960   %and = and i1 %y, %x_inv
961   %or = or i1 %x, %and
962   ret i1 %or
965 define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
966 ; CHECK-LABEL: @or_andn_cmp_1_logical(
967 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
968 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
969 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
970 ; CHECK-NEXT:    ret i1 [[OR]]
972   %x = icmp sgt i32 %a, %b
973   %x_inv = icmp sle i32 %a, %b
974   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
975   %and = select i1 %y, i1 %x_inv, i1 false
976   %or = select i1 %x, i1 true, i1 %and
977   ret i1 %or
980 ; Commute the 'or':
981 ; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
983 define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
984 ; CHECK-LABEL: @or_andn_cmp_2(
985 ; CHECK-NEXT:    [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
986 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
987 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]
988 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
990   %x = icmp sge <2 x i32> %a, %b
991   %x_inv = icmp slt <2 x i32> %a, %b
992   %y = icmp ugt <2 x i32> %c, <i32 42, i32 47>      ; thwart complexity-based ordering
993   %and = and <2 x i1> %y, %x_inv
994   %or = or <2 x i1> %and, %x
995   ret <2 x i1> %or
998 ; Commute the 'and':
999 ; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
1001 define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
1002 ; CHECK-LABEL: @or_andn_cmp_3(
1003 ; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1004 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1005 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X]], [[Y]]
1006 ; CHECK-NEXT:    ret i1 [[OR]]
1008   %x = icmp ugt i72 %a, %b
1009   %x_inv = icmp ule i72 %a, %b
1010   %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
1011   %and = and i1 %x_inv, %y
1012   %or = or i1 %x, %and
1013   ret i1 %or
1016 define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
1017 ; CHECK-LABEL: @or_andn_cmp_3_logical(
1018 ; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1019 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1020 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1021 ; CHECK-NEXT:    ret i1 [[OR]]
1023   %x = icmp ugt i72 %a, %b
1024   %x_inv = icmp ule i72 %a, %b
1025   %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
1026   %and = select i1 %x_inv, i1 %y, i1 false
1027   %or = select i1 %x, i1 true, i1 %and
1028   ret i1 %or
1031 ; Commute the 'or':
1032 ; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
1034 define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
1035 ; CHECK-LABEL: @or_andn_cmp_4(
1036 ; CHECK-NEXT:    [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
1037 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
1038 ; CHECK-NEXT:    [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]
1039 ; CHECK-NEXT:    ret <3 x i1> [[OR]]
1041   %x = icmp eq <3 x i32> %a, %b
1042   %x_inv = icmp ne <3 x i32> %a, %b
1043   %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1>      ; thwart complexity-based ordering
1044   %and = and <3 x i1> %x_inv, %y
1045   %or = or <3 x i1> %and, %x
1046   ret <3 x i1> %or
1049 ; In the next 4 tests, vary the types and predicates for extra coverage.
1050 ; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp
1052 define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
1053 ; CHECK-LABEL: @orn_and_cmp_1(
1054 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1055 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1056 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
1057 ; CHECK-NEXT:    ret i1 [[OR]]
1059   %x = icmp sgt i37 %a, %b
1060   %x_inv = icmp sle i37 %a, %b
1061   %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
1062   %and = and i1 %y, %x
1063   %or = or i1 %x_inv, %and
1064   ret i1 %or
1067 define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
1068 ; CHECK-LABEL: @orn_and_cmp_1_logical(
1069 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1070 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1071 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1072 ; CHECK-NEXT:    ret i1 [[OR]]
1074   %x = icmp sgt i37 %a, %b
1075   %x_inv = icmp sle i37 %a, %b
1076   %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
1077   %and = select i1 %y, i1 %x, i1 false
1078   %or = select i1 %x_inv, i1 true, i1 %and
1079   ret i1 %or
1082 ; Commute the 'or':
1083 ; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1085 define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
1086 ; CHECK-LABEL: @orn_and_cmp_2(
1087 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1088 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1089 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1090 ; CHECK-NEXT:    ret i1 [[OR]]
1092   %x = icmp sge i16 %a, %b
1093   %x_inv = icmp slt i16 %a, %b
1094   %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
1095   %and = and i1 %y, %x
1096   %or = or i1 %and, %x_inv
1097   ret i1 %or
1100 define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
1101 ; CHECK-LABEL: @orn_and_cmp_2_logical(
1102 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1103 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1104 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]]
1105 ; CHECK-NEXT:    ret i1 [[OR]]
1107   %x = icmp sge i16 %a, %b
1108   %x_inv = icmp slt i16 %a, %b
1109   %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
1110   %and = select i1 %y, i1 %x, i1 false
1111   %or = select i1 %and, i1 true, i1 %x_inv
1112   ret i1 %or
1115 ; Commute the 'and':
1116 ; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
1118 define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
1119 ; CHECK-LABEL: @orn_and_cmp_3(
1120 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
1121 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
1122 ; CHECK-NEXT:    [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]
1123 ; CHECK-NEXT:    ret <4 x i1> [[OR]]
1125   %x = icmp ugt <4 x i32> %a, %b
1126   %x_inv = icmp ule <4 x i32> %a, %b
1127   %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1>      ; thwart complexity-based ordering
1128   %and = and <4 x i1> %x, %y
1129   %or = or <4 x i1> %x_inv, %and
1130   ret <4 x i1> %or
1133 ; Commute the 'or':
1134 ; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1136 define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
1137 ; CHECK-LABEL: @orn_and_cmp_4(
1138 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1139 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1140 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1141 ; CHECK-NEXT:    ret i1 [[OR]]
1143   %x = icmp eq i32 %a, %b
1144   %x_inv = icmp ne i32 %a, %b
1145   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1146   %and = and i1 %x, %y
1147   %or = or i1 %and, %x_inv
1148   ret i1 %or
1151 define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
1152 ; CHECK-LABEL: @orn_and_cmp_4_logical(
1153 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1154 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1155 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1156 ; CHECK-NEXT:    ret i1 [[OR]]
1158   %x = icmp eq i32 %a, %b
1159   %x_inv = icmp ne i32 %a, %b
1160   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1161   %and = select i1 %x, i1 %y, i1 false
1162   %or = select i1 %and, i1 true, i1 %x_inv
1163   ret i1 %or
1166 ; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
1167 define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
1168 ; CHECK-LABEL: @test51(
1169 ; 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>
1170 ; CHECK-NEXT:    ret <16 x i1> [[TMP1]]
1172   %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>
1173   %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>
1174   %tmp3 = or <16 x i1> %tmp, %tmp2
1175   ret <16 x i1> %tmp3
1178 ; This would infinite loop because it reaches a transform
1179 ; that was not expecting a constant-foldable value.
1181 define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
1182 ; CHECK-LABEL: @PR46712(
1183 ; CHECK-NEXT:  entry:
1184 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1185 ; CHECK:       true:
1186 ; CHECK-NEXT:    [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1187 ; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1188 ; CHECK-NEXT:    br label [[END]]
1189 ; CHECK:       end:
1190 ; CHECK-NEXT:    [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1191 ; CHECK-NEXT:    ret i32 [[T5]]
1193 entry:
1194   %t2 = or i1 %x, %y
1195   %conv = sext i1 %t2 to i32
1196   %cmp = icmp sge i32 %conv, 1
1197   %conv2 = zext i1 %cmp to i64
1198   br i1 %b, label %true, label %end
1200 true:
1201   %bool4 = icmp eq i64 %conv2, 0
1202   %bool5 = icmp ne i64 %z, 0
1203   %and = and i1 %bool4, %bool5
1204   %sel = select i1 %and, i1 false, i1 true
1205   br label %end
1207 end:
1208   %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1209   %conv8 = zext i1 %t5 to i32
1210   ret i32 %conv8
1213 define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
1214 ; CHECK-LABEL: @PR46712_logical(
1215 ; CHECK-NEXT:  entry:
1216 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1217 ; CHECK:       true:
1218 ; CHECK-NEXT:    [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0
1219 ; CHECK-NEXT:    [[SEL:%.*]] = zext i1 [[BOOL5]] to i32
1220 ; CHECK-NEXT:    br label [[END]]
1221 ; CHECK:       end:
1222 ; CHECK-NEXT:    [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ]
1223 ; CHECK-NEXT:    ret i32 [[T5]]
1225 entry:
1226   %t2 = select i1 %x, i1 true, i1 %y
1227   %conv = sext i1 %t2 to i32
1228   %cmp = icmp sge i32 %conv, 1
1229   %conv2 = zext i1 %cmp to i64
1230   br i1 %b, label %true, label %end
1232 true:
1233   %bool4 = icmp eq i64 %conv2, 0
1234   %bool5 = icmp ne i64 %z, 0
1235   %and = select i1 %bool4, i1 %bool5, i1 false
1236   %sel = select i1 %and, i1 false, i1 true
1237   br label %end
1239 end:
1240   %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1241   %conv8 = zext i1 %t5 to i32
1242   ret i32 %conv8
1245 ; (~x & y) | ~(x | y) --> ~x
1246 define i32 @PR38929(i32 %0, i32 %1) {
1247 ; CHECK-LABEL: @PR38929(
1248 ; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1
1249 ; CHECK-NEXT:    ret i32 [[TMP3]]
1251   %3 = xor i32 %0, -1
1252   %4 = and i32 %3, %1
1253   %5 = or i32 %1, %0
1254   %6 = xor i32 %5, -1
1255   %7 = or i32 %4, %6
1256   ret i32 %7
1259 define i32 @test1(i32 %x, i32 %y) {
1260 ; CHECK-LABEL: @test1(
1261 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1262 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1263 ; CHECK-NEXT:    ret i32 [[OR1]]
1265   %xor = xor i32 %y, %x
1266   %or = or i32 %y, %x
1267   %neg = xor i32 %or, -1
1268   %or1 = or i32 %xor, %neg
1269   ret i32 %or1
1272 define i32 @test2(i32 %x, i32 %y) {
1273 ; CHECK-LABEL: @test2(
1274 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1275 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1276 ; CHECK-NEXT:    ret i32 [[OR1]]
1278   %or = or i32 %x, %y
1279   %neg = xor i32 %or, -1
1280   %xor = xor i32 %y, %x
1281   %or1 = or i32 %xor, %neg
1282   ret i32 %or1
1285 define i32 @test3(i32 %x, i32 %y) {
1286 ; CHECK-LABEL: @test3(
1287 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
1288 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1289 ; CHECK-NEXT:    ret i32 [[OR1]]
1291   %or = or i32 %y, %x
1292   %neg = xor i32 %or, -1
1293   %xor = xor i32 %x, %y
1294   %or1 = or i32 %xor, %neg
1295   ret i32 %or1
1298 define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
1299 ; CHECK-LABEL: @test4_vec(
1300 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
1301 ; CHECK-NEXT:    [[OR1:%.*]] = xor <2 x i32> [[TMP1]], <i32 -1, i32 -1>
1302 ; CHECK-NEXT:    ret <2 x i32> [[OR1]]
1304   %or = or <2 x i32> %y, %x
1305   %neg = xor <2 x i32> %or, <i32 -1, i32 -1>
1306   %xor = xor <2 x i32> %y, %x
1307   %or1 = or <2 x i32> %xor, %neg
1308   ret <2 x i32> %or1
1311 define i32 @test5_use(i32 %x, i32 %y) {
1312 ; CHECK-LABEL: @test5_use(
1313 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1314 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[OR]], -1
1315 ; CHECK-NEXT:    call void @use(i32 [[NEG]])
1316 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1317 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1318 ; CHECK-NEXT:    ret i32 [[OR1]]
1320   %or = or i32 %y, %x
1321   %neg = xor i32 %or, -1
1322   %xor = xor i32 %y, %x
1323   call void @use(i32 %neg)
1324   %or1 = or i32 %xor, %neg
1325   ret i32 %or1
1328 define i32 @test5_use2(i32 %x, i32 %y) {
1329 ; CHECK-LABEL: @test5_use2(
1330 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1331 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
1332 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1333 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1334 ; CHECK-NEXT:    ret i32 [[OR1]]
1336   %or = or i32 %y, %x
1337   %neg = xor i32 %or, -1
1338   %xor = xor i32 %y, %x
1339   call void @use(i32 %xor)
1340   %or1 = or i32 %xor, %neg
1341   ret i32 %or1
1343 define i32 @test5_use3(i32 %x, i32 %y) {
1344 ; CHECK-LABEL: @test5_use3(
1345 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1346 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[OR]], -1
1347 ; CHECK-NEXT:    call void @use(i32 [[NEG]])
1348 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
1349 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
1350 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
1351 ; CHECK-NEXT:    ret i32 [[OR1]]
1353   %or = or i32 %y, %x
1354   %neg = xor i32 %or, -1
1355   call void @use(i32 %neg)
1356   %xor = xor i32 %y, %x
1357   call void @use(i32 %xor)
1358   %or1 = or i32 %xor, %neg
1359   ret i32 %or1
1362 define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) {
1363 ; CHECK-LABEL: @ashr_bitwidth_mask(
1364 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1365 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1366 ; CHECK-NEXT:    ret i8 [[R]]
1368   %sign = ashr i8 %x, 7
1369   %r = or i8 %sign, %y
1370   ret i8 %r
1373 define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {
1374 ; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute(
1375 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>
1376 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr <2 x i8> [[X:%.*]], <i8 7, i8 7>
1377 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i8> [[Y]], [[SIGN]]
1378 ; CHECK-NEXT:    ret <2 x i8> [[R]]
1380   %y = mul <2 x i8> %py, <i8 42, i8 2>      ; thwart complexity-based ordering
1381   %sign = ashr <2 x i8> %x, <i8 7, i8 7>
1382   %r = or <2 x i8> %y, %sign
1383   ret <2 x i8> %r
1386 define i32 @ashr_bitwidth_mask_use(i32 %x, i32 %y) {
1387 ; CHECK-LABEL: @ashr_bitwidth_mask_use(
1388 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i32 [[X:%.*]], 7
1389 ; CHECK-NEXT:    call void @use(i32 [[SIGN]])
1390 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[SIGN]], [[Y:%.*]]
1391 ; CHECK-NEXT:    ret i32 [[R]]
1393   %sign = ashr i32 %x, 7
1394   call void @use(i32 %sign)
1395   %r = or i32 %sign, %y
1396   ret i32 %r
1399 define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) {
1400 ; CHECK-LABEL: @ashr_not_bitwidth_mask(
1401 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6
1402 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1403 ; CHECK-NEXT:    ret i8 [[R]]
1405   %sign = ashr i8 %x, 6
1406   %r = or i8 %sign, %y
1407   ret i8 %r
1410 define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {
1411 ; CHECK-LABEL: @lshr_bitwidth_mask(
1412 ; CHECK-NEXT:    [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7
1413 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1414 ; CHECK-NEXT:    ret i8 [[R]]
1416   %sign = lshr i8 %x, 7
1417   %r = or i8 %sign, %y
1418   ret i8 %r
1421 define i1 @cmp_overlap(i32 %x) {
1422 ; CHECK-LABEL: @cmp_overlap(
1423 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
1424 ; CHECK-NEXT:    ret i1 [[TMP1]]
1426   %isneg = icmp slt i32 %x, 0
1427   %negx = sub i32 0, %x
1428   %isnotneg = icmp sgt i32 %negx, -1
1429   %r = or i1 %isneg, %isnotneg
1430   ret i1 %r
1433 define <2 x i1> @cmp_overlap_splat(<2 x i5> %x) {
1434 ; CHECK-LABEL: @cmp_overlap_splat(
1435 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i5> [[X:%.*]], <i5 1, i5 1>
1436 ; CHECK-NEXT:    ret <2 x i1> [[TMP1]]
1438   %isneg = icmp slt <2 x i5> %x, zeroinitializer
1439   %negx = sub <2 x i5> zeroinitializer, %x
1440   %isnotneg = icmp sgt <2 x i5> %negx, <i5 -1, i5 -1>
1441   %r = or <2 x i1> %isneg, %isnotneg
1442   ret <2 x i1> %r
1445 define i32 @mul_no_common_bits(i32 %p1, i32 %p2) {
1446 ; CHECK-LABEL: @mul_no_common_bits(
1447 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
1448 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1449 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[Y]], 1
1450 ; CHECK-NEXT:    [[R:%.*]] = mul i32 [[X]], [[TMP1]]
1451 ; CHECK-NEXT:    ret i32 [[R]]
1453   %x = and i32 %p1, 7
1454   %y = shl i32 %p2, 3
1455   %m = mul i32 %x, %y
1456   %r = or i32 %m, %x
1457   ret i32 %r
1460 define i32 @mul_no_common_bits_const_op(i32 %p) {
1461 ; CHECK-LABEL: @mul_no_common_bits_const_op(
1462 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1463 ; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[X]], 25
1464 ; CHECK-NEXT:    ret i32 [[R]]
1466   %x = and i32 %p, 7
1467   %m = mul i32 %x, 24
1468   %r = or i32 %m, %x
1469   ret i32 %r
1472 define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) {
1473 ; CHECK-LABEL: @mul_no_common_bits_commute(
1474 ; CHECK-NEXT:    [[X:%.*]] = and <2 x i12> [[P:%.*]], <i12 1, i12 1>
1475 ; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw <2 x i12> [[X]], <i12 15, i12 17>
1476 ; CHECK-NEXT:    ret <2 x i12> [[R]]
1478   %x = and <2 x i12> %p, <i12 1, i12 1>
1479   %m = mul <2 x i12> %x, <i12 14, i12 16>
1480   %r = or <2 x i12> %x, %m
1481   ret <2 x i12> %r
1484 ; negative test - extra use requires extra instructions
1486 define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) {
1487 ; CHECK-LABEL: @mul_no_common_bits_uses(
1488 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
1489 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1490 ; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y]]
1491 ; CHECK-NEXT:    call void @use(i32 [[M]])
1492 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
1493 ; CHECK-NEXT:    ret i32 [[R]]
1495   %x = and i32 %p1, 7
1496   %y = shl i32 %p2, 3
1497   %m = mul i32 %x, %y
1498   call void @use(i32 %m)
1499   %r = or i32 %m, %x
1500   ret i32 %r
1503 ; negative test - probably not good to create an extra mul
1505 define i32 @mul_no_common_bits_const_op_uses(i32 %p) {
1506 ; CHECK-LABEL: @mul_no_common_bits_const_op_uses(
1507 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1508 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 24
1509 ; CHECK-NEXT:    call void @use(i32 [[M]])
1510 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
1511 ; CHECK-NEXT:    ret i32 [[R]]
1513   %x = and i32 %p, 7
1514   %m = mul i32 %x, 24
1515   call void @use(i32 %m)
1516   %r = or i32 %m, %x
1517   ret i32 %r
1520 ; negative test - %x and %m may have set 3rd bit
1522 define i32 @mul_common_bits(i32 %p) {
1523 ; CHECK-LABEL: @mul_common_bits(
1524 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1525 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 12
1526 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
1527 ; CHECK-NEXT:    ret i32 [[R]]
1529   %x = and i32 %p, 7
1530   %m = mul i32 %x, 12
1531   %r = or i32 %m, %x
1532   ret i32 %r