[lanai] Use peephole optimizer to generate more conditional ALU operations.

Summary:
* Similiar to the ARM backend yse the peephole optimizer to generate more conditional ALU operations;
* Add predicated type with default always true to RR instructions in LanaiInstrInfo.td;
* Move LanaiSetflagAluCombiner into optimizeCompare;
* The ASM parser can currently only handle explicitly specified CC, so specify ".t" (true) where needed in the ASM test;
* Remove unused MachineOperand flags;

Reviewers: eliben

Subscribers: aemerson

Differential Revision: http://reviews.llvm.org/D22072

llvm-svn: 274807
diff --git a/llvm/lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp b/llvm/lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp
index 799f587..c3c4468 100644
--- a/llvm/lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp
+++ b/llvm/lib/Target/Lanai/AsmParser/LanaiAsmParser.cpp
@@ -357,6 +357,20 @@
     return isInt<10>(Value);
   }
 
+  bool isCondCode() {
+    if (!isImm())
+      return false;
+
+    const MCConstantExpr *ConstExpr = dyn_cast<MCConstantExpr>(Imm.Value);
+    if (!ConstExpr)
+      return false;
+    uint64_t Value = ConstExpr->getValue();
+    // The condition codes are between 0 (ICC_T) and 15 (ICC_LE). If the
+    // unsigned value of the immediate is less than LPCC::UNKNOWN (16) then
+    // value corresponds to a valid condition code.
+    return Value < LPCC::UNKNOWN;
+  }
+
   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
     // Add as immediates where possible. Null MCExpr = 0
     if (Expr == nullptr)
@@ -388,6 +402,11 @@
     addExpr(Inst, getImm());
   }
 
+  void addCondCodeOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    addExpr(Inst, getImm());
+  }
+
   void addMemImmOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     const MCExpr *Expr = getMemOffset();
@@ -1031,7 +1050,16 @@
     LPCC::CondCode CondCode = LPCC::suffixToLanaiCondCode(Mnemonic);
     if (CondCode != LPCC::UNKNOWN) {
       size_t Next = Mnemonic.rfind('.', Name.size());
-      Mnemonic = Mnemonic.substr(0, Next + 1);
+      // 'sel' doesn't use a predicate operand whose printer adds the period,
+      // but instead has the period as part of the identifier (i.e., 'sel.' is
+      // expected by the generated matcher). If the mnemonic starts with 'sel'
+      // then include the period as part of the mnemonic, else don't include it
+      // as part of the mnemonic.
+      if (Mnemonic.startswith("sel")) {
+        Mnemonic = Mnemonic.substr(0, Next + 1);
+      } else {
+        Mnemonic = Mnemonic.substr(0, Next);
+      }
       Operands->push_back(LanaiOperand::CreateToken(Mnemonic, NameLoc));
       Operands->push_back(LanaiOperand::createImm(
           MCConstantExpr::create(CondCode, getContext()), NameLoc, NameLoc));
diff --git a/llvm/lib/Target/Lanai/CMakeLists.txt b/llvm/lib/Target/Lanai/CMakeLists.txt
index e5aec96..867f616 100644
--- a/llvm/lib/Target/Lanai/CMakeLists.txt
+++ b/llvm/lib/Target/Lanai/CMakeLists.txt
@@ -23,7 +23,6 @@
   LanaiMemAluCombiner.cpp
   LanaiRegisterInfo.cpp
   LanaiSelectionDAGInfo.cpp
-  LanaiSetflagAluCombiner.cpp
   LanaiSubtarget.cpp
   LanaiTargetMachine.cpp
   LanaiTargetObjectFile.cpp
diff --git a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp
index 3a71b80..d8ead5d 100644
--- a/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp
+++ b/llvm/lib/Target/Lanai/Disassembler/LanaiDisassembler.cpp
@@ -62,6 +62,10 @@
 static DecodeStatus decodeBranch(MCInst &Inst, unsigned Insn, uint64_t Address,
                                  const void *Decoder);
 
+static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
+                                           uint64_t Address,
+                                           const void *Decoder);
+
 static DecodeStatus decodeShiftImm(MCInst &Inst, unsigned Insn,
                                    uint64_t Address, const void *Decoder);
 
@@ -226,3 +230,12 @@
 
   return MCDisassembler::Success;
 }
+
+static DecodeStatus decodePredicateOperand(MCInst &Inst, unsigned Val,
+                                           uint64_t Address,
+                                           const void *Decoder) {
+  if (Val >= LPCC::UNKNOWN)
+    return MCDisassembler::Fail;
+  Inst.addOperand(MCOperand::createImm(Val));
+  return MCDisassembler::Success;
+}
diff --git a/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp b/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp
index 4a1dcd8..82b720c 100644
--- a/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp
+++ b/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.cpp
@@ -284,6 +284,22 @@
 
 void LanaiInstPrinter::printCCOperand(const MCInst *MI, int OpNo,
                                       raw_ostream &OS) {
-  const int CC = static_cast<const int>(MI->getOperand(OpNo).getImm());
-  OS << lanaiCondCodeToString(static_cast<LPCC::CondCode>(CC));
+  LPCC::CondCode CC =
+      static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
+  // Handle the undefined value here for printing so we don't abort().
+  if (CC >= LPCC::UNKNOWN)
+    OS << "<und>";
+  else
+    OS << lanaiCondCodeToString(CC);
+}
+
+void LanaiInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNo,
+                                             raw_ostream &OS) {
+  LPCC::CondCode CC =
+      static_cast<LPCC::CondCode>(MI->getOperand(OpNo).getImm());
+  // Handle the undefined value here for printing so we don't abort().
+  if (CC >= LPCC::UNKNOWN)
+    OS << "<und>";
+  else if (CC != LPCC::ICC_T)
+    OS << "." << lanaiCondCodeToString(CC);
 }
diff --git a/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.h b/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.h
index 4bd5bb0..1c9d186 100644
--- a/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.h
+++ b/llvm/lib/Target/Lanai/InstPrinter/LanaiInstPrinter.h
@@ -29,6 +29,7 @@
                  const MCSubtargetInfo &STI) override;
   void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O,
                     const char *Modifier = 0);
