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:
Martin Storsjö authored and Martin Storsjo committed 2016-11-01 11:13:50 +02:00
1 parent f3b034f10a
commit be1357f467
3 files changed
+797

No files matched your search

+361
View File
@@ -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
+250
View File
@@ -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
+186
View File
@@ -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