Index: include/llvm/CodeGen/GlobalISel/InstructionSelector.h
===================================================================
--- include/llvm/CodeGen/GlobalISel/InstructionSelector.h
+++ include/llvm/CodeGen/GlobalISel/InstructionSelector.h
@@ -17,20 +17,48 @@
 #define LLVM_CODEGEN_GLOBALISEL_INSTRUCTIONSELECTOR_H
 
 #include <cstdint>
+#include <bitset>
 
 namespace llvm {
 class MachineInstr;
+class MachineFunction;
 class MachineOperand;
 class MachineRegisterInfo;
 class RegisterBankInfo;
 class TargetInstrInfo;
 class TargetRegisterInfo;
 
+/// Container class for CodeGen predicate results.
+/// This is convenient because std::bitset does not have a constructor
+/// with an initializer list of set bits.
+///
+/// Each InstructionSelector subclass should define a PredicateBitset class with:
+///   const unsigned MAX_SUBTARGET_PREDICATES = 192;
+///   using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
+/// and updating the constant to suit the target.
+template <std::size_t MaxPredicates>
+class PredicateBitsetImpl : public std::bitset<MaxPredicates> {
+public:
+  // Cannot inherit constructors because it's not supported by VC++..
+  PredicateBitsetImpl() = default;
+
+  PredicateBitsetImpl(const std::bitset<MaxPredicates> &B)
+      : std::bitset<MaxPredicates>(B) {}
+
+  PredicateBitsetImpl(std::initializer_list<unsigned> Init) {
+    for (auto I : Init)
+      std::bitset<MaxPredicates>::set(I);
+  }
+};
+
 /// Provides the logic to select generic machine instructions.
 class InstructionSelector {
 public:
   virtual ~InstructionSelector() {}
 
+  /// This is executed before selecting a function.
+  virtual void beginFunction(const MachineFunction &MF) {}
+
   /// Select the (possibly generic) instruction \p I to only use target-specific
   /// opcodes. It is OK to insert multiple instructions, but they cannot be
   /// generic pre-isel instructions.
Index: include/llvm/Target/GlobalISel/Target.td
===================================================================
--- include/llvm/Target/GlobalISel/Target.td
+++ include/llvm/Target/GlobalISel/Target.td
@@ -154,10 +154,14 @@
 // === Rules ===
 
 // Defines a GlobalISel matcher rule.
-class GIRule<list<GIMatchInsn> insnmatchers, list<GIAction> actions> {
+class GIRule<list<GIMatchInsn> insnmatchers, list<GIAction> actions,
+             list<Predicate> predicates = []> {
   // A list of instruction matchers. These form the roots of the match.
   list<GIMatchInsn> InsnMatchers = insnmatchers;
 
   // A list of actions to take in response to the rule.
   list<GIAction> Actions = actions;
+
+  // A list of predicates that must be satisfied for the rule to be attempted.
+  list<Predicate> Predicates = predicates;
 }
Index: lib/Target/AArch64/AArch64InstructionSelector.h
===================================================================
--- lib/Target/AArch64/AArch64InstructionSelector.h
+++ lib/Target/AArch64/AArch64InstructionSelector.h
@@ -31,12 +31,16 @@
 class MachineFunction;
 class MachineRegisterInfo;
 
+const unsigned MAX_SUBTARGET_PREDICATES = 32;
+using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
+
 class AArch64InstructionSelector : public InstructionSelector {
 public:
   AArch64InstructionSelector(const AArch64TargetMachine &TM,
                              const AArch64Subtarget &STI,
                              const AArch64RegisterBankInfo &RBI);
 
+  void beginFunction(const MachineFunction &MF) override;
   bool select(MachineInstr &I) const override;
 
 private:
@@ -57,6 +61,13 @@
   const AArch64InstrInfo &TII;
   const AArch64RegisterInfo &TRI;
   const AArch64RegisterBankInfo &RBI;
+  bool ForCodeSize;
+
+  PredicateBitset AvailableFeatures;
+  PredicateBitset getAvailableFeatures() const { return AvailableFeatures; }
+  PredicateBitset
+  computeAvailableFeatures(const MachineFunction *MF,
+                           const AArch64Subtarget *Subtarget) const;
 
 // We declare the temporaries used by selectImpl() in the class to minimize the
 // cost of constructing placeholder values.
Index: lib/Target/AArch64/AArch64InstructionSelector.cpp
===================================================================
--- lib/Target/AArch64/AArch64InstructionSelector.cpp
+++ lib/Target/AArch64/AArch64InstructionSelector.cpp
@@ -45,7 +45,7 @@
     const AArch64TargetMachine &TM, const AArch64Subtarget &STI,
     const AArch64RegisterBankInfo &RBI)
     : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
-      TRI(*STI.getRegisterInfo()), RBI(RBI)
+      TRI(*STI.getRegisterInfo()), RBI(RBI), ForCodeSize(), AvailableFeatures()
 #define GET_GLOBALISEL_TEMPORARIES_INIT
 #include "AArch64GenGlobalISel.inc"
 #undef GET_GLOBALISEL_TEMPORARIES_INIT
@@ -480,6 +480,12 @@
   return true;
 }
 
+void AArch64InstructionSelector::beginFunction(
+    const MachineFunction &MF) {
+  ForCodeSize = MF.getFunction()->optForSize();
+  AvailableFeatures = computeAvailableFeatures(&MF, &STI);
+}
+
 bool AArch64InstructionSelector::select(MachineInstr &I) const {
   assert(I.getParent() && "Instruction should be in a basic block!");
   assert(I.getParent()->getParent() && "Instruction should be in a function!");
Index: lib/Target/X86/X86InstructionSelector.h
===================================================================
--- lib/Target/X86/X86InstructionSelector.h
+++ lib/Target/X86/X86InstructionSelector.h
@@ -29,11 +29,15 @@
 class MachineRegisterInfo;
 class MachineFunction;
 
+const unsigned MAX_SUBTARGET_PREDICATES = 192;
+using PredicateBitset = PredicateBitsetImpl<MAX_SUBTARGET_PREDICATES>;
+
 class X86InstructionSelector : public InstructionSelector {
 public:
-  X86InstructionSelector(const X86Subtarget &STI,
+  X86InstructionSelector(const X86TargetMachine &TM, const X86Subtarget &STI,
                          const X86RegisterBankInfo &RBI);
 
+  void beginFunction(const MachineFunction &MF) override;
   bool select(MachineInstr &I) const override;
 
 private:
@@ -54,10 +58,18 @@
   bool selectLoadStoreOp(MachineInstr &I, MachineRegisterInfo &MRI,
                          MachineFunction &MF) const;
 
+  const X86TargetMachine &TM;
   const X86Subtarget &STI;
   const X86InstrInfo &TII;
   const X86RegisterInfo &TRI;
   const X86RegisterBankInfo &RBI;
+  bool OptForSize;
+  bool OptForMinSize;
+
+  PredicateBitset AvailableFeatures;
+  PredicateBitset getAvailableFeatures() const { return AvailableFeatures; }
+  PredicateBitset computeAvailableFeatures(const MachineFunction *MF,
+                                           const X86Subtarget *Subtarget) const;
 
 #define GET_GLOBALISEL_TEMPORARIES_DECL
 #include "X86GenGlobalISel.inc"
Index: lib/Target/X86/X86InstructionSelector.cpp
===================================================================
--- lib/Target/X86/X86InstructionSelector.cpp
+++ lib/Target/X86/X86InstructionSelector.cpp
@@ -40,10 +40,12 @@
 #include "X86GenGlobalISel.inc"
 #undef GET_GLOBALISEL_IMPL
 
-X86InstructionSelector::X86InstructionSelector(const X86Subtarget &STI,
+X86InstructionSelector::X86InstructionSelector(const X86TargetMachine &TM,
+                                               const X86Subtarget &STI,
                                                const X86RegisterBankInfo &RBI)
-    : InstructionSelector(), STI(STI), TII(*STI.getInstrInfo()),
-      TRI(*STI.getRegisterInfo()), RBI(RBI)
+    : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()),
+      TRI(*STI.getRegisterInfo()), RBI(RBI), OptForSize(false),
+      OptForMinSize(false), AvailableFeatures()
 #define GET_GLOBALISEL_TEMPORARIES_INIT
 #include "X86GenGlobalISel.inc"
 #undef GET_GLOBALISEL_TEMPORARIES_INIT
@@ -131,6 +133,12 @@
   return true;
 }
 
+void X86InstructionSelector::beginFunction(const MachineFunction &MF) {
+  OptForSize = MF.getFunction()->optForSize();
+  OptForMinSize = MF.getFunction()->optForMinSize();
+  AvailableFeatures = computeAvailableFeatures(&MF, &STI);
+}
+
 bool X86InstructionSelector::select(MachineInstr &I) const {
   assert(I.getParent() && "Instruction should be in a basic block!");
   assert(I.getParent()->getParent() && "Instruction should be in a function!");
Index: lib/Target/X86/X86TargetMachine.cpp
===================================================================
--- lib/Target/X86/X86TargetMachine.cpp
+++ lib/Target/X86/X86TargetMachine.cpp
@@ -287,7 +287,7 @@
 
     auto *RBI = new X86RegisterBankInfo(*I->getRegisterInfo());
     GISel->RegBankInfo.reset(RBI);
-    GISel->InstSelector.reset(new X86InstructionSelector(*I, *RBI));
+    GISel->InstSelector.reset(new X86InstructionSelector(*this, *I, *RBI));
 
 #endif
     I->setGISelAccessor(*GISel);
Index: test/TableGen/GlobalISelEmitter-GIRule.td
===================================================================
--- test/TableGen/GlobalISelEmitter-GIRule.td
+++ test/TableGen/GlobalISelEmitter-GIRule.td
@@ -25,7 +25,31 @@
 def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;
 def Z : OperandWithDefaultOps <i32, (ops R0)>;
 
-//===- Test the function definition boilerplate. --------------------------===//
+def HasA : Predicate<"Subtarget->hasA()">;
+def HasB : Predicate<"Subtarget->hasB()">;
+
+//===- Test the function boilerplate. -------------------------------------===//
+
+// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
+// CHECK-NEXT:    Feature_HasABit = 0,
+// CHECK-NEXT:    Feature_HasBBit = 1,
+// CHECK-NEXT:  };
+
+// CHECK-LABEL: static const char *SubtargetFeatureNames[] = {
+// CHECK-NEXT:    "Feature_HasA",
+// CHECK-NEXT:    "Feature_HasB",
+// CHECK-NEXT:    nullptr
+// CHECK-NEXT:  };
+
+// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
+// CHECK-NEXT:  computeAvailableFeatures(const MachineFunction *MF, const MyTargetSubtarget *Subtarget) const {
+// CHECK-NEXT:    PredicateBitset Features;
+// CHECK-NEXT:    if (Subtarget->hasA())
+// CHECK-NEXT:      Features[Feature_HasABit] = 1;
+// CHECK-NEXT:    if (Subtarget->hasB())
+// CHECK-NEXT:      Features[Feature_HasBBit] = 1;
+// CHECK-NEXT:    return Features;
+// CHECK-NEXT:  }
 
 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
 // CHECK: MachineFunction &MF = *I.getParent()->getParent();
@@ -113,6 +137,9 @@
 //===- Test a nested instruction match. -----------------------------------===//
 
 // CHECK-LABEL: if ([&]() {
+// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit};
+// CHECK-NEXT:    if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT:      return false;
 // CHECK-NEXT:    MachineInstr &MI0 = I;
 // CHECK-NEXT:    if (MI0.getNumOperands() < 3)
 // CHECK-NEXT:      return false;
@@ -150,6 +177,9 @@
 
 // We also get a second rule by commutativity.
 // CHECK-LABEL: if ([&]() {
+// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit};
+// CHECK-NEXT:    if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT:      return false;
 // CHECK-NEXT:    MachineInstr &MI0 = I;
 // CHECK-NEXT:    if (MI0.getNumOperands() < 3)
 // CHECK-NEXT:      return false;
@@ -202,7 +232,7 @@
    GICopyOperand<"src1">,
    GICopyOperand<"src2">,
    GICopyOperand<"src3">]>
- ]>;
+ ], [HasA]>;
 
 // Commutativity is manual at the moment.
 def Rule3X: GIRule<
@@ -220,11 +250,14 @@
    GICopyOperand<"src1">,
    GICopyOperand<"src2">,
    GICopyOperand<"src3">]>
- ]>;
+ ], [HasA]>;
 
 //===- Test another simple pattern with regclass operands. ----------------===//
 
 // CHECK-LABEL: if ([&]() {
+// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit};
+// CHECK-NEXT:    if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT:      return false;
 // CHECK-NEXT:    MachineInstr &MI0 = I;
 // CHECK-NEXT:    if (MI0.getNumOperands() < 3)
 // CHECK-NEXT:      return false;
@@ -257,7 +290,8 @@
    GIMatchOperand<"src1", [GIMatchLLT<s32>, GIMatchRegBankForClass<GPR32>]>,
    GIMatchOperand<"src2", [GIMatchLLT<s32>, GIMatchRegBankForClass<GPR32>]>]>
  ],
- [GIBuildMI<MUL, [GICopyOperand<"dst">, GICopyOperand<"src2">, GICopyOperand<"src1">]>]>;
+ [GIBuildMI<MUL, [GICopyOperand<"dst">, GICopyOperand<"src2">, GICopyOperand<"src1">]>],
+ [HasA, HasB]>;
 
 //===- Test a pattern with ComplexPattern operands. -----------------------===//
 //
Index: test/TableGen/GlobalISelEmitter.td
===================================================================
--- test/TableGen/GlobalISelEmitter.td
+++ test/TableGen/GlobalISelEmitter.td
@@ -28,7 +28,31 @@
 def m1 : OperandWithDefaultOps <i32, (ops (i32 -1))>;
 def Z : OperandWithDefaultOps <i32, (ops R0)>;
 