+  void printPredicateOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printMemRiOperand(const MCInst *MI, int OpNo, raw_ostream &O,
                          const char *Modifier = 0);
   void printMemRrOperand(const MCInst *MI, int OpNo, raw_ostream &O,
diff --git a/llvm/lib/Target/Lanai/LanaiAsmPrinter.cpp b/llvm/lib/Target/Lanai/LanaiAsmPrinter.cpp
index 0effa5c..d3ff9e8 100644
--- a/llvm/lib/Target/Lanai/LanaiAsmPrinter.cpp
+++ b/llvm/lib/Target/Lanai/LanaiAsmPrinter.cpp
@@ -65,7 +65,6 @@
 void LanaiAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
                                    raw_ostream &O, const char *Modifier) {
   const MachineOperand &MO = MI->getOperand(OpNum);
-  unsigned TF = MO.getTargetFlags();
 
   switch (MO.getType()) {
   case MachineOperand::MO_Register:
@@ -81,10 +80,7 @@
     break;
 
   case MachineOperand::MO_GlobalAddress:
-    if (TF == LanaiII::MO_PLT)
-      O << "plt(" << *getSymbol(MO.getGlobal()) << ")";
-    else
-      O << *getSymbol(MO.getGlobal());
+    O << *getSymbol(MO.getGlobal());
     break;
 
   case MachineOperand::MO_BlockAddress: {
@@ -94,10 +90,7 @@
   }
 
   case MachineOperand::MO_ExternalSymbol:
-    if (TF == LanaiII::MO_PLT)
-      O << "plt(" << *GetExternalSymbolSymbol(MO.getSymbolName()) << ")";
-    else
-      O << *GetExternalSymbolSymbol(MO.getSymbolName());
+    O << *GetExternalSymbolSymbol(MO.getSymbolName());
     break;
 
   case MachineOperand::MO_JumpTableIndex:
@@ -116,7 +109,6 @@
 }
 
 // PrintAsmOperand - Print out an operand for an inline asm expression.
-//
 bool LanaiAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
                                       unsigned AsmVariant,
                                       const char *ExtraCode, raw_ostream &O) {
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
index fd2d7ff..a383cf8 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp
@@ -124,6 +124,12 @@
     setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
   }
 
+  setTargetDAGCombine(ISD::ADD);
+  setTargetDAGCombine(ISD::SUB);
+  setTargetDAGCombine(ISD::AND);
+  setTargetDAGCombine(ISD::OR);
+  setTargetDAGCombine(ISD::XOR);
+
   // Function alignments (log2)
   setMinFunctionAlignment(2);
   setPrefFunctionAlignment(2);
@@ -1268,3 +1274,167 @@
   SDValue Ops[2] = {Lo, Hi};
   return DAG.getMergeValues(Ops, dl);
 }
+
+// Helper function that checks if N is a null or all ones constant.
+static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
+  return AllOnes ? isAllOnesConstant(N) : isNullConstant(N);
+}
+
+// Return true if N is conditionally 0 or all ones.
+// Detects these expressions where cc is an i1 value:
+//
+//   (select cc 0, y)   [AllOnes=0]
+//   (select cc y, 0)   [AllOnes=0]
+//   (zext cc)          [AllOnes=0]
+//   (sext cc)          [AllOnes=0/1]
+//   (select cc -1, y)  [AllOnes=1]
+//   (select cc y, -1)  [AllOnes=1]
+//
+// * AllOnes determines whether to check for an all zero (AllOnes false) or an
+//   all ones operand (AllOnes true).
+// * Invert is set when N is the all zero/ones constant when CC is false.
+// * OtherOp is set to the alternative value of N.
+//
+// For example, for (select cc X, Y) and AllOnes = 0 if:
+// * X = 0, Invert = False and OtherOp = Y
+// * Y = 0, Invert = True and OtherOp = X
+static bool isConditionalZeroOrAllOnes(SDNode *N, bool AllOnes, SDValue &CC,
+                                       bool &Invert, SDValue &OtherOp,
+                                       SelectionDAG &DAG) {
+  switch (N->getOpcode()) {
+  default:
+    return false;
+  case ISD::SELECT: {
+    CC = N->getOperand(0);
+    SDValue N1 = N->getOperand(1);
+    SDValue N2 = N->getOperand(2);
+    if (isZeroOrAllOnes(N1, AllOnes)) {
+      Invert = false;
+      OtherOp = N2;
+      return true;
+    }
+    if (isZeroOrAllOnes(N2, AllOnes)) {
+      Invert = true;
+      OtherOp = N1;
+      return true;
+    }
+    return false;
+  }
+  case ISD::ZERO_EXTEND: {
+    // (zext cc) can never be the all ones value.
+    if (AllOnes)
+      return false;
+    CC = N->getOperand(0);
+    if (CC.getValueType() != MVT::i1)
+      return false;
+    SDLoc dl(N);
+    EVT VT = N->getValueType(0);
+    OtherOp = DAG.getConstant(1, dl, VT);
+    Invert = true;
+    return true;
+  }
+  case ISD::SIGN_EXTEND: {
+    CC = N->getOperand(0);
+    if (CC.getValueType() != MVT::i1)
+      return false;
+    SDLoc dl(N);
+    EVT VT = N->getValueType(0);
+    Invert = !AllOnes;
+    if (AllOnes)
+      // When looking for an AllOnes constant, N is an sext, and the 'other'
+      // value is 0.
+      OtherOp = DAG.getConstant(0, dl, VT);
+    else
+      OtherOp =
+          DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), dl, VT);
+    return true;
+  }
+  }
+}
+
+// Combine a constant select operand into its use:
+//
+//   (add (select cc, 0, c), x)  -> (select cc, x, (add, x, c))
+//   (sub x, (select cc, 0, c))  -> (select cc, x, (sub, x, c))
+//   (and (select cc, -1, c), x) -> (select cc, x, (and, x, c))  [AllOnes=1]
+//   (or  (select cc, 0, c), x)  -> (select cc, x, (or, x, c))
+//   (xor (select cc, 0, c), x)  -> (select cc, x, (xor, x, c))
+//
+// The transform is rejected if the select doesn't have a constant operand that
+// is null, or all ones when AllOnes is set.
+//
+// Also recognize sext/zext from i1:
+//
+//   (add (zext cc), x) -> (select cc (add x, 1), x)
+//   (add (sext cc), x) -> (select cc (add x, -1), x)
+//
+// These transformations eventually create predicated instructions.
+static SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp,
+                                   TargetLowering::DAGCombinerInfo &DCI,
+                                   bool AllOnes) {
+  SelectionDAG &DAG = DCI.DAG;
+  EVT VT = N->getValueType(0);
+  SDValue NonConstantVal;
+  SDValue CCOp;
+  bool SwapSelectOps;
+  if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
+                                  NonConstantVal, DAG))
+    return SDValue();
+
+  // Slct is now know to be the desired identity constant when CC is true.
+  SDValue TrueVal = OtherOp;
+  SDValue FalseVal =
+      DAG.getNode(N->getOpcode(), SDLoc(N), VT, OtherOp, NonConstantVal);
+  // Unless SwapSelectOps says CC should be false.
+  if (SwapSelectOps)
+    std::swap(TrueVal, FalseVal);
+
+  return DAG.getNode(ISD::SELECT, SDLoc(N), VT, CCOp, TrueVal, FalseVal);
+}
+
+// Attempt combineSelectAndUse on each operand of a commutative operator N.
+static SDValue
+combineSelectAndUseCommutative(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
+                               bool AllOnes) {
+  SDValue N0 = N->getOperand(0);
+  SDValue N1 = N->getOperand(1);
+  if (N0.getNode()->hasOneUse())
+    if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
+      return Result;
+  if (N1.getNode()->hasOneUse())
+    if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
+      return Result;
+  return SDValue();
+}
+
+// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
+static SDValue PerformSUBCombine(SDNode *N,
+                                 TargetLowering::DAGCombinerInfo &DCI) {
+  SDValue N0 = N->getOperand(0);
+  SDValue N1 = N->getOperand(1);
+
+  // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
+  if (N1.getNode()->hasOneUse())
+    if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, /*AllOnes=*/false))
+      return Result;
+
+  return SDValue();
+}
+
+SDValue LanaiTargetLowering::PerformDAGCombine(SDNode *N,
+                                               DAGCombinerInfo &DCI) const {
+  switch (N->getOpcode()) {
+  default:
+    break;
+  case ISD::ADD:
+  case ISD::OR:
+  case ISD::XOR:
+    return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/false);
+  case ISD::AND:
+    return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/true);
+  case ISD::SUB:
+    return PerformSUBCombine(N, DCI);
+  }
+
+  return SDValue();
+}
diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.h b/llvm/lib/Target/Lanai/LanaiISelLowering.h
index 20ca9a0..16ce8ed 100644
--- a/llvm/lib/Target/Lanai/LanaiISelLowering.h
+++ b/llvm/lib/Target/Lanai/LanaiISelLowering.h
@@ -103,6 +103,8 @@
                                     std::vector<SDValue> &Ops,
                                     SelectionDAG &DAG) const override;
 
