diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index de18bafd3827d..bb470c2c24161 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -390,10 +390,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, { RTLIB::SINTTOFP_I64_F64, "__i64tod", CallingConv::ARM_AAPCS_VFP }, { 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) { @@ -781,6 +777,14 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, setOperationAction(ISD::UDIV, MVT::i32, LibCall); } + if (Subtarget->isTargetWindows() && !Subtarget->hasDivide()) { + setOperationAction(ISD::SDIV, MVT::i32, Custom); + setOperationAction(ISD::UDIV, MVT::i32, Custom); + + setOperationAction(ISD::SDIV, MVT::i64, 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) @@ -7010,8 +7014,14 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG); 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: return LowerUDIV(Op, DAG); + case ISD::SDIV: + if (Subtarget->isTargetWindows()) + return LowerDIV_Windows(Op, DAG, /* Signed */ true); + return LowerSDIV(Op, DAG); + case ISD::UDIV: + if (Subtarget->isTargetWindows()) + return LowerDIV_Windows(Op, DAG, /* Signed */ false); + return LowerUDIV(Op, DAG); case ISD::ADDC: case ISD::ADDE: case ISD::SUBC: @@ -8008,7 +8018,7 @@ ARMTargetLowering::EmitLowered__dbzchk(MachineInstr *MI, MF->push_back(ContBB); ContBB->splice(ContBB->begin(), MBB, std::next(MachineBasicBlock::iterator(MI)), MBB->end()); - MBB->addSuccessor(ContBB); + ContBB->transferSuccessorsAndUpdatePHIs(MBB); MachineBasicBlock *TrapBB = MF->CreateMachineBasicBlock(); MF->push_back(TrapBB); @@ -8018,6 +8028,7 @@ ARMTargetLowering::EmitLowered__dbzchk(MachineInstr *MI, BuildMI(*MBB, MI, DL, TII->get(ARM::tCBZ)) .addReg(MI->getOperand(0).getReg()) .addMBB(TrapBB); + MBB->addSuccessor(ContBB); MI->eraseFromParent(); return ContBB; diff --git a/llvm/test/CodeGen/ARM/Windows/dbzchk.ll b/llvm/test/CodeGen/ARM/Windows/dbzchk.ll new file mode 100644 index 0000000000000..341d39070d00c --- /dev/null +++ b/llvm/test/CodeGen/ARM/Windows/dbzchk.ll @@ -0,0 +1,80 @@ +; RUN: llc -mtriple thumbv7--windows-itanium -print-machineinstrs=expand-isel-pseudos -o /dev/null %s 2>&1 | FileCheck %s -check-prefix CHECK-DIV + +; int f(int n, int d) { +; if (n / d) +; return 1; +; return 0; +; } + +define arm_aapcs_vfpcc i32 @f(i32 %n, i32 %d) { +entry: + %retval = alloca i32, align 4 + %n.addr = alloca i32, align 4 + %d.addr = alloca i32, align 4 + store i32 %n, i32* %n.addr, align 4 + store i32 %d, i32* %d.addr, align 4 + %0 = load i32, i32* %n.addr, align 4 + %1 = load i32, i32* %d.addr, align 4 + %div = sdiv i32 %0, %1 + %tobool = icmp ne i32 %div, 0 + br i1 %tobool, label %if.then, label %if.end + +if.then: + store i32 1, i32* %retval, align 4 + br label %return + +if.end: + store i32 0, i32* %retval, align 4 + br label %return + +return: + %2 = load i32, i32* %retval, align 4 + ret i32 %2 +} + +; CHECK-DIV-DAG: BB#0 +; CHECK-DIV-DAG: Successors according to CFG: BB#5({{.*}}) BB#4 +; 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 -o /dev/null %s 2>&1 | FileCheck %s -check-prefix CHECK-MOD + +; int r; +; int g(int l, int m) { +; if (m <= 0) +; return 0; +; return (r = l % m); +; } + +@r = common global i32 0, align 4 + +define arm_aapcs_vfpcc i32 @g(i32 %l, i32 %m) { +entry: + %cmp = icmp eq i32 %m, 0 + br i1 %cmp, label %return, label %if.end + +if.end: + %rem = urem i32 %l, %m + store i32 %rem, i32* @r, align 4 + br label %return + +return: + %retval.0 = phi i32 [ %rem, %if.end ], [ 0, %entry ] + ret i32 %retval.0 +} + +; 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: BB#3 +; CHECK-MOD-DAG: Successors according to CFG: BB#2 +; CHECK-MOD-DAG: BB#4 + diff --git a/llvm/test/CodeGen/ARM/Windows/division.ll b/llvm/test/CodeGen/ARM/Windows/division.ll index b3ef9c6d278b6..098226e3f335f 100644 --- a/llvm/test/CodeGen/ARM/Windows/division.ll +++ b/llvm/test/CodeGen/ARM/Windows/division.ll @@ -7,8 +7,10 @@ entry: ret i32 %div } -; CHECK-LABEL: sdiv32 -; CHECK: b __rt_sdiv +; CHECK-LABEL: sdiv32: +; CHECK: cbz r0 +; CHECK: bl __rt_sdiv +; CHECK: udf.w #249 define arm_aapcs_vfpcc i32 @udiv32(i32 %divisor, i32 %divident) { entry: @@ -17,7 +19,9 @@ entry: } ; CHECK-LABEL: udiv32: -; CHECK: b __rt_udiv +; CHECK: cbz r0 +; CHECK: bl __rt_udiv +; CHECK: udf.w #249 define arm_aapcs_vfpcc i64 @sdiv64(i64 %divisor, i64 %divident) { entry: @@ -25,8 +29,11 @@ entry: ret i64 %div } -; CHECK-LABEL: sdiv64 +; CHECK-LABEL: sdiv64: +; CHECK: orr.w r12, r0, r1 +; CHECK-NEXT: cbz r12 ; CHECK: bl __rt_sdiv64 +; CHECK: udf.w #249 define arm_aapcs_vfpcc i64 @udiv64(i64 %divisor, i64 %divident) { entry: @@ -35,4 +42,8 @@ entry: } ; CHECK-LABEL: udiv64: +; CHECK: orr.w r12, r0, r1 +; CHECK-NEXT: cbz r12 ; CHECK: bl __rt_udiv64 +; CHECK: udf.w #249 + diff --git a/llvm/test/CodeGen/ARM/Windows/overflow.ll b/llvm/test/CodeGen/ARM/Windows/overflow.ll deleted file mode 100644 index 5f74f25ac2242..0000000000000 --- a/llvm/test/CodeGen/ARM/Windows/overflow.ll +++ /dev/null @@ -1,77 +0,0 @@ -; RUN: llc -mtriple thumbv7-windows-gnu -filetype asm -o - %s - -define i32 @divsoverflow32(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 = sdiv i32 -2147483647, %3 - %7 = icmp sgt i32 %5, %6 - br i1 %7, label %8, label %9 - call void (...) @abort_simpl32() - 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_simpl32(...) - -define i64 @divsoverflow64(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 = sdiv i64 -9223372036854775808, %3 - %7 = icmp sgt i64 %5, %6 - br i1 %7, label %8, label %9 - call void (...) @abort_simpl64() - 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_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(...)