-//===- Test the function definition boilerplate. --------------------------===//
+def HasA : Predicate<"Subtarget->hasA()">;
+def HasB : Predicate<"Subtarget->hasB()">;
+
+//===- Test the function boilerplate. -------------------------------------===//
+
+// CHECK-LABEL: enum SubtargetFeatureBits : uint8_t {
+// CHECK-NEXT:    Feature_HasABit = 0,
+// CHECK-NEXT:    Feature_HasBBit = 1,
+// CHECK-NEXT:  };
+
+// CHECK-LABEL: static const char *SubtargetFeatureNames[] = {
+// CHECK-NEXT:    "Feature_HasA",
+// CHECK-NEXT:    "Feature_HasB",
+// CHECK-NEXT:    nullptr
+// CHECK-NEXT:  };
+
+// CHECK-LABEL: PredicateBitset MyTargetInstructionSelector::
+// CHECK-NEXT:  computeAvailableFeatures(const MachineFunction *MF, const MyTargetSubtarget *Subtarget) const {
+// CHECK-NEXT:    PredicateBitset Features;
+// CHECK-NEXT:    if (Subtarget->hasA())
+// CHECK-NEXT:      Features[Feature_HasABit] = 1;
+// CHECK-NEXT:    if (Subtarget->hasB())
+// CHECK-NEXT:      Features[Feature_HasBBit] = 1;
+// CHECK-NEXT:    return Features;
+// CHECK-NEXT:  }
 
 // CHECK: bool MyTargetInstructionSelector::selectImpl(MachineInstr &I) const {
 // CHECK: MachineFunction &MF = *I.getParent()->getParent();
