[llvm] r182184 - X86: Bad peephole interaction between adc, MOV32r0

David Majnemer david.majnemer at gmail.com
Fri May 17 18:02:03 PDT 2013


Author: majnemer
Date: Fri May 17 20:02:03 2013
New Revision: 182184

URL: http://llvm.org/viewvc/llvm-project?rev=182184&view=rev
Log:
X86: Bad peephole interaction between adc, MOV32r0

The peephole tries to reorder MOV32r0 instructions such that they are
before the instruction that modifies EFLAGS.

The problem is that the peephole does not consider the case where the
instruction that modifies EFLAGS also depends on the previous state of
EFLAGS.

Instead, walk backwards until we find an instruction that has a def for
EFLAGS but does not have a use.
If we find such an instruction, insert the MOV32r0 before it.
If it cannot find such an instruction, skip the optimization.

Added:
    llvm/trunk/test/CodeGen/X86/pr16031.ll
Modified:
    llvm/trunk/lib/Target/X86/X86InstrInfo.cpp

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.cpp?rev=182184&r1=182183&r2=182184&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.cpp Fri May 17 20:02:03 2013
@@ -3449,10 +3449,25 @@ optimizeCompareInstr(MachineInstr *CmpIn
 
   // The instruction to be updated is either Sub or MI.
   Sub = IsCmpZero ? MI : Sub;
-  // Move Movr0Inst to the place right before Sub.
+  // Move Movr0Inst to the appropriate place before Sub.
   if (Movr0Inst) {
-    Sub->getParent()->remove(Movr0Inst);
-    Sub->getParent()->insert(MachineBasicBlock::iterator(Sub), Movr0Inst);
+    // Look backwards until we find a def that doesn't use the current EFLAGS.
+    Def = Sub;
+    MachineBasicBlock::reverse_iterator
+      InsertI = MachineBasicBlock::reverse_iterator(++Def),
+                InsertE = Sub->getParent()->rend();
+    for (; InsertI != InsertE; ++InsertI) {
+      MachineInstr *Instr = &*InsertI;
+      if (!Instr->readsRegister(X86::EFLAGS, TRI) &&
+          Instr->modifiesRegister(X86::EFLAGS, TRI)) {
+        Sub->getParent()->remove(Movr0Inst);
+        Instr->getParent()->insert(MachineBasicBlock::iterator(Instr),
+                                   Movr0Inst);
+        break;
+      }
+    }
+    if (InsertI == InsertE)
+      return false;
   }
 
   // Make sure Sub instruction defines EFLAGS and mark the def live.

Added: llvm/trunk/test/CodeGen/X86/pr16031.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pr16031.ll?rev=182184&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/pr16031.ll (added)
+++ llvm/trunk/test/CodeGen/X86/pr16031.ll Fri May 17 20:02:03 2013
@@ -0,0 +1,27 @@
+; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -mcpu=corei7-avx | FileCheck %s
+
+; CHECK: main:
+; CHECK: pushl %esi
+; CHECK-NEXT: movl  $-12, %eax
+; CHECK-NEXT: movl  $-1, %edx
+; CHECK-NEXT: testb $1, 8(%esp)
+; CHECK-NEXT: cmovel    %edx, %eax
+; CHECK-NEXT: xorl  %ecx, %ecx
+; CHECK-NEXT: movl  %eax, %esi
+; CHECK-NEXT: addl  $-1, %esi
+; CHECK-NEXT: movl  $-1, %esi
+; CHECK-NEXT: adcl  $-1, %esi
+; CHECK-NEXT: cmovsl    %ecx, %eax
+; CHECK-NEXT: cmovsl    %ecx, %edx
+; CHECK-NEXT: popl  %esi
+define i64 @main(i1 %tobool1) nounwind {
+entry:
+  %0 = zext i1 %tobool1 to i32
+  %. = xor i32 %0, 1
+  %.21 = select i1 %tobool1, i32 -12, i32 -1
+  %conv = sext i32 %.21 to i64
+  %1 = add i64 %conv, -1
+  %cmp10 = icmp slt i64 %1, 0
+  %sub17 = select i1 %cmp10, i64 0, i64 %conv
+  ret i64 %sub17
+}





More information about the llvm-commits mailing list