From d36696c4e0ccd10a91bad2e3383c50347e2ea5ec Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 12 Oct 2012 01:15:47 +0000 Subject: [PATCH] Legalizer optimize a pair of div / mod to a call to divrem libcall if they are not legal. However, it should use a div instruction + mul + sub if divide is legal. The rem legalization code was missing a check and incorrectly uses a divrem libcall even when div is legal. rdar://12481395 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165778 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 2 ++ test/CodeGen/ARM/divmod.ll | 46 +++++++++++++++++------- 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index bb4f365b216..2ec129f7308 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3153,6 +3153,8 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) { Tmp3 = Node->getOperand(1); if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) || (isDivRemLibcallAvailable(Node, isSigned, TLI) && + // If div is legal, it's better to do the normal expansion + !TLI.isOperationLegalOrCustom(DivOpc, Node->getValueType(0)) && useDivRem(Node, isSigned, false))) { Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Tmp2, Tmp3).getValue(1); } else if (TLI.isOperationLegalOrCustom(DivOpc, VT)) { diff --git a/test/CodeGen/ARM/divmod.ll b/test/CodeGen/ARM/divmod.ll index 7fbf8f40903..577f8aa7d39 100644 --- a/test/CodeGen/ARM/divmod.ll +++ b/test/CodeGen/ARM/divmod.ll @@ -1,10 +1,18 @@ -; RUN: llc < %s -mtriple=arm-apple-ios5.0 -mcpu=cortex-a8 | FileCheck %s +; RUN: llc < %s -mtriple=arm-apple-ios5.0 -mcpu=cortex-a8 | FileCheck %s -check-prefix=A8 +; RUN: llc < %s -mtriple=arm-apple-ios5.0 -mcpu=swift | FileCheck %s -check-prefix=SWIFT + +; rdar://12481395 define void @foo(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp { entry: -; CHECK: foo: -; CHECK: bl ___divmodsi4 -; CHECK-NOT: bl ___divmodsi4 +; A8: foo: +; A8: bl ___divmodsi4 +; A8-NOT: bl ___divmodsi4 + +; SWIFT: foo: +; SWIFT: sdiv +; SWIFT: mls +; SWIFT-NOT: bl __divmodsi4 %div = sdiv i32 %x, %y store i32 %div, i32* %P, align 4 %rem = srem i32 %x, %y @@ -15,9 +23,14 @@ entry: define void @bar(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp { entry: -; CHECK: bar: -; CHECK: bl ___udivmodsi4 -; CHECK-NOT: bl ___udivmodsi4 +; A8: bar: +; A8: bl ___udivmodsi4 +; A8-NOT: bl ___udivmodsi4 + +; SWIFT: bar: +; SWIFT: udiv +; SWIFT: mls +; SWIFT-NOT: bl __udivmodsi4 %div = udiv i32 %x, %y store i32 %div, i32* %P, align 4 %rem = urem i32 %x, %y @@ -32,14 +45,18 @@ entry: define void @do_indent(i32 %cols) nounwind { entry: -; CHECK: do_indent: +; A8: do_indent: +; SWIFT: do_indent: %0 = load i32* @flags, align 4 %1 = and i32 %0, 67108864 %2 = icmp eq i32 %1, 0 br i1 %2, label %bb1, label %bb bb: -; CHECK: bl ___divmodsi4 +; A8: bl ___divmodsi4 +; SWIFT: sdiv +; SWIFT: mls +; SWIFT-NOT: bl __divmodsi4 %3 = load i32* @tabsize, align 4 %4 = srem i32 %cols, %3 %5 = sdiv i32 %cols, %3 @@ -60,9 +77,14 @@ declare i8* @__memset_chk(i8*, i32, i32, i32) nounwind ; rdar://11714607 define i32 @howmany(i32 %x, i32 %y) nounwind { entry: -; CHECK: howmany: -; CHECK: bl ___udivmodsi4 -; CHECK-NOT: ___udivsi3 +; A8: howmany: +; A8: bl ___udivmodsi4 +; A8-NOT: ___udivsi3 + +; SWIFT: howmany: +; SWIFT: udiv +; SWIFT: mls +; SWIFT-NOT: bl __udivmodsi4 %rem = urem i32 %x, %y %div = udiv i32 %x, %y %not.cmp = icmp ne i32 %rem, 0 -- 2.34.1