@@ -100,6 +124,9 @@
 //===- Test a nested instruction match. -----------------------------------===//
 
 // CHECK-LABEL: if ([&]() {
+// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit};
+// CHECK-NEXT:    if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT:      return false;
 // CHECK-NEXT:    MachineInstr &MI0 = I;
 // CHECK-NEXT:    if (MI0.getNumOperands() < 3)
 // CHECK-NEXT:      return false;
@@ -137,6 +164,9 @@
 
 // We also get a second rule by commutativity.
 // CHECK-LABEL: if ([&]() {
+// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit};
+// CHECK-NEXT:    if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT:      return false;
 // CHECK-NEXT:    MachineInstr &MI0 = I;
 // CHECK-NEXT:    if (MI0.getNumOperands() < 3)
 // CHECK-NEXT:      return false;
@@ -174,11 +204,15 @@
 
 def MULADD : I<(outs GPR32:$dst), (ins GPR32:$src1, GPR32:$src2, GPR32:$src3),
                [(set GPR32:$dst,
-                     (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>;
+                     (mul (add GPR32:$src1, GPR32:$src2), GPR32:$src3))]>,
+             Requires<[HasA]>;
 
 //===- Test another simple pattern with regclass operands. ----------------===//
 
 // CHECK-LABEL: if ([&]() {
+// CHECK-NEXT:    PredicateBitset ExpectedFeatures = {Feature_HasABit, Feature_HasBBit};
+// CHECK-NEXT:    if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)
+// CHECK-NEXT:      return false;
 // CHECK-NEXT:    MachineInstr &MI0 = I;
 // CHECK-NEXT:    if (MI0.getNumOperands() < 3)
 // CHECK-NEXT:      return false;
@@ -204,7 +238,8 @@
 // CHECK-NEXT:  }()) { return true; }
 
 def MUL : I<(outs GPR32:$dst), (ins GPR32:$src2, GPR32:$src1),
-             [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>;
+             [(set GPR32:$dst, (mul GPR32:$src1, GPR32:$src2))]>,
+          Requires<[HasA, HasB]>;
 
 //===- Test a pattern with ComplexPattern operands. -----------------------===//
 //
Index: utils/TableGen/AsmMatcherEmitter.cpp
===================================================================
--- utils/TableGen/AsmMatcherEmitter.cpp
+++ utils/TableGen/AsmMatcherEmitter.cpp
@@ -2858,7 +2858,7 @@
   emitValidateOperandClass(Info, OS);
 
   // Emit the available features compute function.
-  SubtargetFeatureInfo::emitComputeAvailableFeatures(
+  SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
       Info.Target.getName(), ClassName, "ComputeAvailableFeatures",
       Info.SubtargetFeatures, OS);
 
Index: utils/TableGen/CodeEmitterGen.cpp
===================================================================
--- utils/TableGen/CodeEmitterGen.cpp
+++ utils/TableGen/CodeEmitterGen.cpp
@@ -336,7 +336,7 @@
   o << "#endif // NDEBUG\n";
 
   // Emit the available features compute function.
-  SubtargetFeatureInfo::emitComputeAvailableFeatures(
+  SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
       Target.getName(), "MCCodeEmitter", "computeAvailableFeatures",
       SubtargetFeatures, o);
 
Index: utils/TableGen/GlobalISelEmitter.cpp
===================================================================
--- utils/TableGen/GlobalISelEmitter.cpp
+++ utils/TableGen/GlobalISelEmitter.cpp
@@ -31,6 +31,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "CodeGenDAGPatterns.h"
+#include "SubtargetFeatureInfo.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/SmallSet.h"
@@ -161,20 +162,6 @@
   return Explanation;
 }
 
-static std::string explainRulePredicates(const ArrayRef<Init *> Predicates) {
-  std::string Explanation = "";
-  StringRef Separator = "";
-  for (const auto *P : Predicates) {
-    Explanation += Separator;
-
-    if (const DefInit *PDef = dyn_cast<DefInit>(P)) {
-      Explanation += PDef->getDef()->getName();
-    } else
-      Explanation += "<unknown>";
-  }
-  return Explanation;
-}
-
 static bool isTrivialOperatorNode(const TreePatternNode *N,
                                   std::string &Explanation) {
   std::string Separator = "";
@@ -220,6 +207,8 @@
   /// ID for the next instruction variable defined with defineInsnVar()
   unsigned NextInsnVarID;
 
+  std::vector<Record *> RequiredFeatures;
+
 public:
   RuleMatcher()
       : Matchers(), Actions(), InsnVariableNames(), NextInsnVarID(0) {}
@@ -227,6 +216,7 @@
   RuleMatcher &operator=(RuleMatcher &&Other) = default;
 
   InstructionMatcher &addInstructionMatcher();
+  void addRequiredFeature(Record *Feature);
 
   template <class Kind, class... Args> Kind &addAction(Args &&... args);
 
@@ -237,7 +227,9 @@
   void emitCxxCaptureStmts(raw_ostream &OS, StringRef Expr);
 
   void emitTblgen(raw_ostream &OS, IndentStr Indent);
-  void emit(raw_ostream &OS);
+  void emit(raw_ostream &OS,
+            std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
+                SubtargetFeatures);
 
   /// Compare the priority of this object and B.
   ///
@@ -1216,6 +1208,10 @@
   return *Matchers.back();
 }
 
+void RuleMatcher::addRequiredFeature(Record *Feature) {
+  RequiredFeatures.push_back(Feature);
+}
+
 template <class Kind, class... Args>
 Kind &RuleMatcher::addAction(Args &&... args) {
   Actions.emplace_back(llvm::make_unique<Kind>(std::forward<Args>(args)...));
@@ -1255,11 +1251,16 @@
   OS << Indent << "], [\n";
   for (const auto &Action : Actions)
     Action->emitTblgen(OS, Indent + 1);
+  OS << Indent << "], [\n";
+  for (const auto &RequiredFeature : RequiredFeatures)
+    OS << Indent << " " << RequiredFeature->getName() << ",";
   OS << Indent << "]>\n";
   OS << "#endif // 0\n";
 }
 
-void RuleMatcher::emit(raw_ostream &OS) {
+void RuleMatcher::emit(raw_ostream &OS,
+                       std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
+                           SubtargetFeatures) {
   if (Matchers.empty())
     llvm_unreachable("Unexpected empty matcher!");
 
@@ -1273,7 +1274,22 @@
   //    %elt0(s32), %elt1(s32) = TGT_LOAD_PAIR %ptr
   // on some targets but we don't need to make use of that yet.
   assert(Matchers.size() == 1 && "Cannot handle multi-root matchers yet");
-  OS << "if ([&]() {\n";
+
+  OS << "if (";
+  OS << "[&]() {\n";
+  if (!RequiredFeatures.empty()) {
+    OS << "  PredicateBitset ExpectedFeatures = {";
+    StringRef Separator = "";
+    for (const auto &Predicate : RequiredFeatures) {
+      const auto &I = SubtargetFeatures.find(Predicate);
+      assert(I != SubtargetFeatures.end() && "Didn't import predicate?");
+      OS << Separator << I->second.getEnumBitName();
+      Separator = ", ";
+    }
+    OS << "};\n";
+    OS << "if ((AvailableFeatures & ExpectedFeatures) != ExpectedFeatures)\n"
+       << "  return false;\n";
+  }
 
   emitCxxCaptureStmts(OS, "I");
 
@@ -1388,11 +1404,14 @@
   /// GIComplexPatternEquiv.
   DenseMap<const Record *, const Record *> ComplexPatternEquivs;
 
+  // Map of predicates to their subtarget features.
+  std::map<Record *, SubtargetFeatureInfo, LessRecordByID> SubtargetFeatures;
+
   void gatherNodeEquivs();
   const CodeGenInstruction *findNodeEquiv(Record *N) const;
 
   Expected<bool> importRulePredicates(RuleMatcher &M,
-                                      ArrayRef<Init *> Predicates) const;
+                                      ArrayRef<Init *> Predicates);
   Expected<InstructionMatcher &>
   importSelDAGMatcher(InstructionMatcher &InsnMatcher,
                       const TreePatternNode *Src) const;
@@ -1424,6 +1443,8 @@
   /// Analyze pattern \p P, returning a matcher for it if possible.
   /// Otherwise, return an Error explaining why we don't support it.
   Expected<RuleMatcher> runOnPattern(const PatternToMatch &P);
+
+  void declareSubtargetFeature(Record *Predicate);
 };
 
 void GlobalISelEmitter::gatherNodeEquivs() {
@@ -1457,10 +1478,13 @@
 
 Expected<bool>
 GlobalISelEmitter::importRulePredicates(RuleMatcher &M,
-                                        ArrayRef<Init *> Predicates) const {
-  if (!Predicates.empty())
-    return failedImport("Pattern has a rule predicate (" +
-                        explainRulePredicates(Predicates) + ")");
+                                        ArrayRef<Init *> Predicates) {
+  for (const Init *Predicate : Predicates) {
+    const DefInit *PredicateDef = static_cast<const DefInit *>(Predicate);
+    declareSubtargetFeature(PredicateDef->getDef());
+    M.addRequiredFeature(PredicateDef->getDef());
+  }
+
   return true;
 }
 
@@ -1782,6 +1806,8 @@
                                   "  =>  " +
                                   llvm::to_string(*P.getDstPattern()));
 
+  // Import any rule predicates for the rule. We do this last so that rejected
+  // rules don't use up precious feature bits.
   auto TrueOrError = importRulePredicates(M, P.getPredicates()->getValues());
   if (auto Error = TrueOrError.takeError())
     return std::move(Error);
@@ -2037,6 +2063,11 @@
       PrintFatalError(ActionDef->getLoc(), "Action was not a GIAction");
     }
 