+  SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
+
 private:
   SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee,
                          CallingConv::ID CallConv, bool IsVarArg,
diff --git a/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp b/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp
index 797fd8e..8616042 100644
--- a/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp
+++ b/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp
@@ -122,7 +122,7 @@
   return false;
 }
 
-static LPCC::CondCode GetOppositeBranchCondition(LPCC::CondCode CC) {
+static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC) {
   switch (CC) {
   case LPCC::ICC_T: //  true
     return LPCC::ICC_F;
@@ -161,6 +161,397 @@
   }
 }
 
+std::pair<unsigned, unsigned>
+LanaiInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
+  return std::make_pair(TF, 0u);
+}
+
+ArrayRef<std::pair<unsigned, const char *>>
+LanaiInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
+  using namespace LanaiII;
+  static const std::pair<unsigned, const char *> TargetFlags[] = {
+      {MO_ABS_HI, "lanai-hi"},
+      {MO_ABS_LO, "lanai-lo"},
+      {MO_NO_FLAG, "lanai-nf"}};
+  return makeArrayRef(TargetFlags);
+}
+
+bool LanaiInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
+                                    unsigned &SrcReg2, int &CmpMask,
+                                    int &CmpValue) const {
+  switch (MI.getOpcode()) {
+  default:
+    break;
+  case Lanai::SFSUB_F_RI_LO:
+  case Lanai::SFSUB_F_RI_HI:
+    SrcReg = MI.getOperand(0).getReg();
+    SrcReg2 = 0;
+    CmpMask = ~0;
+    CmpValue = MI.getOperand(1).getImm();
+    return true;
+  case Lanai::SFSUB_F_RR:
+    SrcReg = MI.getOperand(0).getReg();
+    SrcReg2 = MI.getOperand(1).getReg();
+    CmpMask = ~0;
+    CmpValue = 0;
+    return true;
+  }
+
+  return false;
+}
+
+// isRedundantFlagInstr - check whether the first instruction, whose only
+// purpose is to update flags, can be made redundant.
+// * SFSUB_F_RR can be made redundant by SUB_RI if the operands are the same.
+// * SFSUB_F_RI can be made redundant by SUB_I if the operands are the same.
+inline static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg,
+                                        unsigned SrcReg2, int ImmValue,
+                                        MachineInstr *OI) {
+  if (CmpI->getOpcode() == Lanai::SFSUB_F_RR &&
+      OI->getOpcode() == Lanai::SUB_R &&
+      ((OI->getOperand(1).getReg() == SrcReg &&
+        OI->getOperand(2).getReg() == SrcReg2) ||
+       (OI->getOperand(1).getReg() == SrcReg2 &&
+        OI->getOperand(2).getReg() == SrcReg)))
+    return true;
+
+  if (((CmpI->getOpcode() == Lanai::SFSUB_F_RI_LO &&
+        OI->getOpcode() == Lanai::SUB_I_LO) ||
+       (CmpI->getOpcode() == Lanai::SFSUB_F_RI_HI &&
+        OI->getOpcode() == Lanai::SUB_I_HI)) &&
+      OI->getOperand(1).getReg() == SrcReg &&
+      OI->getOperand(2).getImm() == ImmValue)
+    return true;
+  return false;
+}
+
+inline static unsigned flagSettingOpcodeVariant(unsigned OldOpcode) {
+  switch (OldOpcode) {
+  case Lanai::ADD_I_HI:
+    return Lanai::ADD_F_I_HI;
+  case Lanai::ADD_I_LO:
+    return Lanai::ADD_F_I_LO;
+  case Lanai::ADD_R:
+    return Lanai::ADD_F_R;
+  case Lanai::ADDC_I_HI:
+    return Lanai::ADDC_F_I_HI;
+  case Lanai::ADDC_I_LO:
+    return Lanai::ADDC_F_I_LO;
+  case Lanai::ADDC_R:
+    return Lanai::ADDC_F_R;
+  case Lanai::AND_I_HI:
+    return Lanai::AND_F_I_HI;
+  case Lanai::AND_I_LO:
+    return Lanai::AND_F_I_LO;
+  case Lanai::AND_R:
+    return Lanai::AND_F_R;
+  case Lanai::OR_I_HI:
+    return Lanai::OR_F_I_HI;
+  case Lanai::OR_I_LO:
+    return Lanai::OR_F_I_LO;
+  case Lanai::OR_R:
+    return Lanai::OR_F_R;
+  case Lanai::SL_I:
+    return Lanai::SL_F_I;
+  case Lanai::SRL_R:
+    return Lanai::SRL_F_R;
+  case Lanai::SA_I:
+    return Lanai::SA_F_I;
+  case Lanai::SRA_R:
+    return Lanai::SRA_F_R;
+  case Lanai::SUB_I_HI:
+    return Lanai::SUB_F_I_HI;
+  case Lanai::SUB_I_LO:
+    return Lanai::SUB_F_I_LO;
+  case Lanai::SUB_R:
+    return Lanai::SUB_F_R;
+  case Lanai::SUBB_I_HI:
+    return Lanai::SUBB_F_I_HI;
+  case Lanai::SUBB_I_LO:
+    return Lanai::SUBB_F_I_LO;
+  case Lanai::SUBB_R:
+    return Lanai::SUBB_F_R;
+  case Lanai::XOR_I_HI:
+    return Lanai::XOR_F_I_HI;
+  case Lanai::XOR_I_LO:
+    return Lanai::XOR_F_I_LO;
+  case Lanai::XOR_R:
+    return Lanai::XOR_F_R;
+  default:
+    return Lanai::NOP;
+  }
+}
+
+bool LanaiInstrInfo::optimizeCompareInstr(
+    MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask,
+    int CmpValue, const MachineRegisterInfo *MRI) const {
+  // Get the unique definition of SrcReg.
+  MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
+  if (!MI)
+    return false;
+
+  // Get ready to iterate backward from CmpInstr.
+  MachineBasicBlock::iterator I = CmpInstr, E = MI,
+                              B = CmpInstr.getParent()->begin();
+
+  // Early exit if CmpInstr is at the beginning of the BB.
+  if (I == B)
+    return false;
+
+  // There are two possible candidates which can be changed to set SR:
+  // One is MI, the other is a SUB instruction.
+  // * For SFSUB_F_RR(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
+  // * For SFSUB_F_RI(r1, CmpValue), we are looking for SUB(r1, CmpValue).
+  MachineInstr *Sub = nullptr;
+  if (SrcReg2 != 0)
+    // MI is not a candidate to transform into a flag setting instruction.
+    MI = nullptr;
+  else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {
+    // Conservatively refuse to convert an instruction which isn't in the same
+    // BB as the comparison. Don't return if SFSUB_F_RI and CmpValue != 0 as Sub
+    // may still be a candidate.
+    if (CmpInstr.getOpcode() == Lanai::SFSUB_F_RI_LO)
+      MI = nullptr;
+    else
+      return false;
+  }
+
+  // Check that SR isn't set between the comparison instruction and the
+  // instruction we want to change while searching for Sub.
+  const TargetRegisterInfo *TRI = &getRegisterInfo();
+  for (--I; I != E; --I) {
+    const MachineInstr &Instr = *I;
+
+    if (Instr.modifiesRegister(Lanai::SR, TRI) ||
+        Instr.readsRegister(Lanai::SR, TRI))
+      // This instruction modifies or uses SR after the one we want to change.
+      // We can't do this transformation.
+      return false;
+
+    // Check whether CmpInstr can be made redundant by the current instruction.
+    if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &*I)) {
+      Sub = &*I;
+      break;
+    }
+
+    // Don't search outside the containing basic block.
+    if (I == B)
+      return false;
+  }
+
+  // Return false if no candidates exist.
+  if (!MI && !Sub)
+    return false;
+
+  // The single candidate is called MI.
+  if (!MI)
+    MI = Sub;
+
+  if (flagSettingOpcodeVariant(MI->getOpcode()) != Lanai::NOP) {
+    bool isSafe = false;
+
+    SmallVector<std::pair<MachineOperand *, LPCC::CondCode>, 4>
+        OperandsToUpdate;
+    I = CmpInstr;
+    E = CmpInstr.getParent()->end();
+    while (!isSafe && ++I != E) {
+      const MachineInstr &Instr = *I;
+      for (unsigned IO = 0, EO = Instr.getNumOperands(); !isSafe && IO != EO;
+           ++IO) {
+        const MachineOperand &MO = Instr.getOperand(IO);
+        if (MO.isRegMask() && MO.clobbersPhysReg(Lanai::SR)) {
+          isSafe = true;
+          break;
+        }
+        if (!MO.isReg() || MO.getReg() != Lanai::SR)
+          continue;
+        if (MO.isDef()) {
+          isSafe = true;
+          break;
+        }
+        // Condition code is after the operand before SR.
+        LPCC::CondCode CC;
+        CC = (LPCC::CondCode)Instr.getOperand(IO - 1).getImm();
+
+        if (Sub) {
+          LPCC::CondCode NewCC = getOppositeCondition(CC);
+          if (NewCC == LPCC::ICC_T)
+            return false;
+          // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on
+          // CMP needs to be updated to be based on SUB.  Push the condition
+          // code operands to OperandsToUpdate.  If it is safe to remove
+          // CmpInstr, the condition code of these operands will be modified.
+          if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
+              Sub->getOperand(2).getReg() == SrcReg) {
+            OperandsToUpdate.push_back(
+                std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
+          }
+        } else {
+          // No Sub, so this is x = <op> y, z; cmp x, 0.
+          switch (CC) {
+          case LPCC::ICC_EQ: // Z
+          case LPCC::ICC_NE: // Z
+          case LPCC::ICC_MI: // N
+          case LPCC::ICC_PL: // N
+          case LPCC::ICC_F:  // none
+          case LPCC::ICC_T:  // none
+            // SR can be used multiple times, we should continue.
+            break;
+          case LPCC::ICC_CS: // C
+          case LPCC::ICC_CC: // C
+          case LPCC::ICC_VS: // V
+          case LPCC::ICC_VC: // V
+          case LPCC::ICC_HI: // C Z
+          case LPCC::ICC_LS: // C Z
+          case LPCC::ICC_GE: // N V
+          case LPCC::ICC_LT: // N V
+          case LPCC::ICC_GT: // Z N V
+          case LPCC::ICC_LE: // Z N V
+            // The instruction uses the V bit or C bit which is not safe.
+            return false;
+          case LPCC::UNKNOWN:
+            return false;
+          }
+        }
+      }
+    }
+
+    // If SR is not killed nor re-defined, we should check whether it is
+    // live-out. If it is live-out, do not optimize.
+    if (!isSafe) {
+      MachineBasicBlock *MBB = CmpInstr.getParent();
+      for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
+                                            SE = MBB->succ_end();
+           SI != SE; ++SI)
+        if ((*SI)->isLiveIn(Lanai::SR))
+          return false;
+    }
+
+    // Toggle the optional operand to SR.
+    MI->setDesc(get(flagSettingOpcodeVariant(MI->getOpcode())));
+    MI->addRegisterDefined(Lanai::SR);
+    CmpInstr.eraseFromParent();
+    return true;
+  }
+
+  return false;
+}
+
+bool LanaiInstrInfo::analyzeSelect(const MachineInstr &MI,
+                                   SmallVectorImpl<MachineOperand> &Cond,
+                                   unsigned &TrueOp, unsigned &FalseOp,
+                                   bool &Optimizable) const {
+  assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
+  // Select operands:
+  // 0: Def.
+  // 1: True use.
+  // 2: False use.
+  // 3: Condition code.
+  TrueOp = 1;
+  FalseOp = 2;
+  Cond.push_back(MI.getOperand(3));
+  Optimizable = true;
+  return false;
+}
+
+// Identify instructions that can be folded into a SELECT instruction, and
+// return the defining instruction.
+static MachineInstr *canFoldIntoSelect(unsigned Reg,
+                                       const MachineRegisterInfo &MRI,
+                                       const TargetInstrInfo *TII) {
+  if (!TargetRegisterInfo::isVirtualRegister(Reg))
+    return nullptr;
+  if (!MRI.hasOneNonDBGUse(Reg))
+    return nullptr;
+  MachineInstr *MI = MRI.getVRegDef(Reg);
+  if (!MI)
+    return nullptr;
+  // MI is folded into the SELECT by predicating it.
+  if (!MI->isPredicable())
+    return nullptr;
+  // Check if MI has any non-dead defs or physreg uses. This also detects
+  // predicated instructions which will be reading SR.
+  for (unsigned i = 1, e = MI->getNumOperands(); i != e; ++i) {
+    const MachineOperand &MO = MI->getOperand(i);
+    // Reject frame index operands.
+    if (MO.isFI() || MO.isCPI() || MO.isJTI())
+      return nullptr;
+    if (!MO.isReg())
+      continue;
+    // MI can't have any tied operands, that would conflict with predication.
+    if (MO.isTied())
+      return nullptr;
+    if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+      return nullptr;
+    if (MO.isDef() && !MO.isDead())
+      return nullptr;
+  }
+  bool DontMoveAcrossStores = true;
+  if (!MI->isSafeToMove(/*AliasAnalysis=*/nullptr, DontMoveAcrossStores))
+    return nullptr;
+  return MI;
+}
+
+MachineInstr *
+LanaiInstrInfo::optimizeSelect(MachineInstr &MI,
+                               SmallPtrSetImpl<MachineInstr *> &SeenMIs,
+                               bool PreferFalse) const {
+  assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
+  MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
+  MachineInstr *DefMI = canFoldIntoSelect(MI.getOperand(1).getReg(), MRI, this);
+  bool Invert = !DefMI;
+  if (!DefMI)
+    DefMI = canFoldIntoSelect(MI.getOperand(2).getReg(), MRI, this);
+  if (!DefMI)
+    return nullptr;
+
+  // Find new register class to use.
+  MachineOperand FalseReg = MI.getOperand(Invert ? 1 : 2);
+  unsigned DestReg = MI.getOperand(0).getReg();
+  const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
+  if (!MRI.constrainRegClass(DestReg, PreviousClass))
+    return nullptr;
+
+  // Create a new predicated version of DefMI.
+  MachineInstrBuilder NewMI =
+      BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), DefMI->getDesc(), DestReg);
+
+  // Copy all the DefMI operands, excluding its (null) predicate.
+  const MCInstrDesc &DefDesc = DefMI->getDesc();
+  for (unsigned i = 1, e = DefDesc.getNumOperands();
+       i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
+    NewMI.addOperand(DefMI->getOperand(i));
+
+  unsigned CondCode = MI.getOperand(3).getImm();
+  if (Invert)
+    NewMI.addImm(getOppositeCondition(LPCC::CondCode(CondCode)));
+  else
+    NewMI.addImm(CondCode);
+  NewMI.copyImplicitOps(MI);
+
+  // The output register value when the predicate is false is an implicit
+  // register operand tied to the first def.  The tie makes the register
+  // allocator ensure the FalseReg is allocated the same register as operand 0.
+  FalseReg.setImplicit();
+  NewMI.addOperand(FalseReg);
+  NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
+
+  // Update SeenMIs set: register newly created MI and erase removed DefMI.
+  SeenMIs.insert(NewMI);
+  SeenMIs.erase(DefMI);
+
+  // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
+  // DefMI would be invalid when transferred inside the loop.  Checking for a
+  // loop is expensive, but at least remove kill flags if they are in different
+  // BBs.
+  if (DefMI->getParent() != MI.getParent())
+    NewMI->clearKillInfo();
+
+  // The caller will erase MI, but not DefMI.
+  DefMI->eraseFromParent();
+  return NewMI;
+}
+
 // The AnalyzeBranch function is used to examine conditional instructions and
 // remove unnecessary instructions. This method is used by BranchFolder and
 // IfConverter machine function passes to improve the CFG.
