[mlir][scf]: Add value bound between scf for loop yield and result (#123200)
[llvm-project.git] / llvm / test / Transforms / InstCombine / or.ll
blob95f89e4ce11cd5b0804b2e2af60a753fee3afc23
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -passes=instcombine -S | FileCheck %s --check-prefixes=CHECK,CONSTVEC
3 ; RUN: opt < %s -passes=instcombine -S -use-constant-int-for-fixed-length-splat | FileCheck %s --check-prefixes=CHECK,CONSTSPLAT
5 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"
6 declare void @use(i32)
8 ; Should be eliminated
9 define i32 @test12(i32 %A) {
10 ; CHECK-LABEL: @test12(
11 ; CHECK-NEXT:    [[C:%.*]] = and i32 [[A:%.*]], 8
12 ; CHECK-NEXT:    ret i32 [[C]]
14   %B = or i32 %A, 4
15   %C = and i32 %B, 8
16   ret i32 %C
19 define i32 @test13(i32 %A) {
20 ; CHECK-LABEL: @test13(
21 ; CHECK-NEXT:    ret i32 8
23   %B = or i32 %A, 12
24   ; Always equal to 8
25   %C = and i32 %B, 8
26   ret i32 %C
29 define i1 @test14(i32 %A, i32 %B) {
30 ; CHECK-LABEL: @test14(
31 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
32 ; CHECK-NEXT:    ret i1 [[D]]
34   %C1 = icmp ult i32 %A, %B
35   %C2 = icmp ugt i32 %A, %B
36   ; (A < B) | (A > B) === A != B
37   %D = or i1 %C1, %C2
38   ret i1 %D
41 define i1 @test14_commuted(i32 %A, i32 %B) {
42 ; CHECK-LABEL: @test14_commuted(
43 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[B:%.*]], [[A:%.*]]
44 ; CHECK-NEXT:    ret i1 [[D]]
46   %C1 = icmp ult i32 %A, %B
47   %C2 = icmp ult i32 %B, %A
48   ; (A < B) | (A > B) === A != B
49   %D = or i1 %C1, %C2
50   ret i1 %D
53 define i1 @test14_logical(i32 %A, i32 %B) {
54 ; CHECK-LABEL: @test14_logical(
55 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
56 ; CHECK-NEXT:    ret i1 [[D]]
58   %C1 = icmp ult i32 %A, %B
59   %C2 = icmp ugt i32 %A, %B
60   ; (A < B) | (A > B) === A != B
61   %D = select i1 %C1, i1 true, i1 %C2
62   ret i1 %D
65 define i1 @test15(i32 %A, i32 %B) {
66 ; CHECK-LABEL: @test15(
67 ; CHECK-NEXT:    [[D:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
68 ; CHECK-NEXT:    ret i1 [[D]]
70   %C1 = icmp ult i32 %A, %B
71   %C2 = icmp eq i32 %A, %B
72   ; (A < B) | (A == B) === A <= B
73   %D = or i1 %C1, %C2
74   ret i1 %D
77 define i1 @test15_logical(i32 %A, i32 %B) {
78 ; CHECK-LABEL: @test15_logical(
79 ; CHECK-NEXT:    [[D:%.*]] = icmp ule i32 [[A:%.*]], [[B:%.*]]
80 ; CHECK-NEXT:    ret i1 [[D]]
82   %C1 = icmp ult i32 %A, %B
83   %C2 = icmp eq i32 %A, %B
84   ; (A < B) | (A == B) === A <= B
85   %D = select i1 %C1, i1 true, i1 %C2
86   ret i1 %D
89 define i32 @test16(i32 %A) {
90 ; CHECK-LABEL: @test16(
91 ; CHECK-NEXT:    ret i32 [[A:%.*]]
93   %B = and i32 %A, 1
94   ; -2 = ~1
95   %C = and i32 %A, -2
96   ; %D = and int %B, -1 == %B
97   %D = or i32 %B, %C
98   ret i32 %D
101 define i32 @test17(i32 %A) {
102 ; CHECK-LABEL: @test17(
103 ; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], 5
104 ; CHECK-NEXT:    ret i32 [[D]]
106   %B = and i32 %A, 1
107   %C = and i32 %A, 4
108   ; %D = and int %B, 5
109   %D = or i32 %B, %C
110   ret i32 %D
113 define i1 @test18(i32 %A) {
114 ; CHECK-LABEL: @test18(
115 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -100
116 ; CHECK-NEXT:    [[D:%.*]] = icmp ult i32 [[TMP1]], -50
117 ; CHECK-NEXT:    ret i1 [[D]]
119   %B = icmp sge i32 %A, 100
120   %C = icmp slt i32 %A, 50
121   %D = or i1 %B, %C
122   ret i1 %D
125 define i1 @test18_logical(i32 %A) {
126 ; CHECK-LABEL: @test18_logical(
127 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[A:%.*]], -100
128 ; CHECK-NEXT:    [[D:%.*]] = icmp ult i32 [[TMP1]], -50
129 ; CHECK-NEXT:    ret i1 [[D]]
131   %B = icmp sge i32 %A, 100
132   %C = icmp slt i32 %A, 50
133   %D = select i1 %B, i1 true, i1 %C
134   ret i1 %D
137 define <2 x i1> @test18vec(<2 x i32> %A) {
138 ; CHECK-LABEL: @test18vec(
139 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[A:%.*]], splat (i32 -100)
140 ; CHECK-NEXT:    [[D:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 -50)
141 ; CHECK-NEXT:    ret <2 x i1> [[D]]
143   %B = icmp sge <2 x i32> %A, <i32 100, i32 100>
144   %C = icmp slt <2 x i32> %A, <i32 50, i32 50>
145   %D = or <2 x i1> %B, %C
146   ret <2 x i1> %D
149 define i32 @test20(i32 %x) {
150 ; CHECK-LABEL: @test20(
151 ; CHECK-NEXT:    ret i32 [[X:%.*]]
153   %y = and i32 %x, 123
154   %z = or i32 %y, %x
155   ret i32 %z
158 ; TODO: This should combine to t1 + 2.
159 define i32 @test21(i32 %t1) {
160 ; CHECK-LABEL: @test21(
161 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[T1:%.*]], -2
162 ; CHECK-NEXT:    [[T3:%.*]] = add i32 [[TMP1]], 2
163 ; CHECK-NEXT:    [[T5:%.*]] = and i32 [[T1]], 1
164 ; CHECK-NEXT:    [[T6:%.*]] = or disjoint i32 [[T5]], [[T3]]
165 ; CHECK-NEXT:    ret i32 [[T6]]
167   %t1.mask1 = add i32 %t1, 2
168   %t3 = and i32 %t1.mask1, -2
169   %t5 = and i32 %t1, 1
170   ;; add tmp.1, 2
171   %t6 = or i32 %t5, %t3
172   ret i32 %t6
175 define i32 @test22(i32 %B) {
176 ; CHECK-LABEL: @test22(
177 ; CHECK-NEXT:    ret i32 [[B:%.*]]
179   %ELIM41 = and i32 %B, 1
180   %ELIM7 = and i32 %B, -2
181   %ELIM5 = or i32 %ELIM41, %ELIM7
182   ret i32 %ELIM5
185 define i16 @test23(i16 %A) {
186 ; CHECK-LABEL: @test23(
187 ; CHECK-NEXT:    [[B:%.*]] = lshr i16 [[A:%.*]], 1
188 ; CHECK-NEXT:    [[D:%.*]] = xor i16 [[B]], -24575
189 ; CHECK-NEXT:    ret i16 [[D]]
191   %B = lshr i16 %A, 1
192   ;; fold or into xor
193   %C = or i16 %B, -32768
194   %D = xor i16 %C, 8193
195   ret i16 %D
198 define <2 x i16> @test23vec(<2 x i16> %A) {
199 ; CHECK-LABEL: @test23vec(
200 ; CHECK-NEXT:    [[B:%.*]] = lshr <2 x i16> [[A:%.*]], splat (i16 1)
201 ; CHECK-NEXT:    [[D:%.*]] = xor <2 x i16> [[B]], splat (i16 -24575)
202 ; CHECK-NEXT:    ret <2 x i16> [[D]]
204   %B = lshr <2 x i16> %A, <i16 1, i16 1>
205   ;; fold or into xor
206   %C = or <2 x i16> %B, <i16 -32768, i16 -32768>
207   %D = xor <2 x i16> %C, <i16 8193, i16 8193>
208   ret <2 x i16> %D
211 ; PR3266 & PR5276
212 define i1 @test25(i32 %A, i32 %B) {
213 ; CHECK-LABEL: @test25(
214 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
215 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
216 ; CHECK-NEXT:    [[E_NOT:%.*]] = and i1 [[C]], [[D]]
217 ; CHECK-NEXT:    ret i1 [[E_NOT]]
219   %C = icmp eq i32 %A, 0
220   %D = icmp eq i32 %B, 57
221   %E = or i1 %C, %D
222   %F = xor i1 %E, -1
223   ret i1 %F
226 define i1 @test25_logical(i32 %A, i32 %B) {
227 ; CHECK-LABEL: @test25_logical(
228 ; CHECK-NEXT:    [[C:%.*]] = icmp ne i32 [[A:%.*]], 0
229 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[B:%.*]], 57
230 ; CHECK-NEXT:    [[E_NOT:%.*]] = select i1 [[C]], i1 [[D]], i1 false
231 ; CHECK-NEXT:    ret i1 [[E_NOT]]
233   %C = icmp eq i32 %A, 0
234   %D = icmp eq i32 %B, 57
235   %E = select i1 %C, i1 true, i1 %D
236   %F = xor i1 %E, -1
237   ret i1 %F
240 ; PR5634
241 define i1 @and_icmp_eq_0(i32 %A, i32 %B) {
242 ; CHECK-LABEL: @and_icmp_eq_0(
243 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
244 ; CHECK-NEXT:    [[D:%.*]] = icmp eq i32 [[TMP1]], 0
245 ; CHECK-NEXT:    ret i1 [[D]]
247   %C1 = icmp eq i32 %A, 0
248   %C2 = icmp eq i32 %B, 0
249   ; (A == 0) & (A == 0)   -->   (A|B) == 0
250   %D = and i1 %C1, %C2
251   ret i1 %D
254 define <2 x i1> @and_icmp_eq_0_vector(<2 x i32> %A, <2 x i32> %B) {
255 ; CHECK-LABEL: @and_icmp_eq_0_vector(
256 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
257 ; CHECK-NEXT:    [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
258 ; CHECK-NEXT:    ret <2 x i1> [[D]]
260   %C1 = icmp eq <2 x i32> %A, zeroinitializer
261   %C2 = icmp eq <2 x i32> %B, zeroinitializer
262   %D = and <2 x i1> %C1, %C2
263   ret <2 x i1> %D
266 define <2 x i1> @and_icmp_eq_0_vector_poison1(<2 x i32> %A, <2 x i32> %B) {
267 ; CHECK-LABEL: @and_icmp_eq_0_vector_poison1(
268 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
269 ; CHECK-NEXT:    [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
270 ; CHECK-NEXT:    ret <2 x i1> [[D]]
272   %C1 = icmp eq <2 x i32> %A, <i32 0, i32 poison>
273   %C2 = icmp eq <2 x i32> %B, <i32 0, i32 poison>
274   %D = and <2 x i1> %C1, %C2
275   ret <2 x i1> %D
278 define <2 x i1> @and_icmp_eq_0_vector_poison2(<2 x i32> %A, <2 x i32> %B) {
279 ; CHECK-LABEL: @and_icmp_eq_0_vector_poison2(
280 ; CHECK-NEXT:    [[TMP1:%.*]] = or <2 x i32> [[A:%.*]], [[B:%.*]]
281 ; CHECK-NEXT:    [[D:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer
282 ; CHECK-NEXT:    ret <2 x i1> [[D]]
284   %C1 = icmp eq <2 x i32> %A, <i32 0, i32 poison>
285   %C2 = icmp eq <2 x i32> %B, <i32 poison, i32 0>
286   %D = and <2 x i1> %C1, %C2
287   ret <2 x i1> %D
290 define i1 @and_icmp_eq_0_logical(i32 %A, i32 %B) {
291 ; CHECK-LABEL: @and_icmp_eq_0_logical(
292 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i32 [[A:%.*]], 0
293 ; CHECK-NEXT:    [[C2:%.*]] = icmp eq i32 [[B:%.*]], 0
294 ; CHECK-NEXT:    [[D:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
295 ; CHECK-NEXT:    ret i1 [[D]]
297   %C1 = icmp eq i32 %A, 0
298   %C2 = icmp eq i32 %B, 0
299   ; (A == 0) & (A == 0)   -->   (A|B) == 0
300   %D = select i1 %C1, i1 %C2, i1 false
301   ret i1 %D
304 define i1 @test27(ptr %A, ptr %B) {
305 ; CHECK-LABEL: @test27(
306 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq ptr [[A:%.*]], null
307 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq ptr [[B:%.*]], null
308 ; CHECK-NEXT:    [[E:%.*]] = and i1 [[TMP1]], [[TMP2]]
309 ; CHECK-NEXT:    ret i1 [[E]]
311   %C1 = ptrtoint ptr %A to i32
312   %C2 = ptrtoint ptr %B to i32
313   %D = or i32 %C1, %C2
314   %E = icmp eq i32 %D, 0
315   ret i1 %E
318 define <2 x i1> @test27vec(<2 x ptr> %A, <2 x ptr> %B) {
319 ; CHECK-LABEL: @test27vec(
320 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x ptr> [[A:%.*]], zeroinitializer
321 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x ptr> [[B:%.*]], zeroinitializer
322 ; CHECK-NEXT:    [[E:%.*]] = and <2 x i1> [[TMP1]], [[TMP2]]
323 ; CHECK-NEXT:    ret <2 x i1> [[E]]
325   %C1 = ptrtoint <2 x ptr> %A to <2 x i32>
326   %C2 = ptrtoint <2 x ptr> %B to <2 x i32>
327   %D = or <2 x i32> %C1, %C2
328   %E = icmp eq <2 x i32> %D, zeroinitializer
329   ret <2 x i1> %E
332 ; PR5634
333 define i1 @test28(i32 %A, i32 %B) {
334 ; CHECK-LABEL: @test28(
335 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
336 ; CHECK-NEXT:    [[D:%.*]] = icmp ne i32 [[TMP1]], 0
337 ; CHECK-NEXT:    ret i1 [[D]]
339   %C1 = icmp ne i32 %A, 0
340   %C2 = icmp ne i32 %B, 0
341   ; (A != 0) | (A != 0)   -->   (A|B) != 0
342   %D = or i1 %C1, %C2
343   ret i1 %D
346 define i1 @test28_logical(i32 %A, i32 %B) {
347 ; CHECK-LABEL: @test28_logical(
348 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i32 [[A:%.*]], 0
349 ; CHECK-NEXT:    [[C2:%.*]] = icmp ne i32 [[B:%.*]], 0
350 ; CHECK-NEXT:    [[D:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
351 ; CHECK-NEXT:    ret i1 [[D]]
353   %C1 = icmp ne i32 %A, 0
354   %C2 = icmp ne i32 %B, 0
355   ; (A != 0) | (A != 0)   -->   (A|B) != 0
356   %D = select i1 %C1, i1 true, i1 %C2
357   ret i1 %D
360 define i1 @test29(ptr %A, ptr %B) {
361 ; CHECK-LABEL: @test29(
362 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne ptr [[A:%.*]], null
363 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne ptr [[B:%.*]], null
364 ; CHECK-NEXT:    [[E:%.*]] = or i1 [[TMP1]], [[TMP2]]
365 ; CHECK-NEXT:    ret i1 [[E]]
367   %C1 = ptrtoint ptr %A to i32
368   %C2 = ptrtoint ptr %B to i32
369   %D = or i32 %C1, %C2
370   %E = icmp ne i32 %D, 0
371   ret i1 %E
374 define <2 x i1> @test29vec(<2 x ptr> %A, <2 x ptr> %B) {
375 ; CHECK-LABEL: @test29vec(
376 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x ptr> [[A:%.*]], zeroinitializer
377 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne <2 x ptr> [[B:%.*]], zeroinitializer
378 ; CHECK-NEXT:    [[E:%.*]] = or <2 x i1> [[TMP1]], [[TMP2]]
379 ; CHECK-NEXT:    ret <2 x i1> [[E]]
381   %C1 = ptrtoint <2 x ptr> %A to <2 x i32>
382   %C2 = ptrtoint <2 x ptr> %B to <2 x i32>
383   %D = or <2 x i32> %C1, %C2
384   %E = icmp ne <2 x i32> %D, zeroinitializer
385   ret <2 x i1> %E
388 ; PR4216
389 define i32 @test30(i32 %A) {
390 ; CHECK-LABEL: @test30(
391 ; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], -58312
392 ; CHECK-NEXT:    [[E:%.*]] = or disjoint i32 [[D]], 32962
393 ; CHECK-NEXT:    ret i32 [[E]]
395   %B = or i32 %A, 32962   ; 0b1000_0000_1100_0010
396   %C = and i32 %A, -65536 ; 0xffff0000
397   %D = and i32 %B, 40186  ; 0b1001_1100_1111_1010
398   %E = or i32 %D, %C
399   ret i32 %E
402 define <2 x i32> @test30vec(<2 x i32> %A) {
403 ; CONSTVEC-LABEL: @test30vec(
404 ; CONSTVEC-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -58312)
405 ; CONSTVEC-NEXT:    [[E:%.*]] = or disjoint <2 x i32> [[TMP1]], splat (i32 32962)
406 ; CONSTVEC-NEXT:    ret <2 x i32> [[E]]
408 ; CONSTSPLAT-LABEL: @test30vec(
409 ; CONSTSPLAT-NEXT:    [[D:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 -58312)
410 ; CONSTSPLAT-NEXT:    [[E:%.*]] = or disjoint <2 x i32> [[D]], splat (i32 32962)
411 ; CONSTSPLAT-NEXT:    ret <2 x i32> [[E]]
413   %B = or <2 x i32> %A, <i32 32962, i32 32962>
414   %C = and <2 x i32> %A, <i32 -65536, i32 -65536>
415   %D = and <2 x i32> %B, <i32 40186, i32 40186>
416   %E = or <2 x i32> %D, %C
417   ret <2 x i32> %E
420 ; PR4216
421 define i64 @test31(i64 %A) {
422 ; CHECK-LABEL: @test31(
423 ; CHECK-NEXT:    [[E:%.*]] = and i64 [[A:%.*]], 4294908984
424 ; CHECK-NEXT:    [[F:%.*]] = or disjoint i64 [[E]], 32962
425 ; CHECK-NEXT:    ret i64 [[F]]
427   %B = or i64 %A, 194
428   %D = and i64 %B, 250
430   %C = or i64 %A, 32768
431   %E = and i64 %C, 4294941696
433   %F = or i64 %D, %E
434   ret i64 %F
437 define <2 x i64> @test31vec(<2 x i64> %A) {
438 ; CHECK-LABEL: @test31vec(
439 ; CHECK-NEXT:    [[E:%.*]] = and <2 x i64> [[A:%.*]], splat (i64 4294908984)
440 ; CHECK-NEXT:    [[F:%.*]] = or disjoint <2 x i64> [[E]], splat (i64 32962)
441 ; CHECK-NEXT:    ret <2 x i64> [[F]]
443   %B = or <2 x i64> %A, <i64 194, i64 194>
444   %D = and <2 x i64> %B, <i64 250, i64 250>
446   %C = or <2 x i64> %A, <i64 32768, i64 32768>
447   %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>
449   %F = or <2 x i64> %D, %E
450   ret <2 x i64> %F
453 ; codegen is mature enough to handle vector selects.
454 define <4 x i32> @test32(<4 x i1> %and.i1352, <4 x i32> %vecinit6.i176, <4 x i32> %vecinit6.i191) {
455 ; CHECK-LABEL: @test32(
456 ; CHECK-NEXT:    [[OR_I:%.*]] = select <4 x i1> [[AND_I1352:%.*]], <4 x i32> [[VECINIT6_I176:%.*]], <4 x i32> [[VECINIT6_I191:%.*]]
457 ; CHECK-NEXT:    ret <4 x i32> [[OR_I]]
459   %and.i135 = sext <4 x i1> %and.i1352 to <4 x i32>
460   %and.i129 = and <4 x i32> %vecinit6.i176, %and.i135
461   %neg.i = xor <4 x i32> %and.i135, <i32 -1, i32 -1, i32 -1, i32 -1>
462   %and.i = and <4 x i32> %vecinit6.i191, %neg.i
463   %or.i = or <4 x i32> %and.i, %and.i129
464   ret <4 x i32> %or.i
467 define i1 @test33(i1 %X, i1 %Y) {
468 ; CHECK-LABEL: @test33(
469 ; CHECK-NEXT:    [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
470 ; CHECK-NEXT:    ret i1 [[A]]
472   %a = or i1 %X, %Y
473   %b = or i1 %a, %X
474   ret i1 %b
477 define i1 @test33_logical(i1 %X, i1 %Y) {
478 ; CHECK-LABEL: @test33_logical(
479 ; CHECK-NEXT:    [[A:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]]
480 ; CHECK-NEXT:    ret i1 [[A]]
482   %a = select i1 %X, i1 true, i1 %Y
483   %b = select i1 %a, i1 true, i1 %X
484   ret i1 %b
487 define i32 @test34(i32 %X, i32 %Y) {
488 ; CHECK-LABEL: @test34(
489 ; CHECK-NEXT:    [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
490 ; CHECK-NEXT:    ret i32 [[A]]
492   %a = or i32 %X, %Y
493   %b = or i32 %Y, %a
494   ret i32 %b
497 define i32 @test35(i32 %a, i32 %b) {
498 ; CHECK-LABEL: @test35(
499 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[A:%.*]], [[B:%.*]]
500 ; CHECK-NEXT:    [[TMP2:%.*]] = or i32 [[TMP1]], 1135
501 ; CHECK-NEXT:    ret i32 [[TMP2]]
503   %1 = or i32 %a, 1135
504   %2 = or i32 %1, %b
505   ret i32 %2
508 define i1 @test36(i32 %x) {
509 ; CHECK-LABEL: @test36(
510 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -23
511 ; CHECK-NEXT:    [[RET2:%.*]] = icmp ult i32 [[TMP1]], 3
512 ; CHECK-NEXT:    ret i1 [[RET2]]
514   %cmp1 = icmp eq i32 %x, 23
515   %cmp2 = icmp eq i32 %x, 24
516   %ret1 = or i1 %cmp1, %cmp2
517   %cmp3 = icmp eq i32 %x, 25
518   %ret2 = or i1 %ret1, %cmp3
519   ret i1 %ret2
522 define i1 @test36_logical(i32 %x) {
523 ; CHECK-LABEL: @test36_logical(
524 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -23
525 ; CHECK-NEXT:    [[RET2:%.*]] = icmp ult i32 [[TMP1]], 3
526 ; CHECK-NEXT:    ret i1 [[RET2]]
528   %cmp1 = icmp eq i32 %x, 23
529   %cmp2 = icmp eq i32 %x, 24
530   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
531   %cmp3 = icmp eq i32 %x, 25
532   %ret2 = select i1 %ret1, i1 true, i1 %cmp3
533   ret i1 %ret2
536 define i1 @test37(i32 %x) {
537 ; CHECK-LABEL: @test37(
538 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
539 ; CHECK-NEXT:    [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31
540 ; CHECK-NEXT:    ret i1 [[RET1]]
542   %add1 = add i32 %x, 7
543   %cmp1 = icmp ult i32 %add1, 30
544   %cmp2 = icmp eq i32 %x, 23
545   %ret1 = or i1 %cmp1, %cmp2
546   ret i1 %ret1
549 define i1 @test37_logical(i32 %x) {
550 ; CHECK-LABEL: @test37_logical(
551 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
552 ; CHECK-NEXT:    [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31
553 ; CHECK-NEXT:    ret i1 [[RET1]]
555   %add1 = add i32 %x, 7
556   %cmp1 = icmp ult i32 %add1, 30
557   %cmp2 = icmp eq i32 %x, 23
558   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
559   ret i1 %ret1
562 define <2 x i1> @test37_uniform(<2 x i32> %x) {
563 ; CHECK-LABEL: @test37_uniform(
564 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], splat (i32 7)
565 ; CHECK-NEXT:    [[RET1:%.*]] = icmp ult <2 x i32> [[TMP1]], splat (i32 31)
566 ; CHECK-NEXT:    ret <2 x i1> [[RET1]]
568   %add1 = add <2 x i32> %x, <i32 7, i32 7>
569   %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 30>
570   %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 23>
571   %ret1 = or <2 x i1> %cmp1, %cmp2
572   ret <2 x i1> %ret1
575 define <2 x i1> @test37_poison(<2 x i32> %x) {
576 ; CHECK-LABEL: @test37_poison(
577 ; CHECK-NEXT:    [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 poison>
578 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 poison>
579 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 poison>
580 ; CHECK-NEXT:    [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
581 ; CHECK-NEXT:    ret <2 x i1> [[RET1]]
583   %add1 = add <2 x i32> %x, <i32 7, i32 poison>
584   %cmp1 = icmp ult <2 x i32> %add1, <i32 30, i32 poison>
585   %cmp2 = icmp eq <2 x i32> %x, <i32 23, i32 poison>
586   %ret1 = or <2 x i1> %cmp1, %cmp2
587   ret <2 x i1> %ret1
590 define i1 @test38(i32 %x) {
591 ; CHECK-LABEL: @test38(
592 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
593 ; CHECK-NEXT:    [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31
594 ; CHECK-NEXT:    ret i1 [[RET1]]
596   %add1 = add i32 %x, 7
597   %cmp1 = icmp eq i32 %x, 23
598   %cmp2 = icmp ult i32 %add1, 30
599   %ret1 = or i1 %cmp1, %cmp2
600   ret i1 %ret1
603 define i1 @test38_logical(i32 %x) {
604 ; CHECK-LABEL: @test38_logical(
605 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 7
606 ; CHECK-NEXT:    [[RET1:%.*]] = icmp ult i32 [[TMP1]], 31
607 ; CHECK-NEXT:    ret i1 [[RET1]]
609   %add1 = add i32 %x, 7
610   %cmp1 = icmp eq i32 %x, 23
611   %cmp2 = icmp ult i32 %add1, 30
612   %ret1 = select i1 %cmp1, i1 true, i1 %cmp2
613   ret i1 %ret1
616 define <2 x i1> @test38_nonuniform(<2 x i32> %x) {
617 ; CHECK-LABEL: @test38_nonuniform(
618 ; CHECK-NEXT:    [[ADD1:%.*]] = add <2 x i32> [[X:%.*]], <i32 7, i32 24>
619 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp eq <2 x i32> [[X]], <i32 23, i32 8>
620 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i32> [[ADD1]], <i32 30, i32 32>
621 ; CHECK-NEXT:    [[RET1:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
622 ; CHECK-NEXT:    ret <2 x i1> [[RET1]]
624   %add1 = add <2 x i32> %x, <i32 7, i32 24>
625   %cmp1 = icmp eq <2 x i32> %x, <i32 23, i32 8>
626   %cmp2 = icmp ult <2 x i32> %add1, <i32 30, i32 32>
627   %ret1 = or <2 x i1> %cmp1, %cmp2
628   ret <2 x i1> %ret1
631 ; (~A & B) | A --> A | B
633 define i32 @test39a(i32 %a, float %b) {
634 ; CHECK-LABEL: @test39a(
635 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
636 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
637 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
638 ; CHECK-NEXT:    ret i32 [[OR]]
640   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
641   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
642   %nota = xor i32 %a1, -1
643   %and = and i32 %nota, %b1
644   %or = or i32 %and, %a1
645   ret i32 %or
648 ; Commute 'and' operands:
649 ; (B & ~A) | A --> A | B
651 define i32 @test39b(i32 %a, float %b) {
652 ; CHECK-LABEL: @test39b(
653 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
654 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
655 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
656 ; CHECK-NEXT:    ret i32 [[OR]]
658   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
659   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
660   %nota = xor i32 %a1, -1
661   %and = and i32 %b1, %nota
662   %or = or i32 %and, %a1
663   ret i32 %or
666 ; Commute 'or' operands:
667 ; A | (~A & B) --> A | B
669 define i32 @test39c(i32 %a, float %b) {
670 ; CHECK-LABEL: @test39c(
671 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
672 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
673 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
674 ; CHECK-NEXT:    ret i32 [[OR]]
676   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
677   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
678   %nota = xor i32 %a1, -1
679   %and = and i32 %nota, %b1
680   %or = or i32 %a1, %and
681   ret i32 %or
684 ; Commute 'and' operands:
685 ; A | (B & ~A) --> A | B
687 define i32 @test39d(i32 %a, float %b) {
688 ; CHECK-LABEL: @test39d(
689 ; CHECK-NEXT:    [[A1:%.*]] = mul i32 [[A:%.*]], 42
690 ; CHECK-NEXT:    [[B1:%.*]] = bitcast float [[B:%.*]] to i32
691 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[A1]], [[B1]]
692 ; CHECK-NEXT:    ret i32 [[OR]]
694   %a1 = mul i32 %a, 42          ; thwart complexity-based ordering
695   %b1 = bitcast float %b to i32 ; thwart complexity-based ordering
696   %nota = xor i32 %a1, -1
697   %and = and i32 %b1, %nota
698   %or = or i32 %a1, %and
699   ret i32 %or
702 define i32 @test40(i32 %a, i32 %b) {
703 ; CHECK-LABEL: @test40(
704 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
705 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]
706 ; CHECK-NEXT:    ret i32 [[OR]]
708   %and = and i32 %a, %b
709   %xor = xor i32 %a, -1
710   %or = or i32 %and, %xor
711   ret i32 %or
714 define i32 @test40b(i32 %a, i32 %b) {
715 ; CHECK-LABEL: @test40b(
716 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
717 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]
718 ; CHECK-NEXT:    ret i32 [[OR]]
720   %and = and i32 %b, %a
721   %xor = xor i32 %a, -1
722   %or = or i32 %and, %xor
723   ret i32 %or
726 define i32 @test40c(i32 %a, i32 %b) {
727 ; CHECK-LABEL: @test40c(
728 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
729 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]
730 ; CHECK-NEXT:    ret i32 [[OR]]
732   %and = and i32 %b, %a
733   %xor = xor i32 %a, -1
734   %or = or i32 %xor, %and
735   ret i32 %or
738 define i32 @test40d(i32 %a, i32 %b) {
739 ; CHECK-LABEL: @test40d(
740 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], -1
741 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[B:%.*]], [[XOR]]
742 ; CHECK-NEXT:    ret i32 [[OR]]
744   %and = and i32 %a, %b
745   %xor = xor i32 %a, -1
746   %or = or i32 %xor, %and
747   ret i32 %or
750 define i32 @test45(i32 %x, i32 %y, i32 %z) {
751 ; CHECK-LABEL: @test45(
752 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z:%.*]]
753 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[TMP1]], [[Y:%.*]]
754 ; CHECK-NEXT:    ret i32 [[OR1]]
756   %or = or i32 %y, %z
757   %and = and i32 %x, %or
758   %or1 = or i32 %and, %y
759   ret i32 %or1
762 define i32 @test45_uses1(i32 %x, i32 %y, i32 %z) {
763 ; CHECK-LABEL: @test45_uses1(
764 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]]
765 ; CHECK-NEXT:    call void @use(i32 [[OR]])
766 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Z]]
767 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[TMP1]], [[Y]]
768 ; CHECK-NEXT:    ret i32 [[OR1]]
770   %or = or i32 %y, %z
771   call void @use(i32 %or)
772   %and = and i32 %x, %or
773   %or1 = or i32 %and, %y
774   ret i32 %or1
777 define i32 @test45_uses2(i32 %x, i32 %y, i32 %z) {
778 ; CHECK-LABEL: @test45_uses2(
779 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[Z:%.*]]
780 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X:%.*]], [[OR]]
781 ; CHECK-NEXT:    call void @use(i32 [[AND]])
782 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[AND]], [[Y]]
783 ; CHECK-NEXT:    ret i32 [[OR1]]
785   %or = or i32 %y, %z
786   %and = and i32 %x, %or
787   call void @use(i32 %and)
788   %or1 = or i32 %and, %y
789   ret i32 %or1
792 define i32 @test45_commuted1(i32 %x, i32 %y, i32 %z) {
793 ; CHECK-LABEL: @test45_commuted1(
794 ; CHECK-NEXT:    [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
795 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Z:%.*]], [[X:%.*]]
796 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[YY]], [[TMP1]]
797 ; CHECK-NEXT:    ret i32 [[OR1]]
799   %yy = mul i32 %y, %y ; thwart complexity-based ordering
800   %or = or i32 %yy, %z
801   %and = and i32 %or, %x
802   %or1 = or i32 %yy, %and
803   ret i32 %or1
806 define i32 @test45_commuted2(i32 %x, i32 %y, i32 %z) {
807 ; CHECK-LABEL: @test45_commuted2(
808 ; CHECK-NEXT:    [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
809 ; CHECK-NEXT:    [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
810 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[XX]], [[Z:%.*]]
811 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[TMP1]], [[YY]]
812 ; CHECK-NEXT:    ret i32 [[OR1]]
814   %yy = mul i32 %y, %y ; thwart complexity-based ordering
815   %xx = mul i32 %x, %x ; thwart complexity-based ordering
816   %or = or i32 %yy, %z
817   %and = and i32 %xx, %or
818   %or1 = or i32 %and, %yy
819   ret i32 %or1
822 define i32 @test45_commuted3(i32 %x, i32 %y, i32 %z) {
823 ; CHECK-LABEL: @test45_commuted3(
824 ; CHECK-NEXT:    [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
825 ; CHECK-NEXT:    [[ZZ:%.*]] = mul i32 [[Z:%.*]], [[Z]]
826 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[ZZ]], [[X:%.*]]
827 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[TMP1]], [[YY]]
828 ; CHECK-NEXT:    ret i32 [[OR1]]
830   %yy = mul i32 %y, %y ; thwart complexity-based ordering
831   %zz = mul i32 %z, %z ; thwart complexity-based ordering
832   %or = or i32 %zz, %yy
833   %and = and i32 %or, %x
834   %or1 = or i32 %and, %yy
835   ret i32 %or1
838 define i1 @test46(i8 signext %c)  {
839 ; CHECK-LABEL: @test46(
840 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
841 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
842 ; CHECK-NEXT:    [[OR:%.*]] = icmp ult i8 [[TMP2]], 26
843 ; CHECK-NEXT:    ret i1 [[OR]]
845   %c.off = add i8 %c, -97
846   %cmp1 = icmp ult i8 %c.off, 26
847   %c.off17 = add i8 %c, -65
848   %cmp2 = icmp ult i8 %c.off17, 26
849   %or = or i1 %cmp1, %cmp2
850   ret i1 %or
853 define i1 @test46_logical(i8 signext %c)  {
854 ; CHECK-LABEL: @test46_logical(
855 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
856 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
857 ; CHECK-NEXT:    [[OR:%.*]] = icmp ult i8 [[TMP2]], 26
858 ; CHECK-NEXT:    ret i1 [[OR]]
860   %c.off = add i8 %c, -97
861   %cmp1 = icmp ult i8 %c.off, 26
862   %c.off17 = add i8 %c, -65
863   %cmp2 = icmp ult i8 %c.off17, 26
864   %or = select i1 %cmp1, i1 true, i1 %cmp2
865   ret i1 %or
868 define <2 x i1> @test46_uniform(<2 x i8> %c)  {
869 ; CHECK-LABEL: @test46_uniform(
870 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[C:%.*]], splat (i8 -33)
871 ; CHECK-NEXT:    [[TMP2:%.*]] = add <2 x i8> [[TMP1]], splat (i8 -65)
872 ; CHECK-NEXT:    [[OR:%.*]] = icmp ult <2 x i8> [[TMP2]], splat (i8 26)
873 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
875   %c.off = add <2 x i8> %c, <i8 -97, i8 -97>
876   %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 26>
877   %c.off17 = add <2 x i8> %c, <i8 -65, i8 -65>
878   %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 26>
879   %or = or <2 x i1> %cmp1, %cmp2
880   ret <2 x i1> %or
883 define <2 x i1> @test46_poison(<2 x i8> %c)  {
884 ; CHECK-LABEL: @test46_poison(
885 ; CHECK-NEXT:    [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -97, i8 poison>
886 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], <i8 26, i8 poison>
887 ; CHECK-NEXT:    [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -65, i8 poison>
888 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], <i8 26, i8 poison>
889 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
890 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
892   %c.off = add <2 x i8> %c, <i8 -97, i8 poison>
893   %cmp1 = icmp ult <2 x i8> %c.off, <i8 26, i8 poison>
894   %c.off17 = add <2 x i8> %c, <i8 -65, i8 poison>
895   %cmp2 = icmp ult <2 x i8> %c.off17, <i8 26, i8 poison>
896   %or = or <2 x i1> %cmp1, %cmp2
897   ret <2 x i1> %or
900 ; This is the variant of the above pattern where one of the ranges is
901 ; represented with an add.
902 define i1 @two_ranges_to_mask_and_range_degenerate(i16 %x) {
903 ; CHECK-LABEL: @two_ranges_to_mask_and_range_degenerate(
904 ; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[X:%.*]], -20
905 ; CHECK-NEXT:    [[OR:%.*]] = icmp ult i16 [[TMP1]], 12
906 ; CHECK-NEXT:    ret i1 [[OR]]
908   %cmp1 = icmp ult i16 %x, 12
909   %cmp2 = icmp uge i16 %x, 16
910   %cmp3 = icmp ult i16 %x, 28
911   %and = and i1 %cmp2, %cmp3
912   %or = or i1 %cmp1, %and
913   ret i1 %or
916 define i1 @test47(i8 signext %c)  {
917 ; CHECK-LABEL: @test47(
918 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
919 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
920 ; CHECK-NEXT:    [[OR:%.*]] = icmp ult i8 [[TMP2]], 27
921 ; CHECK-NEXT:    ret i1 [[OR]]
923   %c.off = add i8 %c, -65
924   %cmp1 = icmp ule i8 %c.off, 26
925   %c.off17 = add i8 %c, -97
926   %cmp2 = icmp ule i8 %c.off17, 26
927   %or = or i1 %cmp1, %cmp2
928   ret i1 %or
931 define i1 @test47_logical(i8 signext %c)  {
932 ; CHECK-LABEL: @test47_logical(
933 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[C:%.*]], -33
934 ; CHECK-NEXT:    [[TMP2:%.*]] = add i8 [[TMP1]], -65
935 ; CHECK-NEXT:    [[OR:%.*]] = icmp ult i8 [[TMP2]], 27
936 ; CHECK-NEXT:    ret i1 [[OR]]
938   %c.off = add i8 %c, -65
939   %cmp1 = icmp ule i8 %c.off, 26
940   %c.off17 = add i8 %c, -97
941   %cmp2 = icmp ule i8 %c.off17, 26
942   %or = select i1 %cmp1, i1 true, i1 %cmp2
943   ret i1 %or
946 define <2 x i1> @test47_nonuniform(<2 x i8> %c)  {
947 ; CHECK-LABEL: @test47_nonuniform(
948 ; CHECK-NEXT:    [[C_OFF:%.*]] = add <2 x i8> [[C:%.*]], <i8 -65, i8 -97>
949 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult <2 x i8> [[C_OFF]], splat (i8 27)
950 ; CHECK-NEXT:    [[C_OFF17:%.*]] = add <2 x i8> [[C]], <i8 -97, i8 -65>
951 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult <2 x i8> [[C_OFF17]], splat (i8 27)
952 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[CMP1]], [[CMP2]]
953 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
955   %c.off = add <2 x i8> %c, <i8 -65, i8 -97>
956   %cmp1 = icmp ule <2 x i8> %c.off, <i8 26, i8 26>
957   %c.off17 = add <2 x i8> %c, <i8 -97, i8 -65>
958   %cmp2 = icmp ule <2 x i8> %c.off17, <i8 26, i8 26>
959   %or = or <2 x i1> %cmp1, %cmp2
960   ret <2 x i1> %or
963 define i32 @test49(i1 %C) {
964 ; CHECK-LABEL: @test49(
965 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], i32 1019, i32 123
966 ; CHECK-NEXT:    ret i32 [[V]]
968   %A = select i1 %C, i32 1000, i32 10
969   %V = or i32 %A, 123
970   ret i32 %V
973 define <2 x i32> @test49vec(i1 %C) {
974 ; CHECK-LABEL: @test49vec(
975 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> splat (i32 1019), <2 x i32> splat (i32 123)
976 ; CHECK-NEXT:    ret <2 x i32> [[V]]
978   %A = select i1 %C, <2 x i32> <i32 1000, i32 1000>, <2 x i32> <i32 10, i32 10>
979   %V = or <2 x i32> %A, <i32 123, i32 123>
980   ret <2 x i32> %V
983 define <2 x i32> @test49vec2(i1 %C) {
984 ; CHECK-LABEL: @test49vec2(
985 ; CHECK-NEXT:    [[V:%.*]] = select i1 [[C:%.*]], <2 x i32> <i32 1019, i32 2509>, <2 x i32> <i32 123, i32 351>
986 ; CHECK-NEXT:    ret <2 x i32> [[V]]
988   %A = select i1 %C, <2 x i32> <i32 1000, i32 2500>, <2 x i32> <i32 10, i32 30>
989   %V = or <2 x i32> %A, <i32 123, i32 333>
990   ret <2 x i32> %V
993 define i32 @test50(i1 %which) {
994 ; CHECK-LABEL: @test50(
995 ; CHECK-NEXT:  entry:
996 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
997 ; CHECK:       delay:
998 ; CHECK-NEXT:    br label [[FINAL]]
999 ; CHECK:       final:
1000 ; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 1019, [[ENTRY:%.*]] ], [ 123, [[DELAY]] ]
1001 ; CHECK-NEXT:    ret i32 [[A]]
1003 entry:
1004   br i1 %which, label %final, label %delay
1006 delay:
1007   br label %final
1009 final:
1010   %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
1011   %value = or i32 %A, 123
1012   ret i32 %value
1015 define <2 x i32> @test50vec(i1 %which) {
1016 ; CHECK-LABEL: @test50vec(
1017 ; CHECK-NEXT:  entry:
1018 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1019 ; CHECK:       delay:
1020 ; CHECK-NEXT:    br label [[FINAL]]
1021 ; CHECK:       final:
1022 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ splat (i32 1019), [[ENTRY:%.*]] ], [ splat (i32 123), [[DELAY]] ]
1023 ; CHECK-NEXT:    ret <2 x i32> [[A]]
1025 entry:
1026   br i1 %which, label %final, label %delay
1028 delay:
1029   br label %final
1031 final:
1032   %A = phi <2 x i32> [ <i32 1000, i32 1000>, %entry ], [ <i32 10, i32 10>, %delay ]
1033   %value = or <2 x i32> %A, <i32 123, i32 123>
1034   ret <2 x i32> %value
1037 define <2 x i32> @test50vec2(i1 %which) {
1038 ; CHECK-LABEL: @test50vec2(
1039 ; CHECK-NEXT:  entry:
1040 ; CHECK-NEXT:    br i1 [[WHICH:%.*]], label [[FINAL:%.*]], label [[DELAY:%.*]]
1041 ; CHECK:       delay:
1042 ; CHECK-NEXT:    br label [[FINAL]]
1043 ; CHECK:       final:
1044 ; CHECK-NEXT:    [[A:%.*]] = phi <2 x i32> [ <i32 1019, i32 2509>, [[ENTRY:%.*]] ], [ <i32 123, i32 351>, [[DELAY]] ]
1045 ; CHECK-NEXT:    ret <2 x i32> [[A]]
1047 entry:
1048   br i1 %which, label %final, label %delay
1050 delay:
1051   br label %final
1053 final:
1054   %A = phi <2 x i32> [ <i32 1000, i32 2500>, %entry ], [ <i32 10, i32 30>, %delay ]
1055   %value = or <2 x i32> %A, <i32 123, i32 333>
1056   ret <2 x i32> %value
1059 ; In the next 4 tests, vary the types and predicates for extra coverage.
1060 ; (X | (Y & ~X)) -> (X | Y), where 'not' is an inverted cmp
1062 define i1 @or_andn_cmp_1(i32 %a, i32 %b, i32 %c) {
1063 ; CHECK-LABEL: @or_andn_cmp_1(
1064 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
1065 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1066 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X]], [[Y]]
1067 ; CHECK-NEXT:    ret i1 [[OR]]
1069   %x = icmp sgt i32 %a, %b
1070   %x_inv = icmp sle i32 %a, %b
1071   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1072   %and = and i1 %y, %x_inv
1073   %or = or i1 %x, %and
1074   ret i1 %or
1077 define i1 @or_andn_cmp_1_logical(i32 %a, i32 %b, i32 %c) {
1078 ; CHECK-LABEL: @or_andn_cmp_1_logical(
1079 ; CHECK-NEXT:    [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]
1080 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1081 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1082 ; CHECK-NEXT:    ret i1 [[OR]]
1084   %x = icmp sgt i32 %a, %b
1085   %x_inv = icmp sle i32 %a, %b
1086   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1087   %and = select i1 %y, i1 %x_inv, i1 false
1088   %or = select i1 %x, i1 true, i1 %and
1089   ret i1 %or
1092 ; Commute the 'or':
1093 ; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
1095 define <2 x i1> @or_andn_cmp_2(<2 x i32> %a, <2 x i32> %b, <2 x i32> %c) {
1096 ; CHECK-LABEL: @or_andn_cmp_2(
1097 ; CHECK-NEXT:    [[X:%.*]] = icmp sge <2 x i32> [[A:%.*]], [[B:%.*]]
1098 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <2 x i32> [[C:%.*]], <i32 42, i32 47>
1099 ; CHECK-NEXT:    [[OR:%.*]] = or <2 x i1> [[Y]], [[X]]
1100 ; CHECK-NEXT:    ret <2 x i1> [[OR]]
1102   %x = icmp sge <2 x i32> %a, %b
1103   %x_inv = icmp slt <2 x i32> %a, %b
1104   %y = icmp ugt <2 x i32> %c, <i32 42, i32 47>      ; thwart complexity-based ordering
1105   %and = and <2 x i1> %y, %x_inv
1106   %or = or <2 x i1> %and, %x
1107   ret <2 x i1> %or
1110 ; Commute the 'and':
1111 ; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
1113 define i1 @or_andn_cmp_3(i72 %a, i72 %b, i72 %c) {
1114 ; CHECK-LABEL: @or_andn_cmp_3(
1115 ; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1116 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1117 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X]], [[Y]]
1118 ; CHECK-NEXT:    ret i1 [[OR]]
1120   %x = icmp ugt i72 %a, %b
1121   %x_inv = icmp ule i72 %a, %b
1122   %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
1123   %and = and i1 %x_inv, %y
1124   %or = or i1 %x, %and
1125   ret i1 %or
1128 define i1 @or_andn_cmp_3_logical(i72 %a, i72 %b, i72 %c) {
1129 ; CHECK-LABEL: @or_andn_cmp_3_logical(
1130 ; CHECK-NEXT:    [[X:%.*]] = icmp ugt i72 [[A:%.*]], [[B:%.*]]
1131 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i72 [[C:%.*]], 42
1132 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[Y]]
1133 ; CHECK-NEXT:    ret i1 [[OR]]
1135   %x = icmp ugt i72 %a, %b
1136   %x_inv = icmp ule i72 %a, %b
1137   %y = icmp ugt i72 %c, 42      ; thwart complexity-based ordering
1138   %and = select i1 %x_inv, i1 %y, i1 false
1139   %or = select i1 %x, i1 true, i1 %and
1140   ret i1 %or
1143 ; Commute the 'or':
1144 ; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
1146 define <3 x i1> @or_andn_cmp_4(<3 x i32> %a, <3 x i32> %b, <3 x i32> %c) {
1147 ; CHECK-LABEL: @or_andn_cmp_4(
1148 ; CHECK-NEXT:    [[X:%.*]] = icmp eq <3 x i32> [[A:%.*]], [[B:%.*]]
1149 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <3 x i32> [[C:%.*]], <i32 42, i32 43, i32 -1>
1150 ; CHECK-NEXT:    [[OR:%.*]] = or <3 x i1> [[Y]], [[X]]
1151 ; CHECK-NEXT:    ret <3 x i1> [[OR]]
1153   %x = icmp eq <3 x i32> %a, %b
1154   %x_inv = icmp ne <3 x i32> %a, %b
1155   %y = icmp ugt <3 x i32> %c, <i32 42, i32 43, i32 -1>      ; thwart complexity-based ordering
1156   %and = and <3 x i1> %x_inv, %y
1157   %or = or <3 x i1> %and, %x
1158   ret <3 x i1> %or
1161 ; In the next 4 tests, vary the types and predicates for extra coverage.
1162 ; (~X | (Y & X)) -> (~X | Y), where 'not' is an inverted cmp
1164 define i1 @orn_and_cmp_1(i37 %a, i37 %b, i37 %c) {
1165 ; CHECK-LABEL: @orn_and_cmp_1(
1166 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1167 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1168 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[X_INV]], [[Y]]
1169 ; CHECK-NEXT:    ret i1 [[OR]]
1171   %x = icmp sgt i37 %a, %b
1172   %x_inv = icmp sle i37 %a, %b
1173   %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
1174   %and = and i1 %y, %x
1175   %or = or i1 %x_inv, %and
1176   ret i1 %or
1179 define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i37 %c) {
1180 ; CHECK-LABEL: @orn_and_cmp_1_logical(
1181 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]
1182 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i37 [[C:%.*]], 42
1183 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1184 ; CHECK-NEXT:    ret i1 [[OR]]
1186   %x = icmp sgt i37 %a, %b
1187   %x_inv = icmp sle i37 %a, %b
1188   %y = icmp ugt i37 %c, 42      ; thwart complexity-based ordering
1189   %and = select i1 %y, i1 %x, i1 false
1190   %or = select i1 %x_inv, i1 true, i1 %and
1191   ret i1 %or
1194 ; Commute the 'or':
1195 ; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1197 define i1 @orn_and_cmp_2(i16 %a, i16 %b, i16 %c) {
1198 ; CHECK-LABEL: @orn_and_cmp_2(
1199 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1200 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1201 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1202 ; CHECK-NEXT:    ret i1 [[OR]]
1204   %x = icmp sge i16 %a, %b
1205   %x_inv = icmp slt i16 %a, %b
1206   %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
1207   %and = and i1 %y, %x
1208   %or = or i1 %and, %x_inv
1209   ret i1 %or
1212 define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i16 %c) {
1213 ; CHECK-LABEL: @orn_and_cmp_2_logical(
1214 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]
1215 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i16 [[C:%.*]], 42
1216 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[Y]], i1 true, i1 [[X_INV]]
1217 ; CHECK-NEXT:    ret i1 [[OR]]
1219   %x = icmp sge i16 %a, %b
1220   %x_inv = icmp slt i16 %a, %b
1221   %y = icmp ugt i16 %c, 42      ; thwart complexity-based ordering
1222   %and = select i1 %y, i1 %x, i1 false
1223   %or = select i1 %and, i1 true, i1 %x_inv
1224   ret i1 %or
1227 ; Commute the 'and':
1228 ; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
1230 define <4 x i1> @orn_and_cmp_3(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c) {
1231 ; CHECK-LABEL: @orn_and_cmp_3(
1232 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ule <4 x i32> [[A:%.*]], [[B:%.*]]
1233 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt <4 x i32> [[C:%.*]], <i32 42, i32 0, i32 1, i32 -1>
1234 ; CHECK-NEXT:    [[OR:%.*]] = or <4 x i1> [[X_INV]], [[Y]]
1235 ; CHECK-NEXT:    ret <4 x i1> [[OR]]
1237   %x = icmp ugt <4 x i32> %a, %b
1238   %x_inv = icmp ule <4 x i32> %a, %b
1239   %y = icmp ugt <4 x i32> %c, <i32 42, i32 0, i32 1, i32 -1>      ; thwart complexity-based ordering
1240   %and = and <4 x i1> %x, %y
1241   %or = or <4 x i1> %x_inv, %and
1242   ret <4 x i1> %or
1245 ; Commute the 'or':
1246 ; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1248 define i1 @orn_and_cmp_4(i32 %a, i32 %b, i32 %c) {
1249 ; CHECK-LABEL: @orn_and_cmp_4(
1250 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1251 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1252 ; CHECK-NEXT:    [[OR:%.*]] = or i1 [[Y]], [[X_INV]]
1253 ; CHECK-NEXT:    ret i1 [[OR]]
1255   %x = icmp eq i32 %a, %b
1256   %x_inv = icmp ne i32 %a, %b
1257   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1258   %and = and i1 %x, %y
1259   %or = or i1 %and, %x_inv
1260   ret i1 %or
1263 define i1 @orn_and_cmp_4_logical(i32 %a, i32 %b, i32 %c) {
1264 ; CHECK-LABEL: @orn_and_cmp_4_logical(
1265 ; CHECK-NEXT:    [[X_INV:%.*]] = icmp ne i32 [[A:%.*]], [[B:%.*]]
1266 ; CHECK-NEXT:    [[Y:%.*]] = icmp ugt i32 [[C:%.*]], 42
1267 ; CHECK-NEXT:    [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]
1268 ; CHECK-NEXT:    ret i1 [[OR]]
1270   %x = icmp eq i32 %a, %b
1271   %x_inv = icmp ne i32 %a, %b
1272   %y = icmp ugt i32 %c, 42      ; thwart complexity-based ordering
1273   %and = select i1 %x, i1 %y, i1 false
1274   %or = select i1 %and, i1 true, i1 %x_inv
1275   ret i1 %or
1278 ; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
1279 define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) {
1280 ; CHECK-LABEL: @test51(
1281 ; CHECK-NEXT:    [[TMP3:%.*]] = 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>
1282 ; CHECK-NEXT:    ret <16 x i1> [[TMP3]]
1284   %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>
1285   %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>
1286   %tmp3 = or <16 x i1> %tmp, %tmp2
1287   ret <16 x i1> %tmp3
1290 ; This would infinite loop because it reaches a transform
1291 ; that was not expecting a constant-foldable value.
1293 define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) {
1294 ; CHECK-LABEL: @PR46712(
1295 ; CHECK-NEXT:  entry:
1296 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1297 ; CHECK:       true:
1298 ; CHECK-NEXT:    [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0
1299 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i32
1300 ; CHECK-NEXT:    br label [[END]]
1301 ; CHECK:       end:
1302 ; CHECK-NEXT:    [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ]
1303 ; CHECK-NEXT:    ret i32 [[T5]]
1305 entry:
1306   %t2 = or i1 %x, %y
1307   %conv = sext i1 %t2 to i32
1308   %cmp = icmp sge i32 %conv, 1
1309   %conv2 = zext i1 %cmp to i64
1310   br i1 %b, label %true, label %end
1312 true:
1313   %bool4 = icmp eq i64 %conv2, 0
1314   %bool5 = icmp ne i64 %z, 0
1315   %and = and i1 %bool4, %bool5
1316   %sel = select i1 %and, i1 false, i1 true
1317   br label %end
1319 end:
1320   %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1321   %conv8 = zext i1 %t5 to i32
1322   ret i32 %conv8
1325 define i32 @PR46712_logical(i1 %x, i1 %y, i1 %b, i64 %z) {
1326 ; CHECK-LABEL: @PR46712_logical(
1327 ; CHECK-NEXT:  entry:
1328 ; CHECK-NEXT:    br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]]
1329 ; CHECK:       true:
1330 ; CHECK-NEXT:    [[BOOL5_NOT:%.*]] = icmp eq i64 [[Z:%.*]], 0
1331 ; CHECK-NEXT:    [[TMP0:%.*]] = zext i1 [[BOOL5_NOT]] to i32
1332 ; CHECK-NEXT:    br label [[END]]
1333 ; CHECK:       end:
1334 ; CHECK-NEXT:    [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP0]], [[TRUE]] ]
1335 ; CHECK-NEXT:    ret i32 [[T5]]
1337 entry:
1338   %t2 = select i1 %x, i1 true, i1 %y
1339   %conv = sext i1 %t2 to i32
1340   %cmp = icmp sge i32 %conv, 1
1341   %conv2 = zext i1 %cmp to i64
1342   br i1 %b, label %true, label %end
1344 true:
1345   %bool4 = icmp eq i64 %conv2, 0
1346   %bool5 = icmp ne i64 %z, 0
1347   %and = select i1 %bool4, i1 %bool5, i1 false
1348   %sel = select i1 %and, i1 false, i1 true
1349   br label %end
1351 end:
1352   %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1353   %conv8 = zext i1 %t5 to i32
1354   ret i32 %conv8
1357 ; (~x & y) | ~(x | y) --> ~x
1358 define i32 @PR38929(i32 %0, i32 %1) {
1359 ; CHECK-LABEL: @PR38929(
1360 ; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1
1361 ; CHECK-NEXT:    ret i32 [[TMP3]]
1363   %3 = xor i32 %0, -1
1364   %4 = and i32 %3, %1
1365   %5 = or i32 %1, %0
1366   %6 = xor i32 %5, -1
1367   %7 = or i32 %4, %6
1368   ret i32 %7
1371 define i32 @test1(i32 %x, i32 %y) {
1372 ; CHECK-LABEL: @test1(
1373 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1374 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1375 ; CHECK-NEXT:    ret i32 [[OR1]]
1377   %xor = xor i32 %y, %x
1378   %or = or i32 %y, %x
1379   %neg = xor i32 %or, -1
1380   %or1 = or i32 %xor, %neg
1381   ret i32 %or1
1384 define i32 @test2(i32 %x, i32 %y) {
1385 ; CHECK-LABEL: @test2(
1386 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y:%.*]], [[X:%.*]]
1387 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1388 ; CHECK-NEXT:    ret i32 [[OR1]]
1390   %or = or i32 %x, %y
1391   %neg = xor i32 %or, -1
1392   %xor = xor i32 %y, %x
1393   %or1 = or i32 %xor, %neg
1394   ret i32 %or1
1397 define i32 @test3(i32 %x, i32 %y) {
1398 ; CHECK-LABEL: @test3(
1399 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], [[Y:%.*]]
1400 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1401 ; CHECK-NEXT:    ret i32 [[OR1]]
1403   %or = or i32 %y, %x
1404   %neg = xor i32 %or, -1
1405   %xor = xor i32 %x, %y
1406   %or1 = or i32 %xor, %neg
1407   ret i32 %or1
1410 define <2 x i32> @test4_vec(<2 x i32> %x, <2 x i32> %y) {
1411 ; CHECK-LABEL: @test4_vec(
1412 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[Y:%.*]], [[X:%.*]]
1413 ; CHECK-NEXT:    [[OR1:%.*]] = xor <2 x i32> [[TMP1]], splat (i32 -1)
1414 ; CHECK-NEXT:    ret <2 x i32> [[OR1]]
1416   %or = or <2 x i32> %y, %x
1417   %neg = xor <2 x i32> %or, <i32 -1, i32 -1>
1418   %xor = xor <2 x i32> %y, %x
1419   %or1 = or <2 x i32> %xor, %neg
1420   ret <2 x i32> %or1
1423 define i32 @test5_use(i32 %x, i32 %y) {
1424 ; CHECK-LABEL: @test5_use(
1425 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1426 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[OR]], -1
1427 ; CHECK-NEXT:    call void @use(i32 [[NEG]])
1428 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1429 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1430 ; CHECK-NEXT:    ret i32 [[OR1]]
1432   %or = or i32 %y, %x
1433   %neg = xor i32 %or, -1
1434   %xor = xor i32 %y, %x
1435   call void @use(i32 %neg)
1436   %or1 = or i32 %xor, %neg
1437   ret i32 %or1
1440 define i32 @test5_use2(i32 %x, i32 %y) {
1441 ; CHECK-LABEL: @test5_use2(
1442 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y:%.*]], [[X:%.*]]
1443 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
1444 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[Y]], [[X]]
1445 ; CHECK-NEXT:    [[OR1:%.*]] = xor i32 [[TMP1]], -1
1446 ; CHECK-NEXT:    ret i32 [[OR1]]
1448   %or = or i32 %y, %x
1449   %neg = xor i32 %or, -1
1450   %xor = xor i32 %y, %x
1451   call void @use(i32 %xor)
1452   %or1 = or i32 %xor, %neg
1453   ret i32 %or1
1455 define i32 @test5_use3(i32 %x, i32 %y) {
1456 ; CHECK-LABEL: @test5_use3(
1457 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1458 ; CHECK-NEXT:    [[NEG:%.*]] = xor i32 [[OR]], -1
1459 ; CHECK-NEXT:    call void @use(i32 [[NEG]])
1460 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[Y]], [[X]]
1461 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
1462 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[XOR]], [[NEG]]
1463 ; CHECK-NEXT:    ret i32 [[OR1]]
1465   %or = or i32 %y, %x
1466   %neg = xor i32 %or, -1
1467   call void @use(i32 %neg)
1468   %xor = xor i32 %y, %x
1469   call void @use(i32 %xor)
1470   %or1 = or i32 %xor, %neg
1471   ret i32 %or1
1474 define i8 @ashr_bitwidth_mask(i8 %x, i8 %y) {
1475 ; CHECK-LABEL: @ashr_bitwidth_mask(
1476 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 7
1477 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1478 ; CHECK-NEXT:    ret i8 [[R]]
1480   %sign = ashr i8 %x, 7
1481   %r = or i8 %sign, %y
1482   ret i8 %r
1485 define <2 x i8> @ashr_bitwidth_mask_vec_commute(<2 x i8> %x, <2 x i8> %py) {
1486 ; CHECK-LABEL: @ashr_bitwidth_mask_vec_commute(
1487 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i8> [[PY:%.*]], <i8 42, i8 2>
1488 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr <2 x i8> [[X:%.*]], splat (i8 7)
1489 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i8> [[Y]], [[SIGN]]
1490 ; CHECK-NEXT:    ret <2 x i8> [[R]]
1492   %y = mul <2 x i8> %py, <i8 42, i8 2>      ; thwart complexity-based ordering
1493   %sign = ashr <2 x i8> %x, <i8 7, i8 7>
1494   %r = or <2 x i8> %y, %sign
1495   ret <2 x i8> %r
1498 define i32 @ashr_bitwidth_mask_use(i32 %x, i32 %y) {
1499 ; CHECK-LABEL: @ashr_bitwidth_mask_use(
1500 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i32 [[X:%.*]], 7
1501 ; CHECK-NEXT:    call void @use(i32 [[SIGN]])
1502 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[SIGN]], [[Y:%.*]]
1503 ; CHECK-NEXT:    ret i32 [[R]]
1505   %sign = ashr i32 %x, 7
1506   call void @use(i32 %sign)
1507   %r = or i32 %sign, %y
1508   ret i32 %r
1511 define i8 @ashr_not_bitwidth_mask(i8 %x, i8 %y) {
1512 ; CHECK-LABEL: @ashr_not_bitwidth_mask(
1513 ; CHECK-NEXT:    [[SIGN:%.*]] = ashr i8 [[X:%.*]], 6
1514 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1515 ; CHECK-NEXT:    ret i8 [[R]]
1517   %sign = ashr i8 %x, 6
1518   %r = or i8 %sign, %y
1519   ret i8 %r
1522 define i8 @lshr_bitwidth_mask(i8 %x, i8 %y) {
1523 ; CHECK-LABEL: @lshr_bitwidth_mask(
1524 ; CHECK-NEXT:    [[SIGN:%.*]] = lshr i8 [[X:%.*]], 7
1525 ; CHECK-NEXT:    [[R:%.*]] = or i8 [[SIGN]], [[Y:%.*]]
1526 ; CHECK-NEXT:    ret i8 [[R]]
1528   %sign = lshr i8 %x, 7
1529   %r = or i8 %sign, %y
1530   ret i8 %r
1533 define i1 @cmp_overlap(i32 %x) {
1534 ; CHECK-LABEL: @cmp_overlap(
1535 ; CHECK-NEXT:    [[R:%.*]] = icmp slt i32 [[X:%.*]], 1
1536 ; CHECK-NEXT:    ret i1 [[R]]
1538   %isneg = icmp slt i32 %x, 0
1539   %negx = sub i32 0, %x
1540   %isnotneg = icmp sgt i32 %negx, -1
1541   %r = or i1 %isneg, %isnotneg
1542   ret i1 %r
1545 define <2 x i1> @cmp_overlap_splat(<2 x i5> %x) {
1546 ; CHECK-LABEL: @cmp_overlap_splat(
1547 ; CHECK-NEXT:    [[R:%.*]] = icmp slt <2 x i5> [[X:%.*]], splat (i5 1)
1548 ; CHECK-NEXT:    ret <2 x i1> [[R]]
1550   %isneg = icmp slt <2 x i5> %x, zeroinitializer
1551   %negx = sub <2 x i5> zeroinitializer, %x
1552   %isnotneg = icmp sgt <2 x i5> %negx, <i5 -1, i5 -1>
1553   %r = or <2 x i1> %isneg, %isnotneg
1554   ret <2 x i1> %r
1557 define i32 @mul_no_common_bits(i32 %p1, i32 %p2) {
1558 ; CHECK-LABEL: @mul_no_common_bits(
1559 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
1560 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1561 ; CHECK-NEXT:    [[TMP1:%.*]] = or disjoint i32 [[Y]], 1
1562 ; CHECK-NEXT:    [[R:%.*]] = mul i32 [[X]], [[TMP1]]
1563 ; CHECK-NEXT:    ret i32 [[R]]
1565   %x = and i32 %p1, 7
1566   %y = shl i32 %p2, 3
1567   %m = mul i32 %x, %y
1568   %r = or i32 %m, %x
1569   ret i32 %r
1572 define i32 @mul_no_common_bits_const_op(i32 %p) {
1573 ; CHECK-LABEL: @mul_no_common_bits_const_op(
1574 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1575 ; CHECK-NEXT:    [[R:%.*]] = mul nuw nsw i32 [[X]], 25
1576 ; CHECK-NEXT:    ret i32 [[R]]
1578   %x = and i32 %p, 7
1579   %m = mul i32 %x, 24
1580   %r = or i32 %m, %x
1581   ret i32 %r
1584 define <2 x i12> @mul_no_common_bits_commute(<2 x i12> %p) {
1585 ; CHECK-LABEL: @mul_no_common_bits_commute(
1586 ; CHECK-NEXT:    [[TMP1:%.*]] = trunc <2 x i12> [[P:%.*]] to <2 x i1>
1587 ; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP1]], <2 x i12> <i12 15, i12 17>, <2 x i12> zeroinitializer
1588 ; CHECK-NEXT:    ret <2 x i12> [[R]]
1590   %x = and <2 x i12> %p, <i12 1, i12 1>
1591   %m = mul <2 x i12> %x, <i12 14, i12 16>
1592   %r = or <2 x i12> %x, %m
1593   ret <2 x i12> %r
1596 define i32 @mul_no_common_bits_commute2(i32 %p1, i32 %p2) {
1597 ; CHECK-LABEL: @mul_no_common_bits_commute2(
1598 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
1599 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1600 ; CHECK-NEXT:    [[M:%.*]] = mul i32 [[Y]], [[X]]
1601 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i32 [[M]], [[X]]
1602 ; CHECK-NEXT:    ret i32 [[R]]
1604   %x = and i32 %p1, 7
1605   %y = shl i32 %p2, 3
1606   %m = mul i32 %y, %x
1607   %r = or i32 %m, %x
1608   ret i32 %r
1611 define i32 @mul_no_common_bits_disjoint(i32 %x, i32 %y) {
1612 ; CHECK-LABEL: @mul_no_common_bits_disjoint(
1613 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[Y:%.*]], 1
1614 ; CHECK-NEXT:    [[R:%.*]] = mul i32 [[X:%.*]], [[TMP1]]
1615 ; CHECK-NEXT:    ret i32 [[R]]
1617   %m = mul i32 %x, %y
1618   %r = or disjoint i32 %m, %x
1619   ret i32 %r
1622 define i32 @mul_no_common_bits_const_op_disjoint(i32 %x, i32 %y) {
1623 ; CHECK-LABEL: @mul_no_common_bits_const_op_disjoint(
1624 ; CHECK-NEXT:    [[R:%.*]] = mul i32 [[X:%.*]], 25
1625 ; CHECK-NEXT:    ret i32 [[R]]
1627   %m = mul i32 %x, 24
1628   %r = or disjoint i32 %m, %x
1629   ret i32 %r
1632 ; negative test - extra use requires extra instructions
1634 define i32 @mul_no_common_bits_uses(i32 %p1, i32 %p2) {
1635 ; CHECK-LABEL: @mul_no_common_bits_uses(
1636 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P1:%.*]], 7
1637 ; CHECK-NEXT:    [[Y:%.*]] = shl i32 [[P2:%.*]], 3
1638 ; CHECK-NEXT:    [[M:%.*]] = mul i32 [[X]], [[Y]]
1639 ; CHECK-NEXT:    call void @use(i32 [[M]])
1640 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i32 [[M]], [[X]]
1641 ; CHECK-NEXT:    ret i32 [[R]]
1643   %x = and i32 %p1, 7
1644   %y = shl i32 %p2, 3
1645   %m = mul i32 %x, %y
1646   call void @use(i32 %m)
1647   %r = or i32 %m, %x
1648   ret i32 %r
1651 ; negative test - probably not good to create an extra mul
1653 define i32 @mul_no_common_bits_const_op_uses(i32 %p) {
1654 ; CHECK-LABEL: @mul_no_common_bits_const_op_uses(
1655 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1656 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 24
1657 ; CHECK-NEXT:    call void @use(i32 [[M]])
1658 ; CHECK-NEXT:    [[R:%.*]] = or disjoint i32 [[M]], [[X]]
1659 ; CHECK-NEXT:    ret i32 [[R]]
1661   %x = and i32 %p, 7
1662   %m = mul i32 %x, 24
1663   call void @use(i32 %m)
1664   %r = or i32 %m, %x
1665   ret i32 %r
1668 ; negative test - %x and %m may have set 3rd bit
1670 define i32 @mul_common_bits(i32 %p) {
1671 ; CHECK-LABEL: @mul_common_bits(
1672 ; CHECK-NEXT:    [[X:%.*]] = and i32 [[P:%.*]], 7
1673 ; CHECK-NEXT:    [[M:%.*]] = mul nuw nsw i32 [[X]], 12
1674 ; CHECK-NEXT:    [[R:%.*]] = or i32 [[M]], [[X]]
1675 ; CHECK-NEXT:    ret i32 [[R]]
1677   %x = and i32 %p, 7
1678   %m = mul i32 %x, 12
1679   %r = or i32 %m, %x
1680   ret i32 %r
1683 define <4 x i1> @and_or_not_or_logical_vec(<4 x i32> %ap, <4 x i32> %bp) {
1684 ; CHECK-LABEL: @and_or_not_or_logical_vec(
1685 ; CHECK-NEXT:    [[A:%.*]] = icmp ne <4 x i32> [[AP:%.*]], zeroinitializer
1686 ; CHECK-NEXT:    ret <4 x i1> [[A]]
1688   %A = icmp eq <4 x i32> %ap, zeroinitializer
1689   %B = icmp eq <4 x i32> %bp, zeroinitializer
1690   %V = xor <4 x i1> %A, <i1 true, i1 true, i1 true, i1 true>
1691   %X = select <4 x i1> %B, <4 x i1> %V, <4 x i1> zeroinitializer
1692   %W = or <4 x i1> %B, %A
1693   %Y = xor <4 x i1> %W, <i1 true, i1 true, i1 true, i1 true>
1694   %Z = or <4 x i1> %X, %Y
1695   ret <4 x i1> %Z
1698 ; Make sure SimplifyDemandedBits drops the disjoint flag.
1699 define i8 @drop_disjoint(i8 %x) {
1700 ; CHECK-LABEL: @drop_disjoint(
1701 ; CHECK-NEXT:    [[B:%.*]] = or i8 [[X:%.*]], 1
1702 ; CHECK-NEXT:    ret i8 [[B]]
1704   %a = and i8 %x, -2
1705   %b = or disjoint i8 %a, 1
1706   ret i8 %b
1709 ; Make sure we drop disjoint when combining the Ors.
1710 define i32 @assoc_cast_assoc_disjoint(i16 %x) {
1711 ; CHECK-LABEL: @assoc_cast_assoc_disjoint(
1712 ; CHECK-NEXT:    [[B:%.*]] = zext i16 [[X:%.*]] to i32
1713 ; CHECK-NEXT:    [[C:%.*]] = or i32 [[B]], 65537
1714 ; CHECK-NEXT:    ret i32 [[C]]
1716   %a = or i16 %x, 1
1717   %b = zext i16 %a to i32
1718   %c = or disjoint i32 %b, 65536
1719   ret i32 %c
1722 ; (X & C1) | C2 -> X & (C1 | C2) iff (X & C2) == C2
1723 define i32 @test_or_and_disjoint(i32 %a) {
1724 ; CHECK-LABEL: @test_or_and_disjoint(
1725 ; CHECK-NEXT:    [[A0:%.*]] = and i32 [[A:%.*]], 24
1726 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A0]], 8
1727 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1728 ; CHECK:       if.then:
1729 ; CHECK-NEXT:    [[A2:%.*]] = and i32 [[A]], 15
1730 ; CHECK-NEXT:    ret i32 [[A2]]
1731 ; CHECK:       if.else:
1732 ; CHECK-NEXT:    ret i32 0
1734   %a0 = and i32 %a, 24
1735   %cmp = icmp eq i32 %a0, 8
1736   br i1 %cmp, label %if.then, label %if.else
1737 if.then:
1738   %a1 = and i32 %a, 7
1739   %a2 = or i32 %a1, 8
1740   ret i32 %a2
1741 if.else:
1742   ret i32 0
1745 define i32 @test_or_and_mixed(i32 %a) {
1746 ; CHECK-LABEL: @test_or_and_mixed(
1747 ; CHECK-NEXT:    [[A0:%.*]] = and i32 [[A:%.*]], 27
1748 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A0]], 11
1749 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1750 ; CHECK:       if.then:
1751 ; CHECK-NEXT:    [[A2:%.*]] = and i32 [[A]], 15
1752 ; CHECK-NEXT:    ret i32 [[A2]]
1753 ; CHECK:       if.else:
1754 ; CHECK-NEXT:    ret i32 0
1756   %a0 = and i32 %a, 27
1757   %cmp = icmp eq i32 %a0, 11
1758   br i1 %cmp, label %if.then, label %if.else
1759 if.then:
1760   %a1 = and i32 %a, 7
1761   %a2 = or i32 %a1, 11
1762   ret i32 %a2
1763 if.else:
1764   ret i32 0
1767 ; Negative tests
1769 define i32 @test_or_and_disjoint_fail(i32 %a) {
1770 ; CHECK-LABEL: @test_or_and_disjoint_fail(
1771 ; CHECK-NEXT:    [[A0:%.*]] = and i32 [[A:%.*]], 24
1772 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A0]], 16
1773 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1774 ; CHECK:       if.then:
1775 ; CHECK-NEXT:    [[A1:%.*]] = and i32 [[A]], 7
1776 ; CHECK-NEXT:    [[A2:%.*]] = or disjoint i32 [[A1]], 8
1777 ; CHECK-NEXT:    ret i32 [[A2]]
1778 ; CHECK:       if.else:
1779 ; CHECK-NEXT:    ret i32 0
1781   %a0 = and i32 %a, 24
1782   %cmp = icmp eq i32 %a0, 16
1783   br i1 %cmp, label %if.then, label %if.else
1784 if.then:
1785   %a1 = and i32 %a, 7
1786   %a2 = or i32 %a1, 8
1787   ret i32 %a2
1788 if.else:
1789   ret i32 0
1792 define i32 @test_or_and_disjoint_multiuse(i32 %a) {
1793 ; CHECK-LABEL: @test_or_and_disjoint_multiuse(
1794 ; CHECK-NEXT:    [[A0:%.*]] = and i32 [[A:%.*]], 24
1795 ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[A0]], 8
1796 ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
1797 ; CHECK:       if.then:
1798 ; CHECK-NEXT:    [[A1:%.*]] = and i32 [[A]], 7
1799 ; CHECK-NEXT:    call void @use(i32 [[A1]])
1800 ; CHECK-NEXT:    [[A2:%.*]] = or disjoint i32 [[A1]], 8
1801 ; CHECK-NEXT:    ret i32 [[A2]]
1802 ; CHECK:       if.else:
1803 ; CHECK-NEXT:    ret i32 0
1805   %a0 = and i32 %a, 24
1806   %cmp = icmp eq i32 %a0, 8
1807   br i1 %cmp, label %if.then, label %if.else
1808 if.then:
1809   %a1 = and i32 %a, 7
1810   call void @use(i32 %a1)
1811   %a2 = or i32 %a1, 8
1812   ret i32 %a2
1813 if.else:
1814   ret i32 0
1817 ; Tests from PR76554
1818 define i32 @test_or_and_xor_constant(i32 %x, i32 %y) {
1819 ; CHECK-LABEL: @test_or_and_xor_constant(
1820 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[Y:%.*]], [[X:%.*]]
1821 ; CHECK-NEXT:    [[D:%.*]] = and i32 [[TMP1]], -2147483648
1822 ; CHECK-NEXT:    ret i32 [[D]]
1824   %a = and i32 %x, -2147483648
1825   %b = xor i32 %a, -2147483648
1826   %c = and i32 %b, %y
1827   %d = or i32 %c, %a
1828   ret i32 %d
1831 define i32 @test_or_and_xor(i32 %a, i32 %b, i32 %c) {
1832 ; CHECK-LABEL: @test_or_and_xor(
1833 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
1834 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1835 ; CHECK-NEXT:    ret i32 [[OR]]
1837   %xor = xor i32 %a, %b
1838   %and = and i32 %xor, %c
1839   %or = or i32 %and, %a
1840   ret i32 %or
1843 define i32 @test_or_and_xor_commuted1(i32 %a, i32 %b, i32 %c) {
1844 ; CHECK-LABEL: @test_or_and_xor_commuted1(
1845 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
1846 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1847 ; CHECK-NEXT:    ret i32 [[OR]]
1849   %xor = xor i32 %b, %a
1850   %and = and i32 %xor, %c
1851   %or = or i32 %and, %a
1852   ret i32 %or
1855 define i32 @test_or_and_xor_commuted2(i32 %a, i32 %b, i32 %c) {
1856 ; CHECK-LABEL: @test_or_and_xor_commuted2(
1857 ; CHECK-NEXT:    [[CC:%.*]] = mul i32 [[C:%.*]], [[C]]
1858 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[CC]], [[B:%.*]]
1859 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[TMP1]], [[A:%.*]]
1860 ; CHECK-NEXT:    ret i32 [[OR]]
1862   %cc = mul i32 %c, %c
1863   %xor = xor i32 %a, %b
1864   %and = and i32 %cc, %xor
1865   %or = or i32 %and, %a
1866   ret i32 %or
1869 define i32 @test_or_and_xor_commuted3(i32 %a, i32 %b, i32 %c) {
1870 ; CHECK-LABEL: @test_or_and_xor_commuted3(
1871 ; CHECK-NEXT:    [[AA:%.*]] = mul i32 [[A:%.*]], [[A]]
1872 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B:%.*]], [[C:%.*]]
1873 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AA]], [[TMP1]]
1874 ; CHECK-NEXT:    ret i32 [[OR]]
1876   %aa = mul i32 %a, %a
1877   %xor = xor i32 %aa, %b
1878   %and = and i32 %xor, %c
1879   %or = or i32 %aa, %and
1880   ret i32 %or
1883 define i32 @test_or_and_xor_multiuse1(i32 %a, i32 %b, i32 %c) {
1884 ; CHECK-LABEL: @test_or_and_xor_multiuse1(
1885 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1886 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
1887 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[B]], [[C:%.*]]
1888 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[TMP1]], [[A]]
1889 ; CHECK-NEXT:    ret i32 [[OR]]
1891   %xor = xor i32 %a, %b
1892   call void @use(i32 %xor)
1893   %and = and i32 %xor, %c
1894   %or = or i32 %and, %a
1895   ret i32 %or
1898 ; Negative tests
1900 define i32 @test_or_and_xor_mismatched_op(i32 %a, i32 %b, i32 %c, i32 %d) {
1901 ; CHECK-LABEL: @test_or_and_xor_mismatched_op(
1902 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1903 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR]], [[C:%.*]]
1904 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[D:%.*]]
1905 ; CHECK-NEXT:    ret i32 [[OR]]
1907   %xor = xor i32 %a, %b
1908   %and = and i32 %xor, %c
1909   %or = or i32 %and, %d
1910   ret i32 %or
1913 define i32 @test_or_and_xor_multiuse2(i32 %a, i32 %b, i32 %c) {
1914 ; CHECK-LABEL: @test_or_and_xor_multiuse2(
1915 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1916 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[XOR]], [[C:%.*]]
1917 ; CHECK-NEXT:    call void @use(i32 [[AND]])
1918 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[A]]
1919 ; CHECK-NEXT:    ret i32 [[OR]]
1921   %xor = xor i32 %a, %b
1922   %and = and i32 %xor, %c
1923   call void @use(i32 %and)
1924   %or = or i32 %and, %a
1925   ret i32 %or
1928 define i32 @test_or_add_xor(i32 %a, i32 %b, i32 %c) {
1929 ; CHECK-LABEL: @test_or_add_xor(
1930 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[A:%.*]], [[B:%.*]]
1931 ; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[XOR]], [[C:%.*]]
1932 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[ADD]], [[A]]
1933 ; CHECK-NEXT:    ret i32 [[OR]]
1935   %xor = xor i32 %a, %b
1936   %add = add i32 %xor, %c
1937   %or = or i32 %add, %a
1938   ret i32 %or
1941 define i32 @test_or_and_and_multiuse(i32 %a, i32 %b, i32 %c) {
1942 ; CHECK-LABEL: @test_or_and_and_multiuse(
1943 ; CHECK-NEXT:    [[AND1:%.*]] = and i32 [[A:%.*]], [[B:%.*]]
1944 ; CHECK-NEXT:    [[AND2:%.*]] = and i32 [[AND1]], [[C:%.*]]
1945 ; CHECK-NEXT:    call void @use(i32 [[AND1]])
1946 ; CHECK-NEXT:    call void @use(i32 [[AND2]])
1947 ; CHECK-NEXT:    ret i32 [[A]]
1949   %and1 = and i32 %a, %b
1950   %and2 = and i32 %and1, %c
1951   call void @use(i32 %and1)
1952   call void @use(i32 %and2)
1953   %or = or i32 %and2, %a
1954   ret i32 %or
1957 define i32 @or_xor_and(i32 %x, i32 %y, i32 %z) {
1958 ; CHECK-LABEL: @or_xor_and(
1959 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
1960 ; CHECK-NEXT:    ret i32 [[OR1]]
1962   %and = and i32 %y, %z
1963   %xor = xor i32 %x, %and
1964   %or1 = or i32 %xor, %y
1965   ret i32 %or1
1968 define i32 @or_xor_and_uses1(i32 %x, i32 %y, i32 %z) {
1969 ; CHECK-LABEL: @or_xor_and_uses1(
1970 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]]
1971 ; CHECK-NEXT:    call void @use(i32 [[AND]])
1972 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[X:%.*]], [[Y]]
1973 ; CHECK-NEXT:    ret i32 [[OR1]]
1975   %and = and i32 %y, %z
1976   call void @use(i32 %and)
1977   %xor = xor i32 %x, %and
1978   %or1 = or i32 %xor, %y
1979   ret i32 %or1
1982 define i32 @or_xor_and_uses2(i32 %x, i32 %y, i32 %z) {
1983 ; CHECK-LABEL: @or_xor_and_uses2(
1984 ; CHECK-NEXT:    [[AND:%.*]] = and i32 [[Y:%.*]], [[Z:%.*]]
1985 ; CHECK-NEXT:    [[XOR:%.*]] = xor i32 [[X:%.*]], [[AND]]
1986 ; CHECK-NEXT:    call void @use(i32 [[XOR]])
1987 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[X]], [[Y]]
1988 ; CHECK-NEXT:    ret i32 [[OR1]]
1990   %and = and i32 %y, %z
1991   %xor = xor i32 %x, %and
1992   call void @use(i32 %xor)
1993   %or1 = or i32 %xor, %y
1994   ret i32 %or1
1997 define i32 @or_xor_and_commuted1(i32 %x, i32 %y, i32 %z) {
1998 ; CHECK-LABEL: @or_xor_and_commuted1(
1999 ; CHECK-NEXT:    [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
2000 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[YY]], [[X:%.*]]
2001 ; CHECK-NEXT:    ret i32 [[OR1]]
2003   %yy = mul i32 %y, %y ; thwart complexity-based ordering
2004   %and = and i32 %yy, %z
2005   %xor = xor i32 %and, %x
2006   %or1 = or i32 %yy, %xor
2007   ret i32 %or1
2010 define i32 @or_xor_and_commuted2(i32 %x, i32 %y, i32 %z) {
2011 ; CHECK-LABEL: @or_xor_and_commuted2(
2012 ; CHECK-NEXT:    [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
2013 ; CHECK-NEXT:    [[XX:%.*]] = mul i32 [[X:%.*]], [[X]]
2014 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[XX]], [[YY]]
2015 ; CHECK-NEXT:    ret i32 [[OR1]]
2017   %yy = mul i32 %y, %y ; thwart complexity-based ordering
2018   %xx = mul i32 %x, %x ; thwart complexity-based ordering
2019   %and = and i32 %yy, %z
2020   %xor = xor i32 %xx, %and
2021   %or1 = or i32 %xor, %yy
2022   ret i32 %or1
2025 define i32 @or_xor_and_commuted3(i32 %x, i32 %y, i32 %z) {
2026 ; CHECK-LABEL: @or_xor_and_commuted3(
2027 ; CHECK-NEXT:    [[YY:%.*]] = mul i32 [[Y:%.*]], [[Y]]
2028 ; CHECK-NEXT:    [[OR1:%.*]] = or i32 [[X:%.*]], [[YY]]
2029 ; CHECK-NEXT:    ret i32 [[OR1]]
2031   %yy = mul i32 %y, %y ; thwart complexity-based ordering
2032   %zz = mul i32 %z, %z ; thwart complexity-based ordering
2033   %and = and i32 %zz, %yy
2034   %xor = xor i32 %and, %x
2035   %or1 = or i32 %xor, %yy
2036   ret i32 %or1