+    for (Record *Predicate : RuleDef->getValueAsListOfDefs("Predicates")) {
+      declareSubtargetFeature(Predicate);
+      Matcher.addRequiredFeature(Predicate);
+    }
+
     Rules.push_back(std::move(Matcher));
   }
 
@@ -2065,15 +2096,22 @@
     OS << ", TempOp" << I << "(MachineOperand::CreatePlaceholder())\n";
   OS << "#endif // ifdef GET_GLOBALISEL_TEMPORARIES_INIT\n\n";
 
-  OS << "#ifdef GET_GLOBALISEL_IMPL\n"
-     << "bool " << Target.getName()
+  OS << "#ifdef GET_GLOBALISEL_IMPL\n";
+  SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(SubtargetFeatures,
+                                                           OS);
+  SubtargetFeatureInfo::emitNameTable(SubtargetFeatures, OS);
+  SubtargetFeatureInfo::emitComputeAvailableFeatures(
+      Target.getName(), "InstructionSelector", "computeAvailableFeatures",
+      SubtargetFeatures, OS);
+
+  OS << "bool " << Target.getName()
      << "InstructionSelector::selectImpl(MachineInstr &I) const {\n"
      << "  MachineFunction &MF = *I.getParent()->getParent();\n"
      << "  const MachineRegisterInfo &MRI = MF.getRegInfo();\n";
 
   for (auto &Rule : Rules) {
     Rule.emitTblgen(OS, 0);
-    Rule.emit(OS);
+    Rule.emit(OS, SubtargetFeatures);
     ++NumPatternEmitted;
   }
 
