mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-06 11:19:09 +00:00
Lower X%C into X/C+stuff. This allows the 'division by a constant' logic to
apply to rems as well as divs. This fixes PR945 and speeds up ReedSolomon from 14.57s to 10.90s (which is now faster than gcc). It compiles CodeGen/X86/rem.ll into: _test1: subl $4, %esp movl %esi, (%esp) movl $2155905153, %ecx movl 8(%esp), %esi movl %esi, %eax imull %ecx addl %esi, %edx movl %edx, %eax shrl $31, %eax sarl $7, %edx addl %eax, %edx imull $255, %edx, %eax subl %eax, %esi movl %esi, %eax movl (%esp), %esi addl $4, %esp ret _test2: movl 4(%esp), %eax movl %eax, %ecx sarl $31, %ecx shrl $24, %ecx addl %eax, %ecx andl $4294967040, %ecx subl %ecx, %eax ret _test3: subl $4, %esp movl %esi, (%esp) movl $2155905153, %ecx movl 8(%esp), %esi movl %esi, %eax mull %ecx shrl $7, %edx imull $255, %edx, %eax subl %eax, %esi movl %esi, %eax movl (%esp), %esi addl $4, %esp ret instead of div/idiv instructions. llvm-svn: 30920
This commit is contained in:
parent
ae912d4d65
commit
70444d5663
@ -885,6 +885,18 @@ SDOperand DAGCombiner::visitSREM(SDNode *N) {
|
||||
if (TLI.MaskedValueIsZero(N1, SignBit) &&
|
||||
TLI.MaskedValueIsZero(N0, SignBit))
|
||||
return DAG.getNode(ISD::UREM, VT, N0, N1);
|
||||
|
||||
// Unconditionally lower X%C -> X-X/C*C. This allows the X/C logic to hack on
|
||||
// the remainder operation.
|
||||
if (N1C && !N1C->isNullValue()) {
|
||||
SDOperand Div = DAG.getNode(ISD::SDIV, VT, N0, N1);
|
||||
SDOperand Mul = DAG.getNode(ISD::MUL, VT, Div, N1);
|
||||
SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul);
|
||||
AddToWorkList(Div.Val);
|
||||
AddToWorkList(Mul.Val);
|
||||
return Sub;
|
||||
}
|
||||
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
@ -911,6 +923,18 @@ SDOperand DAGCombiner::visitUREM(SDNode *N) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unconditionally lower X%C -> X-X/C*C. This allows the X/C logic to hack on
|
||||
// the remainder operation.
|
||||
if (N1C && !N1C->isNullValue()) {
|
||||
SDOperand Div = DAG.getNode(ISD::UDIV, VT, N0, N1);
|
||||
SDOperand Mul = DAG.getNode(ISD::MUL, VT, Div, N1);
|
||||
SDOperand Sub = DAG.getNode(ISD::SUB, VT, N0, Mul);
|
||||
AddToWorkList(Div.Val);
|
||||
AddToWorkList(Mul.Val);
|
||||
return Sub;
|
||||
}
|
||||
|
||||
return SDOperand();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user