summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen
diff options
context:
space:
mode:
authorDiana Picus <diana.picus@linaro.org>2017-06-15 10:53:31 +0000
committerDiana Picus <diana.picus@linaro.org>2017-06-15 10:53:31 +0000
commit02e11010b2d46b231f2fd925e5c5b76f0811ccb4 (patch)
tree2669f0869156538b0e1f92b9287af8ae6df7565b /llvm/test/CodeGen
parent8fd1601d322235b34f97505f795f83f56be587c1 (diff)
downloadbcm5719-llvm-02e11010b2d46b231f2fd925e5c5b76f0811ccb4.tar.gz
bcm5719-llvm-02e11010b2d46b231f2fd925e5c5b76f0811ccb4.zip
[ARM] GlobalISel: Add support for i32 modulo
Add support for modulo for targets that have hardware division and for those that don't. When hardware division is not available, we have to choose the correct libcall to use. This is generally straightforward, except for AEABI. The AEABI variant is trickier than the other libcalls because it returns { quotient, remainder }, instead of just one value like the other libcalls that we've seen so far. Therefore, we need to use custom lowering for it. However, we don't want to have too much special code, so we refactor the target-independent code in the legalizer by adding a helper for replacing an instruction with a libcall. This helper is used by the legalizer itself when dealing with simple calls, and also by the custom ARM legalization for the more complicated AEABI divmod calls. llvm-svn: 305459
Diffstat (limited to 'llvm/test/CodeGen')
-rw-r--r--llvm/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll21
-rw-r--r--llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir75
2 files changed, 96 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll
index 2881740b016..c778caacd0f 100644
--- a/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll
+++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-isel-divmod.ll
@@ -66,3 +66,24 @@ define arm_aapcscc i8 @test_udiv_i8(i8 %a, i8 %b) {
ret i8 %r
}
+define arm_aapcscc i32 @test_srem_i32(i32 %x, i32 %y) {
+; CHECK-LABEL: test_srem_i32:
+; 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 i32 %x, %y
+ ret i32 %r
+}
+
+define arm_aapcscc i32 @test_urem_i32(i32 %x, i32 %y) {
+; CHECK-LABEL: test_urem_i32:
+; 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 i32 %x, %y
+ ret i32 %r
+}
diff --git a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir
index 6f3e09d328c..c93e7fa0ec5 100644
--- a/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir
+++ b/llvm/test/CodeGen/ARM/GlobalISel/arm-legalize-divmod.mir
@@ -11,6 +11,9 @@
define void @test_sdiv_i8() { ret void }
define void @test_udiv_i8() { ret void }
+
+ define void @test_srem_i32() { ret void }
+ define void @test_urem_i32() { ret void }
...
---
name: test_sdiv_i32
@@ -228,3 +231,75 @@ body: |
%r0 = COPY %2(s8)
BX_RET 14, _, implicit %r0
...
+---
+name: test_srem_i32
+# CHECK-LABEL: name: test_srem_i32
+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]+]](s32) = COPY %r0
+ ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
+ %0(s32) = COPY %r0
+ %1(s32) = COPY %r1
+ ; HWDIV: [[Q:%[0-9]+]](s32) = G_SDIV [[X]], [[Y]]
+ ; HWDIV: [[P:%[0-9]+]](s32) = G_MUL [[Q]], [[Y]]
+ ; HWDIV: [[R:%[0-9]+]](s32) = G_SUB [[X]], [[P]]
+ ; SOFT: ADJCALLSTACKDOWN
+ ; SOFT-DAG: %r0 = COPY [[X]]
+ ; SOFT-DAG: %r1 = COPY [[Y]]
+ ; SOFT-AEABI: BLX $__aeabi_idivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0, implicit-def %r1
+ ; SOFT-AEABI: [[R:%[0-9]+]](s32) = COPY %r1
+ ; SOFT-DEFAULT: BLX $__modsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+ ; SOFT-DEFAULT: [[R:%[0-9]+]](s32) = COPY %r0
+ ; SOFT: ADJCALLSTACKUP
+ %2(s32) = G_SREM %0, %1
+ ; CHECK: %r0 = COPY [[R]]
+ %r0 = COPY %2(s32)
+ BX_RET 14, _, implicit %r0
+...
+---
+name: test_urem_i32
+# CHECK-LABEL: name: test_urem_i32
+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]+]](s32) = COPY %r0
+ ; CHECK-DAG: [[Y:%[0-9]+]](s32) = COPY %r1
+ %0(s32) = COPY %r0
+ %1(s32) = COPY %r1
+ ; HWDIV: [[Q:%[0-9]+]](s32) = G_UDIV [[X]], [[Y]]
+ ; HWDIV: [[P:%[0-9]+]](s32) = G_MUL [[Q]], [[Y]]
+ ; HWDIV: [[R:%[0-9]+]](s32) = G_SUB [[X]], [[P]]
+ ; SOFT: ADJCALLSTACKDOWN
+ ; SOFT-DAG: %r0 = COPY [[X]]
+ ; SOFT-DAG: %r1 = COPY [[Y]]
+ ; SOFT-AEABI: BLX $__aeabi_uidivmod, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0, implicit-def %r1
+ ; SOFT-AEABI: [[R:%[0-9]+]](s32) = COPY %r1
+ ; SOFT-DEFAULT: BLX $__umodsi3, {{.*}}, implicit %r0, implicit %r1, implicit-def %r0
+ ; SOFT-DEFAULT: [[R:%[0-9]+]](s32) = COPY %r0
+ ; SOFT: ADJCALLSTACKUP
+ %2(s32) = G_UREM %0, %1
+ ; CHECK: %r0 = COPY [[R]]
+ %r0 = COPY %2(s32)
+ BX_RET 14, _, implicit %r0
+...
OpenPOWER on IntegriCloud