[llvm-commits] [llvm] r57548 - /llvm/trunk/lib/Target/X86/X86FastISel.cpp

Chris Lattner sabre at nondot.org
Tue Oct 14 21:13:30 PDT 2008


Author: lattner
Date: Tue Oct 14 23:13:29 2008
New Revision: 57548

URL: http://llvm.org/viewvc/llvm-project?rev=57548&view=rev
Log:
Fold immediates into compares when possible, producing "cmp $4, %eax" instead of
loading 4 into a register and then doing the compare.

Modified:
    llvm/trunk/lib/Target/X86/X86FastISel.cpp

Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=57548&r1=57547&r2=57548&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Tue Oct 14 23:13:29 2008
@@ -530,6 +530,29 @@
   return 0;
 }
 
+/// X86ChooseCmpImmediateOpcode - If we have a comparison with RHS as the RHS
+/// of the comparison, return an opcode that works for the compare (e.g.
+/// CMP32ri) otherwise return 0.
+static unsigned X86ChooseCmpImmediateOpcode(ConstantInt *RHSC) {
+  if (RHSC == 0) return 0;
+  
+  if (RHSC->getType() == Type::Int8Ty)
+    return X86::CMP8ri;
+  if (RHSC->getType() == Type::Int16Ty)
+    return X86::CMP16ri;
+  if (RHSC->getType() == Type::Int32Ty)
+    return X86::CMP32ri;
+  
+  // 64-bit comparisons are only valid if the immediate fits in a 32-bit sext
+  // field.
+  if (RHSC->getType() == Type::Int64Ty &&
+      (int)RHSC->getSExtValue() == RHSC->getSExtValue())
+    return X86::CMP64ri32;
+  
+  // Otherwise, we can't fold the immediate into this comparison.
+  return 0;
+}
+
 bool X86FastISel::X86SelectCmp(Instruction *I) {
   CmpInst *CI = cast<CmpInst>(I);
 
@@ -676,10 +699,20 @@
       if (CompareOpc == 0) return false;
       unsigned Op0Reg = getRegForValue(Op0);
       if (Op0Reg == 0) return false;
-      unsigned Op1Reg = getRegForValue(Op1);
-      if (Op1Reg == 0) return false;
       
-      BuildMI(MBB, TII.get(CompareOpc)).addReg(Op0Reg).addReg(Op1Reg);
+      // We have two options: compare with register or immediate.  If the RHS of
+      // the compare is an immediate that we can fold into this compare, use
+      // CMPri, otherwise use CMPrr.
+      ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1);
+      if (unsigned CompareImmOpc = X86ChooseCmpImmediateOpcode(Op1C)) {
+        BuildMI(MBB, TII.get(CompareOpc)).addReg(Op0Reg)
+                                         .addImm(Op1C->getSExtValue());
+      } else {
+        unsigned Op1Reg = getRegForValue(Op1);
+        if (Op1Reg == 0) return false;
+        BuildMI(MBB, TII.get(CompareOpc)).addReg(Op0Reg).addReg(Op1Reg);
+      }
+      
       BuildMI(MBB, TII.get(BranchOpc)).addMBB(TrueMBB);
       FastEmitBranch(FalseMBB);
       MBB->addSuccessor(TrueMBB);





More information about the llvm-commits mailing list