1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s
3
4; These test cases are inspired by C++2a std::midpoint().
5; See https://bugs.llvm.org/show_bug.cgi?id=40965
6
7; ---------------------------------------------------------------------------- ;
8; 32-bit width
9; ---------------------------------------------------------------------------- ;
10
11; Values come from regs
12
13define 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
34}
35
36define 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
57}
58
59; Values are loaded. Only check signed case.
60
61define 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
84}
85
86define 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
109}
110
111define 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
136}
137
138; ---------------------------------------------------------------------------- ;
139; 64-bit width
140; ---------------------------------------------------------------------------- ;
141
142; Values come from regs
143
144define 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
165}
166
167define 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
188}
189
190; Values are loaded. Only check signed case.
191
192define 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
215}
216
217define 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
240}
241
242define 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
267}
268
269; ---------------------------------------------------------------------------- ;
270; 16-bit width
271; ---------------------------------------------------------------------------- ;
272
273; Values come from regs
274
275define 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
297}
298
299define 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
321}
322
323; Values are loaded. Only check signed case.
324
325define 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
348}
349
350define 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
374}
375
376define 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
401}
402
403; ---------------------------------------------------------------------------- ;
404; 8-bit width
405; ---------------------------------------------------------------------------- ;
406
407; Values come from regs
408
409define 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
431}
432
433define 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
455}
456
457; Values are loaded. Only check signed case.
458
459define 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
482}
483
484define 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
508}
509
510define 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
535}
536