[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / RISCV / srem-lkk.ll
blob5211e5291a26c7d1c89d3fedb552513e6e45a552
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=riscv32 -verify-machineinstrs < %s \
3 ; RUN:   | FileCheck -check-prefixes=CHECK,RV32I %s
4 ; RUN: llc -mtriple=riscv32 -mattr=+m -verify-machineinstrs < %s \
5 ; RUN:   | FileCheck -check-prefixes=CHECK,RV32IM %s
6 ; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
7 ; RUN:   | FileCheck -check-prefixes=CHECK,RV64I %s
8 ; RUN: llc -mtriple=riscv64 -mattr=+m -verify-machineinstrs < %s \
9 ; RUN:   | FileCheck -check-prefixes=CHECK,RV64IM %s
11 define i32 @fold_srem_positive_odd(i32 %x) {
12 ; RV32I-LABEL: fold_srem_positive_odd:
13 ; RV32I:       # %bb.0:
14 ; RV32I-NEXT:    addi sp, sp, -16
15 ; RV32I-NEXT:    .cfi_def_cfa_offset 16
16 ; RV32I-NEXT:    sw ra, 12(sp)
17 ; RV32I-NEXT:    .cfi_offset ra, -4
18 ; RV32I-NEXT:    addi a1, zero, 95
19 ; RV32I-NEXT:    call __modsi3
20 ; RV32I-NEXT:    lw ra, 12(sp)
21 ; RV32I-NEXT:    .cfi_restore ra
22 ; RV32I-NEXT:    addi sp, sp, 16
23 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
24 ; RV32I-NEXT:    ret
26 ; RV32IM-LABEL: fold_srem_positive_odd:
27 ; RV32IM:       # %bb.0:
28 ; RV32IM-NEXT:    lui a1, 706409
29 ; RV32IM-NEXT:    addi a1, a1, 389
30 ; RV32IM-NEXT:    mulh a1, a0, a1
31 ; RV32IM-NEXT:    add a1, a1, a0
32 ; RV32IM-NEXT:    srli a2, a1, 31
33 ; RV32IM-NEXT:    srai a1, a1, 6
34 ; RV32IM-NEXT:    add a1, a1, a2
35 ; RV32IM-NEXT:    addi a2, zero, 95
36 ; RV32IM-NEXT:    mul a1, a1, a2
37 ; RV32IM-NEXT:    sub a0, a0, a1
38 ; RV32IM-NEXT:    .cfi_def_cfa_offset 0
39 ; RV32IM-NEXT:    ret
41 ; RV64I-LABEL: fold_srem_positive_odd:
42 ; RV64I:       # %bb.0:
43 ; RV64I-NEXT:    addi sp, sp, -16
44 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
45 ; RV64I-NEXT:    sd ra, 8(sp)
46 ; RV64I-NEXT:    .cfi_offset ra, -8
47 ; RV64I-NEXT:    sext.w a0, a0
48 ; RV64I-NEXT:    addi a1, zero, 95
49 ; RV64I-NEXT:    call __moddi3
50 ; RV64I-NEXT:    ld ra, 8(sp)
51 ; RV64I-NEXT:    .cfi_restore ra
52 ; RV64I-NEXT:    addi sp, sp, 16
53 ; RV64I-NEXT:    .cfi_def_cfa_offset 0
54 ; RV64I-NEXT:    ret
56 ; RV64IM-LABEL: fold_srem_positive_odd:
57 ; RV64IM:       # %bb.0:
58 ; RV64IM-NEXT:    sext.w a0, a0
59 ; RV64IM-NEXT:    lui a1, 1045903
60 ; RV64IM-NEXT:    addiw a1, a1, -733
61 ; RV64IM-NEXT:    slli a1, a1, 15
62 ; RV64IM-NEXT:    addi a1, a1, 1035
63 ; RV64IM-NEXT:    slli a1, a1, 12
64 ; RV64IM-NEXT:    addi a1, a1, -905
65 ; RV64IM-NEXT:    slli a1, a1, 12
66 ; RV64IM-NEXT:    addi a1, a1, -1767
67 ; RV64IM-NEXT:    mulh a1, a0, a1
68 ; RV64IM-NEXT:    add a1, a1, a0
69 ; RV64IM-NEXT:    srli a2, a1, 63
70 ; RV64IM-NEXT:    srai a1, a1, 6
71 ; RV64IM-NEXT:    add a1, a1, a2
72 ; RV64IM-NEXT:    addi a2, zero, 95
73 ; RV64IM-NEXT:    mul a1, a1, a2
74 ; RV64IM-NEXT:    sub a0, a0, a1
75 ; RV64IM-NEXT:    .cfi_def_cfa_offset 0
76 ; RV64IM-NEXT:    ret
77   %1 = srem i32 %x, 95
78   ret i32 %1
82 define i32 @fold_srem_positive_even(i32 %x) {
83 ; RV32I-LABEL: fold_srem_positive_even:
84 ; RV32I:       # %bb.0:
85 ; RV32I-NEXT:    addi sp, sp, -16
86 ; RV32I-NEXT:    .cfi_def_cfa_offset 16
87 ; RV32I-NEXT:    sw ra, 12(sp)
88 ; RV32I-NEXT:    .cfi_offset ra, -4
89 ; RV32I-NEXT:    addi a1, zero, 1060
90 ; RV32I-NEXT:    call __modsi3
91 ; RV32I-NEXT:    lw ra, 12(sp)
92 ; RV32I-NEXT:    .cfi_restore ra
93 ; RV32I-NEXT:    addi sp, sp, 16
94 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
95 ; RV32I-NEXT:    ret
97 ; RV32IM-LABEL: fold_srem_positive_even:
98 ; RV32IM:       # %bb.0:
99 ; RV32IM-NEXT:    lui a1, 253241
100 ; RV32IM-NEXT:    addi a1, a1, -15
101 ; RV32IM-NEXT:    mulh a1, a0, a1
102 ; RV32IM-NEXT:    srli a2, a1, 31
103 ; RV32IM-NEXT:    srai a1, a1, 8
104 ; RV32IM-NEXT:    add a1, a1, a2
105 ; RV32IM-NEXT:    addi a2, zero, 1060
106 ; RV32IM-NEXT:    mul a1, a1, a2
107 ; RV32IM-NEXT:    sub a0, a0, a1
108 ; RV32IM-NEXT:    .cfi_def_cfa_offset 0
109 ; RV32IM-NEXT:    ret
111 ; RV64I-LABEL: fold_srem_positive_even:
112 ; RV64I:       # %bb.0:
113 ; RV64I-NEXT:    addi sp, sp, -16
114 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
115 ; RV64I-NEXT:    sd ra, 8(sp)
116 ; RV64I-NEXT:    .cfi_offset ra, -8
117 ; RV64I-NEXT:    sext.w a0, a0
118 ; RV64I-NEXT:    addi a1, zero, 1060
119 ; RV64I-NEXT:    call __moddi3
120 ; RV64I-NEXT:    ld ra, 8(sp)
121 ; RV64I-NEXT:    .cfi_restore ra
122 ; RV64I-NEXT:    addi sp, sp, 16
123 ; RV64I-NEXT:    .cfi_def_cfa_offset 0
124 ; RV64I-NEXT:    ret
126 ; RV64IM-LABEL: fold_srem_positive_even:
127 ; RV64IM:       # %bb.0:
128 ; RV64IM-NEXT:    sext.w a0, a0
129 ; RV64IM-NEXT:    lui a1, 506482
130 ; RV64IM-NEXT:    addiw a1, a1, -31
131 ; RV64IM-NEXT:    slli a1, a1, 13
132 ; RV64IM-NEXT:    addi a1, a1, 711
133 ; RV64IM-NEXT:    slli a1, a1, 19
134 ; RV64IM-NEXT:    addi a1, a1, 1979
135 ; RV64IM-NEXT:    mulh a1, a0, a1
136 ; RV64IM-NEXT:    srli a2, a1, 63
137 ; RV64IM-NEXT:    srai a1, a1, 9
138 ; RV64IM-NEXT:    add a1, a1, a2
139 ; RV64IM-NEXT:    addi a2, zero, 1060
140 ; RV64IM-NEXT:    mul a1, a1, a2
141 ; RV64IM-NEXT:    sub a0, a0, a1
142 ; RV64IM-NEXT:    .cfi_def_cfa_offset 0
143 ; RV64IM-NEXT:    ret
144   %1 = srem i32 %x, 1060
145   ret i32 %1
149 define i32 @fold_srem_negative_odd(i32 %x) {
150 ; RV32I-LABEL: fold_srem_negative_odd:
151 ; RV32I:       # %bb.0:
152 ; RV32I-NEXT:    addi sp, sp, -16
153 ; RV32I-NEXT:    .cfi_def_cfa_offset 16
154 ; RV32I-NEXT:    sw ra, 12(sp)
155 ; RV32I-NEXT:    .cfi_offset ra, -4
156 ; RV32I-NEXT:    addi a1, zero, -723
157 ; RV32I-NEXT:    call __modsi3
158 ; RV32I-NEXT:    lw ra, 12(sp)
159 ; RV32I-NEXT:    .cfi_restore ra
160 ; RV32I-NEXT:    addi sp, sp, 16
161 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
162 ; RV32I-NEXT:    ret
164 ; RV32IM-LABEL: fold_srem_negative_odd:
165 ; RV32IM:       # %bb.0:
166 ; RV32IM-NEXT:    lui a1, 677296
167 ; RV32IM-NEXT:    addi a1, a1, -91
168 ; RV32IM-NEXT:    mulh a1, a0, a1
169 ; RV32IM-NEXT:    srli a2, a1, 31
170 ; RV32IM-NEXT:    srai a1, a1, 8
171 ; RV32IM-NEXT:    add a1, a1, a2
172 ; RV32IM-NEXT:    addi a2, zero, -723
173 ; RV32IM-NEXT:    mul a1, a1, a2
174 ; RV32IM-NEXT:    sub a0, a0, a1
175 ; RV32IM-NEXT:    .cfi_def_cfa_offset 0
176 ; RV32IM-NEXT:    ret
178 ; RV64I-LABEL: fold_srem_negative_odd:
179 ; RV64I:       # %bb.0:
180 ; RV64I-NEXT:    addi sp, sp, -16
181 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
182 ; RV64I-NEXT:    sd ra, 8(sp)
183 ; RV64I-NEXT:    .cfi_offset ra, -8
184 ; RV64I-NEXT:    sext.w a0, a0
185 ; RV64I-NEXT:    addi a1, zero, -723
186 ; RV64I-NEXT:    call __moddi3
187 ; RV64I-NEXT:    ld ra, 8(sp)
188 ; RV64I-NEXT:    .cfi_restore ra
189 ; RV64I-NEXT:    addi sp, sp, 16
190 ; RV64I-NEXT:    .cfi_def_cfa_offset 0
191 ; RV64I-NEXT:    ret
193 ; RV64IM-LABEL: fold_srem_negative_odd:
194 ; RV64IM:       # %bb.0:
195 ; RV64IM-NEXT:    sext.w a0, a0
196 ; RV64IM-NEXT:    lui a1, 4781
197 ; RV64IM-NEXT:    addiw a1, a1, 2045
198 ; RV64IM-NEXT:    slli a1, a1, 13
199 ; RV64IM-NEXT:    addi a1, a1, 1371
200 ; RV64IM-NEXT:    slli a1, a1, 13
201 ; RV64IM-NEXT:    addi a1, a1, -11
202 ; RV64IM-NEXT:    slli a1, a1, 12
203 ; RV64IM-NEXT:    addi a1, a1, -1355
204 ; RV64IM-NEXT:    mulh a1, a0, a1
205 ; RV64IM-NEXT:    sub a1, a1, a0
206 ; RV64IM-NEXT:    srli a2, a1, 63
207 ; RV64IM-NEXT:    srai a1, a1, 9
208 ; RV64IM-NEXT:    add a1, a1, a2
209 ; RV64IM-NEXT:    addi a2, zero, -723
210 ; RV64IM-NEXT:    mul a1, a1, a2
211 ; RV64IM-NEXT:    sub a0, a0, a1
212 ; RV64IM-NEXT:    .cfi_def_cfa_offset 0
213 ; RV64IM-NEXT:    ret
214   %1 = srem i32 %x, -723
215   ret i32 %1
219 define i32 @fold_srem_negative_even(i32 %x) {
220 ; RV32I-LABEL: fold_srem_negative_even:
221 ; RV32I:       # %bb.0:
222 ; RV32I-NEXT:    addi sp, sp, -16
223 ; RV32I-NEXT:    .cfi_def_cfa_offset 16
224 ; RV32I-NEXT:    sw ra, 12(sp)
225 ; RV32I-NEXT:    .cfi_offset ra, -4
226 ; RV32I-NEXT:    lui a1, 1048570
227 ; RV32I-NEXT:    addi a1, a1, 1595
228 ; RV32I-NEXT:    call __modsi3
229 ; RV32I-NEXT:    lw ra, 12(sp)
230 ; RV32I-NEXT:    .cfi_restore ra
231 ; RV32I-NEXT:    addi sp, sp, 16
232 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
233 ; RV32I-NEXT:    ret
235 ; RV32IM-LABEL: fold_srem_negative_even:
236 ; RV32IM:       # %bb.0:
237 ; RV32IM-NEXT:    lui a1, 1036895
238 ; RV32IM-NEXT:    addi a1, a1, 999
239 ; RV32IM-NEXT:    mulh a1, a0, a1
240 ; RV32IM-NEXT:    srli a2, a1, 31
241 ; RV32IM-NEXT:    srai a1, a1, 8
242 ; RV32IM-NEXT:    add a1, a1, a2
243 ; RV32IM-NEXT:    lui a2, 1048570
244 ; RV32IM-NEXT:    addi a2, a2, 1595
245 ; RV32IM-NEXT:    mul a1, a1, a2
246 ; RV32IM-NEXT:    sub a0, a0, a1
247 ; RV32IM-NEXT:    .cfi_def_cfa_offset 0
248 ; RV32IM-NEXT:    ret
250 ; RV64I-LABEL: fold_srem_negative_even:
251 ; RV64I:       # %bb.0:
252 ; RV64I-NEXT:    addi sp, sp, -16
253 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
254 ; RV64I-NEXT:    sd ra, 8(sp)
255 ; RV64I-NEXT:    .cfi_offset ra, -8
256 ; RV64I-NEXT:    sext.w a0, a0
257 ; RV64I-NEXT:    lui a1, 1048570
258 ; RV64I-NEXT:    addiw a1, a1, 1595
259 ; RV64I-NEXT:    call __moddi3
260 ; RV64I-NEXT:    ld ra, 8(sp)
261 ; RV64I-NEXT:    .cfi_restore ra
262 ; RV64I-NEXT:    addi sp, sp, 16
263 ; RV64I-NEXT:    .cfi_def_cfa_offset 0
264 ; RV64I-NEXT:    ret
266 ; RV64IM-LABEL: fold_srem_negative_even:
267 ; RV64IM:       # %bb.0:
268 ; RV64IM-NEXT:    sext.w a0, a0
269 ; RV64IM-NEXT:    lui a1, 1036895
270 ; RV64IM-NEXT:    addiw a1, a1, 999
271 ; RV64IM-NEXT:    slli a1, a1, 12
272 ; RV64IM-NEXT:    addi a1, a1, 11
273 ; RV64IM-NEXT:    slli a1, a1, 12
274 ; RV64IM-NEXT:    addi a1, a1, -523
275 ; RV64IM-NEXT:    slli a1, a1, 12
276 ; RV64IM-NEXT:    addi a1, a1, -481
277 ; RV64IM-NEXT:    mulh a1, a0, a1
278 ; RV64IM-NEXT:    srli a2, a1, 63
279 ; RV64IM-NEXT:    srai a1, a1, 12
280 ; RV64IM-NEXT:    add a1, a1, a2
281 ; RV64IM-NEXT:    lui a2, 1048570
282 ; RV64IM-NEXT:    addiw a2, a2, 1595
283 ; RV64IM-NEXT:    mul a1, a1, a2
284 ; RV64IM-NEXT:    sub a0, a0, a1
285 ; RV64IM-NEXT:    .cfi_def_cfa_offset 0
286 ; RV64IM-NEXT:    ret
287   %1 = srem i32 %x, -22981
288   ret i32 %1
292 ; Don't fold if we can combine srem with sdiv.
293 define i32 @combine_srem_sdiv(i32 %x) {
294 ; RV32I-LABEL: combine_srem_sdiv:
295 ; RV32I:       # %bb.0:
296 ; RV32I-NEXT:    addi sp, sp, -16
297 ; RV32I-NEXT:    .cfi_def_cfa_offset 16
298 ; RV32I-NEXT:    sw ra, 12(sp)
299 ; RV32I-NEXT:    sw s0, 8(sp)
300 ; RV32I-NEXT:    sw s1, 4(sp)
301 ; RV32I-NEXT:    .cfi_offset ra, -4
302 ; RV32I-NEXT:    .cfi_offset s0, -8
303 ; RV32I-NEXT:    .cfi_offset s1, -12
304 ; RV32I-NEXT:    mv s0, a0
305 ; RV32I-NEXT:    addi a1, zero, 95
306 ; RV32I-NEXT:    call __modsi3
307 ; RV32I-NEXT:    mv s1, a0
308 ; RV32I-NEXT:    addi a1, zero, 95
309 ; RV32I-NEXT:    mv a0, s0
310 ; RV32I-NEXT:    call __divsi3
311 ; RV32I-NEXT:    add a0, s1, a0
312 ; RV32I-NEXT:    lw s1, 4(sp)
313 ; RV32I-NEXT:    lw s0, 8(sp)
314 ; RV32I-NEXT:    lw ra, 12(sp)
315 ; RV32I-NEXT:    .cfi_restore ra
316 ; RV32I-NEXT:    .cfi_restore s0
317 ; RV32I-NEXT:    .cfi_restore s1
318 ; RV32I-NEXT:    addi sp, sp, 16
319 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
320 ; RV32I-NEXT:    ret
322 ; RV32IM-LABEL: combine_srem_sdiv:
323 ; RV32IM:       # %bb.0:
324 ; RV32IM-NEXT:    lui a1, 706409
325 ; RV32IM-NEXT:    addi a1, a1, 389
326 ; RV32IM-NEXT:    mulh a1, a0, a1
327 ; RV32IM-NEXT:    add a1, a1, a0
328 ; RV32IM-NEXT:    srli a2, a1, 31
329 ; RV32IM-NEXT:    srai a1, a1, 6
330 ; RV32IM-NEXT:    add a1, a1, a2
331 ; RV32IM-NEXT:    addi a2, zero, 95
332 ; RV32IM-NEXT:    mul a2, a1, a2
333 ; RV32IM-NEXT:    sub a0, a0, a2
334 ; RV32IM-NEXT:    add a0, a0, a1
335 ; RV32IM-NEXT:    .cfi_def_cfa_offset 0
336 ; RV32IM-NEXT:    ret
338 ; RV64I-LABEL: combine_srem_sdiv:
339 ; RV64I:       # %bb.0:
340 ; RV64I-NEXT:    addi sp, sp, -32
341 ; RV64I-NEXT:    .cfi_def_cfa_offset 32
342 ; RV64I-NEXT:    sd ra, 24(sp)
343 ; RV64I-NEXT:    sd s0, 16(sp)
344 ; RV64I-NEXT:    sd s1, 8(sp)
345 ; RV64I-NEXT:    .cfi_offset ra, -8
346 ; RV64I-NEXT:    .cfi_offset s0, -16
347 ; RV64I-NEXT:    .cfi_offset s1, -24
348 ; RV64I-NEXT:    sext.w s0, a0
349 ; RV64I-NEXT:    addi a1, zero, 95
350 ; RV64I-NEXT:    mv a0, s0
351 ; RV64I-NEXT:    call __moddi3
352 ; RV64I-NEXT:    mv s1, a0
353 ; RV64I-NEXT:    addi a1, zero, 95
354 ; RV64I-NEXT:    mv a0, s0
355 ; RV64I-NEXT:    call __divdi3
356 ; RV64I-NEXT:    addw a0, s1, a0
357 ; RV64I-NEXT:    ld s1, 8(sp)
358 ; RV64I-NEXT:    ld s0, 16(sp)
359 ; RV64I-NEXT:    ld ra, 24(sp)
360 ; RV64I-NEXT:    .cfi_restore ra
361 ; RV64I-NEXT:    .cfi_restore s0
362 ; RV64I-NEXT:    .cfi_restore s1
363 ; RV64I-NEXT:    addi sp, sp, 32
364 ; RV64I-NEXT:    .cfi_def_cfa_offset 0
365 ; RV64I-NEXT:    ret
367 ; RV64IM-LABEL: combine_srem_sdiv:
368 ; RV64IM:       # %bb.0:
369 ; RV64IM-NEXT:    sext.w a1, a0
370 ; RV64IM-NEXT:    lui a2, 1045903
371 ; RV64IM-NEXT:    addiw a2, a2, -733
372 ; RV64IM-NEXT:    slli a2, a2, 15
373 ; RV64IM-NEXT:    addi a2, a2, 1035
374 ; RV64IM-NEXT:    slli a2, a2, 12
375 ; RV64IM-NEXT:    addi a2, a2, -905
376 ; RV64IM-NEXT:    slli a2, a2, 12
377 ; RV64IM-NEXT:    addi a2, a2, -1767
378 ; RV64IM-NEXT:    mulh a2, a1, a2
379 ; RV64IM-NEXT:    add a1, a2, a1
380 ; RV64IM-NEXT:    srli a2, a1, 63
381 ; RV64IM-NEXT:    srai a1, a1, 6
382 ; RV64IM-NEXT:    add a1, a1, a2
383 ; RV64IM-NEXT:    addi a2, zero, 95
384 ; RV64IM-NEXT:    mul a2, a1, a2
385 ; RV64IM-NEXT:    sub a0, a0, a2
386 ; RV64IM-NEXT:    addw a0, a0, a1
387 ; RV64IM-NEXT:    .cfi_def_cfa_offset 0
388 ; RV64IM-NEXT:    ret
389   %1 = srem i32 %x, 95
390   %2 = sdiv i32 %x, 95
391   %3 = add i32 %1, %2
392   ret i32 %3
395 ; Don't fold for divisors that are a power of two.
396 define i32 @dont_fold_srem_power_of_two(i32 %x) {
397 ; RV32I-LABEL: dont_fold_srem_power_of_two:
398 ; RV32I:       # %bb.0:
399 ; RV32I-NEXT:    srai a1, a0, 31
400 ; RV32I-NEXT:    srli a1, a1, 26
401 ; RV32I-NEXT:    add a1, a0, a1
402 ; RV32I-NEXT:    andi a1, a1, -64
403 ; RV32I-NEXT:    sub a0, a0, a1
404 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
405 ; RV32I-NEXT:    ret
407 ; RV32IM-LABEL: dont_fold_srem_power_of_two:
408 ; RV32IM:       # %bb.0:
409 ; RV32IM-NEXT:    srai a1, a0, 31
410 ; RV32IM-NEXT:    srli a1, a1, 26
411 ; RV32IM-NEXT:    add a1, a0, a1
412 ; RV32IM-NEXT:    andi a1, a1, -64
413 ; RV32IM-NEXT:    sub a0, a0, a1
414 ; RV32IM-NEXT:    .cfi_def_cfa_offset 0
415 ; RV32IM-NEXT:    ret
417 ; RV64I-LABEL: dont_fold_srem_power_of_two:
418 ; RV64I:       # %bb.0:
419 ; RV64I-NEXT:    sext.w a1, a0
420 ; RV64I-NEXT:    srli a1, a1, 57
421 ; RV64I-NEXT:    andi a1, a1, 63
422 ; RV64I-NEXT:    add a1, a0, a1
423 ; RV64I-NEXT:    addi a2, zero, 1
424 ; RV64I-NEXT:    slli a2, a2, 32
425 ; RV64I-NEXT:    addi a2, a2, -64
426 ; RV64I-NEXT:    and a1, a1, a2
427 ; RV64I-NEXT:    subw a0, a0, a1
428 ; RV64I-NEXT:    .cfi_def_cfa_offset 0
429 ; RV64I-NEXT:    ret
431 ; RV64IM-LABEL: dont_fold_srem_power_of_two:
432 ; RV64IM:       # %bb.0:
433 ; RV64IM-NEXT:    sext.w a1, a0
434 ; RV64IM-NEXT:    srli a1, a1, 57
435 ; RV64IM-NEXT:    andi a1, a1, 63
436 ; RV64IM-NEXT:    add a1, a0, a1
437 ; RV64IM-NEXT:    addi a2, zero, 1
438 ; RV64IM-NEXT:    slli a2, a2, 32
439 ; RV64IM-NEXT:    addi a2, a2, -64
440 ; RV64IM-NEXT:    and a1, a1, a2
441 ; RV64IM-NEXT:    subw a0, a0, a1
442 ; RV64IM-NEXT:    .cfi_def_cfa_offset 0
443 ; RV64IM-NEXT:    ret
444   %1 = srem i32 %x, 64
445   ret i32 %1
448 ; Don't fold if the divisor is one.
449 define i32 @dont_fold_srem_one(i32 %x) {
450 ; CHECK-LABEL: dont_fold_srem_one:
451 ; CHECK:       # %bb.0:
452 ; CHECK-NEXT:    mv a0, zero
453 ; CHECK-NEXT:    .cfi_def_cfa_offset 0
454 ; CHECK-NEXT:    ret
455   %1 = srem i32 %x, 1
456   ret i32 %1
459 ; Don't fold if the divisor is 2^31.
460 define i32 @dont_fold_srem_i32_smax(i32 %x) {
461 ; RV32I-LABEL: dont_fold_srem_i32_smax:
462 ; RV32I:       # %bb.0:
463 ; RV32I-NEXT:    srai a1, a0, 31
464 ; RV32I-NEXT:    srli a1, a1, 1
465 ; RV32I-NEXT:    add a1, a0, a1
466 ; RV32I-NEXT:    lui a2, 524288
467 ; RV32I-NEXT:    and a1, a1, a2
468 ; RV32I-NEXT:    add a0, a0, a1
469 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
470 ; RV32I-NEXT:    ret
472 ; RV32IM-LABEL: dont_fold_srem_i32_smax:
473 ; RV32IM:       # %bb.0:
474 ; RV32IM-NEXT:    srai a1, a0, 31
475 ; RV32IM-NEXT:    srli a1, a1, 1
476 ; RV32IM-NEXT:    add a1, a0, a1
477 ; RV32IM-NEXT:    lui a2, 524288
478 ; RV32IM-NEXT:    and a1, a1, a2
479 ; RV32IM-NEXT:    add a0, a0, a1
480 ; RV32IM-NEXT:    .cfi_def_cfa_offset 0
481 ; RV32IM-NEXT:    ret
483 ; RV64I-LABEL: dont_fold_srem_i32_smax:
484 ; RV64I:       # %bb.0:
485 ; RV64I-NEXT:    sext.w a1, a0
486 ; RV64I-NEXT:    srli a1, a1, 32
487 ; RV64I-NEXT:    lui a2, 524288
488 ; RV64I-NEXT:    addiw a2, a2, -1
489 ; RV64I-NEXT:    and a1, a1, a2
490 ; RV64I-NEXT:    add a1, a0, a1
491 ; RV64I-NEXT:    addi a2, zero, 1
492 ; RV64I-NEXT:    slli a2, a2, 31
493 ; RV64I-NEXT:    and a1, a1, a2
494 ; RV64I-NEXT:    addw a0, a0, a1
495 ; RV64I-NEXT:    .cfi_def_cfa_offset 0
496 ; RV64I-NEXT:    ret
498 ; RV64IM-LABEL: dont_fold_srem_i32_smax:
499 ; RV64IM:       # %bb.0:
500 ; RV64IM-NEXT:    sext.w a1, a0
501 ; RV64IM-NEXT:    srli a1, a1, 32
502 ; RV64IM-NEXT:    lui a2, 524288
503 ; RV64IM-NEXT:    addiw a2, a2, -1
504 ; RV64IM-NEXT:    and a1, a1, a2
505 ; RV64IM-NEXT:    add a1, a0, a1
506 ; RV64IM-NEXT:    addi a2, zero, 1
507 ; RV64IM-NEXT:    slli a2, a2, 31
508 ; RV64IM-NEXT:    and a1, a1, a2
509 ; RV64IM-NEXT:    addw a0, a0, a1
510 ; RV64IM-NEXT:    .cfi_def_cfa_offset 0
511 ; RV64IM-NEXT:    ret
512   %1 = srem i32 %x, 2147483648
513   ret i32 %1
516 ; Don't fold i64 srem
517 define i64 @dont_fold_srem_i64(i64 %x) {
518 ; RV32I-LABEL: dont_fold_srem_i64:
519 ; RV32I:       # %bb.0:
520 ; RV32I-NEXT:    addi sp, sp, -16
521 ; RV32I-NEXT:    .cfi_def_cfa_offset 16
522 ; RV32I-NEXT:    sw ra, 12(sp)
523 ; RV32I-NEXT:    .cfi_offset ra, -4
524 ; RV32I-NEXT:    addi a2, zero, 98
525 ; RV32I-NEXT:    mv a3, zero
526 ; RV32I-NEXT:    call __moddi3
527 ; RV32I-NEXT:    lw ra, 12(sp)
528 ; RV32I-NEXT:    .cfi_restore ra
529 ; RV32I-NEXT:    addi sp, sp, 16
530 ; RV32I-NEXT:    .cfi_def_cfa_offset 0
531 ; RV32I-NEXT:    ret
533 ; RV32IM-LABEL: dont_fold_srem_i64:
534 ; RV32IM:       # %bb.0:
535 ; RV32IM-NEXT:    addi sp, sp, -16
536 ; RV32IM-NEXT:    .cfi_def_cfa_offset 16
537 ; RV32IM-NEXT:    sw ra, 12(sp)
538 ; RV32IM-NEXT:    .cfi_offset ra, -4
539 ; RV32IM-NEXT:    addi a2, zero, 98
540 ; RV32IM-NEXT:    mv a3, zero
541 ; RV32IM-NEXT:    call __moddi3
542 ; RV32IM-NEXT:    lw ra, 12(sp)
543 ; RV32IM-NEXT:    .cfi_restore ra
544 ; RV32IM-NEXT:    addi sp, sp, 16
545 ; RV32IM-NEXT:    .cfi_def_cfa_offset 0
546 ; RV32IM-NEXT:    ret
548 ; RV64I-LABEL: dont_fold_srem_i64:
549 ; RV64I:       # %bb.0:
550 ; RV64I-NEXT:    addi sp, sp, -16
551 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
552 ; RV64I-NEXT:    sd ra, 8(sp)
553 ; RV64I-NEXT:    .cfi_offset ra, -8
554 ; RV64I-NEXT:    addi a1, zero, 98
555 ; RV64I-NEXT:    call __moddi3
556 ; RV64I-NEXT:    ld ra, 8(sp)
557 ; RV64I-NEXT:    .cfi_restore ra
558 ; RV64I-NEXT:    addi sp, sp, 16
559 ; RV64I-NEXT:    .cfi_def_cfa_offset 0
560 ; RV64I-NEXT:    ret
562 ; RV64IM-LABEL: dont_fold_srem_i64:
563 ; RV64IM:       # %bb.0:
564 ; RV64IM-NEXT:    lui a1, 2675
565 ; RV64IM-NEXT:    addiw a1, a1, -251
566 ; RV64IM-NEXT:    slli a1, a1, 13
567 ; RV64IM-NEXT:    addi a1, a1, 1839
568 ; RV64IM-NEXT:    slli a1, a1, 13
569 ; RV64IM-NEXT:    addi a1, a1, 167
570 ; RV64IM-NEXT:    slli a1, a1, 13
571 ; RV64IM-NEXT:    addi a1, a1, 1505
572 ; RV64IM-NEXT:    mulh a1, a0, a1
573 ; RV64IM-NEXT:    srli a2, a1, 63
574 ; RV64IM-NEXT:    srai a1, a1, 5
575 ; RV64IM-NEXT:    add a1, a1, a2
576 ; RV64IM-NEXT:    addi a2, zero, 98
577 ; RV64IM-NEXT:    mul a1, a1, a2
578 ; RV64IM-NEXT:    sub a0, a0, a1
579 ; RV64IM-NEXT:    .cfi_def_cfa_offset 0
580 ; RV64IM-NEXT:    ret
581   %1 = srem i64 %x, 98
582   ret i64 %1