[DAGCombiner] Add target hook function to decide folding (mul (add x, c1), c2)
[llvm-project.git] / llvm / test / Transforms / InstCombine / compare-3way.ll
blob663d470df87457d686b333fc3564e339c1620047
1 ; RUN: opt -S -instcombine < %s | FileCheck %s
3 declare void @use(i32)
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)
9 define 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
19 normal:
20   ret void
21 unreached:
22   call void @use(i32 %result)
23   ret void
26 define 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
35 normal:
36   ret void
37 unreached:
38   call void @use(i32 %result)
39   ret void
42 define 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
51 normal:
52   ret void
53 unreached:
54   call void @use(i32 %result)
55   ret void
58 define 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
68 normal:
69   ret void
70 unreached:
71   call void @use(i32 %result)
72   ret void
75 define 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
85 normal:
86   ret void
87 unreached:
88   call void @use(i32 %result)
89   ret void
92 define 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
102 normal:
103   ret void
104 unreached:
105   call void @use(i32 %result)
106   ret void
109 define 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
119 normal:
120   ret void
121 unreached:
122   call void @use(i32 %result)
123   ret void
126 define 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
136 normal:
137   ret void
138 unreached:
139   call void @use(i32 %result)
140   ret void
143 define 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
153 normal:
154   ret void
155 unreached:
156   call void @use(i32 %result)
157   ret void
160 define 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
170 normal:
171   ret void
172 unreached:
173   call void @use(i32 %result)
174   ret void
177 define 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
187 normal:
188   ret void
189 unreached:
190   call void @use(i32 %result)
191   ret void
194 define 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
204 normal:
205   ret void
206 unreached:
207   call void @use(i32 %result)
208   ret void
211 define 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
220 normal:
221   ret void
222 unreached:
223   call void @use(i32 %result)
224   ret void
227 define 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
237 normal:
238   ret void
239 unreached:
240   call void @use(i32 %result)
241   ret void
244 define 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
254 normal:
255   ret void
256 unreached:
257   call void @use(i32 %result)
258   ret void
261 define 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
270 normal:
271   ret void
272 unreached:
273   call void @use(i32 %result)
274   ret void
277 define 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
287 normal:
288   ret void
289 unreached:
290   call void @use(i32 %result)
291   ret void
294 define 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
304 normal:
305   ret void
306 unreached:
307   call void @use(i32 %result)
308   ret void
311 ; These five make sure we didn't accidentally hard code one of the
312 ; produced values
314 define 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
324 normal:
325   ret void
326 unreached:
327   call void @use(i32 %result)
328   ret void
331 define 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
341 normal:
342   ret void
343 unreached:
344   call void @use(i32 %result)
345   ret void
348 define 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
358 normal:
359   ret void
360 unreached:
361   call void @use(i32 %result)
362   ret void
365 define 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
374 normal:
375   ret void
376 unreached:
377   call void @use(i32 %result)
378   ret void
381 define 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
390 normal:
391   ret void
392 unreached:
393   call void @use(i32 %result)
394   ret void