mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 08:26:29 +00:00
Emit a single _udivmodsi4 libcall instead of two separate _udivsi3 and
_umodsi3 libcalls if they have the same arguments. This optimization was apparently broken if one of the node was replaced in place. rdar://11714607 llvm-svn: 158900
This commit is contained in:
parent
99fb206e0c
commit
5e3a175c65
@ -1930,9 +1930,11 @@ static bool isDivRemLibcallAvailable(SDNode *Node, bool isSigned,
|
||||
return TLI.getLibcallName(LC) != 0;
|
||||
}
|
||||
|
||||
/// UseDivRem - Only issue divrem libcall if both quotient and remainder are
|
||||
/// useDivRem - Only issue divrem libcall if both quotient and remainder are
|
||||
/// needed.
|
||||
static bool UseDivRem(SDNode *Node, bool isSigned, bool isDIV) {
|
||||
static bool useDivRem(SDNode *Node, bool isSigned, bool isDIV) {
|
||||
// The other use might have been replaced with a divrem already.
|
||||
unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM;
|
||||
unsigned OtherOpcode = 0;
|
||||
if (isSigned)
|
||||
OtherOpcode = isDIV ? ISD::SREM : ISD::SDIV;
|
||||
@ -1946,7 +1948,7 @@ static bool UseDivRem(SDNode *Node, bool isSigned, bool isDIV) {
|
||||
SDNode *User = *UI;
|
||||
if (User == Node)
|
||||
continue;
|
||||
if (User->getOpcode() == OtherOpcode &&
|
||||
if ((User->getOpcode() == OtherOpcode || User->getOpcode() == DivRemOpc) &&
|
||||
User->getOperand(0) == Op0 &&
|
||||
User->getOperand(1) == Op1)
|
||||
return true;
|
||||
@ -3092,7 +3094,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
||||
Tmp3 = Node->getOperand(1);
|
||||
if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) ||
|
||||
(isDivRemLibcallAvailable(Node, isSigned, TLI) &&
|
||||
UseDivRem(Node, isSigned, false))) {
|
||||
useDivRem(Node, isSigned, false))) {
|
||||
Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Tmp2, Tmp3).getValue(1);
|
||||
} else if (TLI.isOperationLegalOrCustom(DivOpc, VT)) {
|
||||
// X % Y -> X-X/Y*Y
|
||||
@ -3120,7 +3122,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
||||
SDVTList VTs = DAG.getVTList(VT, VT);
|
||||
if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) ||
|
||||
(isDivRemLibcallAvailable(Node, isSigned, TLI) &&
|
||||
UseDivRem(Node, isSigned, true)))
|
||||
useDivRem(Node, isSigned, true)))
|
||||
Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Node->getOperand(0),
|
||||
Node->getOperand(1));
|
||||
else if (isSigned)
|
||||
|
@ -1,4 +1,4 @@
|
||||
; RUN: llc < %s -mtriple=arm-apple-ios5.0 | FileCheck %s
|
||||
; RUN: llc < %s -mtriple=arm-apple-ios5.0 -mcpu=cortex-a8 | FileCheck %s
|
||||
|
||||
define void @foo(i32 %x, i32 %y, i32* nocapture %P) nounwind ssp {
|
||||
entry:
|
||||
@ -56,3 +56,17 @@ bb1:
|
||||
|
||||
declare i32 @llvm.objectsize.i32(i8*, i1) nounwind readnone
|
||||
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
|
||||
%rem = urem i32 %x, %y
|
||||
%div = udiv i32 %x, %y
|
||||
%not.cmp = icmp ne i32 %rem, 0
|
||||
%add = zext i1 %not.cmp to i32
|
||||
%cond = add i32 %add, %div
|
||||
ret i32 %cond
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user