diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp
new file mode 100644
index 0000000..57f6a8d
--- /dev/null
+++ b/lib/CodeGen/IfConversion.cpp
@@ -0,0 +1,304 @@
+//===-- IfConversion.cpp - Machine code if conversion pass. ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the Evan Cheng and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the machine instruction level if-conversion pass.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "ifconversion"
+#include "llvm/CodeGen/Passes.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+using namespace llvm;
+
+STATISTIC(NumIfConvBBs, "Number of if-converted blocks");
+
+namespace {
+  class IfConverter : public MachineFunctionPass {
+    enum BBICKind {
+      ICInvalid,       // BB data invalid.
+      ICNotClassfied,  // BB data valid, but not classified.
+      ICTriangle,      // BB is part of a triangle sub-CFG.
+      ICDiamond,       // BB is part of a diamond sub-CFG.
+      ICTriangleEntry, // BB is entry of a triangle sub-CFG.
+      ICDiamondEntry   // BB is entry of a diamond sub-CFG.
+    };
+
+    /// BBInfo - One per MachineBasicBlock, this is used to cache the result
+    /// if-conversion feasibility analysis. This includes results from
+    /// TargetInstrInfo::AnalyzeBranch() (i.e. TBB, FBB, and Cond), and its
+    /// classification, and common merge block of its successors (if it's a
+    /// diamond shape).
+    struct BBInfo {
+      BBICKind Kind;
+      MachineBasicBlock *EBB;
+      MachineBasicBlock *TBB;
+      MachineBasicBlock *FBB;
+      MachineBasicBlock *CMBB;
+      std::vector<MachineOperand> Cond;
+      BBInfo() : Kind(ICInvalid), EBB(0), TBB(0), FBB(0), CMBB(0) {}
+    };
+
+    /// BBAnalysis - Results of if-conversion feasibility analysis indexed by
+    /// basic block number.
+    std::vector<BBInfo> BBAnalysis;
+
+    const TargetInstrInfo *TII;
+    bool MadeChange;
+  public:
+    static char ID;
+    IfConverter() : MachineFunctionPass((intptr_t)&ID) {}
+
+    virtual bool runOnMachineFunction(MachineFunction &MF);
+    virtual const char *getPassName() const { return "If converter"; }
+
+  private:
+    void AnalyzeBlock(MachineBasicBlock *BB);
+    void InitialFunctionAnalysis(MachineFunction &MF,
+                                 std::vector<int> &Candidates);
+    bool IfConvertDiamond(BBInfo &BBI);
+    bool IfConvertTriangle(BBInfo &BBI);
+    bool isBlockPredicatable(MachineBasicBlock *BB,
+                             bool IgnoreTerm = false) const;
+    void PredicateBlock(MachineBasicBlock *BB,
+                        std::vector<MachineOperand> &Cond,
+                        bool IgnoreTerm = false);
+    void MergeBlocks(MachineBasicBlock *TBB, MachineBasicBlock *FBB);
+  };
+  char IfConverter::ID = 0;
+}
+
+FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); }
+
+bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
+  TII = MF.getTarget().getInstrInfo();
+  if (!TII) return false;
+
+  MadeChange = false;
+
+  MF.RenumberBlocks();
+  unsigned NumBBs = MF.getNumBlockIDs();
+  BBAnalysis.resize(NumBBs);
+
+  std::vector<int> Candidates;
+  // Do an intial analysis for each basic block and finding all the potential
+  // candidates to perform if-convesion.
+  InitialFunctionAnalysis(MF, Candidates);
+
+  for (unsigned i = 0, e = Candidates.size(); i != e; ++i) {
+    BBInfo &BBI = BBAnalysis[i];
+    switch (BBI.Kind) {
+    default: assert(false && "Unexpected!");
+      break;
+    case ICTriangleEntry:
+      MadeChange |= IfConvertTriangle(BBI);
+      break;
+    case ICDiamondEntry:
+      MadeChange |= IfConvertDiamond(BBI);
+      break;
+    }
+  }
+  return MadeChange;
+}
+
+static MachineBasicBlock *findFalseBlock(MachineBasicBlock *BB,
+                                         MachineBasicBlock *TBB) {
+  for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
+         E = BB->succ_end(); SI != E; ++SI) {
+    MachineBasicBlock *SuccBB = *SI;
+    if (SuccBB != TBB)
+      return SuccBB;
+  }
+  return NULL;
+}
+
+void IfConverter::AnalyzeBlock(MachineBasicBlock *BB) {
+  BBInfo &BBI = BBAnalysis[BB->getNumber()];
+
+  if (BBI.Kind != ICInvalid)
+    return;  // Always analyzed.
+  BBI.EBB = BB;
+
+  // Look for 'root' of a simple (non-nested) triangle or diamond.
+  BBI.Kind = ICNotClassfied;
+  if (TII->AnalyzeBranch(*BB, BBI.TBB, BBI.FBB, BBI.Cond)
+      || !BBI.TBB || BBI.Cond.size() == 0)
+    return;
+  AnalyzeBlock(BBI.TBB);
+  BBInfo &TBBI = BBAnalysis[BBI.TBB->getNumber()];
+  if (TBBI.Kind != ICNotClassfied)
+    return;
+  
+  if (!BBI.FBB)
+    BBI.FBB = findFalseBlock(BB, BBI.TBB);  
+  AnalyzeBlock(BBI.FBB);
+  BBInfo &FBBI = BBAnalysis[BBI.FBB->getNumber()];
+  if (FBBI.Kind != ICNotClassfied)
+    return;
+
+  // TODO: Only handle very simple cases for now.
+  if (TBBI.FBB || FBBI.FBB || TBBI.Cond.size() > 1 || FBBI.Cond.size() > 1)
+    return;
+
+  if (TBBI.TBB && TBBI.TBB == BBI.FBB) {
+    // Triangle:
+    //   EBB
+    //   | \_
+    //   |  |
+    //   | TBB
+    //   |  /
+    //   FBB
+    BBI.Kind = ICTriangleEntry;
+    TBBI.Kind = FBBI.Kind = ICTriangle;
+  } else if (TBBI.TBB == FBBI.TBB) {
+    // Diamond:
+    //   EBB
+    //   / \_
+    //  |   |
+    // TBB FBB
+    //   \ /
+    //   MBB
+    // Note MBB can be empty in case both TBB and FBB are return blocks.
+    BBI.Kind = ICDiamondEntry;
+    TBBI.Kind = FBBI.Kind = ICDiamond;
+    BBI.CMBB = TBBI.TBB;
+  }
+  return;
+}
+
+void IfConverter::InitialFunctionAnalysis(MachineFunction &MF,
+                                          std::vector<int> &Candidates) {
+  for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) {
+    MachineBasicBlock *BB = I;
+    AnalyzeBlock(BB);
+    BBInfo &BBI = BBAnalysis[BB->getNumber()];
+    if (BBI.Kind == ICTriangleEntry || BBI.Kind == ICDiamondEntry)
+      Candidates.push_back(BB->getNumber());
+  }
+}
+
+bool IfConverter::IfConvertTriangle(BBInfo &BBI) {
+  if (isBlockPredicatable(BBI.TBB, true)) {
+    // Predicate the 'true' block after removing its branch.
+    TII->RemoveBranch(*BBI.TBB);
+    PredicateBlock(BBI.TBB, BBI.Cond);
+
+    // Join the 'true' and 'false' blocks by copying the instructions
+    // from the 'false' block to the 'true' block.
+    MergeBlocks(BBI.TBB, BBI.FBB);
+
+    // Adjust entry block, it should have but a single unconditional
+    // branch.
+    BBI.EBB->removeSuccessor(BBI.FBB);
+    TII->RemoveBranch(*BBI.EBB);
+    std::vector<MachineOperand> NoCond;
+    TII->InsertBranch(*BBI.EBB, BBI.TBB, NULL, NoCond);
+
+    // FIXME: Must maintain LiveIns.
+    NumIfConvBBs++;
+    return true;
+  }
+  return false;
+}
+
+bool IfConverter::IfConvertDiamond(BBInfo &BBI) {
+  if (isBlockPredicatable(BBI.TBB, true) &&
+      isBlockPredicatable(BBI.FBB, true)) {
+    std::vector<MachineInstr*> Dups;
+    if (!BBI.CMBB) {
+      // No common merge block. Check if the terminators (e.g. return) are
+      // the same or predicatable.
+      MachineBasicBlock::iterator TT = BBI.TBB->getFirstTerminator();
+      MachineBasicBlock::iterator FT = BBI.FBB->getFirstTerminator();
+      while (TT != BBI.TBB->end() && FT != BBI.FBB->end()) {
+        if (TT->isIdenticalTo(FT))
+          Dups.push_back(TT);  // Will erase these later.
+        else if (!TII->isPredicatable(TT) && !TII->isPredicatable(FT))
+          return false; // Can't if-convert. Abort!
+        ++TT;
+        ++FT;
+      }
+
+      while (TT != BBI.TBB->end())
+        if (!TII->isPredicatable(TT))
+          return false; // Can't if-convert. Abort!
+      while (FT != BBI.FBB->end())
+        if (!TII->isPredicatable(FT))
+          return false; // Can't if-convert. Abort!
+    }
+
+    // Remove the duplicated instructions from the 'true' block.
+    for (unsigned i = 0, e = Dups.size(); i != e; ++i)
+      Dups[i]->eraseFromParent();
+    
+    // Predicate the 'true' block after removing its branch.
+    TII->RemoveBranch(*BBI.TBB);
+    PredicateBlock(BBI.TBB, BBI.Cond);
+
+    // Predicate the 'false' block.
+    std::vector<MachineOperand> NewCond(BBI.Cond);
+    TII->ReverseBranchCondition(NewCond);
+    PredicateBlock(BBI.FBB, NewCond, true);
+
+    // Join the 'true' and 'false' blocks by copying the instructions
+    // from the 'false' block to the 'true' block.
+    MergeBlocks(BBI.TBB, BBI.FBB);
+
+    // Adjust entry block, it should have but a single unconditional
+    // branch .
+    BBI.EBB->removeSuccessor(BBI.FBB);
+    TII->RemoveBranch(*BBI.EBB);
+    std::vector<MachineOperand> NoCond;
+    TII->InsertBranch(*BBI.EBB, BBI.TBB, NULL, NoCond);
+
+    // FIXME: Must maintain LiveIns.
+    NumIfConvBBs += 2;
+    return true;
+  }
+  return false;
+}
+
+/// isBlockPredicatable - Returns true if the block is predicatable. In most
+/// cases, that means all the instructions in the block has M_PREDICATED flag.
+/// If IgnoreTerm is true, assume all the terminator instructions can be 
+/// converted or deleted.
+bool IfConverter::isBlockPredicatable(MachineBasicBlock *BB,
+                                      bool IgnoreTerm) const {
+  for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
+       I != E; ++I) {
+    if (IgnoreTerm && TII->isTerminatorInstr(I->getOpcode()))
+      continue;
+    if (!TII->isPredicatable(I))
+      return false;
+  }
+  return true;
+}
+
+/// PredicateBlock - Predicate every instruction in the block with the specified
+/// condition. If IgnoreTerm is true, skip over all terminator instructions.
+void IfConverter::PredicateBlock(MachineBasicBlock *BB,
+                                 std::vector<MachineOperand> &Cond,
+                                 bool IgnoreTerm) {
+  for (MachineBasicBlock::iterator I = BB->begin(), E = BB->end();
+       I != E; ++I) {
+    if (IgnoreTerm && TII->isTerminatorInstr(I->getOpcode()))
+      continue;
+    TII->PredicateInstruction(&*I, Cond);
+  }
+}
+
+/// MergeBlocks - Move all instructions from FBB to the end of TBB.
+///
+void IfConverter::MergeBlocks(MachineBasicBlock *TBB, MachineBasicBlock *FBB) {
+  TBB->splice(TBB->end(), FBB, FBB->begin(), FBB->end());
+}
