[llvm] r254158 - ARM: address WOA unsigned division overflow crash
Martell Malone via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 26 07:34:03 PST 2015
Author: martell
Date: Thu Nov 26 09:34:03 2015
New Revision: 254158
URL: http://llvm.org/viewvc/llvm-project?rev=254158&view=rev
Log:
ARM: address WOA unsigned division overflow crash
Building on r253865 the crash is not limited to signed overflows.
Disable custom handling of unsigned 32-bit and 64-bit integer divide.
Add test cases for both 32-bit and 64-bit unsigned integer overflow.
Modified:
llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
llvm/trunk/lib/Target/ARM/ARMISelLowering.h
llvm/trunk/test/CodeGen/ARM/Windows/division.ll
llvm/trunk/test/CodeGen/ARM/Windows/libcalls.ll
llvm/trunk/test/CodeGen/ARM/Windows/overflow.ll
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp?rev=254158&r1=254157&r2=254158&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.cpp Thu Nov 26 09:34:03 2015
@@ -396,7 +396,9 @@ ARMTargetLowering::ARMTargetLowering(con
{ RTLIB::UINTTOFP_I64_F32, "__u64tos", CallingConv::ARM_AAPCS_VFP },
{ RTLIB::UINTTOFP_I64_F64, "__u64tod", CallingConv::ARM_AAPCS_VFP },
{ RTLIB::SDIV_I32, "__rt_sdiv", CallingConv::ARM_AAPCS_VFP },
+ { RTLIB::UDIV_I32, "__rt_udiv", CallingConv::ARM_AAPCS_VFP },
{ RTLIB::SDIV_I64, "__rt_sdiv64", CallingConv::ARM_AAPCS_VFP },
+ { RTLIB::UDIV_I64, "__rt_udiv64", CallingConv::ARM_AAPCS_VFP },
};
for (const auto &LC : LibraryCalls) {
@@ -783,12 +785,6 @@ ARMTargetLowering::ARMTargetLowering(con
setOperationAction(ISD::UDIV, MVT::i32, LibCall);
}
- if (Subtarget->isTargetWindows() && !Subtarget->hasDivide()) {
- setOperationAction(ISD::UDIV, MVT::i32, Custom);
-
- setOperationAction(ISD::UDIV, MVT::i64, Custom);
- }
-
setOperationAction(ISD::SREM, MVT::i32, Expand);
setOperationAction(ISD::UREM, MVT::i32, Expand);
// Register based DivRem for AEABI (RTABI 4.2)
@@ -6660,6 +6656,7 @@ SDValue ARMTargetLowering::LowerFSINCOS(
}
SDValue ARMTargetLowering::LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG,
+ bool Signed,
SDValue &Chain) const {
EVT VT = Op.getValueType();
assert((VT == MVT::i32 || VT == MVT::i64) &&
@@ -6670,7 +6667,10 @@ SDValue ARMTargetLowering::LowerWindowsD
const auto &TLI = DAG.getTargetLoweringInfo();
const char *Name = nullptr;
- Name = (VT == MVT::i32) ? "__rt_udiv" : "__rt_udiv64";
+ if (Signed)
+ Name = (VT == MVT::i32) ? "__rt_sdiv" : "__rt_sdiv64";
+ else
+ Name = (VT == MVT::i32) ? "__rt_udiv" : "__rt_udiv64";
SDValue ES = DAG.getExternalSymbol(Name, TLI.getPointerTy(DL));
@@ -6692,8 +6692,8 @@ SDValue ARMTargetLowering::LowerWindowsD
return LowerCallTo(CLI).first;
}
-SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op,
- SelectionDAG &DAG) const {
+SDValue ARMTargetLowering::LowerDIV_Windows(SDValue Op, SelectionDAG &DAG,
+ bool Signed) const {
assert(Op.getValueType() == MVT::i32 &&
"unexpected type for custom lowering DIV");
SDLoc dl(Op);
@@ -6701,11 +6701,11 @@ SDValue ARMTargetLowering::LowerDIV_Wind
SDValue DBZCHK = DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other,
DAG.getEntryNode(), Op.getOperand(1));
- return LowerWindowsDIVLibCall(Op, DAG, DBZCHK);
+ return LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
}
void ARMTargetLowering::ExpandDIV_Windows(
- SDValue Op, SelectionDAG &DAG,
+ SDValue Op, SelectionDAG &DAG, bool Signed,
SmallVectorImpl<SDValue> &Results) const {
const auto &DL = DAG.getDataLayout();
const auto &TLI = DAG.getTargetLoweringInfo();
@@ -6723,7 +6723,7 @@ void ARMTargetLowering::ExpandDIV_Window
SDValue DBZCHK =
DAG.getNode(ARMISD::WIN__DBZCHK, dl, MVT::Other, DAG.getEntryNode(), Or);
- SDValue Result = LowerWindowsDIVLibCall(Op, DAG, DBZCHK);
+ SDValue Result = LowerWindowsDIVLibCall(Op, DAG, Signed, DBZCHK);
SDValue Lower = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Result);
SDValue Upper = DAG.getNode(ISD::SRL, dl, MVT::i64, Result,
@@ -6825,10 +6825,7 @@ SDValue ARMTargetLowering::LowerOperatio
case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG);
case ISD::MUL: return LowerMUL(Op, DAG);
case ISD::SDIV: return LowerSDIV(Op, DAG);
- case ISD::UDIV:
- if (Subtarget->isTargetWindows())
- return LowerDIV_Windows(Op, DAG);
- return LowerUDIV(Op, DAG);
+ case ISD::UDIV: return LowerUDIV(Op, DAG);
case ISD::ADDC:
case ISD::ADDE:
case ISD::SUBC:
@@ -6880,8 +6877,10 @@ void ARMTargetLowering::ReplaceNodeResul
ReplaceREADCYCLECOUNTER(N, Results, DAG, Subtarget);
return;
case ISD::UDIV:
+ case ISD::SDIV:
assert(Subtarget->isTargetWindows() && "can only expand DIV on Windows");
- return ExpandDIV_Windows(SDValue(N, 0), DAG, Results);
+ return ExpandDIV_Windows(SDValue(N, 0), DAG, N->getOpcode() == ISD::SDIV,
+ Results);
}
if (Res.getNode())
Results.push_back(Res);
Modified: llvm/trunk/lib/Target/ARM/ARMISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelLowering.h?rev=254158&r1=254157&r2=254158&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelLowering.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelLowering.h Thu Nov 26 09:34:03 2015
@@ -543,10 +543,10 @@ namespace llvm {
const ARMSubtarget *ST) const;
SDValue LowerFSINCOS(SDValue Op, SelectionDAG &DAG) const;
SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;
- SDValue LowerDIV_Windows(SDValue Op, SelectionDAG &DAG) const;
- void ExpandDIV_Windows(SDValue Op, SelectionDAG &DAG,
+ SDValue LowerDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed) const;
+ void ExpandDIV_Windows(SDValue Op, SelectionDAG &DAG, bool Signed,
SmallVectorImpl<SDValue> &Results) const;
- SDValue LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG,
+ SDValue LowerWindowsDIVLibCall(SDValue Op, SelectionDAG &DAG, bool Signed,
SDValue &Chain) const;
SDValue LowerREM(SDNode *N, SelectionDAG &DAG) const;
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
Modified: llvm/trunk/test/CodeGen/ARM/Windows/division.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/Windows/division.ll?rev=254158&r1=254157&r2=254158&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/Windows/division.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/Windows/division.ll Thu Nov 26 09:34:03 2015
@@ -1,6 +1,15 @@
; RUN: llc -mtriple thumbv7-windows-itanium -filetype asm -o - %s | FileCheck %s
; RUN: llc -mtriple thumbv7-windows-msvc -filetype asm -o - %s | FileCheck %s
+define arm_aapcs_vfpcc i32 @sdiv32(i32 %divisor, i32 %divident) {
+entry:
+ %div = sdiv i32 %divident, %divisor
+ ret i32 %div
+}
+
+; CHECK-LABEL: sdiv32
+; CHECK: b __rt_sdiv
+
define arm_aapcs_vfpcc i32 @udiv32(i32 %divisor, i32 %divident) {
entry:
%div = udiv i32 %divident, %divisor
@@ -8,9 +17,16 @@ entry:
}
; CHECK-LABEL: udiv32:
-; CHECK: cbz r0
-; CHECK: bl __rt_udiv
-; CHECK: udf.w #249
+; CHECK: b __rt_udiv
+
+define arm_aapcs_vfpcc i64 @sdiv64(i64 %divisor, i64 %divident) {
+entry:
+ %div = sdiv i64 %divident, %divisor
+ ret i64 %div
+}
+
+; CHECK-LABEL: sdiv64
+; CHECK: bl __rt_sdiv64
define arm_aapcs_vfpcc i64 @udiv64(i64 %divisor, i64 %divident) {
entry:
@@ -19,8 +35,4 @@ entry:
}
; CHECK-LABEL: udiv64:
-; CHECK: orr.w r12, r0, r1
-; CHECK-NEXT: cbz r12
; CHECK: bl __rt_udiv64
-; CHECK: udf.w #249
-
Modified: llvm/trunk/test/CodeGen/ARM/Windows/libcalls.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/Windows/libcalls.ll?rev=254158&r1=254157&r2=254158&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/Windows/libcalls.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/Windows/libcalls.ll Thu Nov 26 09:34:03 2015
@@ -1,24 +1,6 @@
; RUN: llc -mtriple thumbv7-windows-itanium -filetype asm -o - %s | FileCheck %s
; RUN: llc -mtriple thumbv7-windows-msvc -filetype asm -o - %s | FileCheck %s
-define arm_aapcs_vfpcc i32 @sdiv32(i32 %divisor, i32 %divident) {
-entry:
- %div = sdiv i32 %divident, %divisor
- ret i32 %div
-}
-
-; CHECK-LABEL: sdiv32
-; CHECK: b __rt_sdiv
-
-define arm_aapcs_vfpcc i64 @sdiv64(i64 %divisor, i64 %divident) {
-entry:
- %div = sdiv i64 %divident, %divisor
- ret i64 %div
-}
-
-; CHECK-LABEL: sdiv64
-; CHECK: bl __rt_sdiv64
-
define arm_aapcs_vfpcc i64 @stoi64(float %f) {
entry:
%conv = fptosi float %f to i64
Modified: llvm/trunk/test/CodeGen/ARM/Windows/overflow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/ARM/Windows/overflow.ll?rev=254158&r1=254157&r2=254158&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/ARM/Windows/overflow.ll (original)
+++ llvm/trunk/test/CodeGen/ARM/Windows/overflow.ll Thu Nov 26 09:34:03 2015
@@ -1,6 +1,6 @@
; RUN: llc -mtriple thumbv7-windows-gnu -filetype asm -o - %s
-define i32 @divoverflow32(i32 %a, i32 %b) {
+define i32 @divsoverflow32(i32 %a, i32 %b) {
%1 = alloca i32, align 4
%2 = alloca i32, align 4
%3 = load i32, i32* %1, align 4
@@ -9,7 +9,7 @@ define i32 @divoverflow32(i32 %a, i32 %b
%6 = sdiv i32 -2147483647, %3
%7 = icmp sgt i32 %5, %6
br i1 %7, label %8, label %9
- call void (...) @abort_impl32()
+ call void (...) @abort_simpl32()
unreachable
%10 = load i32, i32* %1, align 4
%11 = load i32, i32* %2, align 4
@@ -17,9 +17,9 @@ define i32 @divoverflow32(i32 %a, i32 %b
ret i32 %12
}
-declare void @abort_impl32(...)
+declare void @abort_simpl32(...)
-define i64 @divoverflow64(i64 %a, i64 %b) {
+define i64 @divsoverflow64(i64 %a, i64 %b) {
%1 = alloca i64, align 8
%2 = alloca i64, align 8
%3 = load i64, i64* %1, align 8
@@ -28,7 +28,7 @@ define i64 @divoverflow64(i64 %a, i64 %b
%6 = sdiv i64 -9223372036854775808, %3
%7 = icmp sgt i64 %5, %6
br i1 %7, label %8, label %9
- call void (...) @abort_impl64()
+ call void (...) @abort_simpl64()
unreachable
%10 = load i64, i64* %1, align 8
%11 = load i64, i64* %2, align 8
@@ -36,4 +36,42 @@ define i64 @divoverflow64(i64 %a, i64 %b
ret i64 %12
}
-declare void @abort_impl64(...)
+declare void @abort_simpl64(...)
+
+define i32 @divuoverflow32(i32 %a, i32 %b) {
+ %1 = alloca i32, align 4
+ %2 = alloca i32, align 4
+ %3 = load i32, i32* %1, align 4
+ %4 = load i32, i32* %2, align 4
+ %5 = sub nsw i32 0, %4
+ %6 = udiv i32 4294967296, %3
+ %7 = icmp sgt i32 %5, %6
+ br i1 %7, label %8, label %9
+ call void (...) @abort_uimpl32()
+ unreachable
+ %10 = load i32, i32* %1, align 4
+ %11 = load i32, i32* %2, align 4
+ %12 = mul nsw i32 %10, %11
+ ret i32 %12
+}
+
+declare void @abort_uimpl32(...)
+
+define i64 @divuoverflow64(i64 %a, i64 %b) {
+ %1 = alloca i64, align 8
+ %2 = alloca i64, align 8
+ %3 = load i64, i64* %1, align 8
+ %4 = load i64, i64* %2, align 8
+ %5 = sub nsw i64 0, %4
+ %6 = udiv i64 18446744073709551616, %3
+ %7 = icmp sgt i64 %5, %6
+ br i1 %7, label %8, label %9
+ call void (...) @abort_uimpl64()
+ unreachable
+ %10 = load i64, i64* %1, align 8
+ %11 = load i64, i64* %2, align 8
+ %12 = mul nsw i64 %10, %11
+ ret i64 %12
+}
+
+declare void @abort_uimpl64(...)
More information about the llvm-commits
mailing list