@@ -262,7 +653,7 @@
 
   LPCC::CondCode BranchCond =
       static_cast<LPCC::CondCode>(Condition[0].getImm());
-  Condition[0].setImm(GetOppositeBranchCondition(BranchCond));
+  Condition[0].setImm(getOppositeCondition(BranchCond));
   return false;
 }
 
diff --git a/llvm/lib/Target/Lanai/LanaiInstrInfo.h b/llvm/lib/Target/Lanai/LanaiInstrInfo.h
index ff2a51a..2d12d3d 100644
--- a/llvm/lib/Target/Lanai/LanaiInstrInfo.h
+++ b/llvm/lib/Target/Lanai/LanaiInstrInfo.h
@@ -75,6 +75,12 @@
                                   int64_t &Offset, unsigned &Width,
                                   const TargetRegisterInfo *TRI) const;
 
+  std::pair<unsigned, unsigned>
+  decomposeMachineOperandsTargetFlags(unsigned TF) const override;
+
+  ArrayRef<std::pair<unsigned, const char *>>
+  getSerializableDirectMachineOperandTargetFlags() const override;
+
   bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock,
                      MachineBasicBlock *&FalseBlock,
                      SmallVectorImpl<MachineOperand> &Condition,
@@ -82,6 +88,47 @@
 
   unsigned RemoveBranch(MachineBasicBlock &MBB) const override;
 
