Index: lib/Target/ARM/ARMISelLowering.cpp =================================================================== --- lib/Target/ARM/ARMISelLowering.cpp +++ lib/Target/ARM/ARMISelLowering.cpp @@ -806,6 +806,15 @@ setLibcallName(RTLIB::UDIVREM_I32, "__aeabi_uidivmod"); setLibcallName(RTLIB::UDIVREM_I64, "__aeabi_uldivmod"); + setLibcallName(RTLIB::SREM_I8, "__aeabi_idivmod"); + setLibcallName(RTLIB::SREM_I16, "__aeabi_idivmod"); + setLibcallName(RTLIB::SREM_I32, "__aeabi_idivmod"); + setLibcallName(RTLIB::SREM_I64, "__aeabi_idivmod"); + setLibcallName(RTLIB::UREM_I8, "__aeabi_uidivmod"); + setLibcallName(RTLIB::UREM_I16, "__aeabi_uidivmod"); + setLibcallName(RTLIB::UREM_I32, "__aeabi_uidivmod"); + setLibcallName(RTLIB::UREM_I64, "__aeabi_uidivmod"); + setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::ARM_AAPCS); setLibcallCallingConv(RTLIB::SDIVREM_I16, CallingConv::ARM_AAPCS); setLibcallCallingConv(RTLIB::SDIVREM_I32, CallingConv::ARM_AAPCS); Index: test/CodeGen/ARM/divmod-eabi.ll =================================================================== --- test/CodeGen/ARM/divmod-eabi.ll +++ test/CodeGen/ARM/divmod-eabi.ll @@ -1,16 +1,25 @@ ; RUN: llc -mtriple armv7-none-eabi %s -o - | FileCheck %s --check-prefix=EABI +; RUN: llc -mtriple armv7-none-eabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI ; RUN: llc -mtriple armv7-none-eabihf %s -o - | FileCheck %s --check-prefix=EABI +; RUN: llc -mtriple armv7-none-eabihf %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI ; All "eabi" (Bare, GNU and Android) must lower SREM/UREM to __aeabi_{u,i}divmod ; RUN: llc -mtriple armv7-linux-androideabi %s -o - | FileCheck %s --check-prefix=EABI +; RUN: llc -mtriple armv7-linux-androideabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI-2CALLS ; RUN: llc -mtriple armv7-linux-gnueabi %s -o - | FileCheck %s --check-prefix=EABI +; RUN: llc -mtriple armv7-linux-gnueabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI-2CALLS ; RUN: llc -mtriple armv7-linux-musleabi %s -o - | FileCheck %s --check-prefix=EABI +; RUN: llc -mtriple armv7-linux-musleabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=EABI-2CALLS ; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefix=DARWIN +; RUN: llc -mtriple armv7-apple-darwin %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=DARWIN-O0 ; FIXME: long-term, we will use "-apple-macho" and won't need this exception: ; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - | FileCheck %s --check-prefix=DARWIN +; RUN: llc -mtriple armv7-apple-darwin-eabi %s -o - -O0 -optimize-regalloc | FileCheck %s --check-prefix=DARWIN-O0 define signext i16 @f16(i16 signext %a, i16 signext %b) { ; EABI-LABEL: f16: +; EABI-2CALLS-LABEL: f16: ; DARWIN-LABEL: f16: +; DARWIN-O0-LABEL: f16: entry: %conv = sext i16 %a to i32 %conv1 = sext i16 %b to i32 @@ -19,20 +28,36 @@ ; EABI: __aeabi_idivmod ; EABI: mov [[div:r[0-9]+]], r0 ; EABI: mov [[rem:r[0-9]+]], r1 +; EABI-2CALLS: __aeabi_idiv +; EABI-2CALLS: mov [[div:r[0-9]+]], r0 +; EABI-2CALLS: __aeabi_idivmod +; TODO: Shouldn't the remainder be in r1? Is this another bug or am I missing something? +; EABI-2CALLS: mov [[rem:r[0-9]+]], r0 ; DARWIN: ___divsi3 ; DARWIN: mov [[sum:r[0-9]+]], r0 ; DARWIN: __modsi3 ; DARWIN: add [[sum]]{{.*}}r0 +; DARWIN-O0: ___divsi3 +; DARWIN-O0: mov [[div:r[0-9]+]], r0 +; DARWIN-O0: __modsi3 +; DARWIN-O0: mov [[rem:r[0-9]+]], r0 %rem8 = srem i32 %conv1, %conv ; EABI: __aeabi_idivmod +; EABI-2CALLS: __aeabi_idivmod ; 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 +; EABI-2CALLS: add [[sum:r[0-9]+]], [[rem]], [[div]] +; EABI-2CALLS: add [[res:r[0-9]+]], [[sum]], r0 +; EABI-2CALLS: sxth r0, [[res]] ; DARWIN: add r0{{.*}}[[sum]] ; DARWIN: sxth r0, r0 +; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]] +; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0 +; DARWIN-O0: sxth r0, [[res]] ret i16 %conv14 }