@@ -2082,6 +2120,12 @@
      << "#endif // ifdef GET_GLOBALISEL_IMPL\n";
 }
 
+void GlobalISelEmitter::declareSubtargetFeature(Record *Predicate) {
+  if (SubtargetFeatures.count(Predicate) == 0)
+    SubtargetFeatures.emplace(
+        Predicate, SubtargetFeatureInfo(Predicate, SubtargetFeatures.size()));
+}
+
 } // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
Index: utils/TableGen/SubtargetFeatureInfo.h
===================================================================
--- utils/TableGen/SubtargetFeatureInfo.h
+++ utils/TableGen/SubtargetFeatureInfo.h
@@ -37,6 +37,12 @@
     return "Feature_" + TheDef->getName().str();
   }
 
+  /// \brief The name of the enumerated constant identifying the bitnumber for
+  /// this feature.
+  std::string getEnumBitName() const {
+    return "Feature_" + TheDef->getName().str() + "Bit";
+  }
+
   void dump() const;
   static std::vector<std::pair<Record *, SubtargetFeatureInfo>>
   getAll(const RecordKeeper &Records);
@@ -47,6 +53,12 @@
           &SubtargetFeatures,
       raw_ostream &OS);
 
+  /// Emit the subtarget feature flag definitions.
+  static void emitSubtargetFeatureBitEnumeration(
+      std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
+          &SubtargetFeatures,
+      raw_ostream &OS);
+
   static void emitNameTable(std::map<Record *, SubtargetFeatureInfo,
                                      LessRecordByID> &SubtargetFeatures,
                             raw_ostream &OS);
