diff options
| author | Chris Lattner <sabre@nondot.org> | 2006-10-12 20:58:32 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2006-10-12 20:58:32 +0000 |
| commit | d0620d2773a9958420f9ae02a24b5a5ed3a713f2 (patch) | |
| tree | a6197374361c2c7c5345b925148eb434b0c8b71a /llvm/lib/CodeGen/SelectionDAG | |
| parent | ce34aa8fd7e1f953217f992ba44a648613e749a7 (diff) | |
| download | bcm5719-llvm-d0620d2773a9958420f9ae02a24b5a5ed3a713f2.tar.gz bcm5719-llvm-d0620d2773a9958420f9ae02a24b5a5ed3a713f2.zip | |
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
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG')
| -rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 70ff8371f79..d6379dc858b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -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(); } |

