Codegen signed divides by 2 and -2 more efficiently. In particular
authorChris Lattner <sabre@nondot.org>
Wed, 6 Oct 2004 04:02:39 +0000 (04:02 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 6 Oct 2004 04:02:39 +0000 (04:02 +0000)
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

lib/Target/X86/X86ISelSimple.cpp

index d65b677c955a46faeb6c82e2db39ccc4fad15545..a47bcc3e8ce1067dde4d695e25a0e592482fcb0c 100644 (file)
@@ -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;