diff options
author | Chris Lattner <sabre@nondot.org> | 2004-10-06 04:19:43 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-10-06 04:19:43 +0000 |
commit | 3ffdff6448a6b4609071f9a3af4d89b6a5c8103c (patch) | |
tree | f7f9b4f659cadeabb2c594c2faf2b0fd68388678 | |
parent | 610f1e2785d7278175ed6c332840756e20bc1142 (diff) |
Fix a scary bug with signed division by a power of two. We used to generate:
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
-rw-r--r-- | lib/Target/X86/X86ISelSimple.cpp | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp index a47bcc3e8c..3add1c1ad1 100644 --- a/lib/Target/X86/X86ISelSimple.cpp +++ b/lib/Target/X86/X86ISelSimple.cpp @@ -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; |