xref: /llvm-project/llvm/test/Transforms/InstCombine/or.ll (revision 97298853b4de70dbce9c0a140ac38e3ac179e02e)
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
4
5target 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"
6declare void @use(i32)
7
8; Should be eliminated
9define i32 @test12(i32 %A) {
10; CHECK-LABEL: @test12(
11; CHECK-NEXT:    [[C:%.*]] = and i32 [[A:%.*]], 8
12; CHECK-NEXT:    ret i32 [[C]]
13;
14  %B = or i32 %A, 4
15  %C = and i32 %B, 8
16  ret i32 %C
17}
18
19define i32 @test13(i32 %A) {
20; CHECK-LABEL: @test13(
21; CHECK-NEXT:    ret i32 8
22;
23  %B = or i32 %A, 12
24  ; Always equal to 8
25  %C = and i32 %B, 8
26  ret i32 %C
27}
28
29define 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]]
33;
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
39}
40
41define 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]]
45;
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
51}
52
53define 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]]
57;
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
63}
64
65define 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]]
69;
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
75}
76
77define 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]]
81;
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
87}
88
89define i32 @test16(i32 %A) {
90; CHECK-LABEL: @test16(
91; CHECK-NEXT:    ret i32 [[A:%.*]]
92;
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
99}
100
101define i32 @test17(i32 %A) {
102; CHECK-LABEL: @test17(
103; CHECK-NEXT:    [[D:%.*]] = and i32 [[A:%.*]], 5
104; CHECK-NEXT:    ret i32 [[D]]
105;
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
111}
112
113define 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]]
118;
119  %B = icmp sge i32 %A, 100
120  %C = icmp slt i32 %A, 50
121  %D = or i1 %B, %C
122  ret i1 %D
123}
124
125define 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]]
130;
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
135}
136
137define <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]]
142;
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
147}
148
149define i32 @test20(i32 %x) {
150; CHECK-LABEL: @test20(
151; CHECK-NEXT:    ret i32 [[X:%.*]]
152;
153  %y = and i32 %x, 123
154  %z = or i32 %y, %x
155  ret i32 %z
156}
157
158; TODO: This should combine to t1 + 2.
159define 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]]
166;
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
173}
174
175define i32 @test22(i32 %B) {
176; CHECK-LABEL: @test22(
177; CHECK-NEXT:    ret i32 [[B:%.*]]
178;
179  %ELIM41 = and i32 %B, 1
180  %ELIM7 = and i32 %B, -2
181  %ELIM5 = or i32 %ELIM41, %ELIM7
182  ret i32 %ELIM5
183}
184
185define 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]]
190;
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
196}
197
198define <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]]
203;
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
209}
210
211; PR3266 & PR5276
212define 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]]
218;
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
224}
225
226define 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]]
232;
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
238}
239
240; PR5634
241define 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]]
246;
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
252}
253
254define <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]]
259;
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
264}
265
266define <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]]
271;
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
276}
277
278define <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]]
283;
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
288}
289
290define 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]]
296;
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
302}
303
304define 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]]
310;
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
316}
317
318define <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]]
324;
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
330}
331
332; PR5634
333define 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]]
338;
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
344}
345
346define 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]]
352;
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
358}
359
360define 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]]
366;
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
372}
373
374define <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]]
380;
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
386}
387
388; PR4216
389define 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]]
394;
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
400}
401
402define <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]]
407;
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]]
412;
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
418}
419
420; PR4216
421define 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]]
426;
427  %B = or i64 %A, 194
428  %D = and i64 %B, 250
429
430  %C = or i64 %A, 32768
431  %E = and i64 %C, 4294941696
432
433  %F = or i64 %D, %E
434  ret i64 %F
435}
436
437define <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]]
442;
443  %B = or <2 x i64> %A, <i64 194, i64 194>
444  %D = and <2 x i64> %B, <i64 250, i64 250>
445
446  %C = or <2 x i64> %A, <i64 32768, i64 32768>
447  %E = and <2 x i64> %C, <i64 4294941696, i64 4294941696>
448
449  %F = or <2 x i64> %D, %E
450  ret <2 x i64> %F
451}
452
453; codegen is mature enough to handle vector selects.
454define <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]]
458;
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
465}
466
467define i1 @test33(i1 %X, i1 %Y) {
468; CHECK-LABEL: @test33(
469; CHECK-NEXT:    [[A:%.*]] = or i1 [[X:%.*]], [[Y:%.*]]
470; CHECK-NEXT:    ret i1 [[A]]
471;
472  %a = or i1 %X, %Y
473  %b = or i1 %a, %X
474  ret i1 %b
475}
476
477define 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]]
481;
482  %a = select i1 %X, i1 true, i1 %Y
483  %b = select i1 %a, i1 true, i1 %X
484  ret i1 %b
485}
486
487define i32 @test34(i32 %X, i32 %Y) {
488; CHECK-LABEL: @test34(
489; CHECK-NEXT:    [[A:%.*]] = or i32 [[X:%.*]], [[Y:%.*]]
490; CHECK-NEXT:    ret i32 [[A]]
491;
492  %a = or i32 %X, %Y
493  %b = or i32 %Y, %a
494  ret i32 %b
495}
496
497define 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]]
502;
503  %1 = or i32 %a, 1135
504  %2 = or i32 %1, %b
505  ret i32 %2
506}
507
508define 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]]
513;
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
520}
521
522define 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]]
527;
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
534}
535
536define 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]]
541;
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
547}
548
549define 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]]
554;
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
560}
561
562define <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]]
567;
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
573}
574
575define <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]]
582;
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
588}
589
590define 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]]
595;
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
601}
602
603define 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]]
608;
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
614}
615
616define <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]]
623;
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
629}
630
631; (~A & B) | A --> A | B
632
633define 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]]
639;
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
646}
647
648; Commute 'and' operands:
649; (B & ~A) | A --> A | B
650
651define 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]]
657;
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
664}
665
666; Commute 'or' operands:
667; A | (~A & B) --> A | B
668
669define 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]]
675;
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
682}
683
684; Commute 'and' operands:
685; A | (B & ~A) --> A | B
686
687define 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]]
693;
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
700}
701
702define 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]]
707;
708  %and = and i32 %a, %b
709  %xor = xor i32 %a, -1
710  %or = or i32 %and, %xor
711  ret i32 %or
712}
713
714define 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]]
719;
720  %and = and i32 %b, %a
721  %xor = xor i32 %a, -1
722  %or = or i32 %and, %xor
723  ret i32 %or
724}
725
726define 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]]
731;
732  %and = and i32 %b, %a
733  %xor = xor i32 %a, -1
734  %or = or i32 %xor, %and
735  ret i32 %or
736}
737
738define 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]]
743;
744  %and = and i32 %a, %b
745  %xor = xor i32 %a, -1
746  %or = or i32 %xor, %and
747  ret i32 %or
748}
749
750define 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]]
755;
756  %or = or i32 %y, %z
757  %and = and i32 %x, %or
758  %or1 = or i32 %and, %y
759  ret i32 %or1
760}
761
762define 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]]
769;
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
775}
776
777define 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]]
784;
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
790}
791
792define 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]]
798;
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
804}
805
806define 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]]
813;
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
820}
821
822define 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]]
829;
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
836}
837
838define 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]]
844;
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
851}
852
853define 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]]
859;
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
866}
867
868define <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]]
874;
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
881}
882
883define <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]]
891;
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
898}
899
900; This is the variant of the above pattern where one of the ranges is
901; represented with an add.
902define 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]]
907;
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
914}
915
916define 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]]
922;
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
929}
930
931define 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]]
937;
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
944}
945
946define <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]]
954;
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
961}
962
963define 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]]
967;
968  %A = select i1 %C, i32 1000, i32 10
969  %V = or i32 %A, 123
970  ret i32 %V
971}
972
973define <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]]
977;
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
981}
982
983define <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]]
987;
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
991}
992
993define 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]]
1002;
1003entry:
1004  br i1 %which, label %final, label %delay
1005
1006delay:
1007  br label %final
1008
1009final:
1010  %A = phi i32 [ 1000, %entry ], [ 10, %delay ]
1011  %value = or i32 %A, 123
1012  ret i32 %value
1013}
1014
1015define <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]]
1024;
1025entry:
1026  br i1 %which, label %final, label %delay
1027
1028delay:
1029  br label %final
1030
1031final:
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
1035}
1036
1037define <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]]
1046;
1047entry:
1048  br i1 %which, label %final, label %delay
1049
1050delay:
1051  br label %final
1052
1053final:
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
1057}
1058
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
1061
1062define 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]]
1068;
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
1075}
1076
1077define 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]]
1083;
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
1090}
1091
1092; Commute the 'or':
1093; ((Y & ~X) | X) -> (X | Y), where 'not' is an inverted cmp
1094
1095define <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]]
1101;
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
1108}
1109
1110; Commute the 'and':
1111; (X | (~X & Y)) -> (X | Y), where 'not' is an inverted cmp
1112
1113define 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]]
1119;
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
1126}
1127
1128define 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]]
1134;
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
1141}
1142
1143; Commute the 'or':
1144; ((~X & Y) | X) -> (X | Y), where 'not' is an inverted cmp
1145
1146define <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]]
1152;
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
1159}
1160
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
1163
1164define 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]]
1170;
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
1177}
1178
1179define 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]]
1185;
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
1192}
1193
1194; Commute the 'or':
1195; ((Y & X) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1196
1197define 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]]
1203;
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
1210}
1211
1212define 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]]
1218;
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
1225}
1226
1227; Commute the 'and':
1228; (~X | (X & Y)) -> (~X | Y), where 'not' is an inverted cmp
1229
1230define <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]]
1236;
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
1243}
1244
1245; Commute the 'or':
1246; ((X & Y) | ~X) -> (~X | Y), where 'not' is an inverted cmp
1247
1248define 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]]
1254;
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
1261}
1262
1263define 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]]
1269;
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
1276}
1277
1278; The constant vectors are inverses. Make sure we can turn this into a select without crashing trying to truncate the constant to 16xi1.
1279define <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]]
1283;
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
1288}
1289
1290; This would infinite loop because it reaches a transform
1291; that was not expecting a constant-foldable value.
1292
1293define 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]]
1304;
1305entry:
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
1311
1312true:
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
1318
1319end:
1320  %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1321  %conv8 = zext i1 %t5 to i32
1322  ret i32 %conv8
1323}
1324
1325define 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]]
1336;
1337entry:
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
1343
1344true:
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
1350
1351end:
1352  %t5 = phi i1 [ 0, %entry ], [ %sel, %true ]
1353  %conv8 = zext i1 %t5 to i32
1354  ret i32 %conv8
1355}
1356
1357; (~x & y) | ~(x | y) --> ~x
1358define i32 @PR38929(i32 %0, i32 %1) {
1359; CHECK-LABEL: @PR38929(
1360; CHECK-NEXT:    [[TMP3:%.*]] = xor i32 [[TMP0:%.*]], -1
1361; CHECK-NEXT:    ret i32 [[TMP3]]
1362;
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
1369}
1370
1371define 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]]
1376;
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
1382}
1383
1384define 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]]
1389;
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
1395}
1396
1397define 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]]
1402;
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
1408}
1409
1410define <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]]
1415;
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
1421}
1422
1423define 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]]
1431;
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
1438}
1439
1440define 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]]
1447;
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
1454}
1455define 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]]
1464;
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
1472}
1473
1474define 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]]
1479;
1480  %sign = ashr i8 %x, 7
1481  %r = or i8 %sign, %y
1482  ret i8 %r
1483}
1484
1485define <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]]
1491;
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
1496}
1497
1498define 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]]
1504;
1505  %sign = ashr i32 %x, 7
1506  call void @use(i32 %sign)
1507  %r = or i32 %sign, %y
1508  ret i32 %r
1509}
1510
1511define 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]]
1516;
1517  %sign = ashr i8 %x, 6
1518  %r = or i8 %sign, %y
1519  ret i8 %r
1520}
1521
1522define 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]]
1527;
1528  %sign = lshr i8 %x, 7
1529  %r = or i8 %sign, %y
1530  ret i8 %r
1531}
1532
1533define 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]]
1537;
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
1543}
1544
1545define <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]]
1549;
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
1555}
1556
1557define 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]]
1564;
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
1570}
1571
1572define 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]]
1577;
1578  %x = and i32 %p, 7
1579  %m = mul i32 %x, 24
1580  %r = or i32 %m, %x
1581  ret i32 %r
1582}
1583
1584define <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]]
1589;
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
1594}
1595
1596define 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]]
1603;
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
1609}
1610
1611define 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]]
1616;
1617  %m = mul i32 %x, %y
1618  %r = or disjoint i32 %m, %x
1619  ret i32 %r
1620}
1621
1622define 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]]
1626;
1627  %m = mul i32 %x, 24
1628  %r = or disjoint i32 %m, %x
1629  ret i32 %r
1630}
1631
1632; negative test - extra use requires extra instructions
1633
1634define 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]]
1642;
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
1649}
1650
1651; negative test - probably not good to create an extra mul
1652
1653define 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]]
1660;
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
1666}
1667
1668; negative test - %x and %m may have set 3rd bit
1669
1670define 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]]
1676;
1677  %x = and i32 %p, 7
1678  %m = mul i32 %x, 12
1679  %r = or i32 %m, %x
1680  ret i32 %r
1681}
1682
1683define <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]]
1687;
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
1696}
1697
1698; Make sure SimplifyDemandedBits drops the disjoint flag.
1699define i8 @drop_disjoint(i8 %x) {
1700; CHECK-LABEL: @drop_disjoint(
1701; CHECK-NEXT:    [[B:%.*]] = or i8 [[X:%.*]], 1
1702; CHECK-NEXT:    ret i8 [[B]]
1703;
1704  %a = and i8 %x, -2
1705  %b = or disjoint i8 %a, 1
1706  ret i8 %b
1707}
1708
1709; Make sure we drop disjoint when combining the Ors.
1710define 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]]
1715;
1716  %a = or i16 %x, 1
1717  %b = zext i16 %a to i32
1718  %c = or disjoint i32 %b, 65536
1719  ret i32 %c
1720}
1721
1722; (X & C1) | C2 -> X & (C1 | C2) iff (X & C2) == C2
1723define 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
1733;
1734  %a0 = and i32 %a, 24
1735  %cmp = icmp eq i32 %a0, 8
1736  br i1 %cmp, label %if.then, label %if.else
1737if.then:
1738  %a1 = and i32 %a, 7
1739  %a2 = or i32 %a1, 8
1740  ret i32 %a2
1741if.else:
1742  ret i32 0
1743}
1744
1745define 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
1755;
1756  %a0 = and i32 %a, 27
1757  %cmp = icmp eq i32 %a0, 11
1758  br i1 %cmp, label %if.then, label %if.else
1759if.then:
1760  %a1 = and i32 %a, 7
1761  %a2 = or i32 %a1, 11
1762  ret i32 %a2
1763if.else:
1764  ret i32 0
1765}
1766
1767; Negative tests
1768
1769define 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
1780;
1781  %a0 = and i32 %a, 24
1782  %cmp = icmp eq i32 %a0, 16
1783  br i1 %cmp, label %if.then, label %if.else
1784if.then:
1785  %a1 = and i32 %a, 7
1786  %a2 = or i32 %a1, 8
1787  ret i32 %a2
1788if.else:
1789  ret i32 0
1790}
1791
1792define 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
1804;
1805  %a0 = and i32 %a, 24
1806  %cmp = icmp eq i32 %a0, 8
1807  br i1 %cmp, label %if.then, label %if.else
1808if.then:
1809  %a1 = and i32 %a, 7
1810  call void @use(i32 %a1)
1811  %a2 = or i32 %a1, 8
1812  ret i32 %a2
1813if.else:
1814  ret i32 0
1815}
1816
1817; Tests from PR76554
1818define 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]]
1823;
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
1829}
1830
1831define 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]]
1836;
1837  %xor = xor i32 %a, %b
1838  %and = and i32 %xor, %c
1839  %or = or i32 %and, %a
1840  ret i32 %or
1841}
1842
1843define 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]]
1848;
1849  %xor = xor i32 %b, %a
1850  %and = and i32 %xor, %c
1851  %or = or i32 %and, %a
1852  ret i32 %or
1853}
1854
1855define 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]]
1861;
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
1867}
1868
1869define 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]]
1875;
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
1881}
1882
1883define 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]]
1890;
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
1896}
1897
1898; Negative tests
1899
1900define 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]]
1906;
1907  %xor = xor i32 %a, %b
1908  %and = and i32 %xor, %c
1909  %or = or i32 %and, %d
1910  ret i32 %or
1911}
1912
1913define 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]]
1920;
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
1926}
1927
1928define 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]]
1934;
1935  %xor = xor i32 %a, %b
1936  %add = add i32 %xor, %c
1937  %or = or i32 %add, %a
1938  ret i32 %or
1939}
1940
1941define 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]]
1948;
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
1955}
1956
1957define 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]]
1961;
1962  %and = and i32 %y, %z
1963  %xor = xor i32 %x, %and
1964  %or1 = or i32 %xor, %y
1965  ret i32 %or1
1966}
1967
1968define 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]]
1974;
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
1980}
1981
1982define 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]]
1989;
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
1995}
1996
1997define 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]]
2002;
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
2008}
2009
2010define 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]]
2016;
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
2023}
2024
2025define 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]]
2030;
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
2037}
2038