[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / and-or-icmps.ll
blob00a720b1da265c78ee1b4c8f6f06192d27efc362
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt < %s -instcombine -S | FileCheck %s
4 declare void @use(i1)
6 define i1 @PR1817_1(i32 %X) {
7 ; CHECK-LABEL: @PR1817_1(
8 ; CHECK-NEXT:    [[B:%.*]] = icmp ult i32 [[X:%.*]], 10
9 ; CHECK-NEXT:    ret i1 [[B]]
11   %A = icmp slt i32 %X, 10
12   %B = icmp ult i32 %X, 10
13   %C = and i1 %A, %B
14   ret i1 %C
17 define i1 @PR1817_1_logical(i32 %X) {
18 ; CHECK-LABEL: @PR1817_1_logical(
19 ; CHECK-NEXT:    [[B:%.*]] = icmp ult i32 [[X:%.*]], 10
20 ; CHECK-NEXT:    ret i1 [[B]]
22   %A = icmp slt i32 %X, 10
23   %B = icmp ult i32 %X, 10
24   %C = select i1 %A, i1 %B, i1 false
25   ret i1 %C
28 define i1 @PR1817_2(i32 %X) {
29 ; CHECK-LABEL: @PR1817_2(
30 ; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[X:%.*]], 10
31 ; CHECK-NEXT:    ret i1 [[A]]
33   %A = icmp slt i32 %X, 10
34   %B = icmp ult i32 %X, 10
35   %C = or i1 %A, %B
36   ret i1 %C
39 define i1 @PR1817_2_logical(i32 %X) {
40 ; CHECK-LABEL: @PR1817_2_logical(
41 ; CHECK-NEXT:    [[A:%.*]] = icmp slt i32 [[X:%.*]], 10
42 ; CHECK-NEXT:    ret i1 [[A]]
44   %A = icmp slt i32 %X, 10
45   %B = icmp ult i32 %X, 10
46   %C = select i1 %A, i1 true, i1 %B
47   ret i1 %C
50 define i1 @PR2330(i32 %a, i32 %b) {
51 ; CHECK-LABEL: @PR2330(
52 ; CHECK-NEXT:    [[TMP1:%.*]] = or i32 [[B:%.*]], [[A:%.*]]
53 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 8
54 ; CHECK-NEXT:    ret i1 [[TMP2]]
56   %cmp1 = icmp ult i32 %a, 8
57   %cmp2 = icmp ult i32 %b, 8
58   %and = and i1 %cmp2, %cmp1
59   ret i1 %and
62 define i1 @PR2330_logical(i32 %a, i32 %b) {
63 ; CHECK-LABEL: @PR2330_logical(
64 ; CHECK-NEXT:    [[CMP1:%.*]] = icmp ult i32 [[A:%.*]], 8
65 ; CHECK-NEXT:    [[CMP2:%.*]] = icmp ult i32 [[B:%.*]], 8
66 ; CHECK-NEXT:    [[AND:%.*]] = select i1 [[CMP2]], i1 [[CMP1]], i1 false
67 ; CHECK-NEXT:    ret i1 [[AND]]
69   %cmp1 = icmp ult i32 %a, 8
70   %cmp2 = icmp ult i32 %b, 8
71   %and = select i1 %cmp2, i1 %cmp1, i1 false
72   ret i1 %and
75 ; if LHSC and RHSC differ only by one bit:
76 ; (X == C1 || X == C2) -> (X & ~(C1 ^ C2)) == C1 (C1 has 1 less set bit)
77 ; PR14708: https://bugs.llvm.org/show_bug.cgi?id=14708
79 define i1 @or_eq_with_one_bit_diff_constants1(i32 %x) {
80 ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants1(
81 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
82 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 50
83 ; CHECK-NEXT:    ret i1 [[TMP2]]
85   %cmp1 = icmp eq i32 %x, 50
86   %cmp2 = icmp eq i32 %x, 51
87   %or = or i1 %cmp1, %cmp2
88   ret i1 %or
91 define i1 @or_eq_with_one_bit_diff_constants1_logical(i32 %x) {
92 ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants1_logical(
93 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
94 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 50
95 ; CHECK-NEXT:    ret i1 [[TMP2]]
97   %cmp1 = icmp eq i32 %x, 50
98   %cmp2 = icmp eq i32 %x, 51
99   %or = select i1 %cmp1, i1 true, i1 %cmp2
100   ret i1 %or
103 ; (X != C1 && X != C2) -> (X & ~(C1 ^ C2)) != C1 (C1 has 1 less set bit)
105 define i1 @and_ne_with_one_bit_diff_constants1(i32 %x) {
106 ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants1(
107 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
108 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 50
109 ; CHECK-NEXT:    ret i1 [[TMP2]]
111   %cmp1 = icmp ne i32 %x, 51
112   %cmp2 = icmp ne i32 %x, 50
113   %and = and i1 %cmp1, %cmp2
114   ret i1 %and
117 define i1 @and_ne_with_one_bit_diff_constants1_logical(i32 %x) {
118 ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants1_logical(
119 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -2
120 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 50
121 ; CHECK-NEXT:    ret i1 [[TMP2]]
123   %cmp1 = icmp ne i32 %x, 51
124   %cmp2 = icmp ne i32 %x, 50
125   %and = select i1 %cmp1, i1 %cmp2, i1 false
126   ret i1 %and
129 ; The constants are not necessarily off-by-one, just off-by-one-bit.
131 define i1 @or_eq_with_one_bit_diff_constants2(i32 %x) {
132 ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2(
133 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -33
134 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 65
135 ; CHECK-NEXT:    ret i1 [[TMP2]]
137   %cmp1 = icmp eq i32 %x, 97
138   %cmp2 = icmp eq i32 %x, 65
139   %or = or i1 %cmp1, %cmp2
140   ret i1 %or
143 define i1 @or_eq_with_one_bit_diff_constants2_logical(i32 %x) {
144 ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2_logical(
145 ; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[X:%.*]], -33
146 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 65
147 ; CHECK-NEXT:    ret i1 [[TMP2]]
149   %cmp1 = icmp eq i32 %x, 97
150   %cmp2 = icmp eq i32 %x, 65
151   %or = select i1 %cmp1, i1 true, i1 %cmp2
152   ret i1 %or
155 define i1 @and_ne_with_one_bit_diff_constants2(i19 %x) {
156 ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants2(
157 ; CHECK-NEXT:    [[TMP1:%.*]] = and i19 [[X:%.*]], -129
158 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i19 [[TMP1]], 65
159 ; CHECK-NEXT:    ret i1 [[TMP2]]
161   %cmp1 = icmp ne i19 %x, 65
162   %cmp2 = icmp ne i19 %x, 193
163   %and = and i1 %cmp1, %cmp2
164   ret i1 %and
167 define i1 @and_ne_with_one_bit_diff_constants2_logical(i19 %x) {
168 ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants2_logical(
169 ; CHECK-NEXT:    [[TMP1:%.*]] = and i19 [[X:%.*]], -129
170 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i19 [[TMP1]], 65
171 ; CHECK-NEXT:    ret i1 [[TMP2]]
173   %cmp1 = icmp ne i19 %x, 65
174   %cmp2 = icmp ne i19 %x, 193
175   %and = select i1 %cmp1, i1 %cmp2, i1 false
176   ret i1 %and
179 ; Make sure the constants are treated as unsigned when comparing them.
181 define i1 @or_eq_with_one_bit_diff_constants3(i8 %x) {
182 ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants3(
183 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], 127
184 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 126
185 ; CHECK-NEXT:    ret i1 [[TMP2]]
187   %cmp1 = icmp eq i8 %x, 254
188   %cmp2 = icmp eq i8 %x, 126
189   %or = or i1 %cmp1, %cmp2
190   ret i1 %or
193 define i1 @or_eq_with_one_bit_diff_constants3_logical(i8 %x) {
194 ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants3_logical(
195 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], 127
196 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 126
197 ; CHECK-NEXT:    ret i1 [[TMP2]]
199   %cmp1 = icmp eq i8 %x, 254
200   %cmp2 = icmp eq i8 %x, 126
201   %or = select i1 %cmp1, i1 true, i1 %cmp2
202   ret i1 %or
205 define i1 @and_ne_with_one_bit_diff_constants3(i8 %x) {
206 ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants3(
207 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], 127
208 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 65
209 ; CHECK-NEXT:    ret i1 [[TMP2]]
211   %cmp1 = icmp ne i8 %x, 65
212   %cmp2 = icmp ne i8 %x, 193
213   %and = and i1 %cmp1, %cmp2
214   ret i1 %and
217 define i1 @and_ne_with_one_bit_diff_constants3_logical(i8 %x) {
218 ; CHECK-LABEL: @and_ne_with_one_bit_diff_constants3_logical(
219 ; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[X:%.*]], 127
220 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ne i8 [[TMP1]], 65
221 ; CHECK-NEXT:    ret i1 [[TMP2]]
223   %cmp1 = icmp ne i8 %x, 65
224   %cmp2 = icmp ne i8 %x, 193
225   %and = select i1 %cmp1, i1 %cmp2, i1 false
226   ret i1 %and
229 ; Use an 'add' to eliminate an icmp if the constants are off-by-one (not off-by-one-bit).
230 ; (X == 13 | X == 14) -> X-13 <u 2
232 define i1 @or_eq_with_diff_one(i8 %x) {
233 ; CHECK-LABEL: @or_eq_with_diff_one(
234 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], -13
235 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], 2
236 ; CHECK-NEXT:    ret i1 [[TMP2]]
238   %cmp1 = icmp eq i8 %x, 13
239   %cmp2 = icmp eq i8 %x, 14
240   %or = or i1 %cmp1, %cmp2
241   ret i1 %or
244 define i1 @or_eq_with_diff_one_logical(i8 %x) {
245 ; CHECK-LABEL: @or_eq_with_diff_one_logical(
246 ; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[X:%.*]], -13
247 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i8 [[TMP1]], 2
248 ; CHECK-NEXT:    ret i1 [[TMP2]]
250   %cmp1 = icmp eq i8 %x, 13
251   %cmp2 = icmp eq i8 %x, 14
252   %or = select i1 %cmp1, i1 true, i1 %cmp2
253   ret i1 %or
256 ; (X != 40 | X != 39) -> X-39 >u 1
258 define i1 @and_ne_with_diff_one(i32 %x) {
259 ; CHECK-LABEL: @and_ne_with_diff_one(
260 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -39
261 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[TMP1]], 1
262 ; CHECK-NEXT:    ret i1 [[TMP2]]
264   %cmp1 = icmp ne i32 %x, 40
265   %cmp2 = icmp ne i32 %x, 39
266   %and = and i1 %cmp1, %cmp2
267   ret i1 %and
270 define i1 @and_ne_with_diff_one_logical(i32 %x) {
271 ; CHECK-LABEL: @and_ne_with_diff_one_logical(
272 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -39
273 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i32 [[TMP1]], 1
274 ; CHECK-NEXT:    ret i1 [[TMP2]]
276   %cmp1 = icmp ne i32 %x, 40
277   %cmp2 = icmp ne i32 %x, 39
278   %and = select i1 %cmp1, i1 %cmp2, i1 false
279   ret i1 %and
282 ; Make sure the constants are treated as signed when comparing them.
283 ; PR32524: https://bugs.llvm.org/show_bug.cgi?id=32524
285 define i1 @or_eq_with_diff_one_signed(i32 %x) {
286 ; CHECK-LABEL: @or_eq_with_diff_one_signed(
287 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1
288 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 2
289 ; CHECK-NEXT:    ret i1 [[TMP2]]
291   %cmp1 = icmp eq i32 %x, 0
292   %cmp2 = icmp eq i32 %x, -1
293   %or = or i1 %cmp1, %cmp2
294   ret i1 %or
297 define i1 @or_eq_with_diff_one_signed_logical(i32 %x) {
298 ; CHECK-LABEL: @or_eq_with_diff_one_signed_logical(
299 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], 1
300 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ult i32 [[TMP1]], 2
301 ; CHECK-NEXT:    ret i1 [[TMP2]]
303   %cmp1 = icmp eq i32 %x, 0
304   %cmp2 = icmp eq i32 %x, -1
305   %or = select i1 %cmp1, i1 true, i1 %cmp2
306   ret i1 %or
309 define i1 @and_ne_with_diff_one_signed(i64 %x) {
310 ; CHECK-LABEL: @and_ne_with_diff_one_signed(
311 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[X:%.*]], 1
312 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], 1
313 ; CHECK-NEXT:    ret i1 [[TMP2]]
315   %cmp1 = icmp ne i64 %x, -1
316   %cmp2 = icmp ne i64 %x, 0
317   %and = and i1 %cmp1, %cmp2
318   ret i1 %and
321 define i1 @and_ne_with_diff_one_signed_logical(i64 %x) {
322 ; CHECK-LABEL: @and_ne_with_diff_one_signed_logical(
323 ; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[X:%.*]], 1
324 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt i64 [[TMP1]], 1
325 ; CHECK-NEXT:    ret i1 [[TMP2]]
327   %cmp1 = icmp ne i64 %x, -1
328   %cmp2 = icmp ne i64 %x, 0
329   %and = select i1 %cmp1, i1 %cmp2, i1 false
330   ret i1 %and
333 ; Vectors with splat constants get the same folds.
335 define <2 x i1> @or_eq_with_one_bit_diff_constants2_splatvec(<2 x i32> %x) {
336 ; CHECK-LABEL: @or_eq_with_one_bit_diff_constants2_splatvec(
337 ; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 -33, i32 -33>
338 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], <i32 65, i32 65>
339 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
341   %cmp1 = icmp eq <2 x i32> %x, <i32 97, i32 97>
342   %cmp2 = icmp eq <2 x i32> %x, <i32 65, i32 65>
343   %or = or <2 x i1> %cmp1, %cmp2
344   ret <2 x i1> %or
347 define <2 x i1> @and_ne_with_diff_one_splatvec(<2 x i32> %x) {
348 ; CHECK-LABEL: @and_ne_with_diff_one_splatvec(
349 ; CHECK-NEXT:    [[TMP1:%.*]] = add <2 x i32> [[X:%.*]], <i32 -39, i32 -39>
350 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp ugt <2 x i32> [[TMP1]], <i32 1, i32 1>
351 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
353   %cmp1 = icmp ne <2 x i32> %x, <i32 40, i32 40>
354   %cmp2 = icmp ne <2 x i32> %x, <i32 39, i32 39>
355   %and = and <2 x i1> %cmp1, %cmp2
356   ret <2 x i1> %and
359 ; This is a fuzzer-generated test that would assert because
360 ; we'd get into foldAndOfICmps() without running InstSimplify
361 ; on an 'and' that should have been killed. It's not obvious
362 ; why, but removing anything hides the bug, hence the long test.
364 define void @simplify_before_foldAndOfICmps() {
365 ; CHECK-LABEL: @simplify_before_foldAndOfICmps(
366 ; CHECK-NEXT:    [[A8:%.*]] = alloca i16, align 2
367 ; CHECK-NEXT:    [[L7:%.*]] = load i16, i16* [[A8]], align 2
368 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i16 [[L7]], -1
369 ; CHECK-NEXT:    [[B11:%.*]] = zext i1 [[TMP1]] to i16
370 ; CHECK-NEXT:    [[C10:%.*]] = icmp ugt i16 [[L7]], [[B11]]
371 ; CHECK-NEXT:    [[C5:%.*]] = icmp slt i16 [[L7]], 1
372 ; CHECK-NEXT:    [[C11:%.*]] = icmp ne i16 [[L7]], 0
373 ; CHECK-NEXT:    [[C7:%.*]] = icmp slt i16 [[L7]], 0
374 ; CHECK-NEXT:    [[B15:%.*]] = xor i1 [[C7]], [[C10]]
375 ; CHECK-NEXT:    [[B19:%.*]] = xor i1 [[C11]], [[B15]]
376 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C10]], [[C5]]
377 ; CHECK-NEXT:    [[C3:%.*]] = and i1 [[TMP2]], [[B19]]
378 ; CHECK-NEXT:    [[TMP3:%.*]] = xor i1 [[C10]], true
379 ; CHECK-NEXT:    [[C18:%.*]] = or i1 [[C7]], [[TMP3]]
380 ; CHECK-NEXT:    [[TMP4:%.*]] = sext i1 [[C3]] to i64
381 ; CHECK-NEXT:    [[G26:%.*]] = getelementptr i1, i1* null, i64 [[TMP4]]
382 ; CHECK-NEXT:    store i16 [[L7]], i16* undef, align 2
383 ; CHECK-NEXT:    store i1 [[C18]], i1* undef, align 1
384 ; CHECK-NEXT:    store i1* [[G26]], i1** undef, align 8
385 ; CHECK-NEXT:    ret void
387   %A8 = alloca i16
388   %L7 = load i16, i16* %A8
389   %G21 = getelementptr i16, i16* %A8, i8 -1
390   %B11 = udiv i16 %L7, -1
391   %G4 = getelementptr i16, i16* %A8, i16 %B11
392   %L2 = load i16, i16* %G4
393   %L = load i16, i16* %G4
394   %B23 = mul i16 %B11, %B11
395   %L4 = load i16, i16* %A8
396   %B21 = sdiv i16 %L7, %L4
397   %B7 = sub i16 0, %B21
398   %B18 = mul i16 %B23, %B7
399   %C10 = icmp ugt i16 %L, %B11
400   %B20 = and i16 %L7, %L2
401   %B1 = mul i1 %C10, true
402   %C5 = icmp sle i16 %B21, %L
403   %C11 = icmp ule i16 %B21, %L
404   %C7 = icmp slt i16 %B20, 0
405   %B29 = srem i16 %L4, %B18
406   %B15 = add i1 %C7, %C10
407   %B19 = add i1 %C11, %B15
408   %C6 = icmp sge i1 %C11, %B19
409   %B33 = or i16 %B29, %L4
410   %C13 = icmp uge i1 %C5, %B1
411   %C3 = icmp ult i1 %C13, %C6
412   store i16 undef, i16* %G21
413   %C18 = icmp ule i1 %C10, %C7
414   %G26 = getelementptr i1, i1* null, i1 %C3
415   store i16 %B33, i16* undef
416   store i1 %C18, i1* undef
417   store i1* %G26, i1** undef
418   ret void
421 define i1 @PR42691_1(i32 %x) {
422 ; CHECK-LABEL: @PR42691_1(
423 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 2147483646
424 ; CHECK-NEXT:    ret i1 [[TMP1]]
426   %c1 = icmp slt i32 %x, 0
427   %c2 = icmp eq i32 %x, 2147483647
428   %c = or i1 %c1, %c2
429   ret i1 %c
432 define i1 @PR42691_1_logical(i32 %x) {
433 ; CHECK-LABEL: @PR42691_1_logical(
434 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X:%.*]], 2147483646
435 ; CHECK-NEXT:    ret i1 [[TMP1]]
437   %c1 = icmp slt i32 %x, 0
438   %c2 = icmp eq i32 %x, 2147483647
439   %c = select i1 %c1, i1 true, i1 %c2
440   ret i1 %c
443 define i1 @PR42691_2(i32 %x) {
444 ; CHECK-LABEL: @PR42691_2(
445 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -2
446 ; CHECK-NEXT:    ret i1 [[TMP1]]
448   %c1 = icmp ult i32 %x, 2147483648
449   %c2 = icmp eq i32 %x, 4294967295
450   %c = or i1 %c1, %c2
451   ret i1 %c
454 define i1 @PR42691_2_logical(i32 %x) {
455 ; CHECK-LABEL: @PR42691_2_logical(
456 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -2
457 ; CHECK-NEXT:    ret i1 [[TMP1]]
459   %c1 = icmp ult i32 %x, 2147483648
460   %c2 = icmp eq i32 %x, 4294967295
461   %c = select i1 %c1, i1 true, i1 %c2
462   ret i1 %c
465 define i1 @PR42691_3(i32 %x) {
466 ; CHECK-LABEL: @PR42691_3(
467 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], -2147483647
468 ; CHECK-NEXT:    ret i1 [[TMP1]]
470   %c1 = icmp sge i32 %x, 0
471   %c2 = icmp eq i32 %x, -2147483648
472   %c = or i1 %c1, %c2
473   ret i1 %c
476 define i1 @PR42691_3_logical(i32 %x) {
477 ; CHECK-LABEL: @PR42691_3_logical(
478 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X:%.*]], -2147483647
479 ; CHECK-NEXT:    ret i1 [[TMP1]]
481   %c1 = icmp sge i32 %x, 0
482   %c2 = icmp eq i32 %x, -2147483648
483   %c = select i1 %c1, i1 true, i1 %c2
484   ret i1 %c
487 define i1 @PR42691_4(i32 %x) {
488 ; CHECK-LABEL: @PR42691_4(
489 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
490 ; CHECK-NEXT:    ret i1 [[TMP1]]
492   %c1 = icmp uge i32 %x, 2147483648
493   %c2 = icmp eq i32 %x, 0
494   %c = or i1 %c1, %c2
495   ret i1 %c
498 define i1 @PR42691_4_logical(i32 %x) {
499 ; CHECK-LABEL: @PR42691_4_logical(
500 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 1
501 ; CHECK-NEXT:    ret i1 [[TMP1]]
503   %c1 = icmp uge i32 %x, 2147483648
504   %c2 = icmp eq i32 %x, 0
505   %c = select i1 %c1, i1 true, i1 %c2
506   ret i1 %c
509 define i1 @PR42691_5(i32 %x) {
510 ; CHECK-LABEL: @PR42691_5(
511 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -1
512 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645
513 ; CHECK-NEXT:    ret i1 [[TMP1]]
515   %c1 = icmp slt i32 %x, 1
516   %c2 = icmp eq i32 %x, 2147483647
517   %c = or i1 %c1, %c2
518   ret i1 %c
521 define i1 @PR42691_5_logical(i32 %x) {
522 ; CHECK-LABEL: @PR42691_5_logical(
523 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -1
524 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645
525 ; CHECK-NEXT:    ret i1 [[TMP1]]
527   %c1 = icmp slt i32 %x, 1
528   %c2 = icmp eq i32 %x, 2147483647
529   %c = select i1 %c1, i1 true, i1 %c2
530   ret i1 %c
533 define i1 @PR42691_6(i32 %x) {
534 ; CHECK-LABEL: @PR42691_6(
535 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647
536 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645
537 ; CHECK-NEXT:    ret i1 [[TMP1]]
539   %c1 = icmp ult i32 %x, 2147483649
540   %c2 = icmp eq i32 %x, 4294967295
541   %c = or i1 %c1, %c2
542   ret i1 %c
545 define i1 @PR42691_6_logical(i32 %x) {
546 ; CHECK-LABEL: @PR42691_6_logical(
547 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647
548 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i32 [[X_OFF]], 2147483645
549 ; CHECK-NEXT:    ret i1 [[TMP1]]
551   %c1 = icmp ult i32 %x, 2147483649
552   %c2 = icmp eq i32 %x, 4294967295
553   %c = select i1 %c1, i1 true, i1 %c2
554   ret i1 %c
557 define i1 @PR42691_7(i32 %x) {
558 ; CHECK-LABEL: @PR42691_7(
559 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -1
560 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
561 ; CHECK-NEXT:    ret i1 [[TMP2]]
563   %c1 = icmp uge i32 %x, 2147483649
564   %c2 = icmp eq i32 %x, 0
565   %c = or i1 %c1, %c2
566   ret i1 %c
569 define i1 @PR42691_7_logical(i32 %x) {
570 ; CHECK-LABEL: @PR42691_7_logical(
571 ; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[X:%.*]], -1
572 ; CHECK-NEXT:    [[TMP2:%.*]] = icmp slt i32 [[TMP1]], 0
573 ; CHECK-NEXT:    ret i1 [[TMP2]]
575   %c1 = icmp uge i32 %x, 2147483649
576   %c2 = icmp eq i32 %x, 0
577   %c = select i1 %c1, i1 true, i1 %c2
578   ret i1 %c
581 define i1 @PR42691_8(i32 %x) {
582 ; CHECK-LABEL: @PR42691_8(
583 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647
584 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -2147483635
585 ; CHECK-NEXT:    ret i1 [[TMP1]]
587   %c1 = icmp slt i32 %x, 14
588   %c2 = icmp ne i32 %x, -2147483648
589   %c = and i1 %c1, %c2
590   ret i1 %c
593 define i1 @PR42691_8_logical(i32 %x) {
594 ; CHECK-LABEL: @PR42691_8_logical(
595 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], 2147483647
596 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -2147483635
597 ; CHECK-NEXT:    ret i1 [[TMP1]]
599   %c1 = icmp slt i32 %x, 14
600   %c2 = icmp ne i32 %x, -2147483648
601   %c = select i1 %c1, i1 %c2, i1 false
602   ret i1 %c
605 define i1 @PR42691_9(i32 %x) {
606 ; CHECK-LABEL: @PR42691_9(
607 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -14
608 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 2147483633
609 ; CHECK-NEXT:    ret i1 [[TMP1]]
611   %c1 = icmp sgt i32 %x, 13
612   %c2 = icmp ne i32 %x, 2147483647
613   %c = and i1 %c1, %c2
614   ret i1 %c
617 define i1 @PR42691_9_logical(i32 %x) {
618 ; CHECK-LABEL: @PR42691_9_logical(
619 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -14
620 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], 2147483633
621 ; CHECK-NEXT:    ret i1 [[TMP1]]
623   %c1 = icmp sgt i32 %x, 13
624   %c2 = icmp ne i32 %x, 2147483647
625   %c = select i1 %c1, i1 %c2, i1 false
626   ret i1 %c
629 define i1 @PR42691_10(i32 %x) {
630 ; CHECK-LABEL: @PR42691_10(
631 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -14
632 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -15
633 ; CHECK-NEXT:    ret i1 [[TMP1]]
635   %c1 = icmp ugt i32 %x, 13
636   %c2 = icmp ne i32 %x, 4294967295
637   %c = and i1 %c1, %c2
638   ret i1 %c
641 define i1 @PR42691_10_logical(i32 %x) {
642 ; CHECK-LABEL: @PR42691_10_logical(
643 ; CHECK-NEXT:    [[X_OFF:%.*]] = add i32 [[X:%.*]], -14
644 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i32 [[X_OFF]], -15
645 ; CHECK-NEXT:    ret i1 [[TMP1]]
647   %c1 = icmp ugt i32 %x, 13
648   %c2 = icmp ne i32 %x, 4294967295
649   %c = select i1 %c1, i1 %c2, i1 false
650   ret i1 %c
653 define i1 @substitute_constant_and_eq_eq(i8 %x, i8 %y) {
654 ; CHECK-LABEL: @substitute_constant_and_eq_eq(
655 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
656 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
657 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
658 ; CHECK-NEXT:    ret i1 [[TMP2]]
660   %c1 = icmp eq i8 %x, 42
661   %c2 = icmp eq i8 %x, %y
662   %r = and i1 %c1, %c2
663   ret i1 %r
666 define i1 @substitute_constant_and_eq_eq_logical(i8 %x, i8 %y) {
667 ; CHECK-LABEL: @substitute_constant_and_eq_eq_logical(
668 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
669 ; CHECK-NEXT:    [[C2:%.*]] = icmp eq i8 [[Y:%.*]], 42
670 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C1]], i1 [[C2]], i1 false
671 ; CHECK-NEXT:    ret i1 [[R]]
673   %c1 = icmp eq i8 %x, 42
674   %c2 = icmp eq i8 %x, %y
675   %r = select i1 %c1, i1 %c2, i1 false
676   ret i1 %r
679 define i1 @substitute_constant_and_eq_eq_commute(i8 %x, i8 %y) {
680 ; CHECK-LABEL: @substitute_constant_and_eq_eq_commute(
681 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
682 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
683 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
684 ; CHECK-NEXT:    ret i1 [[TMP2]]
686   %c1 = icmp eq i8 %x, 42
687   %c2 = icmp eq i8 %x, %y
688   %r = and i1 %c2, %c1
689   ret i1 %r
692 define i1 @substitute_constant_and_eq_eq_commute_logical(i8 %x, i8 %y) {
693 ; CHECK-LABEL: @substitute_constant_and_eq_eq_commute_logical(
694 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
695 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], 42
696 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
697 ; CHECK-NEXT:    ret i1 [[TMP2]]
699   %c1 = icmp eq i8 %x, 42
700   %c2 = icmp eq i8 %x, %y
701   %r = select i1 %c2, i1 %c1, i1 false
702   ret i1 %r
705 define i1 @substitute_constant_and_eq_ugt_swap(i8 %x, i8 %y) {
706 ; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap(
707 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
708 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 42
709 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
710 ; CHECK-NEXT:    ret i1 [[TMP2]]
712   %c1 = icmp eq i8 %x, 42
713   %c2 = icmp ugt i8 %y, %x
714   %r = and i1 %c2, %c1
715   ret i1 %r
718 define i1 @substitute_constant_and_eq_ugt_swap_logical(i8 %x, i8 %y) {
719 ; CHECK-LABEL: @substitute_constant_and_eq_ugt_swap_logical(
720 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
721 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 42
722 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
723 ; CHECK-NEXT:    ret i1 [[TMP2]]
725   %c1 = icmp eq i8 %x, 42
726   %c2 = icmp ugt i8 %y, %x
727   %r = select i1 %c2, i1 %c1, i1 false
728   ret i1 %r
731 define <2 x i1> @substitute_constant_and_eq_ne_vec(<2 x i8> %x, <2 x i8> %y) {
732 ; CHECK-LABEL: @substitute_constant_and_eq_ne_vec(
733 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq <2 x i8> [[X:%.*]], <i8 42, i8 97>
734 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne <2 x i8> [[Y:%.*]], <i8 42, i8 97>
735 ; CHECK-NEXT:    [[TMP2:%.*]] = and <2 x i1> [[C1]], [[TMP1]]
736 ; CHECK-NEXT:    ret <2 x i1> [[TMP2]]
738   %c1 = icmp eq <2 x i8> %x, <i8 42, i8 97>
739   %c2 = icmp ne <2 x i8> %x, %y
740   %r = and <2 x i1> %c1, %c2
741   ret <2 x i1> %r
744 define i1 @substitute_constant_and_eq_sgt_use(i8 %x, i8 %y) {
745 ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use(
746 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
747 ; CHECK-NEXT:    call void @use(i1 [[C1]])
748 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 42
749 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
750 ; CHECK-NEXT:    ret i1 [[TMP2]]
752   %c1 = icmp eq i8 %x, 42
753   call void @use(i1 %c1)
754   %c2 = icmp sgt i8 %x, %y
755   %r = and i1 %c2, %c1
756   ret i1 %r
759 define i1 @substitute_constant_and_eq_sgt_use_logical(i8 %x, i8 %y) {
760 ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use_logical(
761 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
762 ; CHECK-NEXT:    call void @use(i1 [[C1]])
763 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 42
764 ; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[C1]], [[TMP1]]
765 ; CHECK-NEXT:    ret i1 [[TMP2]]
767   %c1 = icmp eq i8 %x, 42
768   call void @use(i1 %c1)
769   %c2 = icmp sgt i8 %x, %y
770   %r = select i1 %c2, i1 %c1, i1 false
771   ret i1 %r
774 ; Negative test - extra use
776 define i1 @substitute_constant_and_eq_sgt_use2(i8 %x, i8 %y) {
777 ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use2(
778 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
779 ; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i8 [[X]], [[Y:%.*]]
780 ; CHECK-NEXT:    call void @use(i1 [[C2]])
781 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
782 ; CHECK-NEXT:    ret i1 [[R]]
784   %c1 = icmp eq i8 %x, 42
785   %c2 = icmp sgt i8 %x, %y
786   call void @use(i1 %c2)
787   %r = and i1 %c2, %c1
788   ret i1 %r
791 define i1 @substitute_constant_and_eq_sgt_use2_logical(i8 %x, i8 %y) {
792 ; CHECK-LABEL: @substitute_constant_and_eq_sgt_use2_logical(
793 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
794 ; CHECK-NEXT:    [[C2:%.*]] = icmp sgt i8 [[X]], [[Y:%.*]]
795 ; CHECK-NEXT:    call void @use(i1 [[C2]])
796 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
797 ; CHECK-NEXT:    ret i1 [[R]]
799   %c1 = icmp eq i8 %x, 42
800   %c2 = icmp sgt i8 %x, %y
801   call void @use(i1 %c2)
802   %r = select i1 %c2, i1 %c1, i1 false
803   ret i1 %r
806 ; Extra use does not prevent transform if the expression simplifies:
807 ; X == MAX && X < Y --> false
809 define i1 @slt_and_max(i8 %x, i8 %y)  {
810 ; CHECK-LABEL: @slt_and_max(
811 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
812 ; CHECK-NEXT:    call void @use(i1 [[C2]])
813 ; CHECK-NEXT:    ret i1 false
815   %c1 = icmp eq i8 %x, 127
816   %c2 = icmp slt i8 %x, %y
817   call void @use(i1 %c2)
818   %r = and i1 %c2, %c1
819   ret i1 %r
822 define i1 @slt_and_max_logical(i8 %x, i8 %y)  {
823 ; CHECK-LABEL: @slt_and_max_logical(
824 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i8 [[X:%.*]], [[Y:%.*]]
825 ; CHECK-NEXT:    call void @use(i1 [[C2]])
826 ; CHECK-NEXT:    ret i1 false
828   %c1 = icmp eq i8 %x, 127
829   %c2 = icmp slt i8 %x, %y
830   call void @use(i1 %c2)
831   %r = select i1 %c2, i1 %c1, i1 false
832   ret i1 %r
835 ; Extra use does not prevent transform if the expression simplifies:
836 ; X == MAX && X >= Y --> X == MAX
838 define i1 @sge_and_max(i8 %x, i8 %y)  {
839 ; CHECK-LABEL: @sge_and_max(
840 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127
841 ; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]]
842 ; CHECK-NEXT:    call void @use(i1 [[C2]])
843 ; CHECK-NEXT:    ret i1 [[C1]]
845   %c1 = icmp eq i8 %x, 127
846   %c2 = icmp sge i8 %x, %y
847   call void @use(i1 %c2)
848   %r = and i1 %c2, %c1
849   ret i1 %r
852 define i1 @sge_and_max_logical(i8 %x, i8 %y)  {
853 ; CHECK-LABEL: @sge_and_max_logical(
854 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 127
855 ; CHECK-NEXT:    [[C2:%.*]] = icmp sge i8 [[X]], [[Y:%.*]]
856 ; CHECK-NEXT:    call void @use(i1 [[C2]])
857 ; CHECK-NEXT:    ret i1 [[C1]]
859   %c1 = icmp eq i8 %x, 127
860   %c2 = icmp sge i8 %x, %y
861   call void @use(i1 %c2)
862   %r = select i1 %c2, i1 %c1, i1 false
863   ret i1 %r
866 define i1 @substitute_constant_and_ne_ugt_swap(i8 %x, i8 %y) {
867 ; CHECK-LABEL: @substitute_constant_and_ne_ugt_swap(
868 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
869 ; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[Y:%.*]], [[X]]
870 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
871 ; CHECK-NEXT:    ret i1 [[R]]
873   %c1 = icmp ne i8 %x, 42
874   %c2 = icmp ugt i8 %y, %x
875   %r = and i1 %c2, %c1
876   ret i1 %r
879 define i1 @substitute_constant_and_ne_ugt_swap_logical(i8 %x, i8 %y) {
880 ; CHECK-LABEL: @substitute_constant_and_ne_ugt_swap_logical(
881 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
882 ; CHECK-NEXT:    [[C2:%.*]] = icmp ugt i8 [[Y:%.*]], [[X]]
883 ; CHECK-NEXT:    [[R:%.*]] = and i1 [[C2]], [[C1]]
884 ; CHECK-NEXT:    ret i1 [[R]]
886   %c1 = icmp ne i8 %x, 42
887   %c2 = icmp ugt i8 %y, %x
888   %r = select i1 %c2, i1 %c1, i1 false
889   ret i1 %r
892 define i1 @substitute_constant_or_ne_swap_sle(i8 %x, i8 %y) {
893 ; CHECK-LABEL: @substitute_constant_or_ne_swap_sle(
894 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
895 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
896 ; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
897 ; CHECK-NEXT:    ret i1 [[TMP2]]
899   %c1 = icmp ne i8 %x, 42
900   %c2 = icmp sle i8 %y, %x
901   %r = or i1 %c1, %c2
902   ret i1 %r
905 define i1 @substitute_constant_or_ne_swap_sle_logical(i8 %x, i8 %y) {
906 ; CHECK-LABEL: @substitute_constant_or_ne_swap_sle_logical(
907 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
908 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt i8 [[Y:%.*]], 43
909 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
910 ; CHECK-NEXT:    ret i1 [[R]]
912   %c1 = icmp ne i8 %x, 42
913   %c2 = icmp sle i8 %y, %x
914   %r = select i1 %c1, i1 true, i1 %c2
915   ret i1 %r
918 define i1 @substitute_constant_or_ne_uge_commute(i8 %x, i8 %y) {
919 ; CHECK-LABEL: @substitute_constant_or_ne_uge_commute(
920 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
921 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], 43
922 ; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
923 ; CHECK-NEXT:    ret i1 [[TMP2]]
925   %c1 = icmp ne i8 %x, 42
926   %c2 = icmp uge i8 %x, %y
927   %r = or i1 %c2, %c1
928   ret i1 %r
931 define i1 @substitute_constant_or_ne_uge_commute_logical(i8 %x, i8 %y) {
932 ; CHECK-LABEL: @substitute_constant_or_ne_uge_commute_logical(
933 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
934 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp ult i8 [[Y:%.*]], 43
935 ; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
936 ; CHECK-NEXT:    ret i1 [[TMP2]]
938   %c1 = icmp ne i8 %x, 42
939   %c2 = icmp uge i8 %x, %y
940   %r = select i1 %c2, i1 true, i1 %c1
941   ret i1 %r
944 ; Negative test - not safe to substitute vector constant with undef element
946 define <2 x i1> @substitute_constant_or_ne_slt_swap_vec(<2 x i8> %x, <2 x i8> %y) {
947 ; CHECK-LABEL: @substitute_constant_or_ne_slt_swap_vec(
948 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne <2 x i8> [[X:%.*]], <i8 42, i8 undef>
949 ; CHECK-NEXT:    [[C2:%.*]] = icmp slt <2 x i8> [[Y:%.*]], [[X]]
950 ; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[C1]], [[C2]]
951 ; CHECK-NEXT:    ret <2 x i1> [[R]]
953   %c1 = icmp ne <2 x i8> %x, <i8 42, i8 undef>
954   %c2 = icmp slt <2 x i8> %y, %x
955   %r = or <2 x i1> %c1, %c2
956   ret <2 x i1> %r
959 define i1 @substitute_constant_or_eq_swap_ne(i8 %x, i8 %y) {
960 ; CHECK-LABEL: @substitute_constant_or_eq_swap_ne(
961 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
962 ; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 [[Y:%.*]], [[X]]
963 ; CHECK-NEXT:    [[R:%.*]] = or i1 [[C1]], [[C2]]
964 ; CHECK-NEXT:    ret i1 [[R]]
966   %c1 = icmp eq i8 %x, 42
967   %c2 = icmp ne i8 %y, %x
968   %r = or i1 %c1, %c2
969   ret i1 %r
972 define i1 @substitute_constant_or_eq_swap_ne_logical(i8 %x, i8 %y) {
973 ; CHECK-LABEL: @substitute_constant_or_eq_swap_ne_logical(
974 ; CHECK-NEXT:    [[C1:%.*]] = icmp eq i8 [[X:%.*]], 42
975 ; CHECK-NEXT:    [[C2:%.*]] = icmp ne i8 [[Y:%.*]], [[X]]
976 ; CHECK-NEXT:    [[R:%.*]] = select i1 [[C1]], i1 true, i1 [[C2]]
977 ; CHECK-NEXT:    ret i1 [[R]]
979   %c1 = icmp eq i8 %x, 42
980   %c2 = icmp ne i8 %y, %x
981   %r = select i1 %c1, i1 true, i1 %c2
982   ret i1 %r
985 define i1 @substitute_constant_or_ne_sge_use(i8 %x, i8 %y) {
986 ; CHECK-LABEL: @substitute_constant_or_ne_sge_use(
987 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
988 ; CHECK-NEXT:    call void @use(i1 [[C1]])
989 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
990 ; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
991 ; CHECK-NEXT:    ret i1 [[TMP2]]
993   %c1 = icmp ne i8 %x, 42
994   call void @use(i1 %c1)
995   %c2 = icmp sge i8 %x, %y
996   %r = or i1 %c2, %c1
997   ret i1 %r
1000 define i1 @substitute_constant_or_ne_sge_use_logical(i8 %x, i8 %y) {
1001 ; CHECK-LABEL: @substitute_constant_or_ne_sge_use_logical(
1002 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
1003 ; CHECK-NEXT:    call void @use(i1 [[C1]])
1004 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[Y:%.*]], 43
1005 ; CHECK-NEXT:    [[TMP2:%.*]] = or i1 [[C1]], [[TMP1]]
1006 ; CHECK-NEXT:    ret i1 [[TMP2]]
1008   %c1 = icmp ne i8 %x, 42
1009   call void @use(i1 %c1)
1010   %c2 = icmp sge i8 %x, %y
1011   %r = select i1 %c2, i1 true, i1 %c1
1012   ret i1 %r
1015 ; Negative test - extra use
1017 define i1 @substitute_constant_or_ne_ule_use2(i8 %x, i8 %y) {
1018 ; CHECK-LABEL: @substitute_constant_or_ne_ule_use2(
1019 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
1020 ; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[X]], [[Y:%.*]]
1021 ; CHECK-NEXT:    call void @use(i1 [[C2]])
1022 ; CHECK-NEXT:    [[R:%.*]] = or i1 [[C2]], [[C1]]
1023 ; CHECK-NEXT:    ret i1 [[R]]
1025   %c1 = icmp ne i8 %x, 42
1026   %c2 = icmp ule i8 %x, %y
1027   call void @use(i1 %c2)
1028   %r = or i1 %c2, %c1
1029   ret i1 %r
1032 define i1 @substitute_constant_or_ne_ule_use2_logical(i8 %x, i8 %y) {
1033 ; CHECK-LABEL: @substitute_constant_or_ne_ule_use2_logical(
1034 ; CHECK-NEXT:    [[C1:%.*]] = icmp ne i8 [[X:%.*]], 42
1035 ; CHECK-NEXT:    [[C2:%.*]] = icmp ule i8 [[X]], [[Y:%.*]]
1036 ; CHECK-NEXT:    call void @use(i1 [[C2]])
1037 ; CHECK-NEXT:    [[R:%.*]] = or i1 [[C2]], [[C1]]
1038 ; CHECK-NEXT:    ret i1 [[R]]
1040   %c1 = icmp ne i8 %x, 42
1041   %c2 = icmp ule i8 %x, %y
1042   call void @use(i1 %c2)
1043   %r = select i1 %c2, i1 true, i1 %c1
1044   ret i1 %r