[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / AArch64 / midpoint-int.ll
blob9b80866875dddd507481438fc9b409a256c63650
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
4 ; These test cases are inspired by C++2a std::midpoint().
5 ; See https://bugs.llvm.org/show_bug.cgi?id=40965
7 ; ---------------------------------------------------------------------------- ;
8 ; 32-bit width
9 ; ---------------------------------------------------------------------------- ;
11 ; Values come from regs
13 define i32 @scalar_i32_signed_reg_reg(i32 %a1, i32 %a2) nounwind {
14 ; CHECK-LABEL: scalar_i32_signed_reg_reg:
15 ; CHECK:       // %bb.0:
16 ; CHECK-NEXT:    cmp w0, w1
17 ; CHECK-NEXT:    csel w9, w1, w0, gt
18 ; CHECK-NEXT:    csel w10, w0, w1, gt
19 ; CHECK-NEXT:    mov w8, #-1
20 ; CHECK-NEXT:    sub w9, w10, w9
21 ; CHECK-NEXT:    cneg w8, w8, le
22 ; CHECK-NEXT:    lsr w9, w9, #1
23 ; CHECK-NEXT:    madd w0, w9, w8, w0
24 ; CHECK-NEXT:    ret
25   %t3 = icmp sgt i32 %a1, %a2 ; signed
26   %t4 = select i1 %t3, i32 -1, i32 1
27   %t5 = select i1 %t3, i32 %a2, i32 %a1
28   %t6 = select i1 %t3, i32 %a1, i32 %a2
29   %t7 = sub i32 %t6, %t5
30   %t8 = lshr i32 %t7, 1
31   %t9 = mul nsw i32 %t8, %t4 ; signed
32   %a10 = add nsw i32 %t9, %a1 ; signed
33   ret i32 %a10
36 define i32 @scalar_i32_unsigned_reg_reg(i32 %a1, i32 %a2) nounwind {
37 ; CHECK-LABEL: scalar_i32_unsigned_reg_reg:
38 ; CHECK:       // %bb.0:
39 ; CHECK-NEXT:    cmp w0, w1
40 ; CHECK-NEXT:    csel w9, w1, w0, hi
41 ; CHECK-NEXT:    csel w10, w0, w1, hi
42 ; CHECK-NEXT:    mov w8, #-1
43 ; CHECK-NEXT:    sub w9, w10, w9
44 ; CHECK-NEXT:    cneg w8, w8, ls
45 ; CHECK-NEXT:    lsr w9, w9, #1
46 ; CHECK-NEXT:    madd w0, w9, w8, w0
47 ; CHECK-NEXT:    ret
48   %t3 = icmp ugt i32 %a1, %a2
49   %t4 = select i1 %t3, i32 -1, i32 1
50   %t5 = select i1 %t3, i32 %a2, i32 %a1
51   %t6 = select i1 %t3, i32 %a1, i32 %a2
52   %t7 = sub i32 %t6, %t5
53   %t8 = lshr i32 %t7, 1
54   %t9 = mul i32 %t8, %t4
55   %a10 = add i32 %t9, %a1
56   ret i32 %a10
59 ; Values are loaded. Only check signed case.
61 define i32 @scalar_i32_signed_mem_reg(i32* %a1_addr, i32 %a2) nounwind {
62 ; CHECK-LABEL: scalar_i32_signed_mem_reg:
63 ; CHECK:       // %bb.0:
64 ; CHECK-NEXT:    ldr w8, [x0]
65 ; CHECK-NEXT:    mov w9, #-1
66 ; CHECK-NEXT:    cmp w8, w1
67 ; CHECK-NEXT:    csel w10, w1, w8, gt
68 ; CHECK-NEXT:    csel w11, w8, w1, gt
69 ; CHECK-NEXT:    sub w10, w11, w10
70 ; CHECK-NEXT:    cneg w9, w9, le
71 ; CHECK-NEXT:    lsr w10, w10, #1
72 ; CHECK-NEXT:    madd w0, w10, w9, w8
73 ; CHECK-NEXT:    ret
74   %a1 = load i32, i32* %a1_addr
75   %t3 = icmp sgt i32 %a1, %a2 ; signed
76   %t4 = select i1 %t3, i32 -1, i32 1
77   %t5 = select i1 %t3, i32 %a2, i32 %a1
78   %t6 = select i1 %t3, i32 %a1, i32 %a2
79   %t7 = sub i32 %t6, %t5
80   %t8 = lshr i32 %t7, 1
81   %t9 = mul nsw i32 %t8, %t4 ; signed
82   %a10 = add nsw i32 %t9, %a1 ; signed
83   ret i32 %a10
86 define i32 @scalar_i32_signed_reg_mem(i32 %a1, i32* %a2_addr) nounwind {
87 ; CHECK-LABEL: scalar_i32_signed_reg_mem:
88 ; CHECK:       // %bb.0:
89 ; CHECK-NEXT:    ldr w8, [x1]
90 ; CHECK-NEXT:    mov w9, #-1
91 ; CHECK-NEXT:    cmp w0, w8
92 ; CHECK-NEXT:    csel w10, w8, w0, gt
93 ; CHECK-NEXT:    csel w8, w0, w8, gt
94 ; CHECK-NEXT:    sub w8, w8, w10
95 ; CHECK-NEXT:    cneg w9, w9, le
96 ; CHECK-NEXT:    lsr w8, w8, #1
97 ; CHECK-NEXT:    madd w0, w8, w9, w0
98 ; CHECK-NEXT:    ret
99   %a2 = load i32, i32* %a2_addr
100   %t3 = icmp sgt i32 %a1, %a2 ; signed
101   %t4 = select i1 %t3, i32 -1, i32 1
102   %t5 = select i1 %t3, i32 %a2, i32 %a1
103   %t6 = select i1 %t3, i32 %a1, i32 %a2
104   %t7 = sub i32 %t6, %t5
105   %t8 = lshr i32 %t7, 1
106   %t9 = mul nsw i32 %t8, %t4 ; signed
107   %a10 = add nsw i32 %t9, %a1 ; signed
108   ret i32 %a10
111 define i32 @scalar_i32_signed_mem_mem(i32* %a1_addr, i32* %a2_addr) nounwind {
112 ; CHECK-LABEL: scalar_i32_signed_mem_mem:
113 ; CHECK:       // %bb.0:
114 ; CHECK-NEXT:    ldr w8, [x0]
115 ; CHECK-NEXT:    ldr w9, [x1]
116 ; CHECK-NEXT:    mov w10, #-1
117 ; CHECK-NEXT:    cmp w8, w9
118 ; CHECK-NEXT:    csel w11, w9, w8, gt
119 ; CHECK-NEXT:    csel w9, w8, w9, gt
120 ; CHECK-NEXT:    sub w9, w9, w11
121 ; CHECK-NEXT:    cneg w10, w10, le
122 ; CHECK-NEXT:    lsr w9, w9, #1
123 ; CHECK-NEXT:    madd w0, w9, w10, w8
124 ; CHECK-NEXT:    ret
125   %a1 = load i32, i32* %a1_addr
126   %a2 = load i32, i32* %a2_addr
127   %t3 = icmp sgt i32 %a1, %a2 ; signed
128   %t4 = select i1 %t3, i32 -1, i32 1
129   %t5 = select i1 %t3, i32 %a2, i32 %a1
130   %t6 = select i1 %t3, i32 %a1, i32 %a2
131   %t7 = sub i32 %t6, %t5
132   %t8 = lshr i32 %t7, 1
133   %t9 = mul nsw i32 %t8, %t4 ; signed
134   %a10 = add nsw i32 %t9, %a1 ; signed
135   ret i32 %a10
138 ; ---------------------------------------------------------------------------- ;
139 ; 64-bit width
140 ; ---------------------------------------------------------------------------- ;
142 ; Values come from regs
144 define i64 @scalar_i64_signed_reg_reg(i64 %a1, i64 %a2) nounwind {
145 ; CHECK-LABEL: scalar_i64_signed_reg_reg:
146 ; CHECK:       // %bb.0:
147 ; CHECK-NEXT:    cmp x0, x1
148 ; CHECK-NEXT:    csel x9, x1, x0, gt
149 ; CHECK-NEXT:    csel x10, x0, x1, gt
150 ; CHECK-NEXT:    mov x8, #-1
151 ; CHECK-NEXT:    sub x9, x10, x9
152 ; CHECK-NEXT:    cneg x8, x8, le
153 ; CHECK-NEXT:    lsr x9, x9, #1
154 ; CHECK-NEXT:    madd x0, x9, x8, x0
155 ; CHECK-NEXT:    ret
156   %t3 = icmp sgt i64 %a1, %a2 ; signed
157   %t4 = select i1 %t3, i64 -1, i64 1
158   %t5 = select i1 %t3, i64 %a2, i64 %a1
159   %t6 = select i1 %t3, i64 %a1, i64 %a2
160   %t7 = sub i64 %t6, %t5
161   %t8 = lshr i64 %t7, 1
162   %t9 = mul nsw i64 %t8, %t4 ; signed
163   %a10 = add nsw i64 %t9, %a1 ; signed
164   ret i64 %a10
167 define i64 @scalar_i64_unsigned_reg_reg(i64 %a1, i64 %a2) nounwind {
168 ; CHECK-LABEL: scalar_i64_unsigned_reg_reg:
169 ; CHECK:       // %bb.0:
170 ; CHECK-NEXT:    cmp x0, x1
171 ; CHECK-NEXT:    csel x9, x1, x0, hi
172 ; CHECK-NEXT:    csel x10, x0, x1, hi
173 ; CHECK-NEXT:    mov x8, #-1
174 ; CHECK-NEXT:    sub x9, x10, x9
175 ; CHECK-NEXT:    cneg x8, x8, ls
176 ; CHECK-NEXT:    lsr x9, x9, #1
177 ; CHECK-NEXT:    madd x0, x9, x8, x0
178 ; CHECK-NEXT:    ret
179   %t3 = icmp ugt i64 %a1, %a2
180   %t4 = select i1 %t3, i64 -1, i64 1
181   %t5 = select i1 %t3, i64 %a2, i64 %a1
182   %t6 = select i1 %t3, i64 %a1, i64 %a2
183   %t7 = sub i64 %t6, %t5
184   %t8 = lshr i64 %t7, 1
185   %t9 = mul i64 %t8, %t4
186   %a10 = add i64 %t9, %a1
187   ret i64 %a10
190 ; Values are loaded. Only check signed case.
192 define i64 @scalar_i64_signed_mem_reg(i64* %a1_addr, i64 %a2) nounwind {
193 ; CHECK-LABEL: scalar_i64_signed_mem_reg:
194 ; CHECK:       // %bb.0:
195 ; CHECK-NEXT:    ldr x8, [x0]
196 ; CHECK-NEXT:    mov x9, #-1
197 ; CHECK-NEXT:    cmp x8, x1
198 ; CHECK-NEXT:    csel x10, x1, x8, gt
199 ; CHECK-NEXT:    csel x11, x8, x1, gt
200 ; CHECK-NEXT:    sub x10, x11, x10
201 ; CHECK-NEXT:    cneg x9, x9, le
202 ; CHECK-NEXT:    lsr x10, x10, #1
203 ; CHECK-NEXT:    madd x0, x10, x9, x8
204 ; CHECK-NEXT:    ret
205   %a1 = load i64, i64* %a1_addr
206   %t3 = icmp sgt i64 %a1, %a2 ; signed
207   %t4 = select i1 %t3, i64 -1, i64 1
208   %t5 = select i1 %t3, i64 %a2, i64 %a1
209   %t6 = select i1 %t3, i64 %a1, i64 %a2
210   %t7 = sub i64 %t6, %t5
211   %t8 = lshr i64 %t7, 1
212   %t9 = mul nsw i64 %t8, %t4 ; signed
213   %a10 = add nsw i64 %t9, %a1 ; signed
214   ret i64 %a10
217 define i64 @scalar_i64_signed_reg_mem(i64 %a1, i64* %a2_addr) nounwind {
218 ; CHECK-LABEL: scalar_i64_signed_reg_mem:
219 ; CHECK:       // %bb.0:
220 ; CHECK-NEXT:    ldr x8, [x1]
221 ; CHECK-NEXT:    mov x9, #-1
222 ; CHECK-NEXT:    cmp x0, x8
223 ; CHECK-NEXT:    csel x10, x8, x0, gt
224 ; CHECK-NEXT:    csel x8, x0, x8, gt
225 ; CHECK-NEXT:    sub x8, x8, x10
226 ; CHECK-NEXT:    cneg x9, x9, le
227 ; CHECK-NEXT:    lsr x8, x8, #1
228 ; CHECK-NEXT:    madd x0, x8, x9, x0
229 ; CHECK-NEXT:    ret
230   %a2 = load i64, i64* %a2_addr
231   %t3 = icmp sgt i64 %a1, %a2 ; signed
232   %t4 = select i1 %t3, i64 -1, i64 1
233   %t5 = select i1 %t3, i64 %a2, i64 %a1
234   %t6 = select i1 %t3, i64 %a1, i64 %a2
235   %t7 = sub i64 %t6, %t5
236   %t8 = lshr i64 %t7, 1
237   %t9 = mul nsw i64 %t8, %t4 ; signed
238   %a10 = add nsw i64 %t9, %a1 ; signed
239   ret i64 %a10
242 define i64 @scalar_i64_signed_mem_mem(i64* %a1_addr, i64* %a2_addr) nounwind {
243 ; CHECK-LABEL: scalar_i64_signed_mem_mem:
244 ; CHECK:       // %bb.0:
245 ; CHECK-NEXT:    ldr x8, [x0]
246 ; CHECK-NEXT:    ldr x9, [x1]
247 ; CHECK-NEXT:    mov x10, #-1
248 ; CHECK-NEXT:    cmp x8, x9
249 ; CHECK-NEXT:    csel x11, x9, x8, gt
250 ; CHECK-NEXT:    csel x9, x8, x9, gt
251 ; CHECK-NEXT:    sub x9, x9, x11
252 ; CHECK-NEXT:    cneg x10, x10, le
253 ; CHECK-NEXT:    lsr x9, x9, #1
254 ; CHECK-NEXT:    madd x0, x9, x10, x8
255 ; CHECK-NEXT:    ret
256   %a1 = load i64, i64* %a1_addr
257   %a2 = load i64, i64* %a2_addr
258   %t3 = icmp sgt i64 %a1, %a2 ; signed
259   %t4 = select i1 %t3, i64 -1, i64 1
260   %t5 = select i1 %t3, i64 %a2, i64 %a1
261   %t6 = select i1 %t3, i64 %a1, i64 %a2
262   %t7 = sub i64 %t6, %t5
263   %t8 = lshr i64 %t7, 1
264   %t9 = mul nsw i64 %t8, %t4 ; signed
265   %a10 = add nsw i64 %t9, %a1 ; signed
266   ret i64 %a10
269 ; ---------------------------------------------------------------------------- ;
270 ; 16-bit width
271 ; ---------------------------------------------------------------------------- ;
273 ; Values come from regs
275 define i16 @scalar_i16_signed_reg_reg(i16 %a1, i16 %a2) nounwind {
276 ; CHECK-LABEL: scalar_i16_signed_reg_reg:
277 ; CHECK:       // %bb.0:
278 ; CHECK-NEXT:    sxth w8, w0
279 ; CHECK-NEXT:    mov w9, #-1
280 ; CHECK-NEXT:    cmp w8, w1, sxth
281 ; CHECK-NEXT:    cneg w8, w9, le
282 ; CHECK-NEXT:    csel w9, w1, w0, gt
283 ; CHECK-NEXT:    csel w10, w0, w1, gt
284 ; CHECK-NEXT:    sub w9, w10, w9
285 ; CHECK-NEXT:    ubfx w9, w9, #1, #15
286 ; CHECK-NEXT:    madd w0, w9, w8, w0
287 ; CHECK-NEXT:    ret
288   %t3 = icmp sgt i16 %a1, %a2 ; signed
289   %t4 = select i1 %t3, i16 -1, i16 1
290   %t5 = select i1 %t3, i16 %a2, i16 %a1
291   %t6 = select i1 %t3, i16 %a1, i16 %a2
292   %t7 = sub i16 %t6, %t5
293   %t8 = lshr i16 %t7, 1
294   %t9 = mul nsw i16 %t8, %t4 ; signed
295   %a10 = add nsw i16 %t9, %a1 ; signed
296   ret i16 %a10
299 define i16 @scalar_i16_unsigned_reg_reg(i16 %a1, i16 %a2) nounwind {
300 ; CHECK-LABEL: scalar_i16_unsigned_reg_reg:
301 ; CHECK:       // %bb.0:
302 ; CHECK-NEXT:    and w8, w0, #0xffff
303 ; CHECK-NEXT:    mov w9, #-1
304 ; CHECK-NEXT:    cmp w8, w1, uxth
305 ; CHECK-NEXT:    cneg w8, w9, ls
306 ; CHECK-NEXT:    csel w9, w1, w0, hi
307 ; CHECK-NEXT:    csel w10, w0, w1, hi
308 ; CHECK-NEXT:    sub w9, w10, w9
309 ; CHECK-NEXT:    ubfx w9, w9, #1, #15
310 ; CHECK-NEXT:    madd w0, w9, w8, w0
311 ; CHECK-NEXT:    ret
312   %t3 = icmp ugt i16 %a1, %a2
313   %t4 = select i1 %t3, i16 -1, i16 1
314   %t5 = select i1 %t3, i16 %a2, i16 %a1
315   %t6 = select i1 %t3, i16 %a1, i16 %a2
316   %t7 = sub i16 %t6, %t5
317   %t8 = lshr i16 %t7, 1
318   %t9 = mul i16 %t8, %t4
319   %a10 = add i16 %t9, %a1
320   ret i16 %a10
323 ; Values are loaded. Only check signed case.
325 define i16 @scalar_i16_signed_mem_reg(i16* %a1_addr, i16 %a2) nounwind {
326 ; CHECK-LABEL: scalar_i16_signed_mem_reg:
327 ; CHECK:       // %bb.0:
328 ; CHECK-NEXT:    ldrsh w8, [x0]
329 ; CHECK-NEXT:    mov w9, #-1
330 ; CHECK-NEXT:    cmp w8, w1, sxth
331 ; CHECK-NEXT:    csel w10, w1, w8, gt
332 ; CHECK-NEXT:    csel w11, w8, w1, gt
333 ; CHECK-NEXT:    sub w10, w11, w10
334 ; CHECK-NEXT:    cneg w9, w9, le
335 ; CHECK-NEXT:    ubfx w10, w10, #1, #15
336 ; CHECK-NEXT:    madd w0, w10, w9, w8
337 ; CHECK-NEXT:    ret
338   %a1 = load i16, i16* %a1_addr
339   %t3 = icmp sgt i16 %a1, %a2 ; signed
340   %t4 = select i1 %t3, i16 -1, i16 1
341   %t5 = select i1 %t3, i16 %a2, i16 %a1
342   %t6 = select i1 %t3, i16 %a1, i16 %a2
343   %t7 = sub i16 %t6, %t5
344   %t8 = lshr i16 %t7, 1
345   %t9 = mul nsw i16 %t8, %t4 ; signed
346   %a10 = add nsw i16 %t9, %a1 ; signed
347   ret i16 %a10
350 define i16 @scalar_i16_signed_reg_mem(i16 %a1, i16* %a2_addr) nounwind {
351 ; CHECK-LABEL: scalar_i16_signed_reg_mem:
352 ; CHECK:       // %bb.0:
353 ; CHECK-NEXT:    ldrsh w8, [x1]
354 ; CHECK-NEXT:    sxth w9, w0
355 ; CHECK-NEXT:    mov w10, #-1
356 ; CHECK-NEXT:    cmp w9, w8
357 ; CHECK-NEXT:    cneg w9, w10, le
358 ; CHECK-NEXT:    csel w10, w8, w0, gt
359 ; CHECK-NEXT:    csel w8, w0, w8, gt
360 ; CHECK-NEXT:    sub w8, w8, w10
361 ; CHECK-NEXT:    ubfx w8, w8, #1, #15
362 ; CHECK-NEXT:    madd w0, w8, w9, w0
363 ; CHECK-NEXT:    ret
364   %a2 = load i16, i16* %a2_addr
365   %t3 = icmp sgt i16 %a1, %a2 ; signed
366   %t4 = select i1 %t3, i16 -1, i16 1
367   %t5 = select i1 %t3, i16 %a2, i16 %a1
368   %t6 = select i1 %t3, i16 %a1, i16 %a2
369   %t7 = sub i16 %t6, %t5
370   %t8 = lshr i16 %t7, 1
371   %t9 = mul nsw i16 %t8, %t4 ; signed
372   %a10 = add nsw i16 %t9, %a1 ; signed
373   ret i16 %a10
376 define i16 @scalar_i16_signed_mem_mem(i16* %a1_addr, i16* %a2_addr) nounwind {
377 ; CHECK-LABEL: scalar_i16_signed_mem_mem:
378 ; CHECK:       // %bb.0:
379 ; CHECK-NEXT:    ldrsh w8, [x0]
380 ; CHECK-NEXT:    ldrsh w9, [x1]
381 ; CHECK-NEXT:    mov w10, #-1
382 ; CHECK-NEXT:    cmp w8, w9
383 ; CHECK-NEXT:    csel w11, w9, w8, gt
384 ; CHECK-NEXT:    csel w9, w8, w9, gt
385 ; CHECK-NEXT:    sub w9, w9, w11
386 ; CHECK-NEXT:    cneg w10, w10, le
387 ; CHECK-NEXT:    ubfx w9, w9, #1, #15
388 ; CHECK-NEXT:    madd w0, w9, w10, w8
389 ; CHECK-NEXT:    ret
390   %a1 = load i16, i16* %a1_addr
391   %a2 = load i16, i16* %a2_addr
392   %t3 = icmp sgt i16 %a1, %a2 ; signed
393   %t4 = select i1 %t3, i16 -1, i16 1
394   %t5 = select i1 %t3, i16 %a2, i16 %a1
395   %t6 = select i1 %t3, i16 %a1, i16 %a2
396   %t7 = sub i16 %t6, %t5
397   %t8 = lshr i16 %t7, 1
398   %t9 = mul nsw i16 %t8, %t4 ; signed
399   %a10 = add nsw i16 %t9, %a1 ; signed
400   ret i16 %a10
403 ; ---------------------------------------------------------------------------- ;
404 ; 8-bit width
405 ; ---------------------------------------------------------------------------- ;
407 ; Values come from regs
409 define i8 @scalar_i8_signed_reg_reg(i8 %a1, i8 %a2) nounwind {
410 ; CHECK-LABEL: scalar_i8_signed_reg_reg:
411 ; CHECK:       // %bb.0:
412 ; CHECK-NEXT:    sxtb w8, w0
413 ; CHECK-NEXT:    mov w9, #-1
414 ; CHECK-NEXT:    cmp w8, w1, sxtb
415 ; CHECK-NEXT:    cneg w8, w9, le
416 ; CHECK-NEXT:    csel w9, w1, w0, gt
417 ; CHECK-NEXT:    csel w10, w0, w1, gt
418 ; CHECK-NEXT:    sub w9, w10, w9
419 ; CHECK-NEXT:    ubfx w9, w9, #1, #7
420 ; CHECK-NEXT:    madd w0, w9, w8, w0
421 ; CHECK-NEXT:    ret
422   %t3 = icmp sgt i8 %a1, %a2 ; signed
423   %t4 = select i1 %t3, i8 -1, i8 1
424   %t5 = select i1 %t3, i8 %a2, i8 %a1
425   %t6 = select i1 %t3, i8 %a1, i8 %a2
426   %t7 = sub i8 %t6, %t5
427   %t8 = lshr i8 %t7, 1
428   %t9 = mul nsw i8 %t8, %t4 ; signed
429   %a10 = add nsw i8 %t9, %a1 ; signed
430   ret i8 %a10
433 define i8 @scalar_i8_unsigned_reg_reg(i8 %a1, i8 %a2) nounwind {
434 ; CHECK-LABEL: scalar_i8_unsigned_reg_reg:
435 ; CHECK:       // %bb.0:
436 ; CHECK-NEXT:    and w8, w0, #0xff
437 ; CHECK-NEXT:    mov w9, #-1
438 ; CHECK-NEXT:    cmp w8, w1, uxtb
439 ; CHECK-NEXT:    cneg w8, w9, ls
440 ; CHECK-NEXT:    csel w9, w1, w0, hi
441 ; CHECK-NEXT:    csel w10, w0, w1, hi
442 ; CHECK-NEXT:    sub w9, w10, w9
443 ; CHECK-NEXT:    ubfx w9, w9, #1, #7
444 ; CHECK-NEXT:    madd w0, w9, w8, w0
445 ; CHECK-NEXT:    ret
446   %t3 = icmp ugt i8 %a1, %a2
447   %t4 = select i1 %t3, i8 -1, i8 1
448   %t5 = select i1 %t3, i8 %a2, i8 %a1
449   %t6 = select i1 %t3, i8 %a1, i8 %a2
450   %t7 = sub i8 %t6, %t5
451   %t8 = lshr i8 %t7, 1
452   %t9 = mul i8 %t8, %t4
453   %a10 = add i8 %t9, %a1
454   ret i8 %a10
457 ; Values are loaded. Only check signed case.
459 define i8 @scalar_i8_signed_mem_reg(i8* %a1_addr, i8 %a2) nounwind {
460 ; CHECK-LABEL: scalar_i8_signed_mem_reg:
461 ; CHECK:       // %bb.0:
462 ; CHECK-NEXT:    ldrsb w8, [x0]
463 ; CHECK-NEXT:    mov w9, #-1
464 ; CHECK-NEXT:    cmp w8, w1, sxtb
465 ; CHECK-NEXT:    csel w10, w1, w8, gt
466 ; CHECK-NEXT:    csel w11, w8, w1, gt
467 ; CHECK-NEXT:    sub w10, w11, w10
468 ; CHECK-NEXT:    cneg w9, w9, le
469 ; CHECK-NEXT:    ubfx w10, w10, #1, #7
470 ; CHECK-NEXT:    madd w0, w10, w9, w8
471 ; CHECK-NEXT:    ret
472   %a1 = load i8, i8* %a1_addr
473   %t3 = icmp sgt i8 %a1, %a2 ; signed
474   %t4 = select i1 %t3, i8 -1, i8 1
475   %t5 = select i1 %t3, i8 %a2, i8 %a1
476   %t6 = select i1 %t3, i8 %a1, i8 %a2
477   %t7 = sub i8 %t6, %t5
478   %t8 = lshr i8 %t7, 1
479   %t9 = mul nsw i8 %t8, %t4 ; signed
480   %a10 = add nsw i8 %t9, %a1 ; signed
481   ret i8 %a10
484 define i8 @scalar_i8_signed_reg_mem(i8 %a1, i8* %a2_addr) nounwind {
485 ; CHECK-LABEL: scalar_i8_signed_reg_mem:
486 ; CHECK:       // %bb.0:
487 ; CHECK-NEXT:    ldrsb w8, [x1]
488 ; CHECK-NEXT:    sxtb w9, w0
489 ; CHECK-NEXT:    mov w10, #-1
490 ; CHECK-NEXT:    cmp w9, w8
491 ; CHECK-NEXT:    cneg w9, w10, le
492 ; CHECK-NEXT:    csel w10, w8, w0, gt
493 ; CHECK-NEXT:    csel w8, w0, w8, gt
494 ; CHECK-NEXT:    sub w8, w8, w10
495 ; CHECK-NEXT:    ubfx w8, w8, #1, #7
496 ; CHECK-NEXT:    madd w0, w8, w9, w0
497 ; CHECK-NEXT:    ret
498   %a2 = load i8, i8* %a2_addr
499   %t3 = icmp sgt i8 %a1, %a2 ; signed
500   %t4 = select i1 %t3, i8 -1, i8 1
501   %t5 = select i1 %t3, i8 %a2, i8 %a1
502   %t6 = select i1 %t3, i8 %a1, i8 %a2
503   %t7 = sub i8 %t6, %t5
504   %t8 = lshr i8 %t7, 1
505   %t9 = mul nsw i8 %t8, %t4 ; signed
506   %a10 = add nsw i8 %t9, %a1 ; signed
507   ret i8 %a10
510 define i8 @scalar_i8_signed_mem_mem(i8* %a1_addr, i8* %a2_addr) nounwind {
511 ; CHECK-LABEL: scalar_i8_signed_mem_mem:
512 ; CHECK:       // %bb.0:
513 ; CHECK-NEXT:    ldrsb w8, [x0]
514 ; CHECK-NEXT:    ldrsb w9, [x1]
515 ; CHECK-NEXT:    mov w10, #-1
516 ; CHECK-NEXT:    cmp w8, w9
517 ; CHECK-NEXT:    csel w11, w9, w8, gt
518 ; CHECK-NEXT:    csel w9, w8, w9, gt
519 ; CHECK-NEXT:    sub w9, w9, w11
520 ; CHECK-NEXT:    cneg w10, w10, le
521 ; CHECK-NEXT:    ubfx w9, w9, #1, #7
522 ; CHECK-NEXT:    madd w0, w9, w10, w8
523 ; CHECK-NEXT:    ret
524   %a1 = load i8, i8* %a1_addr
525   %a2 = load i8, i8* %a2_addr
526   %t3 = icmp sgt i8 %a1, %a2 ; signed
527   %t4 = select i1 %t3, i8 -1, i8 1
528   %t5 = select i1 %t3, i8 %a2, i8 %a1
529   %t6 = select i1 %t3, i8 %a1, i8 %a2
530   %t7 = sub i8 %t6, %t5
531   %t8 = lshr i8 %t7, 1
532   %t9 = mul nsw i8 %t8, %t4 ; signed
533   %a10 = add nsw i8 %t9, %a1 ; signed
534   ret i8 %a10