[NFC][RemoveDIs] Prefer iterators over inst-pointers in InstCombine
[llvm-project.git] / llvm / test / CodeGen / AArch64 / srem-vector-lkk.ll
blob0598af7c98063514030d86055caf78fc6a5a5515
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_srem_vec_1(<4 x i16> %x) {
5 ; CHECK-LABEL: fold_srem_vec_1:
6 ; CHECK:       // %bb.0:
7 ; CHECK-NEXT:    adrp x8, .LCPI0_1
8 ; CHECK-NEXT:    ldr d1, [x8, :lo12:.LCPI0_1]
9 ; CHECK-NEXT:    adrp x8, .LCPI0_0
10 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI0_0]
11 ; CHECK-NEXT:    adrp x8, .LCPI0_2
12 ; CHECK-NEXT:    smull v1.4s, v0.4h, v1.4h
13 ; CHECK-NEXT:    shrn v1.4h, v1.4s, #16
14 ; CHECK-NEXT:    mla v1.4h, v0.4h, v2.4h
15 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI0_2]
16 ; CHECK-NEXT:    adrp x8, .LCPI0_3
17 ; CHECK-NEXT:    sshl v1.4h, v1.4h, v2.4h
18 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI0_3]
19 ; CHECK-NEXT:    usra v1.4h, v1.4h, #15
20 ; CHECK-NEXT:    mls v0.4h, v1.4h, v2.4h
21 ; CHECK-NEXT:    ret
22   %1 = srem <4 x i16> %x, <i16 95, i16 -124, i16 98, i16 -1003>
23   ret <4 x i16> %1
26 define <4 x i16> @fold_srem_vec_2(<4 x i16> %x) {
27 ; CHECK-LABEL: fold_srem_vec_2:
28 ; CHECK:       // %bb.0:
29 ; CHECK-NEXT:    mov w8, #44151 // =0xac77
30 ; CHECK-NEXT:    movi v2.4h, #95
31 ; CHECK-NEXT:    dup v1.4h, w8
32 ; CHECK-NEXT:    smull v1.4s, v0.4h, v1.4h
33 ; CHECK-NEXT:    shrn v1.4h, v1.4s, #16
34 ; CHECK-NEXT:    add v1.4h, v1.4h, v0.4h
35 ; CHECK-NEXT:    sshr v1.4h, v1.4h, #6
36 ; CHECK-NEXT:    usra v1.4h, v1.4h, #15
37 ; CHECK-NEXT:    mls v0.4h, v1.4h, v2.4h
38 ; CHECK-NEXT:    ret
39   %1 = srem <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
40   ret <4 x i16> %1
44 ; Don't fold if we can combine srem with sdiv.
45 define <4 x i16> @combine_srem_sdiv(<4 x i16> %x) {
46 ; CHECK-LABEL: combine_srem_sdiv:
47 ; CHECK:       // %bb.0:
48 ; CHECK-NEXT:    mov w8, #44151 // =0xac77
49 ; CHECK-NEXT:    movi v2.4h, #95
50 ; CHECK-NEXT:    dup v1.4h, w8
51 ; CHECK-NEXT:    smull v1.4s, v0.4h, v1.4h
52 ; CHECK-NEXT:    shrn v1.4h, v1.4s, #16
53 ; CHECK-NEXT:    add v1.4h, v1.4h, v0.4h
54 ; CHECK-NEXT:    sshr v1.4h, v1.4h, #6
55 ; CHECK-NEXT:    usra v1.4h, v1.4h, #15
56 ; CHECK-NEXT:    mls v0.4h, v1.4h, v2.4h
57 ; CHECK-NEXT:    add v0.4h, v0.4h, v1.4h
58 ; CHECK-NEXT:    ret
59   %1 = srem <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
60   %2 = sdiv <4 x i16> %x, <i16 95, i16 95, i16 95, i16 95>
61   %3 = add <4 x i16> %1, %2
62   ret <4 x i16> %3
65 ; Don't fold for divisors that are a power of two.
66 define <4 x i16> @dont_fold_srem_power_of_two(<4 x i16> %x) {
67 ; CHECK-LABEL: dont_fold_srem_power_of_two:
68 ; CHECK:       // %bb.0:
69 ; CHECK-NEXT:    adrp x8, .LCPI3_0
70 ; CHECK-NEXT:    ldr d1, [x8, :lo12:.LCPI3_0]
71 ; CHECK-NEXT:    adrp x8, .LCPI3_1
72 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI3_1]
73 ; CHECK-NEXT:    adrp x8, .LCPI3_2
74 ; CHECK-NEXT:    smull v1.4s, v0.4h, v1.4h
75 ; CHECK-NEXT:    shrn v1.4h, v1.4s, #16
76 ; CHECK-NEXT:    add v1.4h, v1.4h, v0.4h
77 ; CHECK-NEXT:    sshl v1.4h, v1.4h, v2.4h
78 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI3_2]
79 ; CHECK-NEXT:    usra v1.4h, v1.4h, #15
80 ; CHECK-NEXT:    mls v0.4h, v1.4h, v2.4h
81 ; CHECK-NEXT:    ret
82   %1 = srem <4 x i16> %x, <i16 64, i16 32, i16 8, i16 95>
83   ret <4 x i16> %1
86 ; Don't fold if the divisor is one.
87 define <4 x i16> @dont_fold_srem_one(<4 x i16> %x) {
88 ; CHECK-LABEL: dont_fold_srem_one:
89 ; CHECK:       // %bb.0:
90 ; CHECK-NEXT:    adrp x8, .LCPI4_0
91 ; CHECK-NEXT:    movi d2, #0x00ffff0000ffff
92 ; CHECK-NEXT:    ldr d1, [x8, :lo12:.LCPI4_0]
93 ; CHECK-NEXT:    adrp x8, .LCPI4_1
94 ; CHECK-NEXT:    smull v1.4s, v0.4h, v1.4h
95 ; CHECK-NEXT:    and v2.8b, v0.8b, v2.8b
96 ; CHECK-NEXT:    shrn v1.4h, v1.4s, #16
97 ; CHECK-NEXT:    add v1.4h, v1.4h, v2.4h
98 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI4_1]
99 ; CHECK-NEXT:    adrp x8, .LCPI4_2
100 ; CHECK-NEXT:    sshl v1.4h, v1.4h, v2.4h
101 ; CHECK-NEXT:    ushr v2.4h, v1.4h, #15
102 ; CHECK-NEXT:    mov v2.h[0], wzr
103 ; CHECK-NEXT:    add v1.4h, v1.4h, v2.4h
104 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI4_2]
105 ; CHECK-NEXT:    mls v0.4h, v1.4h, v2.4h
106 ; CHECK-NEXT:    ret
107   %1 = srem <4 x i16> %x, <i16 1, i16 654, i16 23, i16 5423>
108   ret <4 x i16> %1
111 ; Don't fold if the divisor is 2^15.
112 define <4 x i16> @dont_fold_srem_i16_smax(<4 x i16> %x) {
113 ; CHECK-LABEL: dont_fold_srem_i16_smax:
114 ; CHECK:       // %bb.0:
115 ; CHECK-NEXT:    adrp x8, .LCPI5_1
116 ; CHECK-NEXT:    ldr d1, [x8, :lo12:.LCPI5_1]
117 ; CHECK-NEXT:    adrp x8, .LCPI5_0
118 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI5_0]
119 ; CHECK-NEXT:    adrp x8, .LCPI5_2
120 ; CHECK-NEXT:    smull v1.4s, v0.4h, v1.4h
121 ; CHECK-NEXT:    shrn v1.4h, v1.4s, #16
122 ; CHECK-NEXT:    mla v1.4h, v0.4h, v2.4h
123 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI5_2]
124 ; CHECK-NEXT:    adrp x8, .LCPI5_3
125 ; CHECK-NEXT:    sshl v1.4h, v1.4h, v2.4h
126 ; CHECK-NEXT:    ushr v2.4h, v1.4h, #15
127 ; CHECK-NEXT:    mov v2.h[0], wzr
128 ; CHECK-NEXT:    add v1.4h, v1.4h, v2.4h
129 ; CHECK-NEXT:    ldr d2, [x8, :lo12:.LCPI5_3]
130 ; CHECK-NEXT:    mls v0.4h, v1.4h, v2.4h
131 ; CHECK-NEXT:    ret
132   %1 = srem <4 x i16> %x, <i16 1, i16 32768, i16 23, i16 5423>
133   ret <4 x i16> %1
136 ; Don't fold i64 srem.
137 define <4 x i64> @dont_fold_srem_i64(<4 x i64> %x) {
138 ; CHECK-LABEL: dont_fold_srem_i64:
139 ; CHECK:       // %bb.0:
140 ; CHECK-NEXT:    mov x8, #8549 // =0x2165
141 ; CHECK-NEXT:    fmov x10, d1
142 ; CHECK-NEXT:    mov x9, v1.d[1]
143 ; CHECK-NEXT:    movk x8, #22795, lsl #16
144 ; CHECK-NEXT:    mov x12, #6055 // =0x17a7
145 ; CHECK-NEXT:    mov x11, v0.d[1]
146 ; CHECK-NEXT:    movk x8, #17096, lsl #32
147 ; CHECK-NEXT:    movk x12, #58853, lsl #16
148 ; CHECK-NEXT:    mov x13, #21445 // =0x53c5
149 ; CHECK-NEXT:    movk x8, #45590, lsl #48
150 ; CHECK-NEXT:    movk x12, #47142, lsl #32
151 ; CHECK-NEXT:    movk x13, #1603, lsl #16
152 ; CHECK-NEXT:    smulh x8, x10, x8
153 ; CHECK-NEXT:    movk x12, #24749, lsl #48
154 ; CHECK-NEXT:    movk x13, #15432, lsl #32
155 ; CHECK-NEXT:    movk x13, #25653, lsl #48
156 ; CHECK-NEXT:    movi v0.2d, #0000000000000000
157 ; CHECK-NEXT:    smulh x12, x9, x12
158 ; CHECK-NEXT:    smulh x13, x11, x13
159 ; CHECK-NEXT:    add x8, x8, x10
160 ; CHECK-NEXT:    asr x14, x8, #4
161 ; CHECK-NEXT:    asr x15, x12, #11
162 ; CHECK-NEXT:    add x8, x14, x8, lsr #63
163 ; CHECK-NEXT:    mov w14, #23 // =0x17
164 ; CHECK-NEXT:    add x12, x15, x12, lsr #63
165 ; CHECK-NEXT:    msub x8, x8, x14, x10
166 ; CHECK-NEXT:    asr x10, x13, #8
167 ; CHECK-NEXT:    mov w14, #5423 // =0x152f
168 ; CHECK-NEXT:    add x10, x10, x13, lsr #63
169 ; CHECK-NEXT:    msub x9, x12, x14, x9
170 ; CHECK-NEXT:    mov w12, #654 // =0x28e
171 ; CHECK-NEXT:    msub x10, x10, x12, x11
172 ; CHECK-NEXT:    fmov d1, x8
173 ; CHECK-NEXT:    mov v1.d[1], x9
174 ; CHECK-NEXT:    mov v0.d[1], x10
175 ; CHECK-NEXT:    ret
176   %1 = srem <4 x i64> %x, <i64 1, i64 654, i64 23, i64 5423>
177   ret <4 x i64> %1
180 define <16 x i8> @fold_srem_v16i8(<16 x i8> %x) {
181 ; CHECK-LABEL: fold_srem_v16i8:
182 ; CHECK:       // %bb.0:
183 ; CHECK-NEXT:    movi v1.16b, #103
184 ; CHECK-NEXT:    smull2 v2.8h, v0.16b, v1.16b
185 ; CHECK-NEXT:    smull v1.8h, v0.8b, v1.8b
186 ; CHECK-NEXT:    uzp2 v1.16b, v1.16b, v2.16b
187 ; CHECK-NEXT:    movi v2.16b, #10
188 ; CHECK-NEXT:    sshr v1.16b, v1.16b, #2
189 ; CHECK-NEXT:    usra v1.16b, v1.16b, #7
190 ; CHECK-NEXT:    mls v0.16b, v1.16b, v2.16b
191 ; CHECK-NEXT:    ret
192   %1 = srem <16 x i8> %x, <i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10>
193   ret <16 x i8> %1
196 define <8 x i8> @fold_srem_v8i8(<8 x i8> %x) {
197 ; CHECK-LABEL: fold_srem_v8i8:
198 ; CHECK:       // %bb.0:
199 ; CHECK-NEXT:    movi v1.8b, #103
200 ; CHECK-NEXT:    movi v2.8b, #10
201 ; CHECK-NEXT:    smull v1.8h, v0.8b, v1.8b
202 ; CHECK-NEXT:    shrn v1.8b, v1.8h, #8
203 ; CHECK-NEXT:    sshr v1.8b, v1.8b, #2
204 ; CHECK-NEXT:    usra v1.8b, v1.8b, #7
205 ; CHECK-NEXT:    mls v0.8b, v1.8b, v2.8b
206 ; CHECK-NEXT:    ret
207   %1 = srem <8 x i8> %x, <i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10, i8 10>
208   ret <8 x i8> %1
211 define <8 x i16> @fold_srem_v8i16(<8 x i16> %x) {
212 ; CHECK-LABEL: fold_srem_v8i16:
213 ; CHECK:       // %bb.0:
214 ; CHECK-NEXT:    mov w8, #26215 // =0x6667
215 ; CHECK-NEXT:    dup v1.8h, w8
216 ; CHECK-NEXT:    smull2 v2.4s, v0.8h, v1.8h
217 ; CHECK-NEXT:    smull v1.4s, v0.4h, v1.4h
218 ; CHECK-NEXT:    uzp2 v1.8h, v1.8h, v2.8h
219 ; CHECK-NEXT:    movi v2.8h, #10
220 ; CHECK-NEXT:    sshr v1.8h, v1.8h, #2
221 ; CHECK-NEXT:    usra v1.8h, v1.8h, #15
222 ; CHECK-NEXT:    mls v0.8h, v1.8h, v2.8h
223 ; CHECK-NEXT:    ret
224   %1 = srem <8 x i16> %x, <i16 10, i16 10, i16 10, i16 10, i16 10, i16 10, i16 10, i16 10>
225   ret <8 x i16> %1
228 define <4 x i16> @fold_srem_v4i16(<4 x i16> %x) {
229 ; CHECK-LABEL: fold_srem_v4i16:
230 ; CHECK:       // %bb.0:
231 ; CHECK-NEXT:    mov w8, #26215 // =0x6667
232 ; CHECK-NEXT:    movi v2.4h, #10
233 ; CHECK-NEXT:    dup v1.4h, w8
234 ; CHECK-NEXT:    smull v1.4s, v0.4h, v1.4h
235 ; CHECK-NEXT:    sshr v1.4s, v1.4s, #18
236 ; CHECK-NEXT:    xtn v1.4h, v1.4s
237 ; CHECK-NEXT:    usra v1.4h, v1.4h, #15
238 ; CHECK-NEXT:    mls v0.4h, v1.4h, v2.4h
239 ; CHECK-NEXT:    ret
240   %1 = srem <4 x i16> %x, <i16 10, i16 10, i16 10, i16 10>
241   ret <4 x i16> %1
244 define <4 x i32> @fold_srem_v4i32(<4 x i32> %x) {
245 ; CHECK-LABEL: fold_srem_v4i32:
246 ; CHECK:       // %bb.0:
247 ; CHECK-NEXT:    mov w8, #26215 // =0x6667
248 ; CHECK-NEXT:    movk w8, #26214, lsl #16
249 ; CHECK-NEXT:    dup v1.4s, w8
250 ; CHECK-NEXT:    smull2 v2.2d, v0.4s, v1.4s
251 ; CHECK-NEXT:    smull v1.2d, v0.2s, v1.2s
252 ; CHECK-NEXT:    uzp2 v1.4s, v1.4s, v2.4s
253 ; CHECK-NEXT:    sshr v2.4s, v1.4s, #2
254 ; CHECK-NEXT:    usra v2.4s, v1.4s, #31
255 ; CHECK-NEXT:    movi v1.4s, #10
256 ; CHECK-NEXT:    mls v0.4s, v2.4s, v1.4s
257 ; CHECK-NEXT:    ret
258   %1 = srem <4 x i32> %x, <i32 10, i32 10, i32 10, i32 10>
259   ret <4 x i32> %1
262 define <2 x i32> @fold_srem_v2i32(<2 x i32> %x) {
263 ; CHECK-LABEL: fold_srem_v2i32:
264 ; CHECK:       // %bb.0:
265 ; CHECK-NEXT:    mov w8, #26215 // =0x6667
266 ; CHECK-NEXT:    movi v3.2s, #10
267 ; CHECK-NEXT:    movk w8, #26214, lsl #16
268 ; CHECK-NEXT:    dup v1.2s, w8
269 ; CHECK-NEXT:    smull v1.2d, v0.2s, v1.2s
270 ; CHECK-NEXT:    ushr v2.2d, v1.2d, #63
271 ; CHECK-NEXT:    sshr v1.2d, v1.2d, #34
272 ; CHECK-NEXT:    xtn v2.2s, v2.2d
273 ; CHECK-NEXT:    xtn v1.2s, v1.2d
274 ; CHECK-NEXT:    add v1.2s, v1.2s, v2.2s
275 ; CHECK-NEXT:    mls v0.2s, v1.2s, v3.2s
276 ; CHECK-NEXT:    ret
277   %1 = srem <2 x i32> %x, <i32 10, i32 10>
278   ret <2 x i32> %1
281 define <2 x i64> @fold_srem_v2i64(<2 x i64> %x) {
282 ; CHECK-LABEL: fold_srem_v2i64:
283 ; CHECK:       // %bb.0:
284 ; CHECK-NEXT:    fmov x10, d0
285 ; CHECK-NEXT:    mov x8, #7378697629483820646 // =0x6666666666666666
286 ; CHECK-NEXT:    mov x9, v0.d[1]
287 ; CHECK-NEXT:    movk x8, #26215
288 ; CHECK-NEXT:    smulh x11, x10, x8
289 ; CHECK-NEXT:    smulh x8, x9, x8
290 ; CHECK-NEXT:    asr x12, x11, #2
291 ; CHECK-NEXT:    add x11, x12, x11, lsr #63
292 ; CHECK-NEXT:    asr x13, x8, #2
293 ; CHECK-NEXT:    mov w12, #10 // =0xa
294 ; CHECK-NEXT:    msub x10, x11, x12, x10
295 ; CHECK-NEXT:    add x8, x13, x8, lsr #63
296 ; CHECK-NEXT:    msub x8, x8, x12, x9
297 ; CHECK-NEXT:    fmov d0, x10
298 ; CHECK-NEXT:    mov v0.d[1], x8
299 ; CHECK-NEXT:    ret
300   %1 = srem <2 x i64> %x, <i64 10, i64 10>
301   ret <2 x i64> %1
304 define <1 x i64> @fold_srem_v1i64(<1 x i64> %x) {
305 ; CHECK-LABEL: fold_srem_v1i64:
306 ; CHECK:       // %bb.0:
307 ; CHECK-NEXT:    // kill: def $d0 killed $d0 def $q0
308 ; CHECK-NEXT:    fmov x9, d0
309 ; CHECK-NEXT:    mov x8, #7378697629483820646 // =0x6666666666666666
310 ; CHECK-NEXT:    movk x8, #26215
311 ; CHECK-NEXT:    smulh x8, x9, x8
312 ; CHECK-NEXT:    asr x10, x8, #2
313 ; CHECK-NEXT:    add x8, x10, x8, lsr #63
314 ; CHECK-NEXT:    mov w10, #10 // =0xa
315 ; CHECK-NEXT:    msub x8, x8, x10, x9
316 ; CHECK-NEXT:    fmov d0, x8
317 ; CHECK-NEXT:    ret
318   %1 = srem <1 x i64> %x, <i64 10>
319   ret <1 x i64> %1