@@ -66,6 +78,22 @@
       std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
           &SubtargetFeatures,
       raw_ostream &OS);
+
+  /// Emit the function to compute the list of available features given a
+  /// subtarget.
+  ///
+  /// \param TargetName The name of the target as used in class prefixes (e.g.
+  ///                   <TargetName>Subtarget)
+  /// \param ClassName  The name of the class (without the <Target> prefix)
+  ///                   that will contain the generated functions.
+  /// \param FuncName   The name of the function to emit.
+  /// \param SubtargetFeatures A map of TableGen records to the
+  ///                          SubtargetFeatureInfo equivalent.
+  static void emitComputeAssemblerAvailableFeatures(
+      StringRef TargetName, StringRef ClassName, StringRef FuncName,
+      std::map<Record *, SubtargetFeatureInfo, LessRecordByID>
+          &SubtargetFeatures,
+      raw_ostream &OS);
 };
 } // end namespace llvm
 
Index: utils/TableGen/SubtargetFeatureInfo.cpp
===================================================================
--- utils/TableGen/SubtargetFeatureInfo.cpp
+++ utils/TableGen/SubtargetFeatureInfo.cpp
@@ -59,6 +59,20 @@
   OS << "};\n\n";
 }
 
+void SubtargetFeatureInfo::emitSubtargetFeatureBitEnumeration(
+    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
+    raw_ostream &OS) {
+  OS << "// Bits for subtarget features that participate in "
+     << "instruction matching.\n";
+  OS << "enum SubtargetFeatureBits : "
+     << getMinimalTypeForRange(SubtargetFeatures.size()) << " {\n";
+  for (const auto &SF : SubtargetFeatures) {
+    const SubtargetFeatureInfo &SFI = SF.second;
+    OS << "  " << SFI.getEnumBitName() << " = " << SFI.Index << ",\n";
+  }
+  OS << "};\n\n";
+}
+
 void SubtargetFeatureInfo::emitNameTable(
     std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
     raw_ostream &OS) {
@@ -90,6 +104,24 @@
     StringRef TargetName, StringRef ClassName, StringRef FuncName,
     std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
     raw_ostream &OS) {
+  OS << "PredicateBitset " << TargetName << ClassName << "::\n"
+     << FuncName << "(const MachineFunction *MF, const " << TargetName
+     << "Subtarget *Subtarget) const {\n";
+  OS << "  PredicateBitset Features;\n";
+  for (const auto &SF : SubtargetFeatures) {
+    const SubtargetFeatureInfo &SFI = SF.second;
+
+    OS << "  if (" << SFI.TheDef->getValueAsString("CondString") << ")\n";
+    OS << "    Features[" << SFI.getEnumBitName() << "] = 1;\n";
+  }
+  OS << "  return Features;\n";
+  OS << "}\n\n";
+}
+
+void SubtargetFeatureInfo::emitComputeAssemblerAvailableFeatures(
+    StringRef TargetName, StringRef ClassName, StringRef FuncName,
+    std::map<Record *, SubtargetFeatureInfo, LessRecordByID> &SubtargetFeatures,
+    raw_ostream &OS) {
   OS << "uint64_t " << TargetName << ClassName << "::\n"
      << FuncName << "(const FeatureBitset& FB) const {\n";
   OS << "  uint64_t Features = 0;\n";
Index: utils/TableGen/Types.cpp
===================================================================
--- utils/TableGen/Types.cpp
+++ utils/TableGen/Types.cpp
@@ -40,5 +40,6 @@
   uint64_t MaxIndex = Size;
   if (MaxIndex > 0)
     MaxIndex--;
+  assert(MaxIndex <= 64 && "Too many bits");
   return getMinimalTypeForRange(1ULL << MaxIndex);
 }