+  // For a comparison instruction, return the source registers in SrcReg and
+  // SrcReg2 if having two register operands, and the value it compares against
+  // in CmpValue. Return true if the comparison instruction can be analyzed.
+  bool analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
+                      unsigned &SrcReg2, int &CmpMask,
+                      int &CmpValue) const override;
+
+  // See if the comparison instruction can be converted into something more
+  // efficient. E.g., on Lanai register-register instructions can set the flag
+  // register, obviating the need for a separate compare.
+  bool optimizeCompareInstr(MachineInstr &CmpInstr, unsigned SrcReg,
+                            unsigned SrcReg2, int CmpMask, int CmpValue,
+                            const MachineRegisterInfo *MRI) const override;
+
+  // Analyze the given select instruction, returning true if it cannot be
+  // understood. It is assumed that MI->isSelect() is true.
+  //
+  // When successful, return the controlling condition and the operands that
+  // determine the true and false result values.
+  //
+  //   Result = SELECT Cond, TrueOp, FalseOp
+  //
+  // Lanai can optimize certain select instructions, for example by predicating
+  // the instruction defining one of the operands and sets Optimizable to true.
+  bool analyzeSelect(const MachineInstr &MI,
+                     SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
+                     unsigned &FalseOp, bool &Optimizable) const override;
+
+  // Given a select instruction that was understood by analyzeSelect and
+  // returned Optimizable = true, attempt to optimize MI by merging it with one
+  // of its operands. Returns NULL on failure.
+  //
+  // When successful, returns the new select instruction. The client is
+  // responsible for deleting MI.
+  //
+  // If both sides of the select can be optimized, the TrueOp is modifed.
+  // PreferFalse is not used.
+  MachineInstr *optimizeSelect(MachineInstr &MI,
+                               SmallPtrSetImpl<MachineInstr *> &SeenMIs,
+                               bool PreferFalse) const override;
+
   bool ReverseBranchCondition(
       SmallVectorImpl<MachineOperand> &Condition) const override;
 
