summaryrefslogtreecommitdiff
path: root/test/CodeGen/ARM/divmod-eabi.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/ARM/divmod-eabi.ll')
-rw-r--r--test/CodeGen/ARM/divmod-eabi.ll202
1 files changed, 202 insertions, 0 deletions
diff --git a/test/CodeGen/ARM/divmod-eabi.ll b/test/CodeGen/ARM/divmod-eabi.ll
new file mode 100644
index 0000000000000..404cae0da2b2f
--- /dev/null
+++ b/test/CodeGen/ARM/divmod-eabi.ll
@@ -0,0 +1,202 @@
+; RUN: llc -mtriple armv7-none-eabi %s -o - | FileCheck %s --check-prefix=EABI
+; RUN: llc -mtriple armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=GNU
+; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefix=DARWIN
+
+define signext i16 @f16(i16 signext %a, i16 signext %b) {
+; EABI-LABEL: f16:
+; GNU-LABEL: f16:
+; DARWIN-LABEL: f16:
+entry:
+ %conv = sext i16 %a to i32
+ %conv1 = sext i16 %b to i32
+ %div = sdiv i32 %conv, %conv1
+ %rem = srem i32 %conv, %conv1
+; EABI: __aeabi_idivmod
+; EABI: mov [[div:r[0-9]+]], r0
+; EABI: mov [[rem:r[0-9]+]], r1
+; GNU: __aeabi_idiv
+; GNU: mov [[sum:r[0-9]+]], r0
+; GNU: __modsi3
+; GNU: add [[sum]]{{.*}}r0
+; DARWIN: ___divsi3
+; DARWIN: mov [[sum:r[0-9]+]], r0
+; DARWIN: __modsi3
+; DARWIN: add [[sum]]{{.*}}r0
+ %rem8 = srem i32 %conv1, %conv
+; EABI: __aeabi_idivmod
+; GNU: __modsi3
+; DARWIN: __modsi3
+ %add = add nsw i32 %rem, %div
+ %add13 = add nsw i32 %add, %rem8
+ %conv14 = trunc i32 %add13 to i16
+; EABI: add r0{{.*}}r1
+; EABI: sxth r0, r0
+; GNU: add r0{{.*}}[[sum]]
+; GNU: sxth r0, r0
+; DARWIN: add r0{{.*}}[[sum]]
+; DARWIN: sxth r0, r0
+ ret i16 %conv14
+}
+
+define i32 @f32(i32 %a, i32 %b) {
+; EABI-LABEL: f32:
+; GNU-LABEL: f32:
+; DARWIN-LABEL: f32:
+entry:
+ %div = sdiv i32 %a, %b
+ %rem = srem i32 %a, %b
+; EABI: __aeabi_idivmod
+; EABI: mov [[div:r[0-9]+]], r0
+; EABI: mov [[rem:r[0-9]+]], r1
+; GNU: __aeabi_idiv
+; GNU: mov [[sum:r[0-9]+]], r0
+; GNU: __modsi3
+; GNU: add [[sum]]{{.*}}r0
+; DARWIN: ___divsi3
+; DARWIN: mov [[sum:r[0-9]+]], r0
+; DARWIN: __modsi3
+; DARWIN: add [[sum]]{{.*}}r0
+ %rem1 = srem i32 %b, %a
+; EABI: __aeabi_idivmod
+; GNU: __modsi3
+; DARWIN: __modsi3
+ %add = add nsw i32 %rem, %div
+ %add2 = add nsw i32 %add, %rem1
+; EABI: add r0{{.*}}r1
+; GNU: add r0{{.*}}[[sum]]
+; DARWIN: add r0{{.*}}[[sum]]
+ ret i32 %add2
+}
+
+define i32 @uf(i32 %a, i32 %b) {
+; EABI-LABEL: uf:
+; GNU-LABEL: uf:
+; DARWIN-LABEL: uf:
+entry:
+ %div = udiv i32 %a, %b
+ %rem = urem i32 %a, %b
+; EABI: __aeabi_uidivmod
+; GNU: __aeabi_uidiv
+; GNU: mov [[sum:r[0-9]+]], r0
+; GNU: __umodsi3
+; GNU: add [[sum]]{{.*}}r0
+; DARWIN: ___udivsi3
+; DARWIN: mov [[sum:r[0-9]+]], r0
+; DARWIN: __umodsi3
+; DARWIN: add [[sum]]{{.*}}r0
+ %rem1 = urem i32 %b, %a
+; EABI: __aeabi_uidivmod
+; GNU: __umodsi3
+; DARWIN: __umodsi3
+ %add = add nuw i32 %rem, %div
+ %add2 = add nuw i32 %add, %rem1
+; EABI: add r0{{.*}}r1
+; GNU: add r0{{.*}}[[sum]]
+; DARWIN: add r0{{.*}}[[sum]]
+ ret i32 %add2
+}
+
+; FIXME: AEABI is not lowering long u/srem into u/ldivmod
+define i64 @longf(i64 %a, i64 %b) {
+; EABI-LABEL: longf:
+; GNU-LABEL: longf:
+; DARWIN-LABEL: longf:
+entry:
+ %div = sdiv i64 %a, %b
+ %rem = srem i64 %a, %b
+; EABI: __aeabi_ldivmod
+; GNU: __aeabi_ldivmod
+; GNU: mov [[div1:r[0-9]+]], r0
+; GNU: mov [[div2:r[0-9]+]], r1
+; DARWIN: ___divdi3
+; DARWIN: mov [[div1:r[0-9]+]], r0
+; DARWIN: mov [[div2:r[0-9]+]], r1
+; DARWIN: __moddi3
+ %add = add nsw i64 %rem, %div
+; GNU: adds r0{{.*}}[[div1]]
+; GNU: adc r1{{.*}}[[div2]]
+; DARWIN: adds r0{{.*}}[[div1]]
+; DARWIN: adc r1{{.*}}[[div2]]
+ ret i64 %add
+}
+
+define i32 @g1(i32 %a, i32 %b) {
+; EABI-LABEL: g1:
+; GNU-LABEL: g1:
+; DARWIN-LABEL: g1:
+entry:
+ %div = sdiv i32 %a, %b
+ %rem = srem i32 %a, %b
+; EABI: __aeabi_idivmod
+; GNU: __aeabi_idiv
+; GNU: mov [[sum:r[0-9]+]], r0
+; GNU: __modsi3
+; DARWIN: ___divsi3
+; DARWIN: mov [[sum:r[0-9]+]], r0
+; DARWIN: __modsi3
+ %add = add nsw i32 %rem, %div
+; EABI: add r0{{.*}}r1
+; GNU: add r0{{.*}}[[sum]]
+; DARWIN: add r0{{.*}}[[sum]]
+ ret i32 %add
+}
+
+; On both Darwin and Gnu, this is just a call to __modsi3
+define i32 @g2(i32 %a, i32 %b) {
+; EABI-LABEL: g2:
+; GNU-LABEL: g2:
+; DARWIN-LABEL: g2:
+entry:
+ %rem = srem i32 %a, %b
+; EABI: __aeabi_idivmod
+; GNU: __modsi3
+; DARWIN: __modsi3
+ ret i32 %rem
+; EABI: mov r0, r1
+}
+
+define i32 @g3(i32 %a, i32 %b) {
+; EABI-LABEL: g3:
+; GNU-LABEL: g3:
+; DARWIN-LABEL: g3:
+entry:
+ %rem = srem i32 %a, %b
+; EABI: __aeabi_idivmod
+; EABI: mov [[mod:r[0-9]+]], r1
+; GNU: __modsi3
+; GNU: mov [[sum:r[0-9]+]], r0
+; DARWIN: __modsi3
+; DARWIN: mov [[sum:r[0-9]+]], r0
+ %rem1 = srem i32 %b, %rem
+; EABI: __aeabi_idivmod
+; GNU: __modsi3
+; DARWIN: __modsi3
+ %add = add nsw i32 %rem1, %rem
+; EABI: add r0, r1, [[mod]]
+; GNU: add r0{{.*}}[[sum]]
+; DARWIN: add r0{{.*}}[[sum]]
+ ret i32 %add
+}
+
+define i32 @g4(i32 %a, i32 %b) {
+; EABI-LABEL: g4:
+; GNU-LABEL: g4:
+; DARWIN-LABEL: g4:
+entry:
+ %div = sdiv i32 %a, %b
+; EABI: __aeabi_idivmod
+; EABI: mov [[div:r[0-9]+]], r0
+; GNU __aeabi_idiv
+; GNU: mov [[sum:r[0-9]+]], r0
+; DARWIN: ___divsi3
+; DARWIN: mov [[sum:r[0-9]+]], r0
+ %rem = srem i32 %b, %div
+; EABI: __aeabi_idivmod
+; GNU: __modsi3
+; DARWIN: __modsi3
+ %add = add nsw i32 %rem, %div
+; EABI: add r0, r1, [[div]]
+; GNU: add r0{{.*}}[[sum]]
+; DARWIN: add r0{{.*}}[[sum]]
+ ret i32 %add
+}