Backport more llvm patches from current master
This fixes up handling of divisions on ARM/Windows, and consistently does calls to helper functions using the windows/msvc names, instead of the libgcc naming.
This commit is contained in:
1 parent
f3b034f10a
commit
be1357f467
3 files changed
+797
No files matched your search
@@ -0,0 +1,361 @@
|
|||||||
|
From ed632cebfe6b046152e3f353c7a70ae4c4efea52 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Martin Storsjo <martin@martin.st>
|
||||||
|
Date: Fri, 7 Oct 2016 13:28:53 +0000
|
||||||
|
Subject: [PATCH 7/9] [ARM] Reapply: Use __rt_div functions for divrem on
|
||||||
|
Windows
|
||||||
|
|
||||||
|
Reapplying r283383 after revert in r283442. The additional fix
|
||||||
|
is a getting rid of a stray space in a function name, in the
|
||||||
|
refactoring part of the commit.
|
||||||
|
|
||||||
|
This avoids falling back to calling out to the GCC rem functions
|
||||||
|
(__moddi3, __umoddi3) when targeting Windows.
|
||||||
|
|
||||||
|
The __rt_div functions have flipped the two arguments compared
|
||||||
|
to the __aeabi_divmod functions. To match MSVC, we emit a
|
||||||
|
check for division by zero before actually calling the library
|
||||||
|
function (even if the library function itself also might do
|
||||||
|
the same check).
|
||||||
|
|
||||||
|
Not all calls to __rt_div functions for division are currently
|
||||||
|
merged with calls to the same function with the same parameters
|
||||||
|
for the remainder. This is more wasteful than a div + mls as before,
|
||||||
|
but avoids calls to __moddi3.
|
||||||
|
|
||||||
|
Differential Revision: https://reviews.llvm.org/D25332
|
||||||
|
|
||||||
|
Cherry-picked from SVN trunk commit 283550, git mirror commit
|
||||||
|
c3339a54ac77.
|
||||||
|
---
|
||||||
|
lib/Target/ARM/ARMISelLowering.cpp | 66 ++++++++++++++++++++++++++------------
|
||||||
|
test/CodeGen/ARM/Windows/dbzchk.ll | 2 +-
|
||||||
|
test/CodeGen/ARM/divmod-eabi.ll | 56 +++++++++++++-------------------
|
||||||
|
3 files changed, 68 insertions(+), 56 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
index 3cfcb1e..8db9f54 100644
|
||||||
|
--- a/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
+++ b/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
@@ -803,19 +803,26 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||||
|
setOperationAction(ISD::UREM, MVT::i32, Expand);
|
||||||
|
// Register based DivRem for AEABI (RTABI 4.2)
|
||||||
|
if (Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
|
||||||
|
- Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI()) {
|
||||||
|
+ Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
|
||||||
|
+ Subtarget->isTargetWindows()) {
|
||||||
|
setOperationAction(ISD::SREM, MVT::i64, Custom);
|
||||||
|
setOperationAction(ISD::UREM, MVT::i64, Custom);
|
||||||
|
HasStandaloneRem = false;
|
||||||
|
|
||||||
|
- setLibcallName(RTLIB::SDIVREM_I8, "__aeabi_idivmod");
|
||||||
|
- setLibcallName(RTLIB::SDIVREM_I16, "__aeabi_idivmod");
|
||||||
|
- setLibcallName(RTLIB::SDIVREM_I32, "__aeabi_idivmod");
|
||||||
|
- setLibcallName(RTLIB::SDIVREM_I64, "__aeabi_ldivmod");
|
||||||
|
- setLibcallName(RTLIB::UDIVREM_I8, "__aeabi_uidivmod");
|
||||||
|
- setLibcallName(RTLIB::UDIVREM_I16, "__aeabi_uidivmod");
|
||||||
|
- setLibcallName(RTLIB::UDIVREM_I32, "__aeabi_uidivmod");
|
||||||
|
- setLibcallName(RTLIB::UDIVREM_I64, "__aeabi_uldivmod");
|
||||||
|
+ for (const auto &LC :
|
||||||
|
+ {RTLIB::SDIVREM_I8, RTLIB::SDIVREM_I16, RTLIB::SDIVREM_I32})
|
||||||
|
+ setLibcallName(LC, Subtarget->isTargetWindows() ? "__rt_sdiv"
|
||||||
|
+ : "__aeabi_idivmod");
|
||||||
|
+ setLibcallName(RTLIB::SDIVREM_I64, Subtarget->isTargetWindows()
|
||||||
|
+ ? "__rt_sdiv64"
|
||||||
|
+ : "__aeabi_ldivmod");
|
||||||
|
+ for (const auto &LC :
|
||||||
|
+ {RTLIB::UDIVREM_I8, RTLIB::UDIVREM_I16, RTLIB::UDIVREM_I32})
|
||||||
|
+ setLibcallName(LC, Subtarget->isTargetWindows() ? "__rt_udiv"
|
||||||
|
+ : "__aeabi_uidivmod");
|
||||||
|
+ setLibcallName(RTLIB::UDIVREM_I64, Subtarget->isTargetWindows()
|
||||||
|
+ ? "__rt_udiv64"
|
||||||
|
+ : "__aeabi_uldivmod");
|
||||||
|
|
||||||
|
setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::ARM_AAPCS);
|
||||||
|
setLibcallCallingConv(RTLIB::SDIVREM_I16, CallingConv::ARM_AAPCS);
|
||||||
|
@@ -7029,6 +7036,19 @@ SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op, SelectionDAG &DAG,
|
||||||
|
return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static SDValue WinDBZCheckDenominator(SelectionDAG &DAG, SDNode *N, SDValue InChain) {
|
||||||
|
+ SDLoc DL(N);
|
||||||
|
+ SDValue Op = N->getOperand(1);
|
||||||
|
+ if (N->getValueType(0) == MVT::i32)
|
||||||
|
+ return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain, Op);
|
||||||
|
+ SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op,
|
||||||
|
+ DAG.getConstant(0, DL, MVT::i32));
|
||||||
|
+ SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, Op,
|
||||||
|
+ DAG.getConstant(1, DL, MVT::i32));
|
||||||
|
+ return DAG.getNode(ARMISD::WIN__DBZCHK, DL, MVT::Other, InChain,
|
||||||
|
+ DAG.getNode(ISD::OR, DL, MVT::i32, Lo, Hi));
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void ARMTargetLowering::ExpandDIV_Windows(
|
||||||
|
SDValue Op, SelectionDAG &DAG, bool Signed,
|
||||||
|
SmallVectorImpl<SDValue> &Results) const {
|
||||||
|
@@ -7039,14 +7059,7 @@ void ARMTargetLowering::ExpandDIV_Windows(
|
||||||
|
"unexpected type for custom lowering DIV");
|
||||||
|
SDLoc dl(Op);
|
||||||
|
|
||||||
|
- SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op.getOperand(1),
|
||||||
|
- DAG.getConstant(0, dl, MVT::i32));
|
||||||
|
- SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, MVT::i32, Op.getOperand(1),
|
||||||
|
- DAG.getConstant(1, dl, MVT::i32));
|
||||||
|
- SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i32, Lo, Hi);
|
||||||
|
-
|
||||||
|
- SDValue DBZCHK =
|
||||||
|
- DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other, DAG.getEntryNode(), Or);
|
||||||
|
+ SDValue DBZCHK = WinDBZCheckDenominator(DAG, Op.getNode(), DAG.getEntryNode());
|
||||||
|
|
||||||
|
SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
|
||||||
|
|
||||||
|
@@ -12043,7 +12056,7 @@ static RTLIB::Libcall getDivRemLibcall(
|
||||||
|
}
|
||||||
|
|
||||||
|
static TargetLowering::ArgListTy getDivRemArgList(
|
||||||
|
- const SDNode *N, LLVMContext *Context) {
|
||||||
|
+ const SDNode *N, LLVMContext *Context, const ARMSubtarget *Subtarget) {
|
||||||
|
assert((N->getOpcode() == ISD::SDIVREM || N->getOpcode() == ISD::UDIVREM ||
|
||||||
|
N->getOpcode() == ISD::SREM || N->getOpcode() == ISD::UREM) &&
|
||||||
|
"Unhandled Opcode in getDivRemArgList");
|
||||||
|
@@ -12060,12 +12073,15 @@ static TargetLowering::ArgListTy getDivRemArgList(
|
||||||
|
Entry.isZExt = !isSigned;
|
||||||
|
Args.push_back(Entry);
|
||||||
|
}
|
||||||
|
+ if (Subtarget->isTargetWindows() && Args.size() >= 2)
|
||||||
|
+ std::swap(Args[0], Args[1]);
|
||||||
|
return Args;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
|
||||||
|
assert((Subtarget->isTargetAEABI() || Subtarget->isTargetAndroid() ||
|
||||||
|
- Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI()) &&
|
||||||
|
+ Subtarget->isTargetGNUAEABI() || Subtarget->isTargetMuslAEABI() ||
|
||||||
|
+ Subtarget->isTargetWindows()) &&
|
||||||
|
"Register-based DivRem lowering only");
|
||||||
|
unsigned Opcode = Op->getOpcode();
|
||||||
|
assert((Opcode == ISD::SDIVREM || Opcode == ISD::UDIVREM) &&
|
||||||
|
@@ -12079,13 +12095,17 @@ SDValue ARMTargetLowering::LowerDivRem(SDValue Op, SelectionDAG &DAG) const {
|
||||||
|
SDValue InChain = DAG.getEntryNode();
|
||||||
|
|
||||||
|
TargetLowering::ArgListTy Args = getDivRemArgList(Op.getNode(),
|
||||||
|
- DAG.getContext());
|
||||||
|
+ DAG.getContext(),
|
||||||
|
+ Subtarget);
|
||||||
|
|
||||||
|
SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
|
||||||
|
getPointerTy(DAG.getDataLayout()));
|
||||||
|
|
||||||
|
Type *RetTy = (Type*)StructType::get(Ty, Ty, nullptr);
|
||||||
|
|
||||||
|
+ if (Subtarget->isTargetWindows())
|
||||||
|
+ InChain = WinDBZCheckDenominator(DAG, Op.getNode(), InChain);
|
||||||
|
+
|
||||||
|
SDLoc dl(Op);
|
||||||
|
TargetLowering::CallLoweringInfo CLI(DAG);
|
||||||
|
CLI.setDebugLoc(dl).setChain(InChain)
|
||||||
|
@@ -12119,11 +12139,15 @@ SDValue ARMTargetLowering::LowerREM(SDNode *N, SelectionDAG &DAG) const {
|
||||||
|
RTLIB::Libcall LC = getDivRemLibcall(N, N->getValueType(0).getSimpleVT().
|
||||||
|
SimpleTy);
|
||||||
|
SDValue InChain = DAG.getEntryNode();
|
||||||
|
- TargetLowering::ArgListTy Args = getDivRemArgList(N, DAG.getContext());
|
||||||
|
+ TargetLowering::ArgListTy Args = getDivRemArgList(N, DAG.getContext(),
|
||||||
|
+ Subtarget);
|
||||||
|
bool isSigned = N->getOpcode() == ISD::SREM;
|
||||||
|
SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC),
|
||||||
|
getPointerTy(DAG.getDataLayout()));
|
||||||
|
|
||||||
|
+ if (Subtarget->isTargetWindows())
|
||||||
|
+ InChain = WinDBZCheckDenominator(DAG, N, InChain);
|
||||||
|
+
|
||||||
|
// Lower call
|
||||||
|
CallLoweringInfo CLI(DAG);
|
||||||
|
CLI.setChain(InChain)
|
||||||
|
diff --git a/test/CodeGen/ARM/Windows/dbzchk.ll b/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
index 599a7cf..c078e09 100644
|
||||||
|
--- a/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
+++ b/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
@@ -141,7 +141,7 @@ attributes #0 = { optsize }
|
||||||
|
; CHECK-CFG-ASM-NEXT: udf.w #249
|
||||||
|
; CHECK-CFG-ASM-LABEL: .LBB2_4:
|
||||||
|
; CHECK-CFG-ASM: bl __rt_udiv
|
||||||
|
-; CHECK-CFG-ASM: pop.w {{{.*}}, r11, pc}
|
||||||
|
+; CHECK-CFG-ASM: pop.w {r11, pc}
|
||||||
|
|
||||||
|
; RUN: llc -O0 -mtriple thumbv7--windows-itanium -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-WIN__DBZCHK
|
||||||
|
|
||||||
|
diff --git a/test/CodeGen/ARM/divmod-eabi.ll b/test/CodeGen/ARM/divmod-eabi.ll
|
||||||
|
index 1e4c8fc..ce5a1df 100644
|
||||||
|
--- a/test/CodeGen/ARM/divmod-eabi.ll
|
||||||
|
+++ b/test/CodeGen/ARM/divmod-eabi.ll
|
||||||
|
@@ -42,15 +42,13 @@ entry:
|
||||||
|
; DARWIN-DEFAULT: add [[sum:r[0-9]+]], r0, [[div]]
|
||||||
|
; DARWIN-O0: mov [[rem:r[0-9]+]], r0
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS-DEFAULT: mls [[rem:r[0-9]+]], r0,
|
||||||
|
-; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[rem]], r0
|
||||||
|
-; WINDOWS-O0: mov [[div:r[0-9]+]], r0
|
||||||
|
-; WINDOWS-O0: mls [[rem:r[0-9]+]], [[div]],
|
||||||
|
+; WINDOWS: __rt_sdiv
|
||||||
|
+; WINDOWS-DEFAULT: add [[sum:r[0-9]+]], r1
|
||||||
|
+; WINDOWS-O0: mov [[rem:r[0-9]+]], r1
|
||||||
|
%rem8 = srem i32 %conv1, %conv
|
||||||
|
; EABI: __aeabi_idivmod
|
||||||
|
; DARWIN: __modsi3
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS: mls [[rem1:r[0-9]+]], r0,
|
||||||
|
%add = add nsw i32 %rem, %div
|
||||||
|
%add13 = add nsw i32 %add, %rem8
|
||||||
|
%conv14 = trunc i32 %add13 to i16
|
||||||
|
@@ -60,9 +58,10 @@ entry:
|
||||||
|
; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
|
||||||
|
; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
|
||||||
|
; DARWIN: sxth r0, [[res]]
|
||||||
|
-; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
|
||||||
|
-; WINDOWS: add [[rem1]], [[sum]]
|
||||||
|
-; WINDOWS: sxth [[res:r[0-9]+]], [[rem1]]
|
||||||
|
+; WINDOWS-DEFAULT: adds [[sum1:r[0-9]+]], [[sum]], r1
|
||||||
|
+; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]],
|
||||||
|
+; WINDOWS-O0: add [[sum1:r[0-9]+]], r1
|
||||||
|
+; WINDOWS: sxth [[res:r[0-9]+]], [[sum1]]
|
||||||
|
ret i16 %conv14
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -84,22 +83,20 @@ entry:
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
; WINDOWS: mov [[div:r[0-9]+]], r0
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS: mls [[rem:r[0-9]+]], r0,
|
||||||
|
-; WINDOWS-DEFAULT: add [[div]], [[rem]]
|
||||||
|
+; WINDOWS-DEFAULT: add [[div]], r1
|
||||||
|
%rem1 = srem i32 %b, %a
|
||||||
|
; EABI: __aeabi_idivmod
|
||||||
|
; DARWIN: __modsi3
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS: mls [[rem1:r[0-9]+]], r0,
|
||||||
|
%add = add nsw i32 %rem, %div
|
||||||
|
%add2 = add nsw i32 %add, %rem1
|
||||||
|
; EABI: add r0{{.*}}r1
|
||||||
|
; DARWIN-DEFAULT: add r0, [[sum]], r0
|
||||||
|
; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
|
||||||
|
; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
|
||||||
|
-; WINDOWS-DEFAULT: add [[rem1]], [[div]]
|
||||||
|
+; WINDOWS-DEFAULT: adds r0, [[div]], r1
|
||||||
|
; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
|
||||||
|
-; WINDOWS-O0: add [[rem1]], [[sum]]
|
||||||
|
+; WINDOWS-O0: add [[sum]], r1
|
||||||
|
ret i32 %add2
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -119,22 +116,20 @@ entry:
|
||||||
|
; WINDOWS: __rt_udiv
|
||||||
|
; WINDOWS: mov [[div:r[0-9]+]], r0
|
||||||
|
; WINDOWS: __rt_udiv
|
||||||
|
-; WINDOWS: mls [[rem:r[0-9]+]], r0,
|
||||||
|
-; WINDOWS-DEFAULT: add [[div]], [[rem]]
|
||||||
|
+; WINDOWS-DEFAULT: add [[div]], r1
|
||||||
|
%rem1 = urem i32 %b, %a
|
||||||
|
; EABI: __aeabi_uidivmod
|
||||||
|
; DARWIN: __umodsi3
|
||||||
|
; WINDOWS: __rt_udiv
|
||||||
|
-; WINDOWS: mls [[rem1:r[0-9]+]], r0,
|
||||||
|
%add = add nuw i32 %rem, %div
|
||||||
|
%add2 = add nuw i32 %add, %rem1
|
||||||
|
; EABI: add r0{{.*}}r1
|
||||||
|
; DARWIN-DEFAULT: add r0, [[sum]], r0
|
||||||
|
; DARWIN-O0: add [[sum:r[0-9]+]], [[rem]], [[div]]
|
||||||
|
; DARWIN-O0: add [[res:r[0-9]+]], [[sum]], r0
|
||||||
|
-; WINDOWS-DEFAULT: add [[rem1]], [[div]]
|
||||||
|
-; WINDOWS-O0: adds [[sum:r[0-9]+]], [[rem]], [[div]]
|
||||||
|
-; WINDOWS-O0: add [[rem1]], [[sum]]
|
||||||
|
+; WINDOWS-DEFAULT: adds [[sum:r[0-9]+]], [[div]], r1
|
||||||
|
+; WINDOWS-O0: adds [[sum:r[0-9]+]],
|
||||||
|
+; WINDOWS-O0: add [[sum]], r1
|
||||||
|
ret i32 %add2
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -154,14 +149,11 @@ entry:
|
||||||
|
; DARWIN: mov [[div2:r[0-9]+]], r1
|
||||||
|
; DARWIN: __moddi3
|
||||||
|
; WINDOWS: __rt_sdiv64
|
||||||
|
-; WINDOWS: mov [[div1:r[0-9]+]], r0
|
||||||
|
-; WINDOWS: mov [[div2:r[0-9]+]], r1
|
||||||
|
-; WINDOWS: __moddi3
|
||||||
|
%add = add nsw i64 %rem, %div
|
||||||
|
; DARWIN: adds r0{{.*}}[[div1]]
|
||||||
|
; DARWIN: adc r1{{.*}}[[div2]]
|
||||||
|
-; WINDOWS: adds.w r0, r0, [[div1]]
|
||||||
|
-; WINDOWS: adc.w r1, r1, [[div2]]
|
||||||
|
+; WINDOWS: adds r0, r0, r2
|
||||||
|
+; WINDOWS: adcs r1, r3
|
||||||
|
ret i64 %add
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -179,11 +171,10 @@ entry:
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
; WINDOWS: mov [[div:r[0-9]+]], r0
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS: mls [[rem:r[0-9]+]], r0,
|
||||||
|
%add = add nsw i16 %rem, %div
|
||||||
|
; EABI: add r0, r1
|
||||||
|
; DARWIN: add r0{{.*}}[[div1]]
|
||||||
|
-; WINDOWS: add [[rem]], [[div]]
|
||||||
|
+; WINDOWS: adds r0, r1, [[div]]
|
||||||
|
ret i16 %add
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -201,11 +192,10 @@ entry:
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
; WINDOWS: mov [[div:r[0-9]+]], r0
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS: mls [[rem:r[0-9]+]], r0,
|
||||||
|
%add = add nsw i32 %rem, %div
|
||||||
|
; EABI: add r0{{.*}}r1
|
||||||
|
; DARWIN: add r0{{.*}}[[sum]]
|
||||||
|
-; WINDOWS: add [[rem]], [[div]]
|
||||||
|
+; WINDOWS: adds r0, r1, [[div]]
|
||||||
|
ret i32 %add
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -221,7 +211,7 @@ entry:
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
ret i32 %rem
|
||||||
|
; EABI: mov r0, r1
|
||||||
|
-; WINDOWS: mls r0, r0,
|
||||||
|
+; WINDOWS: mov r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @g3(i32 %a, i32 %b) {
|
||||||
|
@@ -235,16 +225,15 @@ entry:
|
||||||
|
; DARWIN: __modsi3
|
||||||
|
; DARWIN: mov [[sum:r[0-9]+]], r0
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS: mls [[rem:r[0-9]+]], r0,
|
||||||
|
+; WINDOWS: mov [[rem:r[0-9]+]], r1
|
||||||
|
%rem1 = srem i32 %b, %rem
|
||||||
|
; EABI: __aeabi_idivmod
|
||||||
|
; DARWIN: __modsi3
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS: mls [[rem1:r[0-9]+]], r0,
|
||||||
|
%add = add nsw i32 %rem1, %rem
|
||||||
|
; EABI: add r0, r1, [[mod]]
|
||||||
|
; DARWIN: add r0{{.*}}[[sum]]
|
||||||
|
-; WINDOWS: add [[rem1]], [[rem]]
|
||||||
|
+; WINDOWS: adds r0, r1, [[rem]]
|
||||||
|
ret i32 %add
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -264,10 +253,9 @@ entry:
|
||||||
|
; EABI: __aeabi_idivmod
|
||||||
|
; DARWIN: __modsi3
|
||||||
|
; WINDOWS: __rt_sdiv
|
||||||
|
-; WINDOWS: mls [[rem:r[0-9]+]], r0,
|
||||||
|
%add = add nsw i32 %rem, %div
|
||||||
|
; EABI: add r0, r1, [[div]]
|
||||||
|
; DARWIN: add r0{{.*}}[[sum]]
|
||||||
|
-; WINDOWS: add [[rem]], [[div]]
|
||||||
|
+; WINDOWS: adds r0, r1, [[div]]
|
||||||
|
ret i32 %add
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.7.4
|
||||||
|
|
||||||
@@ -0,0 +1,250 @@
|
|||||||
|
From a6c33deef382981590bd9298b492b612bcbae521 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Saleem Abdulrasool <compnerd@compnerd.org>
|
||||||
|
Date: Thu, 27 Oct 2016 16:59:22 +0000
|
||||||
|
Subject: [PATCH 8/9] ARM: ensure that the Windows DBZ check is in range
|
||||||
|
|
||||||
|
The Windows ARM target expects the compiler to emit a division-by-zero check.
|
||||||
|
The check would use the form of:
|
||||||
|
|
||||||
|
cmp r?, #0
|
||||||
|
cbz .Ltrap
|
||||||
|
b .Lbody
|
||||||
|
.Lbody:
|
||||||
|
...
|
||||||
|
.Ltrap:
|
||||||
|
udf #249 @ __brkdiv0
|
||||||
|
|
||||||
|
This works great most of the time. However, if the body of the function is
|
||||||
|
greater than 127 bytes, the branch target limitation of cbz becomes an issue.
|
||||||
|
This occurs in the unoptimized code generation cases sometimes (like in
|
||||||
|
compiler-rt).
|
||||||
|
|
||||||
|
Since this is a matter of correctness, possibly pay a small penalty instead. We
|
||||||
|
now form this slightly differently:
|
||||||
|
|
||||||
|
cbnz .Lbody
|
||||||
|
udf #249 @ __brkdiv0
|
||||||
|
.Lbody:
|
||||||
|
...
|
||||||
|
|
||||||
|
The positive case is through the branch instead of being the next instruction.
|
||||||
|
However, because of the basic block layout, the negated branch is going to be
|
||||||
|
a short distance always (2 bytes away, after the inserted __brkdiv0).
|
||||||
|
|
||||||
|
The new t__brkdiv0 instruction is required to explicitly mark the instruction as
|
||||||
|
a terminator as the generic UDF instruction is not a terminator.
|
||||||
|
|
||||||
|
Addresses PR30532!
|
||||||
|
|
||||||
|
Cherry-picked from SVN trunk commit 285312, git mirror commit
|
||||||
|
b5143b06a12b5.
|
||||||
|
---
|
||||||
|
lib/Target/ARM/ARMISelLowering.cpp | 11 +++------
|
||||||
|
lib/Target/ARM/ARMInstrThumb.td | 7 ++++++
|
||||||
|
test/CodeGen/ARM/Windows/dbzchk.ll | 38 +++++++++++-------------------
|
||||||
|
test/CodeGen/ARM/Windows/division-range.ll | 15 ++++++++++++
|
||||||
|
test/CodeGen/ARM/Windows/division.ll | 20 +++++++---------
|
||||||
|
5 files changed, 47 insertions(+), 44 deletions(-)
|
||||||
|
create mode 100644 test/CodeGen/ARM/Windows/division-range.ll
|
||||||
|
|
||||||
|
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
index 8db9f54..f7b09fa 100644
|
||||||
|
--- a/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
+++ b/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
@@ -8215,16 +8215,11 @@ ARMTargetLowering::EmitLowered__dbzchk(MachineInstr &MI,
|
||||||
|
std::next(MachineBasicBlock::iterator(MI)), MBB->end());
|
||||||
|
ContBB->transferSuccessorsAndUpdatePHIs(MBB);
|
||||||
|
|
||||||
|
- MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
|
||||||
|
- MF->push_back(TrapBB);
|
||||||
|
- BuildMI(TrapBB, DL, TII->get(ARM::t2UDF)).addImm(249);
|
||||||
|
- MBB->addSuccessor(TrapBB);
|
||||||
|
-
|
||||||
|
- BuildMI(*MBB, MI, DL, TII->get(ARM::tCBZ))
|
||||||
|
+ BuildMI(*MBB, MI, DL, TII->get(ARM::tCBNZ))
|
||||||
|
.addReg(MI.getOperand(0).getReg())
|
||||||
|
- .addMBB(TrapBB);
|
||||||
|
- AddDefaultPred(BuildMI(*MBB, MI, DL, TII->get(ARM::t2B)).addMBB(ContBB));
|
||||||
|
+ .addMBB(ContBB);
|
||||||
|
MBB->addSuccessor(ContBB);
|
||||||
|
+ BuildMI(*MBB, MI, DL, TII->get(ARM::t__brkdiv0));
|
||||||
|
|
||||||
|
MI.eraseFromParent();
|
||||||
|
return ContBB;
|
||||||
|
diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td
|
||||||
|
index 93a174f..6c759a1 100644
|
||||||
|
--- a/lib/Target/ARM/ARMInstrThumb.td
|
||||||
|
+++ b/lib/Target/ARM/ARMInstrThumb.td
|
||||||
|
@@ -1259,6 +1259,13 @@ def tUDF : TI<(outs), (ins imm0_255:$imm8), IIC_Br, "udf\t$imm8",
|
||||||
|
let Inst{7-0} = imm8;
|
||||||
|
}
|
||||||
|
|
||||||
|
+def t__brkdiv0 : TI<(outs), (ins), IIC_Br, "__brkdiv0",
|
||||||
|
+ [(int_arm_undefined 249)]>, Encoding16,
|
||||||
|
+ Requires<[IsThumb, IsWindows]> {
|
||||||
|
+ let Inst = 0xdef9;
|
||||||
|
+ let isTerminator = 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// Zero-extend byte
|
||||||
|
def tUXTB : // A8.6.262
|
||||||
|
T1pIMiscEncode<{0,0,1,0,1,1,?}, (outs tGPR:$Rd), (ins tGPR:$Rm),
|
||||||
|
diff --git a/test/CodeGen/ARM/Windows/dbzchk.ll b/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
index c078e09..af23cb2 100644
|
||||||
|
--- a/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
+++ b/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
@@ -33,15 +33,12 @@ return:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-DIV-DAG: BB#0
|
||||||
|
-; CHECK-DIV-DAG: Successors according to CFG: BB#5({{.*}}) BB#4
|
||||||
|
+; CHECK-DIV-DAG: Successors according to CFG: BB#1({{.*}}) BB#2
|
||||||
|
; CHECK-DIV-DAG: BB#1
|
||||||
|
; CHECK-DIV-DAG: Successors according to CFG: BB#3
|
||||||
|
; CHECK-DIV-DAG: BB#2
|
||||||
|
; CHECK-DIV-DAG: Successors according to CFG: BB#3
|
||||||
|
; CHECK-DIV-DAG: BB#3
|
||||||
|
-; CHECK-DIV-DAG: BB#4
|
||||||
|
-; CHECK-DIV-DAG: Successors according to CFG: BB#1({{.*}}) BB#2
|
||||||
|
-; CHECK-DIV-DAG: BB#5
|
||||||
|
|
||||||
|
; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s -check-prefix CHECK-MOD
|
||||||
|
|
||||||
|
@@ -72,11 +69,10 @@ return:
|
||||||
|
; CHECK-MOD-DAG: BB#0
|
||||||
|
; CHECK-MOD-DAG: Successors according to CFG: BB#2({{.*}}) BB#1
|
||||||
|
; CHECK-MOD-DAG: BB#1
|
||||||
|
-; CHECK-MOD-DAG: Successors according to CFG: BB#4({{.*}}) BB#3
|
||||||
|
-; CHECK-MOD-DAG: BB#2
|
||||||
|
+; CHECK-MOD-DAG: Successors according to CFG: BB#3
|
||||||
|
; CHECK-MOD-DAG: BB#3
|
||||||
|
; CHECK-MOD-DAG: Successors according to CFG: BB#2
|
||||||
|
-; CHECK-MOD-DAG: BB#4
|
||||||
|
+; CHECK-MOD-DAG: BB#2
|
||||||
|
|
||||||
|
; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -filetype asm -o /dev/null %s 2>&1 | FileCheck %s -check-prefix CHECK-CFG
|
||||||
|
; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-CFG-ASM
|
||||||
|
@@ -123,25 +119,19 @@ attributes #0 = { optsize }
|
||||||
|
; CHECK-CFG-DAG: t2B <BB#3>
|
||||||
|
|
||||||
|
; CHECK-CFG-DAG: BB#2
|
||||||
|
-; CHECK-CFG-DAG: tCBZ %vreg{{[0-9]}}, <BB#5>
|
||||||
|
-; CHECK-CFG-DAG: t2B <BB#4>
|
||||||
|
+; CHECK-CFG-DAG: tCBNZ %vreg{{[0-9]}}, <BB#4>
|
||||||
|
+; CHECK-CFG-DAG: t__brkdiv0
|
||||||
|
|
||||||
|
; CHECK-CFG-DAG: BB#4
|
||||||
|
|
||||||
|
; CHECK-CFG-DAG: BB#3
|
||||||
|
; CHECK-CFG-DAG: tBX_RET
|
||||||
|
|
||||||
|
-; CHECK-CFG-DAG: BB#5
|
||||||
|
-; CHECK-CFG-DAG: t2UDF 249
|
||||||
|
-
|
||||||
|
; CHECK-CFG-ASM-LABEL: h:
|
||||||
|
-; CHECK-CFG-ASM: cbz r{{[0-9]}}, .LBB2_2
|
||||||
|
-; CHECK-CFG-ASM: b .LBB2_4
|
||||||
|
+; CHECK-CFG-ASM: cbnz r{{[0-9]}}, .LBB2_2
|
||||||
|
+; CHECK-CFG-ASM: __brkdiv0
|
||||||
|
; CHECK-CFG-ASM-LABEL: .LBB2_2:
|
||||||
|
-; CHECK-CFG-ASM-NEXT: udf.w #249
|
||||||
|
-; CHECK-CFG-ASM-LABEL: .LBB2_4:
|
||||||
|
; CHECK-CFG-ASM: bl __rt_udiv
|
||||||
|
-; CHECK-CFG-ASM: pop.w {r11, pc}
|
||||||
|
|
||||||
|
; RUN: llc -O0 -mtriple thumbv7--windows-itanium -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-WIN__DBZCHK
|
||||||
|
|
||||||
|
@@ -182,11 +172,11 @@ return:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-WIN__DBZCHK-LABEL: j:
|
||||||
|
-; CHECK-WIN__DBZCHK: cbz r{{[0-7]}}, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbz r8, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbz r9, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbz r10, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbz r11, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbz ip, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbz lr, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK: cbnz r{{[0-7]}}, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbnz r8, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbnz r9, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbnz r10, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbnz r11, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbnz ip, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbnz lr, .LBB
|
||||||
|
|
||||||
|
diff --git a/test/CodeGen/ARM/Windows/division-range.ll b/test/CodeGen/ARM/Windows/division-range.ll
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..9b1920c
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/test/CodeGen/ARM/Windows/division-range.ll
|
||||||
|
@@ -0,0 +1,15 @@
|
||||||
|
+; RUN: llc -O0 -mtriple thumbv7--windows-itanium -filetype obj -o - %s | llvm-objdump -disassemble - | FileCheck %s
|
||||||
|
+
|
||||||
|
+declare i32 @llvm.arm.space(i32, i32)
|
||||||
|
+
|
||||||
|
+define arm_aapcs_vfpcc i32 @f(i32 %n, i32 %d) local_unnamed_addr {
|
||||||
|
+entry:
|
||||||
|
+ %div = sdiv i32 %n, %d
|
||||||
|
+ call i32 @llvm.arm.space(i32 128, i32 undef)
|
||||||
|
+ ret i32 %div
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+; CHECK: cbnz r1, #0
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
+; CHECK: bl
|
||||||
|
+
|
||||||
|
diff --git a/test/CodeGen/ARM/Windows/division.ll b/test/CodeGen/ARM/Windows/division.ll
|
||||||
|
index f4704ea..b149cb0 100644
|
||||||
|
--- a/test/CodeGen/ARM/Windows/division.ll
|
||||||
|
+++ b/test/CodeGen/ARM/Windows/division.ll
|
||||||
|
@@ -8,9 +8,8 @@ entry:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: sdiv32:
|
||||||
|
-; CHECK: cbz r0
|
||||||
|
-; CHECK: b
|
||||||
|
-; CHECK: udf.w #249
|
||||||
|
+; CHECK: cbnz r0
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
; CHECK: bl __rt_sdiv
|
||||||
|
|
||||||
|
define arm_aapcs_vfpcc i32 @udiv32(i32 %divisor, i32 %divident) {
|
||||||
|
@@ -20,9 +19,8 @@ entry:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: udiv32:
|
||||||
|
-; CHECK: cbz r0
|
||||||
|
-; CHECK: b
|
||||||
|
-; CHECK: udf.w #249
|
||||||
|
+; CHECK: cbnz r0
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
; CHECK: bl __rt_udiv
|
||||||
|
|
||||||
|
define arm_aapcs_vfpcc i64 @sdiv64(i64 %divisor, i64 %divident) {
|
||||||
|
@@ -33,9 +31,8 @@ entry:
|
||||||
|
|
||||||
|
; CHECK-LABEL: sdiv64:
|
||||||
|
; CHECK: orr.w r4, r0, r1
|
||||||
|
-; CHECK-NEXT: cbz r4
|
||||||
|
-; CHECK: b
|
||||||
|
-; CHECK: udf.w #249
|
||||||
|
+; CHECK-NEXT: cbnz r4
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
; CHECK: bl __rt_sdiv64
|
||||||
|
|
||||||
|
define arm_aapcs_vfpcc i64 @udiv64(i64 %divisor, i64 %divident) {
|
||||||
|
@@ -46,8 +43,7 @@ entry:
|
||||||
|
|
||||||
|
; CHECK-LABEL: udiv64:
|
||||||
|
; CHECK: orr.w r4, r0, r1
|
||||||
|
-; CHECK-NEXT: cbz r4
|
||||||
|
-; CHECK: b
|
||||||
|
-; CHECK: udf.w #249
|
||||||
|
+; CHECK-NEXT: cbnz r4
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
; CHECK: bl __rt_udiv64
|
||||||
|
|
||||||
|
--
|
||||||
|
2.7.4
|
||||||
|
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
From 20692f7f7548e98523818db6d83ca66e3ae0dedc Mon Sep 17 00:00:00 2001
|
||||||
|
From: Saleem Abdulrasool <compnerd@compnerd.org>
|
||||||
|
Date: Mon, 31 Oct 2016 22:12:37 +0000
|
||||||
|
Subject: [PATCH 9/9] CodeGen: further loosen -O0 CG for WoA division
|
||||||
|
|
||||||
|
Generate the slowest possible codepath for noopt CodeGen. Even trying to be
|
||||||
|
clever with the negated jump can cause out-of-range jumps. Use a wide branch
|
||||||
|
instead. Although the code is modelled simplistically, the later optimizations
|
||||||
|
would recombine the branching into `cbz` if possible. This re-enables the
|
||||||
|
previous optimization as well as hopefully gives us working code in all cases.
|
||||||
|
|
||||||
|
Addresses PR30356!
|
||||||
|
|
||||||
|
Cherry-picked from SVN trunk commit 285649, git mirror commit
|
||||||
|
f185e91e2bc8.
|
||||||
|
---
|
||||||
|
lib/Target/ARM/ARMISelLowering.cpp | 18 ++++++++++++-----
|
||||||
|
test/CodeGen/ARM/Windows/dbzchk.ll | 31 ++++++++++++++++--------------
|
||||||
|
test/CodeGen/ARM/Windows/division-range.ll | 4 ++--
|
||||||
|
test/CodeGen/ARM/Windows/division.ll | 20 +++++++++----------
|
||||||
|
4 files changed, 42 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
index f7b09fa..6d4e6d7 100644
|
||||||
|
--- a/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
+++ b/lib/Target/ARM/ARMISelLowering.cpp
|
||||||
|
@@ -8214,12 +8214,20 @@ ARMTargetLowering::EmitLowered__dbzchk(MachineInstr &MI,
|
||||||
|
ContBB->splice(ContBB->begin(), MBB,
|
||||||
|
std::next(MachineBasicBlock::iterator(MI)), MBB->end());
|
||||||
|
ContBB->transferSuccessorsAndUpdatePHIs(MBB);
|
||||||
|
-
|
||||||
|
- BuildMI(*MBB, MI, DL, TII->get(ARM::tCBNZ))
|
||||||
|
- .addReg(MI.getOperand(0).getReg())
|
||||||
|
- .addMBB(ContBB);
|
||||||
|
MBB->addSuccessor(ContBB);
|
||||||
|
- BuildMI(*MBB, MI, DL, TII->get(ARM::t__brkdiv0));
|
||||||
|
+
|
||||||
|
+ MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock();
|
||||||
|
+ BuildMI(TrapBB, DL, TII->get(ARM::t__brkdiv0));
|
||||||
|
+ MF->push_back(TrapBB);
|
||||||
|
+ MBB->addSuccessor(TrapBB);
|
||||||
|
+
|
||||||
|
+ AddDefaultPred(BuildMI(*MBB, MI, DL, TII->get(ARM::tCMPi8))
|
||||||
|
+ .addReg(MI.getOperand(0).getReg())
|
||||||
|
+ .addImm(0));
|
||||||
|
+ BuildMI(*MBB, MI, DL, TII->get(ARM::t2Bcc))
|
||||||
|
+ .addMBB(TrapBB)
|
||||||
|
+ .addImm(ARMCC::EQ)
|
||||||
|
+ .addReg(ARM::CPSR);
|
||||||
|
|
||||||
|
MI.eraseFromParent();
|
||||||
|
return ContBB;
|
||||||
|
diff --git a/test/CodeGen/ARM/Windows/dbzchk.ll b/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
index af23cb2..aea3799 100644
|
||||||
|
--- a/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
+++ b/test/CodeGen/ARM/Windows/dbzchk.ll
|
||||||
|
@@ -75,7 +75,7 @@ return:
|
||||||
|
; CHECK-MOD-DAG: BB#2
|
||||||
|
|
||||||
|
; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -filetype asm -o /dev/null %s 2>&1 | FileCheck %s -check-prefix CHECK-CFG
|
||||||
|
-; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-CFG-ASM
|
||||||
|
+; RUN: llc -mtriple thumbv7--windows-itanium -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-CFG-ASM
|
||||||
|
|
||||||
|
; unsigned c;
|
||||||
|
; extern unsigned long g(void);
|
||||||
|
@@ -119,21 +119,24 @@ attributes #0 = { optsize }
|
||||||
|
; CHECK-CFG-DAG: t2B <BB#3>
|
||||||
|
|
||||||
|
; CHECK-CFG-DAG: BB#2
|
||||||
|
-; CHECK-CFG-DAG: tCBNZ %vreg{{[0-9]}}, <BB#4>
|
||||||
|
-; CHECK-CFG-DAG: t__brkdiv0
|
||||||
|
+; CHECK-CFG-DAG: tCMPi8 %vreg{{[0-9]}}, 0
|
||||||
|
+; CHECK-CFG-DAG: t2Bcc <BB#5>
|
||||||
|
|
||||||
|
; CHECK-CFG-DAG: BB#4
|
||||||
|
|
||||||
|
; CHECK-CFG-DAG: BB#3
|
||||||
|
; CHECK-CFG-DAG: tBX_RET
|
||||||
|
|
||||||
|
+; CHECK-CFG-DAG: BB#5
|
||||||
|
+; CHECK-CFG-DAG: t__brkdiv0
|
||||||
|
+
|
||||||
|
; CHECK-CFG-ASM-LABEL: h:
|
||||||
|
-; CHECK-CFG-ASM: cbnz r{{[0-9]}}, .LBB2_2
|
||||||
|
-; CHECK-CFG-ASM: __brkdiv0
|
||||||
|
-; CHECK-CFG-ASM-LABEL: .LBB2_2:
|
||||||
|
+; CHECK-CFG-ASM: cbz r{{[0-9]}}, .LBB2_4
|
||||||
|
; CHECK-CFG-ASM: bl __rt_udiv
|
||||||
|
+; CHECK-CFG-ASM-LABEL: .LBB2_4:
|
||||||
|
+; CHECK-CFG-ASM: __brkdiv0
|
||||||
|
|
||||||
|
-; RUN: llc -O0 -mtriple thumbv7--windows-itanium -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-WIN__DBZCHK
|
||||||
|
+; RUN: llc -O1 -mtriple thumbv7--windows-itanium -verify-machineinstrs -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-WIN__DBZCHK
|
||||||
|
|
||||||
|
; long k(void);
|
||||||
|
; int l(void);
|
||||||
|
@@ -172,11 +175,11 @@ return:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-WIN__DBZCHK-LABEL: j:
|
||||||
|
-; CHECK-WIN__DBZCHK: cbnz r{{[0-7]}}, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbnz r8, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbnz r9, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbnz r10, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbnz r11, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbnz ip, .LBB
|
||||||
|
-; CHECK-WIN__DBZCHK-NOT: cbnz lr, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK: cbz r{{[0-7]}}, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbz r8, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbz r9, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbz r10, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbz r11, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbz ip, .LBB
|
||||||
|
+; CHECK-WIN__DBZCHK-NOT: cbz lr, .LBB
|
||||||
|
|
||||||
|
diff --git a/test/CodeGen/ARM/Windows/division-range.ll b/test/CodeGen/ARM/Windows/division-range.ll
|
||||||
|
index 9b1920c..b14339e 100644
|
||||||
|
--- a/test/CodeGen/ARM/Windows/division-range.ll
|
||||||
|
+++ b/test/CodeGen/ARM/Windows/division-range.ll
|
||||||
|
@@ -9,7 +9,7 @@ entry:
|
||||||
|
ret i32 %div
|
||||||
|
}
|
||||||
|
|
||||||
|
-; CHECK: cbnz r1, #0
|
||||||
|
-; CHECK: __brkdiv0
|
||||||
|
+; CHECK: cmp r1, #0
|
||||||
|
+; CHECK: beq #
|
||||||
|
; CHECK: bl
|
||||||
|
|
||||||
|
diff --git a/test/CodeGen/ARM/Windows/division.ll b/test/CodeGen/ARM/Windows/division.ll
|
||||||
|
index b149cb0..10f86b0 100644
|
||||||
|
--- a/test/CodeGen/ARM/Windows/division.ll
|
||||||
|
+++ b/test/CodeGen/ARM/Windows/division.ll
|
||||||
|
@@ -8,9 +8,9 @@ entry:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: sdiv32:
|
||||||
|
-; CHECK: cbnz r0
|
||||||
|
-; CHECK: __brkdiv0
|
||||||
|
+; CHECK: cbz r0
|
||||||
|
; CHECK: bl __rt_sdiv
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
|
||||||
|
define arm_aapcs_vfpcc i32 @udiv32(i32 %divisor, i32 %divident) {
|
||||||
|
entry:
|
||||||
|
@@ -19,9 +19,9 @@ entry:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: udiv32:
|
||||||
|
-; CHECK: cbnz r0
|
||||||
|
-; CHECK: __brkdiv0
|
||||||
|
+; CHECK: cbz r0
|
||||||
|
; CHECK: bl __rt_udiv
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
|
||||||
|
define arm_aapcs_vfpcc i64 @sdiv64(i64 %divisor, i64 %divident) {
|
||||||
|
entry:
|
||||||
|
@@ -30,10 +30,10 @@ entry:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: sdiv64:
|
||||||
|
-; CHECK: orr.w r4, r0, r1
|
||||||
|
-; CHECK-NEXT: cbnz r4
|
||||||
|
-; CHECK: __brkdiv0
|
||||||
|
+; CHECK: orrs.w r4, r0, r1
|
||||||
|
+; CHECK-NEXT: beq
|
||||||
|
; CHECK: bl __rt_sdiv64
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
|
||||||
|
define arm_aapcs_vfpcc i64 @udiv64(i64 %divisor, i64 %divident) {
|
||||||
|
entry:
|
||||||
|
@@ -42,8 +42,8 @@ entry:
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: udiv64:
|
||||||
|
-; CHECK: orr.w r4, r0, r1
|
||||||
|
-; CHECK-NEXT: cbnz r4
|
||||||
|
-; CHECK: __brkdiv0
|
||||||
|
+; CHECK: orrs.w r4, r0, r1
|
||||||
|
+; CHECK-NEXT: beq
|
||||||
|
; CHECK: bl __rt_udiv64
|
||||||
|
+; CHECK: __brkdiv0
|
||||||
|
|
||||||
|
--
|
||||||
|
2.7.4
|
||||||
|
|
||||||
Reference in new issue
Block a user