summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp4
-rw-r--r--llvm/test/CodeGen/ARM/divmod-hwdiv.ll37
2 files changed, 40 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index e697c8ca533..1cc7da3c9a0 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -13052,7 +13052,9 @@ SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
// rem = a - b * div
// return {div, rem}
// This should be lowered into UDIV/SDIV + MLS later on.
- if (Subtarget->hasDivide() && Op->getValueType(0).isSimple() &&
+ bool hasDivide = Subtarget->isThumb() ? Subtarget->hasDivide()
+ : Subtarget->hasDivideInARMMode();
+ if (hasDivide && Op->getValueType(0).isSimple() &&
Op->getSimpleValueType(0) == MVT::i32) {
unsigned DivOpcode = isSigned ? ISD::SDIV : ISD::UDIV;
const SDValue Dividend = Op->getOperand(0);
diff --git a/llvm/test/CodeGen/ARM/divmod-hwdiv.ll b/llvm/test/CodeGen/ARM/divmod-hwdiv.ll
new file mode 100644
index 00000000000..4cc316ffa3e
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/divmod-hwdiv.ll
@@ -0,0 +1,37 @@
+; The hwdiv subtarget feature should only influence thumb, not arm.
+; RUN: llc < %s -mtriple=arm-gnueabi -mattr=+hwdiv | FileCheck %s -check-prefixes=ALL,AEABI-NOHWDIV
+; RUN: llc < %s -mtriple=arm-gnueabi -mattr=-hwdiv | FileCheck %s -check-prefixes=ALL,AEABI-NOHWDIV
+; RUN: llc < %s -mtriple=thumbv7-gnueabi -mattr=+hwdiv | FileCheck %s -check-prefixes=ALL,THUMB-HWDIV
+; RUN: llc < %s -mtriple=thumbv7-gnueabi -mattr=-hwdiv | FileCheck %s -check-prefixes=ALL,AEABI-NOHWDIV
+
+; The hwdiv-arm subtarget feature should only influence arm, not thumb.
+; RUN: llc < %s -mtriple=arm-gnueabi -mattr=+hwdiv-arm | FileCheck %s -check-prefixes=ALL,ARM-HWDIV
+; RUN: llc < %s -mtriple=arm-gnueabi -mattr=-hwdiv-arm | FileCheck %s -check-prefixes=ALL,AEABI-NOHWDIV
+; RUN: llc < %s -mtriple=thumbv7-gnueabi -mattr=+hwdiv-arm | FileCheck %s -check-prefixes=ALL,AEABI-NOHWDIV
+; RUN: llc < %s -mtriple=thumbv7-gnueabi -mattr=-hwdiv-arm | FileCheck %s -check-prefixes=ALL,AEABI-NOHWDIV
+
+define arm_aapcscc i32 @test_i32_srem(i32 %x, i32 %y) {
+; ALL-LABEL: test_i32_srem:
+; ARM-HWDIV: sdiv [[Q:r[0-9]+]], r0, r1
+; ARM-HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
+; ARM-HWDIV: sub r0, r0, [[P]]
+; THUMB-HWDIV: sdiv [[Q:r[0-9]+]], r0, r1
+; THUMB-HWDIV: mls r0, [[Q]], r1, r0
+; AEABI-NOHWDIV: bl __aeabi_idivmod
+; AEABI-NOHWDIV: mov r0, r1
+ %r = srem i32 %x, %y
+ ret i32 %r
+}
+
+define arm_aapcscc i32 @test_i32_urem(i32 %x, i32 %y) {
+; ALL-LABEL: test_i32_urem:
+; ARM-HWDIV: udiv [[Q:r[0-9]+]], r0, r1
+; ARM-HWDIV: mul [[P:r[0-9]+]], [[Q]], r1
+; ARM-HWDIV: sub r0, r0, [[P]]
+; THUMB-HWDIV: udiv [[Q:r[0-9]+]], r0, r1
+; THUMB-HWDIV: mls r0, [[Q]], r1, r0
+; AEABI-NOHWDIV: bl __aeabi_uidivmod
+; AEABI-NOHWDIV: mov r0, r1
+ %r = urem i32 %x, %y
+ ret i32 %r
+}
OpenPOWER on IntegriCloud