[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / AArch64 / urem-vector-lkk.ll
blobc5951a4993fc37377c1a5ce64bd85a51e459faa5
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 define <4 x i16> @fold_urem_vec_1(<4 x i16> %x) {
5 ; CHECK-LABEL: fold_urem_vec_1:
6 ; CHECK:       // %bb.0:
7 ; CHECK-NEXT:    mov w11, #33437
8 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
9 ; CHECK-NEXT:    umov w10, v0.h[2]
10 ; CHECK-NEXT:    movk w11, #21399, lsl #16
11 ; CHECK-NEXT:    umull x11, w10, w11
12 ; CHECK-NEXT:    umov w8, v0.h[1]
13 ; CHECK-NEXT:    mov w9, #16913
14 ; CHECK-NEXT:    mov w12, #98
15 ; CHECK-NEXT:    lsr x11, x11, #37
16 ; CHECK-NEXT:    movk w9, #8456, lsl #16
17 ; CHECK-NEXT:    msub w10, w11, w12, w10
18 ; CHECK-NEXT:    ubfx w12, w8, #2, #14
19 ; CHECK-NEXT:    umull x9, w12, w9
20 ; CHECK-NEXT:    mov w11, #124
21 ; CHECK-NEXT:    lsr x9, x9, #34
22 ; CHECK-NEXT:    msub w8, w9, w11, w8
23 ; CHECK-NEXT:    mov w9, #8969
24 ; CHECK-NEXT:    umov w12, v0.h[0]
25 ; CHECK-NEXT:    movk w9, #22765, lsl #16
26 ; CHECK-NEXT:    umull x9, w12, w9
27 ; CHECK-NEXT:    lsr x9, x9, #32
28 ; CHECK-NEXT:    sub w11, w12, w9
29 ; CHECK-NEXT:    add w9, w9, w11, lsr #1
30 ; CHECK-NEXT:    mov w11, #95
31 ; CHECK-NEXT:    lsr w9, w9, #6
32 ; CHECK-NEXT:    msub w9, w9, w11, w12
33 ; CHECK-NEXT:    umov w11, v0.h[3]
34 ; CHECK-NEXT:    fmov s0, w9
35 ; CHECK-NEXT:    mov w9, #2287
36 ; CHECK-NEXT:    movk w9, #16727, lsl #16
37 ; CHECK-NEXT:    umull x9, w11, w9
38 ; CHECK-NEXT:    mov v0.h[1], w8
39 ; CHECK-NEXT:    mov w8, #1003
40 ; CHECK-NEXT:    lsr x9, x9, #40
41 ; CHECK-NEXT:    mov v0.h[2], w10
42 ; CHECK-NEXT:    msub w8, w9, w8, w11
43 ; CHECK-NEXT:    mov v0.h[3], w8
44 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
45 ; CHECK-NEXT:    ret
46   %1 = urem <4 x i16> %x, <i16 95, i16 124, i16 98, i16 1003>
47   ret <4 x i16> %1
50 define <4 x i16> @fold_urem_vec_2(<4 x i16> %x) {
51 ; CHECK-LABEL: fold_urem_vec_2:
52 ; CHECK:       // %bb.0:
53 ; CHECK-NEXT:    mov w9, #8969
54 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
55 ; CHECK-NEXT:    umov w8, v0.h[1]
56 ; CHECK-NEXT:    movk w9, #22765, lsl #16
57 ; CHECK-NEXT:    umov w10, v0.h[0]
58 ; CHECK-NEXT:    umull x13, w8, w9
59 ; CHECK-NEXT:    umov w11, v0.h[2]
60 ; CHECK-NEXT:    umull x14, w10, w9
61 ; CHECK-NEXT:    lsr x13, x13, #32
62 ; CHECK-NEXT:    umov w12, v0.h[3]
63 ; CHECK-NEXT:    umull x15, w11, w9
64 ; CHECK-NEXT:    lsr x14, x14, #32
65 ; CHECK-NEXT:    sub w16, w8, w13
66 ; CHECK-NEXT:    umull x9, w12, w9
67 ; CHECK-NEXT:    lsr x15, x15, #32
68 ; CHECK-NEXT:    add w13, w13, w16, lsr #1
69 ; CHECK-NEXT:    sub w16, w10, w14
70 ; CHECK-NEXT:    lsr x9, x9, #32
71 ; CHECK-NEXT:    add w14, w14, w16, lsr #1
72 ; CHECK-NEXT:    sub w16, w11, w15
73 ; CHECK-NEXT:    add w15, w15, w16, lsr #1
74 ; CHECK-NEXT:    sub w16, w12, w9
75 ; CHECK-NEXT:    add w9, w9, w16, lsr #1
76 ; CHECK-NEXT:    mov w16, #95
77 ; CHECK-NEXT:    lsr w13, w13, #6
78 ; CHECK-NEXT:    msub w8, w13, w16, w8
79 ; CHECK-NEXT:    lsr w13, w14, #6
80 ; CHECK-NEXT:    msub w10, w13, w16, w10
81 ; CHECK-NEXT:    lsr w13, w15, #6
82 ; CHECK-NEXT:    fmov s0, w10
83 ; CHECK-NEXT:    msub w11, w13, w16, w11
84 ; CHECK-NEXT:    lsr w9, w9, #6
85 ; CHECK-NEXT:    mov v0.h[1], w8
86 ; CHECK-NEXT:    mov v0.h[2], w11
87 ; CHECK-NEXT:    msub w8, w9, w16, w12
88 ; CHECK-NEXT:    mov v0.h[3], w8
89 ; CHECK-NEXT:    // kill: def $d0 killed $d0 killed $q0
90 ; CHECK-NEXT:    ret
91   %1 = urem <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
92   ret <4 x i16> %1
96 ; Don't fold if we can combine urem with udiv.
97 define <4 x i16> @combine_urem_udiv(<4 x i16> %x) {
98 ; CHECK-LABEL: combine_urem_udiv:
99 ; CHECK:       // %bb.0:
100 ; CHECK-NEXT:    mov w8, #8969
101 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
102 ; CHECK-NEXT:    movk w8, #22765, lsl #16
103 ; CHECK-NEXT:    umov w9, v0.h[1]
104 ; CHECK-NEXT:    umov w10, v0.h[0]
105 ; CHECK-NEXT:    umull x13, w9, w8
106 ; CHECK-NEXT:    umov w11, v0.h[2]
107 ; CHECK-NEXT:    umull x14, w10, w8
108 ; CHECK-NEXT:    lsr x13, x13, #32
109 ; CHECK-NEXT:    umov w12, v0.h[3]
110 ; CHECK-NEXT:    umull x15, w11, w8
111 ; CHECK-NEXT:    lsr x14, x14, #32
112 ; CHECK-NEXT:    sub w16, w9, w13
113 ; CHECK-NEXT:    umull x8, w12, w8
114 ; CHECK-NEXT:    lsr x15, x15, #32
115 ; CHECK-NEXT:    add w13, w13, w16, lsr #1
116 ; CHECK-NEXT:    sub w16, w10, w14
117 ; CHECK-NEXT:    lsr x8, x8, #32
118 ; CHECK-NEXT:    add w14, w14, w16, lsr #1
119 ; CHECK-NEXT:    sub w16, w11, w15
120 ; CHECK-NEXT:    add w15, w15, w16, lsr #1
121 ; CHECK-NEXT:    sub w16, w12, w8
122 ; CHECK-NEXT:    add w8, w8, w16, lsr #1
123 ; CHECK-NEXT:    mov w16, #95
124 ; CHECK-NEXT:    lsr w14, w14, #6
125 ; CHECK-NEXT:    lsr w13, w13, #6
126 ; CHECK-NEXT:    msub w10, w14, w16, w10
127 ; CHECK-NEXT:    lsr w15, w15, #6
128 ; CHECK-NEXT:    msub w9, w13, w16, w9
129 ; CHECK-NEXT:    fmov s0, w14
130 ; CHECK-NEXT:    fmov s1, w10
131 ; CHECK-NEXT:    lsr w8, w8, #6
132 ; CHECK-NEXT:    msub w11, w15, w16, w11
133 ; CHECK-NEXT:    mov v0.h[1], w13
134 ; CHECK-NEXT:    mov v1.h[1], w9
135 ; CHECK-NEXT:    msub w12, w8, w16, w12
136 ; CHECK-NEXT:    mov v0.h[2], w15
137 ; CHECK-NEXT:    mov v1.h[2], w11
138 ; CHECK-NEXT:    mov v1.h[3], w12
139 ; CHECK-NEXT:    mov v0.h[3], w8
140 ; CHECK-NEXT:    add v0.4h, v1.4h, v0.4h
141 ; CHECK-NEXT:    ret
142   %1 = urem <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
143   %2 = udiv <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
144   %3 = add <4 x i16> %1, %2
145   ret <4 x i16> %3
149 ; Don't fold for divisors that are a power of two.
150 define <4 x i16> @dont_fold_urem_power_of_two(<4 x i16> %x) {
151 ; CHECK-LABEL: dont_fold_urem_power_of_two:
152 ; CHECK:       // %bb.0:
153 ; CHECK-NEXT:    mov w9, #8969
154 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
155 ; CHECK-NEXT:    umov w8, v0.h[3]
156 ; CHECK-NEXT:    movk w9, #22765, lsl #16
157 ; CHECK-NEXT:    umull x9, w8, w9
158 ; CHECK-NEXT:    lsr x9, x9, #32
159 ; CHECK-NEXT:    sub w10, w8, w9
160 ; CHECK-NEXT:    add w9, w9, w10, lsr #1
161 ; CHECK-NEXT:    mov w10, #95
162 ; CHECK-NEXT:    lsr w9, w9, #6
163 ; CHECK-NEXT:    msub w8, w9, w10, w8
164 ; CHECK-NEXT:    umov w9, v0.h[0]
165 ; CHECK-NEXT:    and w9, w9, #0x3f
166 ; CHECK-NEXT:    umov w10, v0.h[1]
167 ; CHECK-NEXT:    fmov s1, w9
168 ; CHECK-NEXT:    umov w9, v0.h[2]
169 ; CHECK-NEXT:    and w10, w10, #0x1f
170 ; CHECK-NEXT:    and w9, w9, #0x7
171 ; CHECK-NEXT:    mov v1.h[1], w10
172 ; CHECK-NEXT:    mov v1.h[2], w9
173 ; CHECK-NEXT:    mov v1.h[3], w8
174 ; CHECK-NEXT:    mov v0.16b, v1.16b
175 ; CHECK-NEXT:    ret
176   %1 = urem <4 x i16> %x, <i16 64, i16 32, i16 8, i16 95>
177   ret <4 x i16> %1
180 ; Don't fold if the divisor is one.
181 define <4 x i16> @dont_fold_srem_one(<4 x i16> %x) {
182 ; CHECK-LABEL: dont_fold_srem_one:
183 ; CHECK:       // %bb.0:
184 ; CHECK-NEXT:    mov w9, #17097
185 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
186 ; CHECK-NEXT:    umov w8, v0.h[2]
187 ; CHECK-NEXT:    movk w9, #45590, lsl #16
188 ; CHECK-NEXT:    umull x9, w8, w9
189 ; CHECK-NEXT:    mov w10, #23
190 ; CHECK-NEXT:    lsr x9, x9, #36
191 ; CHECK-NEXT:    umov w11, v0.h[1]
192 ; CHECK-NEXT:    msub w8, w9, w10, w8
193 ; CHECK-NEXT:    mov w9, #30865
194 ; CHECK-NEXT:    movk w9, #51306, lsl #16
195 ; CHECK-NEXT:    ubfx w10, w11, #1, #15
196 ; CHECK-NEXT:    umull x9, w10, w9
197 ; CHECK-NEXT:    mov w10, #654
198 ; CHECK-NEXT:    lsr x9, x9, #40
199 ; CHECK-NEXT:    msub w9, w9, w10, w11
200 ; CHECK-NEXT:    mov w11, #47143
201 ; CHECK-NEXT:    umov w10, v0.h[3]
202 ; CHECK-NEXT:    movk w11, #24749, lsl #16
203 ; CHECK-NEXT:    movi d1, #0000000000000000
204 ; CHECK-NEXT:    umull x11, w10, w11
205 ; CHECK-NEXT:    mov v1.h[1], w9
206 ; CHECK-NEXT:    mov w9, #5423
207 ; CHECK-NEXT:    lsr x11, x11, #43
208 ; CHECK-NEXT:    mov v1.h[2], w8
209 ; CHECK-NEXT:    msub w8, w11, w9, w10
210 ; CHECK-NEXT:    mov v1.h[3], w8
211 ; CHECK-NEXT:    mov v0.16b, v1.16b
212 ; CHECK-NEXT:    ret
213   %1 = urem <4 x i16> %x, <i16 1, i16 654, i16 23, i16 5423>
214   ret <4 x i16> %1
217 ; Don't fold if the divisor is 2^16.
218 define <4 x i16> @dont_fold_urem_i16_smax(<4 x i16> %x) {
219 ; CHECK-LABEL: dont_fold_urem_i16_smax:
220 ; CHECK:       // %bb.0:
221 ; CHECK-NEXT:    ret
222   %1 = urem <4 x i16> %x, <i16 1, i16 65536, i16 23, i16 5423>
223   ret <4 x i16> %1
226 ; Don't fold i64 urem.
227 define <4 x i64> @dont_fold_urem_i64(<4 x i64> %x) {
228 ; CHECK-LABEL: dont_fold_urem_i64:
229 ; CHECK:       // %bb.0:
230 ; CHECK-NEXT:    mov x10, #12109
231 ; CHECK-NEXT:    movk x10, #52170, lsl #16
232 ; CHECK-NEXT:    movk x10, #28749, lsl #32
233 ; CHECK-NEXT:    mov x8, v1.d[1]
234 ; CHECK-NEXT:    movk x10, #49499, lsl #48
235 ; CHECK-NEXT:    umulh x10, x8, x10
236 ; CHECK-NEXT:    mov w11, #5423
237 ; CHECK-NEXT:    lsr x10, x10, #12
238 ; CHECK-NEXT:    msub x8, x10, x11, x8
239 ; CHECK-NEXT:    mov x10, #21445
240 ; CHECK-NEXT:    movk x10, #1603, lsl #16
241 ; CHECK-NEXT:    mov x12, v0.d[1]
242 ; CHECK-NEXT:    movk x10, #15432, lsl #32
243 ; CHECK-NEXT:    movk x10, #25653, lsl #48
244 ; CHECK-NEXT:    lsr x11, x12, #1
245 ; CHECK-NEXT:    umulh x10, x11, x10
246 ; CHECK-NEXT:    mov w11, #654
247 ; CHECK-NEXT:    lsr x10, x10, #7
248 ; CHECK-NEXT:    msub x10, x10, x11, x12
249 ; CHECK-NEXT:    mov x11, #17097
250 ; CHECK-NEXT:    movk x11, #45590, lsl #16
251 ; CHECK-NEXT:    movk x11, #34192, lsl #32
252 ; CHECK-NEXT:    fmov x9, d1
253 ; CHECK-NEXT:    movk x11, #25644, lsl #48
254 ; CHECK-NEXT:    umulh x11, x9, x11
255 ; CHECK-NEXT:    sub x12, x9, x11
256 ; CHECK-NEXT:    add x11, x11, x12, lsr #1
257 ; CHECK-NEXT:    mov w12, #23
258 ; CHECK-NEXT:    lsr x11, x11, #4
259 ; CHECK-NEXT:    msub x9, x11, x12, x9
260 ; CHECK-NEXT:    movi v0.2d, #0000000000000000
261 ; CHECK-NEXT:    fmov d1, x9
262 ; CHECK-NEXT:    mov v1.d[1], x8
263 ; CHECK-NEXT:    mov v0.d[1], x10
264 ; CHECK-NEXT:    ret
265   %1 = urem <4 x i64> %x, <i64 1, i64 654, i64 23, i64 5423>
266   ret <4 x i64> %1