1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt < %s -instcombine -S | FileCheck %s
3
4target 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"
5
6declare void @foo(i32 %x)
7
8define i32 @compare_against_arbitrary_value(i32 %x, i32 %c) {
9; CHECK-LABEL: @compare_against_arbitrary_value(
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
12; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
13; CHECK:       callfoo:
14; CHECK-NEXT:    call void @foo(i32 1)
15; CHECK-NEXT:    br label [[EXIT]]
16; CHECK:       exit:
17; CHECK-NEXT:    ret i32 42
18;
19
20entry:
21  %cmp1 = icmp eq i32 %x, %c
22  %cmp2 = icmp slt i32 %x, %c
23  %select1 = select i1 %cmp2, i32 -1, i32 1
24  %select2 = select i1 %cmp1, i32 0, i32 %select1
25  %cond = icmp sgt i32 %select2, 0
26  br i1 %cond, label %callfoo, label %exit
27
28callfoo:
29  call void @foo(i32 %select2)
30  br label %exit
31
32exit:
33  ret i32 42
34}
35
36define i32 @compare_against_zero(i32 %x) {
37; CHECK-LABEL: @compare_against_zero(
38; CHECK-NEXT:  entry:
39; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
40; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
41; CHECK:       callfoo:
42; CHECK-NEXT:    call void @foo(i32 1)
43; CHECK-NEXT:    br label [[EXIT]]
44; CHECK:       exit:
45; CHECK-NEXT:    ret i32 42
46;
47
48entry:
49  %cmp1 = icmp eq i32 %x, 0
50  %cmp2 = icmp slt i32 %x, 0
51  %select1 = select i1 %cmp2, i32 -1, i32 1
52  %select2 = select i1 %cmp1, i32 0, i32 %select1
53  %cond = icmp sgt i32 %select2, 0
54  br i1 %cond, label %callfoo, label %exit
55
56callfoo:
57  call void @foo(i32 %select2)
58  br label %exit
59
60exit:
61  ret i32 42
62}
63
64define i32 @compare_against_one(i32 %x) {
65; CHECK-LABEL: @compare_against_one(
66; CHECK-NEXT:  entry:
67; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 1
68; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
69; CHECK:       callfoo:
70; CHECK-NEXT:    call void @foo(i32 1)
71; CHECK-NEXT:    br label [[EXIT]]
72; CHECK:       exit:
73; CHECK-NEXT:    ret i32 42
74;
75
76entry:
77  %cmp1 = icmp eq i32 %x, 1
78  %cmp2 = icmp slt i32 %x, 1
79  %select1 = select i1 %cmp2, i32 -1, i32 1
80  %select2 = select i1 %cmp1, i32 0, i32 %select1
81  %cond = icmp sgt i32 %select2, 0
82  br i1 %cond, label %callfoo, label %exit
83
84callfoo:
85  call void @foo(i32 %select2)
86  br label %exit
87
88exit:
89  ret i32 42
90}
91
92define i32 @compare_against_two(i32 %x) {
93; CHECK-LABEL: @compare_against_two(
94; CHECK-NEXT:  entry:
95; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 2
96; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
97; CHECK:       callfoo:
98; CHECK-NEXT:    call void @foo(i32 1)
99; CHECK-NEXT:    br label [[EXIT]]
100; CHECK:       exit:
101; CHECK-NEXT:    ret i32 42
102;
103
104entry:
105  %cmp1 = icmp eq i32 %x, 2
106  %cmp2 = icmp slt i32 %x, 2
107  %select1 = select i1 %cmp2, i32 -1, i32 1
108  %select2 = select i1 %cmp1, i32 0, i32 %select1
109  %cond = icmp sgt i32 %select2, 0
110  br i1 %cond, label %callfoo, label %exit
111
112callfoo:
113  call void @foo(i32 %select2)
114  br label %exit
115
116exit:
117  ret i32 42
118}
119
120define i32 @compare_against_three(i32 %x) {
121; CHECK-LABEL: @compare_against_three(
122; CHECK-NEXT:  entry:
123; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 3
124; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
125; CHECK:       callfoo:
126; CHECK-NEXT:    call void @foo(i32 1)
127; CHECK-NEXT:    br label [[EXIT]]
128; CHECK:       exit:
129; CHECK-NEXT:    ret i32 42
130;
131
132entry:
133  %cmp1 = icmp eq i32 %x, 3
134  %cmp2 = icmp slt i32 %x, 3
135  %select1 = select i1 %cmp2, i32 -1, i32 1
136  %select2 = select i1 %cmp1, i32 0, i32 %select1
137  %cond = icmp sgt i32 %select2, 0
138  br i1 %cond, label %callfoo, label %exit
139
140callfoo:
141  call void @foo(i32 %select2)
142  br label %exit
143
144exit:
145  ret i32 42
146}
147
148define i32 @compare_against_four(i32 %x) {
149; CHECK-LABEL: @compare_against_four(
150; CHECK-NEXT:  entry:
151; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 4
152; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
153; CHECK:       callfoo:
154; CHECK-NEXT:    call void @foo(i32 1)
155; CHECK-NEXT:    br label [[EXIT]]
156; CHECK:       exit:
157; CHECK-NEXT:    ret i32 42
158;
159
160entry:
161  %cmp1 = icmp eq i32 %x, 4
162  %cmp2 = icmp slt i32 %x, 4
163  %select1 = select i1 %cmp2, i32 -1, i32 1
164  %select2 = select i1 %cmp1, i32 0, i32 %select1
165  %cond = icmp sgt i32 %select2, 0
166  br i1 %cond, label %callfoo, label %exit
167
168callfoo:
169  call void @foo(i32 %select2)
170  br label %exit
171
172exit:
173  ret i32 42
174}
175
176define i32 @compare_against_five(i32 %x) {
177; CHECK-LABEL: @compare_against_five(
178; CHECK-NEXT:  entry:
179; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 5
180; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
181; CHECK:       callfoo:
182; CHECK-NEXT:    call void @foo(i32 1)
183; CHECK-NEXT:    br label [[EXIT]]
184; CHECK:       exit:
185; CHECK-NEXT:    ret i32 42
186;
187
188entry:
189  %cmp1 = icmp eq i32 %x, 5
190  %cmp2 = icmp slt i32 %x, 5
191  %select1 = select i1 %cmp2, i32 -1, i32 1
192  %select2 = select i1 %cmp1, i32 0, i32 %select1
193  %cond = icmp sgt i32 %select2, 0
194  br i1 %cond, label %callfoo, label %exit
195
196callfoo:
197  call void @foo(i32 %select2)
198  br label %exit
199
200exit:
201  ret i32 42
202}
203
204define i32 @compare_against_six(i32 %x) {
205; CHECK-LABEL: @compare_against_six(
206; CHECK-NEXT:  entry:
207; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 6
208; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
209; CHECK:       callfoo:
210; CHECK-NEXT:    call void @foo(i32 1)
211; CHECK-NEXT:    br label [[EXIT]]
212; CHECK:       exit:
213; CHECK-NEXT:    ret i32 42
214;
215
216entry:
217  %cmp1 = icmp eq i32 %x, 6
218  %cmp2 = icmp slt i32 %x, 6
219  %select1 = select i1 %cmp2, i32 -1, i32 1
220  %select2 = select i1 %cmp1, i32 0, i32 %select1
221  %cond = icmp sgt i32 %select2, 0
222  br i1 %cond, label %callfoo, label %exit
223
224callfoo:
225  call void @foo(i32 %select2)
226  br label %exit
227
228exit:
229  ret i32 42
230}
231
232; Same as @compare_against_arbitrary_value, but now the three-way comparison
233; returns not idiomatic comparator's result (-1, 0, 1) but some other constants.
234define i32 @compare_against_arbitrary_value_non_idiomatic_1(i32 %x, i32 %c) {
235; CHECK-LABEL: @compare_against_arbitrary_value_non_idiomatic_1(
236; CHECK-NEXT:  entry:
237; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
238; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
239; CHECK:       callfoo:
240; CHECK-NEXT:    call void @foo(i32 425)
241; CHECK-NEXT:    br label [[EXIT]]
242; CHECK:       exit:
243; CHECK-NEXT:    ret i32 42
244;
245
246entry:
247  %cmp1 = icmp eq i32 %x, %c
248  %cmp2 = icmp slt i32 %x, %c
249  %select1 = select i1 %cmp2, i32 -6, i32 425
250  %select2 = select i1 %cmp1, i32 0, i32 %select1
251  %cond = icmp sgt i32 %select2, 0
252  br i1 %cond, label %callfoo, label %exit
253
254callfoo:
255  call void @foo(i32 %select2)
256  br label %exit
257
258exit:
259  ret i32 42
260}
261
262define i32 @compare_against_zero_non_idiomatic_add(i32 %x) {
263; CHECK-LABEL: @compare_against_zero_non_idiomatic_add(
264; CHECK-NEXT:  entry:
265; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
266; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
267; CHECK:       callfoo:
268; CHECK-NEXT:    call void @foo(i32 425)
269; CHECK-NEXT:    br label [[EXIT]]
270; CHECK:       exit:
271; CHECK-NEXT:    ret i32 42
272;
273
274entry:
275  %cmp1 = icmp eq i32 %x, 0
276  %cmp2 = icmp slt i32 %x, 0
277  %select1 = select i1 %cmp2, i32 -6, i32 425
278  %select2 = select i1 %cmp1, i32 0, i32 %select1
279  %cond = icmp sgt i32 %select2, 0
280  br i1 %cond, label %callfoo, label %exit
281
282callfoo:
283  call void @foo(i32 %select2)
284  br label %exit
285
286exit:
287  ret i32 42
288}
289
290; Same as @compare_against_arbitrary_value, but now the three-way comparison
291; returns not idiomatic comparator's result (-1, 0, 1) but some other constants.
292define i32 @compare_against_arbitrary_value_non_idiomatic_2(i32 %x, i32 %c) {
293; CHECK-LABEL: @compare_against_arbitrary_value_non_idiomatic_2(
294; CHECK-NEXT:  entry:
295; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
296; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
297; CHECK:       callfoo:
298; CHECK-NEXT:    call void @foo(i32 425)
299; CHECK-NEXT:    br label [[EXIT]]
300; CHECK:       exit:
301; CHECK-NEXT:    ret i32 42
302;
303
304entry:
305  %cmp1 = icmp eq i32 %x, %c
306  %cmp2 = icmp slt i32 %x, %c
307  %select1 = select i1 %cmp2, i32 -5, i32 425
308  %select2 = select i1 %cmp1, i32 0, i32 %select1
309  %cond = icmp sgt i32 %select2, 0
310  br i1 %cond, label %callfoo, label %exit
311
312callfoo:
313  call void @foo(i32 %select2)
314  br label %exit
315
316exit:
317  ret i32 42
318}
319
320define i32 @compare_against_zero_non_idiomatic_or(i32 %x) {
321; CHECK-LABEL: @compare_against_zero_non_idiomatic_or(
322; CHECK-NEXT:  entry:
323; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 0
324; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
325; CHECK:       callfoo:
326; CHECK-NEXT:    call void @foo(i32 425)
327; CHECK-NEXT:    br label [[EXIT]]
328; CHECK:       exit:
329; CHECK-NEXT:    ret i32 42
330;
331
332entry:
333  %cmp1 = icmp eq i32 %x, 0
334  %cmp2 = icmp slt i32 %x, 0
335  %select1 = select i1 %cmp2, i32 -5, i32 425
336  %select2 = select i1 %cmp1, i32 0, i32 %select1
337  %cond = icmp sgt i32 %select2, 0
338  br i1 %cond, label %callfoo, label %exit
339
340callfoo:
341  call void @foo(i32 %select2)
342  br label %exit
343
344exit:
345  ret i32 42
346}
347
348define i32 @compare_against_arbitrary_value_type_mismatch(i64 %x, i64 %c) {
349; CHECK-LABEL: @compare_against_arbitrary_value_type_mismatch(
350; CHECK-NEXT:  entry:
351; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], [[C:%.*]]
352; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
353; CHECK:       callfoo:
354; CHECK-NEXT:    call void @foo(i32 1)
355; CHECK-NEXT:    br label [[EXIT]]
356; CHECK:       exit:
357; CHECK-NEXT:    ret i32 42
358;
359
360entry:
361  %cmp1 = icmp eq i64 %x, %c
362  %cmp2 = icmp slt i64 %x, %c
363  %select1 = select i1 %cmp2, i32 -1, i32 1
364  %select2 = select i1 %cmp1, i32 0, i32 %select1
365  %cond = icmp sgt i32 %select2, 0
366  br i1 %cond, label %callfoo, label %exit
367
368callfoo:
369  call void @foo(i32 %select2)
370  br label %exit
371
372exit:
373  ret i32 42
374}
375
376define i32 @compare_against_zero_type_mismatch_idiomatic(i64 %x) {
377; CHECK-LABEL: @compare_against_zero_type_mismatch_idiomatic(
378; CHECK-NEXT:  entry:
379; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
380; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
381; CHECK:       callfoo:
382; CHECK-NEXT:    call void @foo(i32 1)
383; CHECK-NEXT:    br label [[EXIT]]
384; CHECK:       exit:
385; CHECK-NEXT:    ret i32 42
386;
387
388entry:
389  %cmp1 = icmp eq i64 %x, 0
390  %cmp2 = icmp slt i64 %x, 0
391  %select1 = select i1 %cmp2, i32 -1, i32 1
392  %select2 = select i1 %cmp1, i32 0, i32 %select1
393  %cond = icmp sgt i32 %select2, 0
394  br i1 %cond, label %callfoo, label %exit
395
396callfoo:
397  call void @foo(i32 %select2)
398  br label %exit
399
400exit:
401  ret i32 42
402}
403
404define i32 @compare_against_zero_type_mismatch_non_idiomatic_1(i64 %x) {
405; CHECK-LABEL: @compare_against_zero_type_mismatch_non_idiomatic_1(
406; CHECK-NEXT:  entry:
407; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
408; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
409; CHECK:       callfoo:
410; CHECK-NEXT:    call void @foo(i32 1)
411; CHECK-NEXT:    br label [[EXIT]]
412; CHECK:       exit:
413; CHECK-NEXT:    ret i32 42
414;
415
416entry:
417  %cmp1 = icmp eq i64 %x, 0
418  %cmp2 = icmp slt i64 %x, 0
419  %select1 = select i1 %cmp2, i32 -7, i32 1
420  %select2 = select i1 %cmp1, i32 0, i32 %select1
421  %cond = icmp sgt i32 %select2, 0
422  br i1 %cond, label %callfoo, label %exit
423
424callfoo:
425  call void @foo(i32 %select2)
426  br label %exit
427
428exit:
429  ret i32 42
430}
431
432define i32 @compare_against_zero_type_mismatch_non_idiomatic_2(i64 %x) {
433; CHECK-LABEL: @compare_against_zero_type_mismatch_non_idiomatic_2(
434; CHECK-NEXT:  entry:
435; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i64 [[X:%.*]], 0
436; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
437; CHECK:       callfoo:
438; CHECK-NEXT:    call void @foo(i32 1)
439; CHECK-NEXT:    br label [[EXIT]]
440; CHECK:       exit:
441; CHECK-NEXT:    ret i32 42
442;
443
444entry:
445  %cmp1 = icmp eq i64 %x, 0
446  %cmp2 = icmp slt i64 %x, 0
447  %select1 = select i1 %cmp2, i32 -6, i32 1
448  %select2 = select i1 %cmp1, i32 0, i32 %select1
449  %cond = icmp sgt i32 %select2, 0
450  br i1 %cond, label %callfoo, label %exit
451
452callfoo:
453  call void @foo(i32 %select2)
454  br label %exit
455
456exit:
457  ret i32 42
458}
459
460declare void @use1(i1)
461define i32 @compare_against_fortytwo_commutatibility_0(i32 %x) {
462; CHECK-LABEL: @compare_against_fortytwo_commutatibility_0(
463; CHECK-NEXT:  entry:
464; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 42
465; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
466; CHECK:       callfoo:
467; CHECK-NEXT:    call void @foo(i32 1)
468; CHECK-NEXT:    br label [[EXIT]]
469; CHECK:       exit:
470; CHECK-NEXT:    ret i32 84
471;
472entry:
473  %cmp1 = icmp eq i32 %x, 42
474  %cmp2 = icmp slt i32 %x, 42
475  %select1 = select i1 %cmp2, i32 -1, i32 1
476  %select2 = select i1 %cmp1, i32 0, i32 %select1
477  %cond = icmp sgt i32 %select2, 0
478  br i1 %cond, label %callfoo, label %exit
479
480callfoo:
481  call void @foo(i32 %select2)
482  br label %exit
483
484exit:
485  ret i32 84
486}
487define i32 @compare_against_fortytwo_commutatibility_1(i32 %x) {
488; CHECK-LABEL: @compare_against_fortytwo_commutatibility_1(
489; CHECK-NEXT:  entry:
490; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], 42
491; CHECK-NEXT:    call void @use1(i1 [[CMP1]])
492; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X]], 42
493; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
494; CHECK:       callfoo:
495; CHECK-NEXT:    call void @foo(i32 1)
496; CHECK-NEXT:    br label [[EXIT]]
497; CHECK:       exit:
498; CHECK-NEXT:    ret i32 84
499;
500entry:
501  %cmp1 = icmp ne i32 %x, 42 ; inverted
502  call void @use1(i1 %cmp1)
503  %cmp2 = icmp slt i32 %x, 42
504  %select1 = select i1 %cmp2, i32 -1, i32 1
505  %select2 = select i1 %cmp1, i32 %select1, i32 0 ; swapped
506  %cond = icmp sgt i32 %select2, 0
507  br i1 %cond, label %callfoo, label %exit
508
509callfoo:
510  call void @foo(i32 %select2)
511  br label %exit
512
513exit:
514  ret i32 84
515}
516define i32 @compare_against_fortytwo_commutatibility_2(i32 %x) {
517; CHECK-LABEL: @compare_against_fortytwo_commutatibility_2(
518; CHECK-NEXT:  entry:
519; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], 42
520; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
521; CHECK:       callfoo:
522; CHECK-NEXT:    call void @foo(i32 1)
523; CHECK-NEXT:    br label [[EXIT]]
524; CHECK:       exit:
525; CHECK-NEXT:    ret i32 84
526;
527entry:
528  %cmp1 = icmp eq i32 %x, 42
529  %cmp2 = icmp sgt i32 %x, 41 ; inverted
530  %select1 = select i1 %cmp2, i32 1, i32 -1 ; swapped
531  %select2 = select i1 %cmp1, i32 0, i32 %select1
532  %cond = icmp sgt i32 %select2, 0
533  br i1 %cond, label %callfoo, label %exit
534
535callfoo:
536  call void @foo(i32 %select2)
537  br label %exit
538
539exit:
540  ret i32 84
541}
542define i32 @compare_against_fortytwo_commutatibility_3(i32 %x) {
543; CHECK-LABEL: @compare_against_fortytwo_commutatibility_3(
544; CHECK-NEXT:  entry:
545; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], 42
546; CHECK-NEXT:    call void @use1(i1 [[CMP1]])
547; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X]], 42
548; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
549; CHECK:       callfoo:
550; CHECK-NEXT:    call void @foo(i32 1)
551; CHECK-NEXT:    br label [[EXIT]]
552; CHECK:       exit:
553; CHECK-NEXT:    ret i32 84
554;
555entry:
556  %cmp1 = icmp ne i32 %x, 42 ; inverted
557  call void @use1(i1 %cmp1)
558  %cmp2 = icmp sgt i32 %x, 41 ; inverted
559  %select1 = select i1 %cmp2, i32 1, i32 -1 ; swapped
560  %select2 = select i1 %cmp1, i32 %select1, i32 0 ; swapped
561  %cond = icmp sgt i32 %select2, 0
562  br i1 %cond, label %callfoo, label %exit
563
564callfoo:
565  call void @foo(i32 %select2)
566  br label %exit
567
568exit:
569  ret i32 84
570}
571
572define i32 @compare_against_arbitrary_value_commutativity0(i32 %x, i32 %c) {
573; CHECK-LABEL: @compare_against_arbitrary_value_commutativity0(
574; CHECK-NEXT:  entry:
575; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
576; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
577; CHECK:       callfoo:
578; CHECK-NEXT:    call void @foo(i32 1)
579; CHECK-NEXT:    br label [[EXIT]]
580; CHECK:       exit:
581; CHECK-NEXT:    ret i32 42
582;
583entry:
584  %cmp1 = icmp eq i32 %x, %c
585  %cmp2 = icmp slt i32 %x, %c
586  %select1 = select i1 %cmp2, i32 -1, i32 1
587  %select2 = select i1 %cmp1, i32 0, i32 %select1
588  %cond = icmp sgt i32 %select2, 0
589  br i1 %cond, label %callfoo, label %exit
590
591callfoo:
592  call void @foo(i32 %select2)
593  br label %exit
594
595exit:
596  ret i32 42
597}
598define i32 @compare_against_arbitrary_value_commutativity1(i32 %x, i32 %c) {
599; CHECK-LABEL: @compare_against_arbitrary_value_commutativity1(
600; CHECK-NEXT:  entry:
601; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X:%.*]], [[C:%.*]]
602; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
603; CHECK:       callfoo:
604; CHECK-NEXT:    call void @foo(i32 1)
605; CHECK-NEXT:    br label [[EXIT]]
606; CHECK:       exit:
607; CHECK-NEXT:    ret i32 42
608;
609entry:
610  %cmp1 = icmp eq i32 %x, %c
611  %cmp2 = icmp sgt i32 %c, %x ; swapped
612  %select1 = select i1 %cmp2, i32 -1, i32 1
613  %select2 = select i1 %cmp1, i32 0, i32 %select1
614  %cond = icmp sgt i32 %select2, 0
615  br i1 %cond, label %callfoo, label %exit
616
617callfoo:
618  call void @foo(i32 %select2)
619  br label %exit
620
621exit:
622  ret i32 42
623}
624define i32 @compare_against_arbitrary_value_commutativity2(i32 %x, i32 %c) {
625; CHECK-LABEL: @compare_against_arbitrary_value_commutativity2(
626; CHECK-NEXT:  entry:
627; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], [[C:%.*]]
628; CHECK-NEXT:    call void @use1(i1 [[CMP1]])
629; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X]], [[C]]
630; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
631; CHECK:       callfoo:
632; CHECK-NEXT:    call void @foo(i32 1)
633; CHECK-NEXT:    br label [[EXIT]]
634; CHECK:       exit:
635; CHECK-NEXT:    ret i32 42
636;
637entry:
638  %cmp1 = icmp ne i32 %x, %c ; inverted
639  call void @use1(i1 %cmp1)
640  %cmp2 = icmp slt i32 %x, %c
641  %select1 = select i1 %cmp2, i32 -1, i32 1
642  %select2 = select i1 %cmp1, i32 %select1, i32 0 ; swapped
643  %cond = icmp sgt i32 %select2, 0
644  br i1 %cond, label %callfoo, label %exit
645
646callfoo:
647  call void @foo(i32 %select2)
648  br label %exit
649
650exit:
651  ret i32 42
652}
653define i32 @compare_against_arbitrary_value_commutativity3(i32 %x, i32 %c) {
654; CHECK-LABEL: @compare_against_arbitrary_value_commutativity3(
655; CHECK-NEXT:  entry:
656; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[X:%.*]], [[C:%.*]]
657; CHECK-NEXT:    call void @use1(i1 [[CMP1]])
658; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[X]], [[C]]
659; CHECK-NEXT:    br i1 [[TMP0]], label [[CALLFOO:%.*]], label [[EXIT:%.*]]
660; CHECK:       callfoo:
661; CHECK-NEXT:    call void @foo(i32 1)
662; CHECK-NEXT:    br label [[EXIT]]
663; CHECK:       exit:
664; CHECK-NEXT:    ret i32 42
665;
666entry:
667  %cmp1 = icmp ne i32 %x, %c ; inverted
668  call void @use1(i1 %cmp1)
669  %cmp2 = icmp sgt i32 %c, %x ; swapped
670  %select1 = select i1 %cmp2, i32 -1, i32 1
671  %select2 = select i1 %cmp1, i32 %select1, i32 0 ; swapped
672  %cond = icmp sgt i32 %select2, 0
673  br i1 %cond, label %callfoo, label %exit
674
675callfoo:
676  call void @foo(i32 %select2)
677  br label %exit
678
679exit:
680  ret i32 42
681}
682