mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-13 06:29:59 +00:00
[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. llvm-svn: 308285
This commit is contained in:
parent
caa2269e29
commit
5112f60df1
@ -66,14 +66,16 @@ ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) {
|
||||
setAction({Op, s32}, Libcall);
|
||||
}
|
||||
|
||||
// FIXME: Support s8 and s16 as well
|
||||
for (unsigned Op : {G_SREM, G_UREM})
|
||||
for (unsigned Op : {G_SREM, G_UREM}) {
|
||||
for (auto Ty : {s8, s16})
|
||||
setAction({Op, Ty}, WidenScalar);
|
||||
if (ST.hasDivideInARMMode())
|
||||
setAction({Op, s32}, Lower);
|
||||
else if (AEABI(ST))
|
||||
setAction({Op, s32}, Custom);
|
||||
else
|
||||
setAction({Op, s32}, Libcall);
|
||||
}
|
||||
|
||||
for (unsigned Op : {G_SEXT, G_ZEXT}) {
|
||||
setAction({Op, s32}, Legal);
|
||||
|
@ -87,3 +87,55 @@ define arm_aapcscc i32 @test_urem_i32(i32 %x, i32 %y) {
|
||||
%r = urem i32 %x, %y
|
||||
ret i32 %r
|
||||
}
|
||||
|
||||
define arm_aapcscc i16 @test_srem_i16(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: test_srem_i16:
|
||||
; CHECK-DAG: sxth r0, r0
|
||||
; CHECK-DAG: sxth r1, r1
|
||||
; HWDIV: sdiv [[Q:r[0-9]+]], r0, r1
|
||||
; HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
|
||||
; HWDIV: sub r0, r0, [[P]]
|
||||
; SOFT-AEABI: blx __aeabi_idivmod
|
||||
; SOFT-DEFAULT: blx __modsi3
|
||||
%r = srem i16 %x, %y
|
||||
ret i16 %r
|
||||
}
|
||||
|
||||
define arm_aapcscc i16 @test_urem_i16(i16 %x, i16 %y) {
|
||||
; CHECK-LABEL: test_urem_i16:
|
||||
; CHECK-DAG: uxth r0, r0
|
||||
; CHECK-DAG: uxth r1, r1
|
||||
; HWDIV: udiv [[Q:r[0-9]+]], r0, r1
|
||||
; HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
|
||||
; HWDIV: sub r0, r0, [[P]]
|
||||
; SOFT-AEABI: blx __aeabi_uidivmod
|
||||
; SOFT-DEFAULT: blx __umodsi3
|
||||
%r = urem i16 %x, %y
|
||||
ret i16 %r
|
||||
}
|
||||
|
||||
define arm_aapcscc i8 @test_srem_i8(i8 %x, i8 %y) {
|
||||
; CHECK-LABEL: test_srem_i8:
|
||||
; CHECK-DAG: sxtb r0, r0
|
||||
; CHECK-DAG: sxtb r1, r1
|
||||
; HWDIV: sdiv [[Q:r[0-9]+]], r0, r1
|
||||
; HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
|
||||
; HWDIV: sub r0, r0, [[P]]
|
||||
; SOFT-AEABI: blx __aeabi_idivmod
|
||||
; SOFT-DEFAULT: blx __modsi3
|
||||
%r = srem i8 %x, %y
|
||||
ret i8 %r
|
||||
}
|
||||
|
||||
define arm_aapcscc i8 @test_urem_i8(i8 %x, i8 %y) {
|
||||
; CHECK-LABEL: test_urem_i8:
|
||||
; CHECK-DAG: uxtb r0, r0
|
||||
; CHECK-DAG: uxtb r1, r1
|
||||
; HWDIV: udiv [[Q:r[0-9]+]], r0, r1
|
||||
; HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
|
||||
; HWDIV: sub r0, r0, [[P]]
|
||||
; SOFT-AEABI: blx __aeabi_uidivmod
|
||||
; SOFT-DEFAULT: blx __umodsi3
|
||||
%r = urem i8 %x, %y
|
||||
ret i8 %r
|
||||
}
|
||||
|
@ -14,6 +14,12 @@
|
||||
|
||||
define void @test_srem_i32() { ret void }
|
||||
define void @test_urem_i32() { ret void }
|
||||
|
||||
define void @test_srem_i16() { ret void }
|
||||
define void @test_urem_i16() { ret void }
|
||||
|
||||
define void @test_srem_i8() { ret void }
|
||||
define void @test_urem_i8() { ret void }
|
||||
...
|
||||
---
|
||||
name: test_sdiv_i32
|
||||
@ -323,3 +329,171 @@ body: |
|
||||
%r0 = COPY %2(s32)
|
||||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
---
|
||||
name: test_srem_i16
|
||||
# CHECK-LABEL: name: test_srem_i16
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %r0, %r1
|
||||
|
||||
; CHECK-DAG: [[X:%[0-9]+]](s16) = COPY %r0
|
||||
; CHECK-DAG: [[Y:%[0-9]+]](s16) = COPY %r1
|
||||
; CHECK-DAG: [[X32:%[0-9]+]](s32) = G_SEXT [[X]](s16)
|
||||
; CHECK-DAG: [[Y32:%[0-9]+]](s32) = G_SEXT [[Y]](s16)
|
||||
%0(s16) = COPY %r0
|
||||
%1(s16) = COPY %r1
|
||||
; HWDIV: [[Q32:%[0-9]+]](s32) = G_SDIV [[X32]], [[Y32]]
|
||||
; HWDIV: [[P32:%[0-9]+]](s32) = G_MUL [[Q32]], [[Y32]]
|
||||
; HWDIV: [[R32:%[0-9]+]](s32) = G_SUB [[X32]], [[P32]]
|
||||
; SOFT-NOT: G_SREM
|
||||
; SOFT: ADJCALLSTACKDOWN
|
||||
; SOFT-DAG: %r0 = COPY [[X32]]
|
||||
; SOFT-DAG: %r1 = COPY [[Y32]]
|
||||
; SOFT-AEABI: BLX $__aeabi_idivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
|
||||
; SOFT-AEABI: [[R32:%[0-9]+]](s32) = COPY %r1
|
||||
; SOFT-DEFAULT: BLX $__modsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
|
||||
; SOFT-DEFAULT: [[R32:%[0-9]+]](s32) = COPY %r0
|
||||
; SOFT: ADJCALLSTACKUP
|
||||
; SOFT-NOT: G_SREM
|
||||
; CHECK: [[R:%[0-9]+]](s16) = G_TRUNC [[R32]]
|
||||
; SOFT-NOT: G_SREM
|
||||
%2(s16) = G_SREM %0, %1
|
||||
; CHECK: %r0 = COPY [[R]]
|
||||
%r0 = COPY %2(s16)
|
||||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
---
|
||||
name: test_urem_i16
|
||||
# CHECK-LABEL: name: test_urem_i16
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %r0, %r1
|
||||
|
||||
; CHECK-DAG: [[X:%[0-9]+]](s16) = COPY %r0
|
||||
; CHECK-DAG: [[Y:%[0-9]+]](s16) = COPY %r1
|
||||
; CHECK-DAG: [[X32:%[0-9]+]](s32) = G_ZEXT [[X]](s16)
|
||||
; CHECK-DAG: [[Y32:%[0-9]+]](s32) = G_ZEXT [[Y]](s16)
|
||||
%0(s16) = COPY %r0
|
||||
%1(s16) = COPY %r1
|
||||
; HWDIV: [[Q32:%[0-9]+]](s32) = G_UDIV [[X32]], [[Y32]]
|
||||
; HWDIV: [[P32:%[0-9]+]](s32) = G_MUL [[Q32]], [[Y32]]
|
||||
; HWDIV: [[R32:%[0-9]+]](s32) = G_SUB [[X32]], [[P32]]
|
||||
; SOFT-NOT: G_UREM
|
||||
; SOFT: ADJCALLSTACKDOWN
|
||||
; SOFT-DAG: %r0 = COPY [[X32]]
|
||||
; SOFT-DAG: %r1 = COPY [[Y32]]
|
||||
; SOFT-AEABI: BLX $__aeabi_uidivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
|
||||
; SOFT-AEABI: [[R32:%[0-9]+]](s32) = COPY %r1
|
||||
; SOFT-DEFAULT: BLX $__umodsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
|
||||
; SOFT-DEFAULT: [[R32:%[0-9]+]](s32) = COPY %r0
|
||||
; SOFT: ADJCALLSTACKUP
|
||||
; SOFT-NOT: G_UREM
|
||||
; CHECK: [[R:%[0-9]+]](s16) = G_TRUNC [[R32]]
|
||||
; SOFT-NOT: G_UREM
|
||||
%2(s16) = G_UREM %0, %1
|
||||
; CHECK: %r0 = COPY [[R]]
|
||||
%r0 = COPY %2(s16)
|
||||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
---
|
||||
name: test_srem_i8
|
||||
# CHECK-LABEL: name: test_srem_i8
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %r0, %r1
|
||||
|
||||
; CHECK-DAG: [[X:%[0-9]+]](s8) = COPY %r0
|
||||
; CHECK-DAG: [[Y:%[0-9]+]](s8) = COPY %r1
|
||||
; CHECK-DAG: [[X32:%[0-9]+]](s32) = G_SEXT [[X]](s8)
|
||||
; CHECK-DAG: [[Y32:%[0-9]+]](s32) = G_SEXT [[Y]](s8)
|
||||
%0(s8) = COPY %r0
|
||||
%1(s8) = COPY %r1
|
||||
; HWDIV: [[Q32:%[0-9]+]](s32) = G_SDIV [[X32]], [[Y32]]
|
||||
; HWDIV: [[P32:%[0-9]+]](s32) = G_MUL [[Q32]], [[Y32]]
|
||||
; HWDIV: [[R32:%[0-9]+]](s32) = G_SUB [[X32]], [[P32]]
|
||||
; SOFT-NOT: G_SREM
|
||||
; SOFT: ADJCALLSTACKDOWN
|
||||
; SOFT-DAG: %r0 = COPY [[X32]]
|
||||
; SOFT-DAG: %r1 = COPY [[Y32]]
|
||||
; SOFT-AEABI: BLX $__aeabi_idivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
|
||||
; SOFT-AEABI: [[R32:%[0-9]+]](s32) = COPY %r1
|
||||
; SOFT-DEFAULT: BLX $__modsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
|
||||
; SOFT-DEFAULT: [[R32:%[0-9]+]](s32) = COPY %r0
|
||||
; SOFT: ADJCALLSTACKUP
|
||||
; SOFT-NOT: G_SREM
|
||||
; CHECK: [[R:%[0-9]+]](s8) = G_TRUNC [[R32]]
|
||||
; SOFT-NOT: G_SREM
|
||||
%2(s8) = G_SREM %0, %1
|
||||
; CHECK: %r0 = COPY [[R]]
|
||||
%r0 = COPY %2(s8)
|
||||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
---
|
||||
name: test_urem_i8
|
||||
# CHECK-LABEL: name: test_urem_i8
|
||||
legalized: false
|
||||
# CHECK: legalized: true
|
||||
regBankSelected: false
|
||||
selected: false
|
||||
tracksRegLiveness: true
|
||||
registers:
|
||||
- { id: 0, class: _ }
|
||||
- { id: 1, class: _ }
|
||||
- { id: 2, class: _ }
|
||||
body: |
|
||||
bb.0:
|
||||
liveins: %r0, %r1
|
||||
|
||||
; CHECK-DAG: [[X:%[0-9]+]](s8) = COPY %r0
|
||||
; CHECK-DAG: [[Y:%[0-9]+]](s8) = COPY %r1
|
||||
; CHECK-DAG: [[X32:%[0-9]+]](s32) = G_ZEXT [[X]](s8)
|
||||
; CHECK-DAG: [[Y32:%[0-9]+]](s32) = G_ZEXT [[Y]](s8)
|
||||
%0(s8) = COPY %r0
|
||||
%1(s8) = COPY %r1
|
||||
; HWDIV: [[Q32:%[0-9]+]](s32) = G_UDIV [[X32]], [[Y32]]
|
||||
; HWDIV: [[P32:%[0-9]+]](s32) = G_MUL [[Q32]], [[Y32]]
|
||||
; HWDIV: [[R32:%[0-9]+]](s32) = G_SUB [[X32]], [[P32]]
|
||||
; SOFT-NOT: G_UREM
|
||||
; SOFT: ADJCALLSTACKDOWN
|
||||
; SOFT-DAG: %r0 = COPY [[X32]]
|
||||
; SOFT-DAG: %r1 = COPY [[Y32]]
|
||||
; SOFT-AEABI: BLX $__aeabi_uidivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
|
||||
; SOFT-AEABI: [[R32:%[0-9]+]](s32) = COPY %r1
|
||||
; SOFT-DEFAULT: BLX $__umodsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
|
||||
; SOFT-DEFAULT: [[R32:%[0-9]+]](s32) = COPY %r0
|
||||
; SOFT: ADJCALLSTACKUP
|
||||
; SOFT-NOT: G_UREM
|
||||
; CHECK: [[R:%[0-9]+]](s8) = G_TRUNC [[R32]]
|
||||
; SOFT-NOT: G_UREM
|
||||
%2(s8) = G_UREM %0, %1
|
||||
; CHECK: %r0 = COPY [[R]]
|
||||
%r0 = COPY %2(s8)
|
||||
BX_RET 14, _, implicit %r0
|
||||
...
|
||||
|
Loading…
Reference in New Issue
Block a user