diff --git a/llvm/lib/Target/Lanai/LanaiInstrInfo.td b/llvm/lib/Target/Lanai/LanaiInstrInfo.td
index 20dd4ee..05f4f75 100644
--- a/llvm/lib/Target/Lanai/LanaiInstrInfo.td
+++ b/llvm/lib/Target/Lanai/LanaiInstrInfo.td
@@ -235,6 +235,15 @@
   let PrintMethod = "printCCOperand";
 }
 
+// Predicate operand. Default to 0 = true.
+def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
+
+def pred : PredicateOperand<i32, (ops i32imm), (ops (i32 0))> {
+  let PrintMethod = "printPredicateOperand";
+  let ParserMatchClass = CondCodeOperand;
+  let DecoderMethod = "decodePredicateOperand";
+}
+
 let hasSideEffects = 0, Inst = 0x00000001 in
   def NOP : InstLanai<(outs), (ins), "nop", []>;
 
@@ -283,16 +292,10 @@
   defm I_ : ALUbase<subOp, AsmStr, OpNode, LoExt, HiExt, [], []>;
 
   // Register Register
-  let JJJJJ = 0, DDDI = 0 in
-    def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2),
-                   !strconcat(AsmStr, "\t$Rs1, $Rs2, $Rd"),
+  let JJJJJ = 0 in
+    def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
+                   !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
                    [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
-  // RR Conditional
-  let JJJJJ = 0, Uses = [SR] in
-    def R_CC : InstRR<subOp, (outs GPR:$Rd),
-                      (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
-                      !strconcat(AsmStr, ".$DDDI\t$Rs1, $Rs2, $Rd"),
-                      []>;
 }
 
 multiclass ALUlogic<bits<3> subOp, string AsmStr, SDNode OpNode,
@@ -302,16 +305,10 @@
                     [(set GPR:$Rd, (OpNode GPR:$Rs1, HiExt:$imm16))]>;
 
   // Register Register
-  let JJJJJ = 0, DDDI = 0 in
-    def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2),
-                   !strconcat(AsmStr, "\t$Rs1, $Rs2, $Rd"),
+  let JJJJJ = 0 in
+    def R : InstRR<subOp, (outs GPR:$Rd), (ins GPR:$Rs1, GPR:$Rs2, pred:$DDDI),
+                   !strconcat(AsmStr, "$DDDI\t$Rs1, $Rs2, $Rd"),
                    [(set GPR:$Rd, (OpNode GPR:$Rs1, GPR:$Rs2))]>;
-  // RR Conditional
-  let JJJJJ = 0, Uses = [SR] in
-    def R_CC : InstRR<subOp, (outs GPR:$Rd),
-                      (ins GPR:$Rs1, GPR:$Rs2, CCOp:$DDDI),
-                      !strconcat(AsmStr, ".$DDDI\t$Rs1, $Rs2, $Rd"),
-                      []>;
 }
 
 // Non flag setting ALU operations
@@ -407,7 +404,7 @@
 def : Pat<(LanaiSubbF GPR:$Rs1, i32hi16:$imm),
           (SUBB_F_I_HI GPR:$Rs1, i32hi16:$imm)>;
 
-def : InstAlias<"mov $src, $dst", (ADD_R GPR:$dst, GPR:$src, R0)>;
+def : InstAlias<"mov $src, $dst", (ADD_R GPR:$dst, GPR:$src, R0, 0)>;
 
 let isAsCheapAsAMove = 1, Rs1 = R0.Num, isCodeGenOnly = 1, H = 1, F = 0,
   isReMaterializable = 1 in
@@ -716,11 +713,15 @@
                      !strconcat(AsmStr, "\t$Rs1, $Rs2, %r0"),
                      [(LanaiSetFlag (i32 GPR:$Rs1), (i32 GPR:$Rs2))]>;
   let F = 1, Rd = R0.Num, H = 0, Defs = [SR] in
-    def _RI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16z:$imm16),
+    def _RI_LO : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32lo16z:$imm16),
                      !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
                      [(LanaiSetFlag (i32 GPR:$Rs1), i32lo16z:$imm16)]>;
+  let F = 1, Rd = R0.Num, H = 1, Defs = [SR] in
+    def _RI_HI : InstRI<op2Val, (outs), (ins GPR:$Rs1, i32hi16:$imm16),
+                     !strconcat(AsmStr, "\t$Rs1, $imm16, %r0"),
+                     [(LanaiSetFlag (i32 GPR:$Rs1), i32hi16:$imm16)]>;
 }
