Skip to content

Commit

Permalink
[ARM] Lower modulo operation to generate __aeabi_divmod on Android
Browse files Browse the repository at this point in the history
    
For a modulo (reminder) operation,
clang -target armv7-none-linux-gnueabi generates "__modsi3"
clang -target armv7-none-eabi generates "__aeabi_idivmod"
clang -target armv7-linux-androideabi generates "__modsi3"
Android bionic libc doesn't provide a __modsi3, instead it provides a
"__aeabi_idivmod". This patch fixes the LLVM ARMISelLowering to generate
the correct call when ever there is a modulo operation.

Differential Revision: http://reviews.llvm.org/D11661

llvm-svn: 243717
  • Loading branch information
Sumanth Gundapaneni committed Jul 31, 2015
1 parent d7bdc27 commit 532a136
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 3 deletions.
7 changes: 4 additions & 3 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,11 +735,11 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::UDIV, MVT::i32, Expand);
}

// FIXME: Also set divmod for SREM on EABI
// FIXME: Also set divmod for SREM on EABI/androideabi
setOperationAction(ISD::SREM, MVT::i32, Expand);
setOperationAction(ISD::UREM, MVT::i32, Expand);
// Register based DivRem for AEABI (RTABI 4.2)
if (Subtarget->isTargetAEABI()) {
if (Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid()) {
setLibcallName(RTLIB::SDIVREM_I8, "__aeabi_idivmod");
setLibcallName(RTLIB::SDIVREM_I16, "__aeabi_idivmod");
setLibcallName(RTLIB::SDIVREM_I32, "__aeabi_idivmod");
Expand Down Expand Up @@ -11159,7 +11159,8 @@ void ARMTargetLowering::LowerAsmOperandForConstraint(SDValue Op,
}

SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
assert(Subtarget->isTargetAEABI() && "Register-based DivRem lowering only");
assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid()) &&
"Register-based DivRem lowering only");
unsigned Opcode = Op->getOpcode();
assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
"Invalid opcode for Div/Rem lowering");
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/CodeGen/ARM/divmod-eabi.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: llc -mtriple armv7-none-eabi %s -o - | FileCheck %s --check-prefix=EABI
; RUN: llc -mtriple armv7-none-eabihf %s -o - | FileCheck %s --check-prefix=EABI
; Both "none-eabi" and "androideabi" 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-gnueabi %s -o - | FileCheck %s --check-prefix=GNU
; RUN: llc -mtriple armv7-apple-darwin %s -o - | FileCheck %s --check-prefix=DARWIN
; FIXME: long-term, we will use "-apple-macho" and won't need this exception:
Expand Down

0 comments on commit 532a136

Please sign in to comment.