From: Chris Lattner Date: Wed, 6 Oct 2004 04:02:39 +0000 (+0000) Subject: Codegen signed divides by 2 and -2 more efficiently. In particular X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=610f1e2785d7278175ed6c332840756e20bc1142;p=oota-llvm.git Codegen signed divides by 2 and -2 more efficiently. In particular instead of: s: ;; X / 2 movl 4(%esp), %eax movl %eax, %ecx shrl $31, %ecx movl %eax, %edx addl %ecx, %edx sarl $1, %eax ret t: ;; X / -2 movl 4(%esp), %eax movl %eax, %ecx shrl $31, %ecx movl %eax, %edx addl %ecx, %edx sarl $1, %eax negl %eax ret Emit: s: movl 4(%esp), %eax cmpl $-2147483648, %eax sbbl $-1, %eax sarl $1, %eax ret t: movl 4(%esp), %eax cmpl $-2147483648, %eax sbbl $-1, %eax sarl $1, %eax negl %eax ret git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16760 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index d65b677c955..a47bcc3e8ce 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -2695,6 +2695,28 @@ void X86ISel::emitDivRemOperation(MachineBasicBlock *BB, return; } + if (V == 2 || V == -2) { // X /s 2 + static const unsigned CMPOpcode[] = { + X86::CMP8ri, X86::CMP16ri, X86::CMP32ri + }; + static const unsigned SBBOpcode[] = { + X86::SBB8ri, X86::SBB16ri, X86::SBB32ri + }; + unsigned Op0Reg = getReg(Op0, BB, IP); + unsigned SignBit = 1 << (CI->getType()->getPrimitiveSize()*8-1); + BuildMI(*BB, IP, CMPOpcode[Class], 2).addReg(Op0Reg).addImm(SignBit); + + unsigned TmpReg = makeAnotherReg(Op0->getType()); + BuildMI(*BB, IP, SBBOpcode[Class], 2, TmpReg).addReg(Op0Reg).addImm(-1); + + unsigned TmpReg2 = V == 2 ? ResultReg : makeAnotherReg(Op0->getType()); + BuildMI(*BB, IP, SAROpcode[Class], 2, TmpReg2).addReg(TmpReg).addImm(1); + if (V == -2) { + BuildMI(*BB, IP, NEGOpcode[Class], 1, ResultReg).addReg(TmpReg2); + } + return; + } + bool isNeg = false; if (V < 0) { // Not a positive power of 2? V = -V;