Fix a scary bug with signed division by a power of two. We used to generate:
authorChris Lattner <sabre@nondot.org>
Wed, 6 Oct 2004 04:19:43 +0000 (04:19 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 6 Oct 2004 04:19:43 +0000 (04:19 +0000)
s:   ;; X / 4
        mov %EAX, DWORD PTR [%ESP + 4]
        mov %ECX, %EAX
        sar %ECX, 1
        shr %ECX, 30
        mov %EDX, %EAX
        add %EDX, %ECX
        sar %EAX, 2
        ret

When we really meant:

s:
        mov %EAX, DWORD PTR [%ESP + 4]
        mov %ECX, %EAX
        sar %ECX, 1
        shr %ECX, 30
        add %EAX, %ECX
        sar %EAX, 2
        ret

Hey, this also reduces register pressure too :)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16761 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/X86ISelSimple.cpp

index a47bcc3e8ce1067dde4d695e25a0e592482fcb0c..3add1c1ad1f64983bb13ff5062a267ae19e06b34 100644 (file)
@@ -2726,11 +2726,8 @@ void X86ISel::emitDivRemOperation(MachineBasicBlock *BB,
         --Log;
         unsigned Op0Reg = getReg(Op0, BB, IP);
         unsigned TmpReg = makeAnotherReg(Op0->getType());
-        if (Log != 1) 
-          BuildMI(*BB, IP, SAROpcode[Class], 2, TmpReg)
-            .addReg(Op0Reg).addImm(Log-1);
-        else
-          BuildMI(*BB, IP, MovOpcode[Class], 1, TmpReg).addReg(Op0Reg);
+        BuildMI(*BB, IP, SAROpcode[Class], 2, TmpReg)
+          .addReg(Op0Reg).addImm(Log-1);
         unsigned TmpReg2 = makeAnotherReg(Op0->getType());
         BuildMI(*BB, IP, SHROpcode[Class], 2, TmpReg2)
           .addReg(TmpReg).addImm(32-Log);
@@ -2740,7 +2737,7 @@ void X86ISel::emitDivRemOperation(MachineBasicBlock *BB,
 
         unsigned TmpReg4 = isNeg ? makeAnotherReg(Op0->getType()) : ResultReg;
         BuildMI(*BB, IP, SAROpcode[Class], 2, TmpReg4)
-          .addReg(Op0Reg).addImm(Log);
+          .addReg(TmpReg3).addImm(Log);
         if (isNeg)
           BuildMI(*BB, IP, NEGOpcode[Class], 1, ResultReg).addReg(TmpReg4);
         return;