-let isCodeGenOnly = 1 in {
+let isCodeGenOnly = 1, isCompare = 1 in {
   defm SFSUB_F : SF<0b010, "sub.f">;
 }
 
diff --git a/llvm/lib/Target/Lanai/LanaiRegisterInfo.cpp b/llvm/lib/Target/Lanai/LanaiRegisterInfo.cpp
index 5d99f12..7bfe992 100644
--- a/llvm/lib/Target/Lanai/LanaiRegisterInfo.cpp
+++ b/llvm/lib/Target/Lanai/LanaiRegisterInfo.cpp
@@ -197,11 +197,16 @@
     }
     // Reg = FrameReg OP Reg
     if (MI.getOpcode() == Lanai::ADD_I_LO) {
-      if (HasNegOffset)
-        MI.setDesc(TII->get(Lanai::SUB_R));
-      else
-        MI.setDesc(TII->get(Lanai::ADD_R));
-    } else if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {
+      BuildMI(*MI.getParent(), II, DL,
+              HasNegOffset ? TII->get(Lanai::SUB_R) : TII->get(Lanai::ADD_R),
+              MI.getOperand(0).getReg())
+          .addReg(FrameReg)
+          .addReg(Reg)
+          .addImm(LPCC::ICC_T);
+      MI.eraseFromParent();
+      return;
+    }
+    if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {
       MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode())));
       if (HasNegOffset) {
         // Change the ALU op (operand 3) from LPAC::ADD (the default) to
diff --git a/llvm/lib/Target/Lanai/LanaiSetflagAluCombiner.cpp b/llvm/lib/Target/Lanai/LanaiSetflagAluCombiner.cpp
deleted file mode 100644
index cd72877..0000000
--- a/llvm/lib/Target/Lanai/LanaiSetflagAluCombiner.cpp
+++ /dev/null
@@ -1,294 +0,0 @@
-//===-- LanaiSetflagAluCombiner.cpp - Pass to combine set flag & ALU ops --===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "Lanai.h"
-#include "LanaiTargetMachine.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/CodeGen/MachineFunctionPass.h"
-#include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/RegisterScavenging.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Target/TargetInstrInfo.h"
-
-using namespace llvm;
-
-#define DEBUG_TYPE "lanai-setflag-alu-combiner"
-
-STATISTIC(NumSetflagAluCombined,
-          "Number of SET_FLAG and ALU instructions combined");
-
-static llvm::cl::opt<bool> DisableSetflagAluCombiner(
-    "disable-lanai-setflag-alu-combiner", llvm::cl::init(false),
-    llvm::cl::desc("Do not combine SET_FLAG and ALU operators"),
-    llvm::cl::Hidden);
-
-namespace llvm {
-void initializeLanaiSetflagAluCombinerPass(PassRegistry &);
-} // namespace llvm
-
-namespace {
-typedef MachineBasicBlock::iterator MbbIterator;
-typedef MachineFunction::iterator MfIterator;
-
-class LanaiSetflagAluCombiner : public MachineFunctionPass {
-public:
-  static char ID;
-  LanaiSetflagAluCombiner() : MachineFunctionPass(ID) {
-    initializeLanaiSetflagAluCombinerPass(*PassRegistry::getPassRegistry());
-  }
-
-  const char *getPassName() const override {
-    return "Lanai SET_FLAG ALU combiner pass";
-  }
-
-  bool runOnMachineFunction(MachineFunction &F) override;
-
-  MachineFunctionProperties getRequiredProperties() const override {
-    return MachineFunctionProperties().set(
-        MachineFunctionProperties::Property::AllVRegsAllocated);
-  }
-
-private:
-  bool CombineSetflagAluInBasicBlock(MachineFunction *MF,
-                                     MachineBasicBlock *BB);
-};
-} // namespace
-
-char LanaiSetflagAluCombiner::ID = 0;
-
-INITIALIZE_PASS(LanaiSetflagAluCombiner, DEBUG_TYPE,
-                "Lanai SET_FLAG ALU combiner pass", false, false)
-
-namespace {
-
-const unsigned kInvalid = -1;
-
-static unsigned flagSettingOpcodeVariant(unsigned OldOpcode) {
-  switch (OldOpcode) {
-  case Lanai::ADD_I_HI:
-    return Lanai::ADD_F_I_HI;
-  case Lanai::ADD_I_LO:
-    return Lanai::ADD_F_I_LO;
-  case Lanai::ADD_R:
-    return Lanai::ADD_F_R;
-  case Lanai::ADD_R_CC:
-    return Lanai::ADD_F_R_CC;
-  case Lanai::ADDC_I_HI:
-    return Lanai::ADDC_F_I_HI;
-  case Lanai::ADDC_I_LO:
-    return Lanai::ADDC_F_I_LO;
-  case Lanai::ADDC_R:
-    return Lanai::ADDC_F_R;
-  case Lanai::ADDC_R_CC:
-    return Lanai::ADDC_F_R_CC;
-  case Lanai::AND_I_HI:
-    return Lanai::AND_F_I_HI;
-  case Lanai::AND_I_LO:
-    return Lanai::AND_F_I_LO;
-  case Lanai::AND_R:
-    return Lanai::AND_F_R;
-  case Lanai::AND_R_CC:
-    return Lanai::AND_F_R_CC;
-  case Lanai::OR_I_HI:
-    return Lanai::OR_F_I_HI;
-  case Lanai::OR_I_LO:
-    return Lanai::OR_F_I_LO;
-  case Lanai::OR_R:
-    return Lanai::OR_F_R;
-  case Lanai::OR_R_CC:
-    return Lanai::OR_F_R_CC;
-  case Lanai::SL_I:
-    return Lanai::SL_F_I;
-  case Lanai::SRL_R:
-    return Lanai::SRL_F_R;
-  case Lanai::SA_I:
-    return Lanai::SA_F_I;
-  case Lanai::SRA_R:
-    return Lanai::SRA_F_R;
-  case Lanai::SUB_I_HI:
-    return Lanai::SUB_F_I_HI;
-  case Lanai::SUB_I_LO:
-    return Lanai::SUB_F_I_LO;
-  case Lanai::SUB_R:
-    return Lanai::SUB_F_R;
-  case Lanai::SUB_R_CC:
-    return Lanai::SUB_F_R_CC;
-  case Lanai::SUBB_I_HI:
-    return Lanai::SUBB_F_I_HI;
-  case Lanai::SUBB_I_LO:
-    return Lanai::SUBB_F_I_LO;
-  case Lanai::SUBB_R:
-    return Lanai::SUBB_F_R;
-  case Lanai::SUBB_R_CC:
-    return Lanai::SUBB_F_R_CC;
-  case Lanai::XOR_I_HI:
-    return Lanai::XOR_F_I_HI;
-  case Lanai::XOR_I_LO:
-    return Lanai::XOR_F_I_LO;
-  case Lanai::XOR_R:
-    return Lanai::XOR_F_R;
-  case Lanai::XOR_R_CC:
-    return Lanai::XOR_F_R_CC;
-  default:
-    return kInvalid;
-  }
-}
-
-// Returns whether opcode corresponds to instruction that sets flags.
-static bool isFlagSettingInstruction(MbbIterator Instruction) {
-  return Instruction->killsRegister(Lanai::SR);
-}
-
-// Return the Conditional Code operand for a given instruction kind. For
-// example, operand at index 1 of a BRIND_CC instruction is the conditional code
-// (eq, ne, etc.). Returns -1 if the instruction does not have a conditional
-// code.
-static int getCCOperandPosition(unsigned Opcode) {
-  switch (Opcode) {
-  case Lanai::BRIND_CC:
-  case Lanai::BRIND_CCA:
-  case Lanai::BRR:
-  case Lanai::BRCC:
-  case Lanai::SCC:
-    return 1;
-  case Lanai::SELECT:
-  case Lanai::ADDC_F_R_CC:
-  case Lanai::ADDC_R_CC:
-  case Lanai::ADD_F_R_CC:
-  case Lanai::ADD_R_CC:
-  case Lanai::AND_F_R_CC:
-  case Lanai::AND_R_CC:
-  case Lanai::OR_F_R_CC:
-  case Lanai::OR_R_CC:
-  case Lanai::SUBB_F_R_CC:
-  case Lanai::SUBB_R_CC:
-  case Lanai::SUB_F_R_CC:
-  case Lanai::SUB_R_CC:
-  case Lanai::XOR_F_R_CC:
-  case Lanai::XOR_R_CC:
-    return 3;
-  default:
-    return -1;
-  }
-}
-
-// Returns true if instruction is a lowered SET_FLAG instruction with 0/R0 as
-// the first operand and whose conditional code is such that it can be merged
-// (i.e., EQ, NE, PL and MI).
-static bool isSuitableSetflag(MbbIterator Instruction, MbbIterator End) {
-  unsigned Opcode = Instruction->getOpcode();
-  if (Opcode == Lanai::SFSUB_F_RI || Opcode == Lanai::SFSUB_F_RR) {
-    const MachineOperand &Operand = Instruction->getOperand(1);
-    if (Operand.isReg() && Operand.getReg() != Lanai::R0)
-      return false;
-    if (Operand.isImm() && Operand.getImm() != 0)
-      return false;
-
-    MbbIterator SCCUserIter = Instruction;
-    while (SCCUserIter != End) {
-      ++SCCUserIter;
-      if (SCCUserIter == End)
-        break;
-      // Skip debug instructions. Debug instructions don't affect codegen.
-      if (SCCUserIter->isDebugValue())
-        continue;
-      // Early exit when encountering flag setting or return instruction.
-      if (isFlagSettingInstruction(SCCUserIter))
-        // Only return true if flags are set post the flag setting instruction
-        // tested or a return is executed.
-        return true;
-      int CCIndex = getCCOperandPosition(SCCUserIter->getOpcode());
-      if (CCIndex != -1) {
-        LPCC::CondCode CC = static_cast<LPCC::CondCode>(
-            SCCUserIter->getOperand(CCIndex).getImm());
-        // Return false if the flag is used outside of a EQ, NE, PL and MI.
-        if (CC != LPCC::ICC_EQ && CC != LPCC::ICC_NE && CC != LPCC::ICC_PL &&
-            CC != LPCC::ICC_MI)
-          return false;
-      }
-    }
-  }
-
-  return false;
-}
-
-// Combines a SET_FLAG instruction comparing a register with 0 and an ALU
-// operation that sets the same register used in the comparison into a single
-// flag setting ALU instruction (both instructions combined are removed and new
-// flag setting ALU operation inserted where ALU instruction was).
-bool LanaiSetflagAluCombiner::CombineSetflagAluInBasicBlock(
-    MachineFunction *MF, MachineBasicBlock *BB) {
-  bool Modified = false;
-  const TargetInstrInfo *TII =
-      MF->getSubtarget<LanaiSubtarget>().getInstrInfo();
-
-  MbbIterator SetflagIter = BB->begin();
-  MbbIterator End = BB->end();
-  MbbIterator Begin = BB->begin();
-  while (SetflagIter != End) {
-    bool Replaced = false;
-    if (isSuitableSetflag(SetflagIter, End)) {
-      MbbIterator AluIter = SetflagIter;
-      while (AluIter != Begin) {
-        --AluIter;
-        // Skip debug instructions. Debug instructions don't affect codegen.
-        if (AluIter->isDebugValue())
-          continue;
-        // Early exit when encountering flag setting instruction.
-        if (isFlagSettingInstruction(AluIter))
-          break;
-        // Check that output of AluIter is equal to input of SetflagIter.
-        if (AluIter->getNumOperands() > 1 && AluIter->getOperand(0).isReg() &&
-            (AluIter->getOperand(0).getReg() ==
-             SetflagIter->getOperand(0).getReg())) {
-          unsigned NewOpc = flagSettingOpcodeVariant(AluIter->getOpcode());
-          if (NewOpc == kInvalid)
-            break;
-
-          // Change the ALU instruction to the flag setting variant.
-          AluIter->setDesc(TII->get(NewOpc));
-          AluIter->addImplicitDefUseOperands(*MF);
-
-          Replaced = true;
-          ++NumSetflagAluCombined;
-          break;
-        }
-      }
-      // Erase the setflag instruction if merged.
-      if (Replaced)
-        BB->erase(SetflagIter++);
-    }
-
-    Modified |= Replaced;
-    if (!Replaced)
-      ++SetflagIter;
-  }
-
-  return Modified;
-}
-
-// Driver function that iterates over the machine basic building blocks of a
-// machine function
-bool LanaiSetflagAluCombiner::runOnMachineFunction(MachineFunction &MF) {
-  if (DisableSetflagAluCombiner)
-    return false;
-
-  bool Modified = false;
-  MfIterator End = MF.end();
-  for (MfIterator MFI = MF.begin(); MFI != End; ++MFI) {
-    Modified |= CombineSetflagAluInBasicBlock(&MF, &*MFI);
-  }
-  return Modified;
-}
-} // namespace
-
-FunctionPass *llvm::createLanaiSetflagAluCombinerPass() {
-  return new LanaiSetflagAluCombiner();
-}
diff --git a/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp b/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
index b43e970..2d1846c 100644
--- a/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
+++ b/llvm/lib/Target/Lanai/LanaiTargetMachine.cpp
@@ -28,7 +28,6 @@
 
 namespace llvm {
 void initializeLanaiMemAluCombinerPass(PassRegistry &);
-void initializeLanaiSetflagAluCombinerPass(PassRegistry &);
 } // namespace llvm
 
 extern "C" void LLVMInitializeLanaiTarget() {
@@ -112,5 +111,4 @@
 // scheduling pass.
 void LanaiPassConfig::addPreSched2() {
   addPass(createLanaiMemAluCombinerPass());
-  addPass(createLanaiSetflagAluCombinerPass());
 }
diff --git a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiBaseInfo.h b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiBaseInfo.h
index 42bda1e..ce7f835 100644
--- a/llvm/lib/Target/Lanai/MCTargetDesc/LanaiBaseInfo.h
+++ b/llvm/lib/Target/Lanai/MCTargetDesc/LanaiBaseInfo.h
@@ -24,7 +24,6 @@
 
 // LanaiII - This namespace holds all of the target specific flags that
 // instruction info tracks.
-//
 namespace LanaiII {
 // Target Operand Flag enum.
 enum TOF {
@@ -36,31 +35,6 @@
   // address.
   MO_ABS_HI,
   MO_ABS_LO,
-
-  // MO_PIC_BASE_OFFSET - On a symbol operand this indicates that the
-  // immediate should get the value of the symbol minus the PIC base label:
-  //    SYMBOL_LABEL - PICBASELABEL
-  MO_PIC_BASE_OFFSET,
-
-  // MO_GOT - On a symbol operand this indicates that the immediate is the
-  // offset to the GOT entry for the symbol name from the base of the GOT.
-  MO_GOT,
-
-  // MO_GOTOFFHI/MO_GOTOFFLO - On a symbol operand this indicates that the
-  // immediate is the offset to the location of the symbol name from the
-  // base of the GOT.
-  MO_GOTOFFHI,
-  MO_GOTOFFLO,
-
-  // MO_GOTPCHI/MO_GOTPCLO - On a symbol operand this indicates that
-  // the immediate is an offset to the GOT entry for the symbol name
-  // from the current code location.
-  MO_GOTPCHI,
-  MO_GOTPCLO,
-
-  // MO_PLT - On a symbol operand this indicates that the immediate is
-  // offset to the PLT entry of symbol name from the current code location.
-  MO_PLT
 };
 } // namespace LanaiII