1; RUN: opt -S -instcombine < %s | FileCheck %s
2
3declare void @use(i32)
4
5; These 18 exercise all combinations of signed comparison
6; for each of the three values produced by your typical
7; 3way compare function (-1, 0, 1)
8
9define void @test_low_sgt(i64 %a, i64 %b) {
10; CHECK-LABEL: @test_low_sgt
11; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
12; CHECK: br i1 [[TMP1]], label %normal, label %unreached
13  %eq = icmp eq i64 %a, %b
14  %slt = icmp slt i64 %a, %b
15  %. = select i1 %slt, i32 -1, i32 1
16  %result = select i1 %eq, i32 0, i32 %.
17  %cmp = icmp sgt i32 %result, -1
18  br i1 %cmp, label %unreached, label %normal
19normal:
20  ret void
21unreached:
22  call void @use(i32 %result)
23  ret void
24}
25
26define void @test_low_slt(i64 %a, i64 %b) {
27; CHECK-LABEL: @test_low_slt
28; CHECK: br i1 false, label %unreached, label %normal
29  %eq = icmp eq i64 %a, %b
30  %slt = icmp slt i64 %a, %b
31  %. = select i1 %slt, i32 -1, i32 1
32  %result = select i1 %eq, i32 0, i32 %.
33  %cmp = icmp slt i32 %result, -1
34  br i1 %cmp, label %unreached, label %normal
35normal:
36  ret void
37unreached:
38  call void @use(i32 %result)
39  ret void
40}
41
42define void @test_low_sge(i64 %a, i64 %b) {
43; CHECK-LABEL: @test_low_sge
44; CHECK: br i1 true, label %unreached, label %normal
45  %eq = icmp eq i64 %a, %b
46  %slt = icmp slt i64 %a, %b
47  %. = select i1 %slt, i32 -1, i32 1
48  %result = select i1 %eq, i32 0, i32 %.
49  %cmp = icmp sge i32 %result, -1
50  br i1 %cmp, label %unreached, label %normal
51normal:
52  ret void
53unreached:
54  call void @use(i32 %result)
55  ret void
56}
57
58define void @test_low_sle(i64 %a, i64 %b) {
59; CHECK-LABEL: @test_low_sle
60; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
61; CHECK: br i1 [[TMP1]], label %unreached, label %normal
62  %eq = icmp eq i64 %a, %b
63  %slt = icmp slt i64 %a, %b
64  %. = select i1 %slt, i32 -1, i32 1
65  %result = select i1 %eq, i32 0, i32 %.
66  %cmp = icmp sle i32 %result, -1
67  br i1 %cmp, label %unreached, label %normal
68normal:
69  ret void
70unreached:
71  call void @use(i32 %result)
72  ret void
73}
74
75define void @test_low_ne(i64 %a, i64 %b) {
76; CHECK-LABEL: @test_low_ne
77; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
78; CHECK: br i1 [[TMP1]], label %normal, label %unreached
79  %eq = icmp eq i64 %a, %b
80  %slt = icmp slt i64 %a, %b
81  %. = select i1 %slt, i32 -1, i32 1
82  %result = select i1 %eq, i32 0, i32 %.
83  %cmp = icmp ne i32 %result, -1
84  br i1 %cmp, label %unreached, label %normal
85normal:
86  ret void
87unreached:
88  call void @use(i32 %result)
89  ret void
90}
91
92define void @test_low_eq(i64 %a, i64 %b) {
93; CHECK-LABEL: @test_low_eq
94; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
95; CHECK: br i1 [[TMP1]], label %unreached, label %normal
96  %eq = icmp eq i64 %a, %b
97  %slt = icmp slt i64 %a, %b
98  %. = select i1 %slt, i32 -1, i32 1
99  %result = select i1 %eq, i32 0, i32 %.
100  %cmp = icmp eq i32 %result, -1
101  br i1 %cmp, label %unreached, label %normal
102normal:
103  ret void
104unreached:
105  call void @use(i32 %result)
106  ret void
107}
108
109define void @test_mid_sgt(i64 %a, i64 %b) {
110; CHECK-LABEL: @test_mid_sgt
111; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
112; CHECK: br i1 [[TMP1]], label %unreached, label %normal
113  %eq = icmp eq i64 %a, %b
114  %slt = icmp slt i64 %a, %b
115  %. = select i1 %slt, i32 -1, i32 1
116  %result = select i1 %eq, i32 0, i32 %.
117  %cmp = icmp sgt i32 %result, 0
118  br i1 %cmp, label %unreached, label %normal
119normal:
120  ret void
121unreached:
122  call void @use(i32 %result)
123  ret void
124}
125
126define void @test_mid_slt(i64 %a, i64 %b) {
127; CHECK-LABEL: @test_mid_slt
128; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
129; CHECK: br i1 [[TMP1]], label %unreached, label %normal
130  %eq = icmp eq i64 %a, %b
131  %slt = icmp slt i64 %a, %b
132  %. = select i1 %slt, i32 -1, i32 1
133  %result = select i1 %eq, i32 0, i32 %.
134  %cmp = icmp slt i32 %result, 0
135  br i1 %cmp, label %unreached, label %normal
136normal:
137  ret void
138unreached:
139  call void @use(i32 %result)
140  ret void
141}
142
143define void @test_mid_sge(i64 %a, i64 %b) {
144; CHECK-LABEL: @test_mid_sge
145; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
146; CHECK: br i1 [[TMP1]], label %normal, label %unreached
147  %eq = icmp eq i64 %a, %b
148  %slt = icmp slt i64 %a, %b
149  %. = select i1 %slt, i32 -1, i32 1
150  %result = select i1 %eq, i32 0, i32 %.
151  %cmp = icmp sge i32 %result, 0
152  br i1 %cmp, label %unreached, label %normal
153normal:
154  ret void
155unreached:
156  call void @use(i32 %result)
157  ret void
158}
159
160define void @test_mid_sle(i64 %a, i64 %b) {
161; CHECK-LABEL: @test_mid_sle
162; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
163; CHECK: br i1 [[TMP1]], label %normal, label %unreached
164  %eq = icmp eq i64 %a, %b
165  %slt = icmp slt i64 %a, %b
166  %. = select i1 %slt, i32 -1, i32 1
167  %result = select i1 %eq, i32 0, i32 %.
168  %cmp = icmp sle i32 %result, 0
169  br i1 %cmp, label %unreached, label %normal
170normal:
171  ret void
172unreached:
173  call void @use(i32 %result)
174  ret void
175}
176
177define void @test_mid_ne(i64 %a, i64 %b) {
178; CHECK-LABEL: @test_mid_ne
179; CHECK: [[TMP1:%.*]] = icmp eq i64 %a, %b
180; CHECK: br i1 [[TMP1]], label %normal, label %unreached
181  %eq = icmp eq i64 %a, %b
182  %slt = icmp slt i64 %a, %b
183  %. = select i1 %slt, i32 -1, i32 1
184  %result = select i1 %eq, i32 0, i32 %.
185  %cmp = icmp ne i32 %result, 0
186  br i1 %cmp, label %unreached, label %normal
187normal:
188  ret void
189unreached:
190  call void @use(i32 %result)
191  ret void
192}
193
194define void @test_mid_eq(i64 %a, i64 %b) {
195; CHECK-LABEL: @test_mid_eq
196; CHECK: icmp eq i64 %a, %b
197; CHECK: br i1 %eq, label %unreached, label %normal
198  %eq = icmp eq i64 %a, %b
199  %slt = icmp slt i64 %a, %b
200  %. = select i1 %slt, i32 -1, i32 1
201  %result = select i1 %eq, i32 0, i32 %.
202  %cmp = icmp eq i32 %result, 0
203  br i1 %cmp, label %unreached, label %normal
204normal:
205  ret void
206unreached:
207  call void @use(i32 %result)
208  ret void
209}
210
211define void @test_high_sgt(i64 %a, i64 %b) {
212; CHECK-LABEL: @test_high_sgt
213; CHECK: br i1 false, label %unreached, label %normal
214  %eq = icmp eq i64 %a, %b
215  %slt = icmp slt i64 %a, %b
216  %. = select i1 %slt, i32 -1, i32 1
217  %result = select i1 %eq, i32 0, i32 %.
218  %cmp = icmp sgt i32 %result, 1
219  br i1 %cmp, label %unreached, label %normal
220normal:
221  ret void
222unreached:
223  call void @use(i32 %result)
224  ret void
225}
226
227define void @test_high_slt(i64 %a, i64 %b) {
228; CHECK-LABEL: @test_high_slt
229; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
230; CHECK: br i1 [[TMP1]], label %normal, label %unreached
231  %eq = icmp eq i64 %a, %b
232  %slt = icmp slt i64 %a, %b
233  %. = select i1 %slt, i32 -1, i32 1
234  %result = select i1 %eq, i32 0, i32 %.
235  %cmp = icmp slt i32 %result, 1
236  br i1 %cmp, label %unreached, label %normal
237normal:
238  ret void
239unreached:
240  call void @use(i32 %result)
241  ret void
242}
243
244define void @test_high_sge(i64 %a, i64 %b) {
245; CHECK-LABEL: @test_high_sge
246; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
247; CHECK: br i1 [[TMP1]], label %unreached, label %normal
248  %eq = icmp eq i64 %a, %b
249  %slt = icmp slt i64 %a, %b
250  %. = select i1 %slt, i32 -1, i32 1
251  %result = select i1 %eq, i32 0, i32 %.
252  %cmp = icmp sge i32 %result, 1
253  br i1 %cmp, label %unreached, label %normal
254normal:
255  ret void
256unreached:
257  call void @use(i32 %result)
258  ret void
259}
260
261define void @test_high_sle(i64 %a, i64 %b) {
262; CHECK-LABEL: @test_high_sle
263; CHECK: br i1 true, label %unreached, label %normal
264  %eq = icmp eq i64 %a, %b
265  %slt = icmp slt i64 %a, %b
266  %. = select i1 %slt, i32 -1, i32 1
267  %result = select i1 %eq, i32 0, i32 %.
268  %cmp = icmp sle i32 %result, 1
269  br i1 %cmp, label %unreached, label %normal
270normal:
271  ret void
272unreached:
273  call void @use(i32 %result)
274  ret void
275}
276
277define void @test_high_ne(i64 %a, i64 %b) {
278; CHECK-LABEL: @test_high_ne
279; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
280; CHECK: br i1 [[TMP1]], label %normal, label %unreached
281  %eq = icmp eq i64 %a, %b
282  %slt = icmp slt i64 %a, %b
283  %. = select i1 %slt, i32 -1, i32 1
284  %result = select i1 %eq, i32 0, i32 %.
285  %cmp = icmp ne i32 %result, 1
286  br i1 %cmp, label %unreached, label %normal
287normal:
288  ret void
289unreached:
290  call void @use(i32 %result)
291  ret void
292}
293
294define void @test_high_eq(i64 %a, i64 %b) {
295; CHECK-LABEL: @test_high_eq
296; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
297; CHECK: br i1 [[TMP1]], label %unreached, label %normal
298  %eq = icmp eq i64 %a, %b
299  %slt = icmp slt i64 %a, %b
300  %. = select i1 %slt, i32 -1, i32 1
301  %result = select i1 %eq, i32 0, i32 %.
302  %cmp = icmp eq i32 %result, 1
303  br i1 %cmp, label %unreached, label %normal
304normal:
305  ret void
306unreached:
307  call void @use(i32 %result)
308  ret void
309}
310
311; These five make sure we didn't accidentally hard code one of the
312; produced values
313
314define void @non_standard_low(i64 %a, i64 %b) {
315; CHECK-LABEL: @non_standard_low
316; CHECK: [[TMP1:%.*]] = icmp slt i64 %a, %b
317; CHECK: br i1 [[TMP1]], label %unreached, label %normal
318  %eq = icmp eq i64 %a, %b
319  %slt = icmp slt i64 %a, %b
320  %. = select i1 %slt, i32 -3, i32 -1
321  %result = select i1 %eq, i32 -2, i32 %.
322  %cmp = icmp eq i32 %result, -3
323  br i1 %cmp, label %unreached, label %normal
324normal:
325  ret void
326unreached:
327  call void @use(i32 %result)
328  ret void
329}
330
331define void @non_standard_mid(i64 %a, i64 %b) {
332; CHECK-LABEL: @non_standard_mid
333; CHECK: icmp eq i64 %a, %b
334; CHECK: br i1 %eq, label %unreached, label %normal
335  %eq = icmp eq i64 %a, %b
336  %slt = icmp slt i64 %a, %b
337  %. = select i1 %slt, i32 -3, i32 -1
338  %result = select i1 %eq, i32 -2, i32 %.
339  %cmp = icmp eq i32 %result, -2
340  br i1 %cmp, label %unreached, label %normal
341normal:
342  ret void
343unreached:
344  call void @use(i32 %result)
345  ret void
346}
347
348define void @non_standard_high(i64 %a, i64 %b) {
349; CHECK-LABEL: @non_standard_high
350; CHECK: [[TMP1:%.*]] = icmp sgt i64 %a, %b
351; CHECK: br i1 [[TMP1]], label %unreached, label %normal
352  %eq = icmp eq i64 %a, %b
353  %slt = icmp slt i64 %a, %b
354  %. = select i1 %slt, i32 -3, i32 -1
355  %result = select i1 %eq, i32 -2, i32 %.
356  %cmp = icmp eq i32 %result, -1
357  br i1 %cmp, label %unreached, label %normal
358normal:
359  ret void
360unreached:
361  call void @use(i32 %result)
362  ret void
363}
364
365define void @non_standard_bound1(i64 %a, i64 %b) {
366; CHECK-LABEL: @non_standard_bound1
367; CHECK: br i1 false, label %unreached, label %normal
368  %eq = icmp eq i64 %a, %b
369  %slt = icmp slt i64 %a, %b
370  %. = select i1 %slt, i32 -3, i32 -1
371  %result = select i1 %eq, i32 -2, i32 %.
372  %cmp = icmp eq i32 %result, -20
373  br i1 %cmp, label %unreached, label %normal
374normal:
375  ret void
376unreached:
377  call void @use(i32 %result)
378  ret void
379}
380
381define void @non_standard_bound2(i64 %a, i64 %b) {
382; CHECK-LABEL: @non_standard_bound2
383; CHECK: br i1 false, label %unreached, label %normal
384  %eq = icmp eq i64 %a, %b
385  %slt = icmp slt i64 %a, %b
386  %. = select i1 %slt, i32 -3, i32 -1
387  %result = select i1 %eq, i32 -2, i32 %.
388  %cmp = icmp eq i32 %result, 0
389  br i1 %cmp, label %unreached, label %normal
390normal:
391  ret void
392unreached:
393  call void @use(i32 %result)
394  ret void
395}
396