llvm.org GIT mirror llvm / 0d7672e
[ARM] GlobalISel: Support G_(S|U)REM for s8 and s16 Widen to s32, and then do whatever Lowering/Custom/Libcall action the subtarget wants. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308285 91177308-0d34-0410-b5e6-96231b3b80d8 Diana Picus 3 years ago
3 changed file(s) with 230 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
6565 setAction({Op, s32}, Libcall);
6666 }
6767
68 // FIXME: Support s8 and s16 as well
69 for (unsigned Op : {G_SREM, G_UREM})
68 for (unsigned Op : {G_SREM, G_UREM}) {
69 for (auto Ty : {s8, s16})
70 setAction({Op, Ty}, WidenScalar);
7071 if (ST.hasDivideInARMMode())
7172 setAction({Op, s32}, Lower);
7273 else if (AEABI(ST))
7374 setAction({Op, s32}, Custom);
7475 else
7576 setAction({Op, s32}, Libcall);
77 }
7678
7779 for (unsigned Op : {G_SEXT, G_ZEXT}) {
7880 setAction({Op, s32}, Legal);
8686 %r = urem i32 %x, %y
8787 ret i32 %r
8888 }
89
90 define arm_aapcscc i16 @test_srem_i16(i16 %x, i16 %y) {
91 ; CHECK-LABEL: test_srem_i16:
92 ; CHECK-DAG: sxth r0, r0
93 ; CHECK-DAG: sxth r1, r1
94 ; HWDIV: sdiv [[Q:r[0-9]+]], r0, r1
95 ; HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
96 ; HWDIV: sub r0, r0, [[P]]
97 ; SOFT-AEABI: blx __aeabi_idivmod
98 ; SOFT-DEFAULT: blx __modsi3
99 %r = srem i16 %x, %y
100 ret i16 %r
101 }
102
103 define arm_aapcscc i16 @test_urem_i16(i16 %x, i16 %y) {
104 ; CHECK-LABEL: test_urem_i16:
105 ; CHECK-DAG: uxth r0, r0
106 ; CHECK-DAG: uxth r1, r1
107 ; HWDIV: udiv [[Q:r[0-9]+]], r0, r1
108 ; HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
109 ; HWDIV: sub r0, r0, [[P]]
110 ; SOFT-AEABI: blx __aeabi_uidivmod
111 ; SOFT-DEFAULT: blx __umodsi3
112 %r = urem i16 %x, %y
113 ret i16 %r
114 }
115
116 define arm_aapcscc i8 @test_srem_i8(i8 %x, i8 %y) {
117 ; CHECK-LABEL: test_srem_i8:
118 ; CHECK-DAG: sxtb r0, r0
119 ; CHECK-DAG: sxtb r1, r1
120 ; HWDIV: sdiv [[Q:r[0-9]+]], r0, r1
121 ; HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
122 ; HWDIV: sub r0, r0, [[P]]
123 ; SOFT-AEABI: blx __aeabi_idivmod
124 ; SOFT-DEFAULT: blx __modsi3
125 %r = srem i8 %x, %y
126 ret i8 %r
127 }
128
129 define arm_aapcscc i8 @test_urem_i8(i8 %x, i8 %y) {
130 ; CHECK-LABEL: test_urem_i8:
131 ; CHECK-DAG: uxtb r0, r0
132 ; CHECK-DAG: uxtb r1, r1
133 ; HWDIV: udiv [[Q:r[0-9]+]], r0, r1
134 ; HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
135 ; HWDIV: sub r0, r0, [[P]]
136 ; SOFT-AEABI: blx __aeabi_uidivmod
137 ; SOFT-DEFAULT: blx __umodsi3
138 %r = urem i8 %x, %y
139 ret i8 %r
140 }
1313
1414 define void @test_srem_i32() { ret void }
1515 define void @test_urem_i32() { ret void }
16
17 define void @test_srem_i16() { ret void }
18 define void @test_urem_i16() { ret void }
19
20 define void @test_srem_i8() { ret void }
21 define void @test_urem_i8() { ret void }
1622 ...
1723 ---
1824 name: test_sdiv_i32
322328 %r0 = COPY %2(s32)
323329 BX_RET 14, _, implicit %r0
324330 ...
331 ---
332 name: test_srem_i16
333 # CHECK-LABEL: name: test_srem_i16
334 legalized: false
335 # CHECK: legalized: true
336 regBankSelected: false
337 selected: false
338 tracksRegLiveness: true
339 registers:
340 - { id: 0, class: _ }
341 - { id: 1, class: _ }
342 - { id: 2, class: _ }
343 body: |
344 bb.0:
345 liveins: %r0, %r1
346
347 ; CHECK-DAG: [[X:%[0-9]+]](s16) = COPY %r0
348 ; CHECK-DAG: [[Y:%[0-9]+]](s16) = COPY %r1
349 ; CHECK-DAG: [[X32:%[0-9]+]](s32) = G_SEXT [[X]](s16)
350 ; CHECK-DAG: [[Y32:%[0-9]+]](s32) = G_SEXT [[Y]](s16)
351 %0(s16) = COPY %r0
352 %1(s16) = COPY %r1
353 ; HWDIV: [[Q32:%[0-9]+]](s32) = G_SDIV [[X32]], [[Y32]]
354 ; HWDIV: [[P32:%[0-9]+]](s32) = G_MUL [[Q32]], [[Y32]]
355 ; HWDIV: [[R32:%[0-9]+]](s32) = G_SUB [[X32]], [[P32]]
356 ; SOFT-NOT: G_SREM
357 ; SOFT: ADJCALLSTACKDOWN
358 ; SOFT-DAG: %r0 = COPY [[X32]]
359 ; SOFT-DAG: %r1 = COPY [[Y32]]
360 ; SOFT-AEABI: BLX $__aeabi_idivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
361 ; SOFT-AEABI: [[R32:%[0-9]+]](s32) = COPY %r1
362 ; SOFT-DEFAULT: BLX $__modsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
363 ; SOFT-DEFAULT: [[R32:%[0-9]+]](s32) = COPY %r0
364 ; SOFT: ADJCALLSTACKUP
365 ; SOFT-NOT: G_SREM
366 ; CHECK: [[R:%[0-9]+]](s16) = G_TRUNC [[R32]]
367 ; SOFT-NOT: G_SREM
368 %2(s16) = G_SREM %0, %1
369 ; CHECK: %r0 = COPY [[R]]
370 %r0 = COPY %2(s16)
371 BX_RET 14, _, implicit %r0
372 ...
373 ---
374 name: test_urem_i16
375 # CHECK-LABEL: name: test_urem_i16
376 legalized: false
377 # CHECK: legalized: true
378 regBankSelected: false
379 selected: false
380 tracksRegLiveness: true
381 registers:
382 - { id: 0, class: _ }
383 - { id: 1, class: _ }
384 - { id: 2, class: _ }
385 body: |
386 bb.0:
387 liveins: %r0, %r1
388
389 ; CHECK-DAG: [[X:%[0-9]+]](s16) = COPY %r0
390 ; CHECK-DAG: [[Y:%[0-9]+]](s16) = COPY %r1
391 ; CHECK-DAG: [[X32:%[0-9]+]](s32) = G_ZEXT [[X]](s16)
392 ; CHECK-DAG: [[Y32:%[0-9]+]](s32) = G_ZEXT [[Y]](s16)
393 %0(s16) = COPY %r0
394 %1(s16) = COPY %r1
395 ; HWDIV: [[Q32:%[0-9]+]](s32) = G_UDIV [[X32]], [[Y32]]
396 ; HWDIV: [[P32:%[0-9]+]](s32) = G_MUL [[Q32]], [[Y32]]
397 ; HWDIV: [[R32:%[0-9]+]](s32) = G_SUB [[X32]], [[P32]]
398 ; SOFT-NOT: G_UREM
399 ; SOFT: ADJCALLSTACKDOWN
400 ; SOFT-DAG: %r0 = COPY [[X32]]
401 ; SOFT-DAG: %r1 = COPY [[Y32]]
402 ; SOFT-AEABI: BLX $__aeabi_uidivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
403 ; SOFT-AEABI: [[R32:%[0-9]+]](s32) = COPY %r1
404 ; SOFT-DEFAULT: BLX $__umodsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
405 ; SOFT-DEFAULT: [[R32:%[0-9]+]](s32) = COPY %r0
406 ; SOFT: ADJCALLSTACKUP
407 ; SOFT-NOT: G_UREM
408 ; CHECK: [[R:%[0-9]+]](s16) = G_TRUNC [[R32]]
409 ; SOFT-NOT: G_UREM
410 %2(s16) = G_UREM %0, %1
411 ; CHECK: %r0 = COPY [[R]]
412 %r0 = COPY %2(s16)
413 BX_RET 14, _, implicit %r0
414 ...
415 ---
416 name: test_srem_i8
417 # CHECK-LABEL: name: test_srem_i8
418 legalized: false
419 # CHECK: legalized: true
420 regBankSelected: false
421 selected: false
422 tracksRegLiveness: true
423 registers:
424 - { id: 0, class: _ }
425 - { id: 1, class: _ }
426 - { id: 2, class: _ }
427 body: |
428 bb.0:
429 liveins: %r0, %r1
430
431 ; CHECK-DAG: [[X:%[0-9]+]](s8) = COPY %r0
432 ; CHECK-DAG: [[Y:%[0-9]+]](s8) = COPY %r1
433 ; CHECK-DAG: [[X32:%[0-9]+]](s32) = G_SEXT [[X]](s8)
434 ; CHECK-DAG: [[Y32:%[0-9]+]](s32) = G_SEXT [[Y]](s8)
435 %0(s8) = COPY %r0
436 %1(s8) = COPY %r1
437 ; HWDIV: [[Q32:%[0-9]+]](s32) = G_SDIV [[X32]], [[Y32]]
438 ; HWDIV: [[P32:%[0-9]+]](s32) = G_MUL [[Q32]], [[Y32]]
439 ; HWDIV: [[R32:%[0-9]+]](s32) = G_SUB [[X32]], [[P32]]
440 ; SOFT-NOT: G_SREM
441 ; SOFT: ADJCALLSTACKDOWN
442 ; SOFT-DAG: %r0 = COPY [[X32]]
443 ; SOFT-DAG: %r1 = COPY [[Y32]]
444 ; SOFT-AEABI: BLX $__aeabi_idivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
445 ; SOFT-AEABI: [[R32:%[0-9]+]](s32) = COPY %r1
446 ; SOFT-DEFAULT: BLX $__modsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
447 ; SOFT-DEFAULT: [[R32:%[0-9]+]](s32) = COPY %r0
448 ; SOFT: ADJCALLSTACKUP
449 ; SOFT-NOT: G_SREM
450 ; CHECK: [[R:%[0-9]+]](s8) = G_TRUNC [[R32]]
451 ; SOFT-NOT: G_SREM
452 %2(s8) = G_SREM %0, %1
453 ; CHECK: %r0 = COPY [[R]]
454 %r0 = COPY %2(s8)
455 BX_RET 14, _, implicit %r0
456 ...
457 ---
458 name: test_urem_i8
459 # CHECK-LABEL: name: test_urem_i8
460 legalized: false
461 # CHECK: legalized: true
462 regBankSelected: false
463 selected: false
464 tracksRegLiveness: true
465 registers:
466 - { id: 0, class: _ }
467 - { id: 1, class: _ }
468 - { id: 2, class: _ }
469 body: |
470 bb.0:
471 liveins: %r0, %r1
472
473 ; CHECK-DAG: [[X:%[0-9]+]](s8) = COPY %r0
474 ; CHECK-DAG: [[Y:%[0-9]+]](s8) = COPY %r1
475 ; CHECK-DAG: [[X32:%[0-9]+]](s32) = G_ZEXT [[X]](s8)
476 ; CHECK-DAG: [[Y32:%[0-9]+]](s32) = G_ZEXT [[Y]](s8)
477 %0(s8) = COPY %r0
478 %1(s8) = COPY %r1
479 ; HWDIV: [[Q32:%[0-9]+]](s32) = G_UDIV [[X32]], [[Y32]]
480 ; HWDIV: [[P32:%[0-9]+]](s32) = G_MUL [[Q32]], [[Y32]]
481 ; HWDIV: [[R32:%[0-9]+]](s32) = G_SUB [[X32]], [[P32]]
482 ; SOFT-NOT: G_UREM
483 ; SOFT: ADJCALLSTACKDOWN
484 ; SOFT-DAG: %r0 = COPY [[X32]]
485 ; SOFT-DAG: %r1 = COPY [[Y32]]
486 ; SOFT-AEABI: BLX $__aeabi_uidivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
487 ; SOFT-AEABI: [[R32:%[0-9]+]](s32) = COPY %r1
488 ; SOFT-DEFAULT: BLX $__umodsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
489 ; SOFT-DEFAULT: [[R32:%[0-9]+]](s32) = COPY %r0
490 ; SOFT: ADJCALLSTACKUP
491 ; SOFT-NOT: G_UREM
492 ; CHECK: [[R:%[0-9]+]](s8) = G_TRUNC [[R32]]
493 ; SOFT-NOT: G_UREM
494 %2(s8) = G_UREM %0, %1
495 ; CHECK: %r0 = COPY [[R]]
496 %r0 = COPY %2(s8)
497 BX_RET 14, _, implicit %r0
498 ...