Index: include/llvm/Analysis/TargetTransformInfo.h
===================================================================
--- include/llvm/Analysis/TargetTransformInfo.h
+++ include/llvm/Analysis/TargetTransformInfo.h
@@ -53,6 +53,17 @@
   Value *PtrVal;
 };
 
+/// \brief This class provides a function that implements target-specific
+/// loop idiom recognition. Targets that want to handle specific loop idioms
+/// should implement this class and return a pointer to it from their
+/// respective TTI implementations.
+/// See \c TargetTransformInfo::getTargetLoopIdiomRecognize below.
+class TargetLoopIdiomRecognize {
+public:
+  virtual bool run(Pass *P, Loop *L) = 0;
+  virtual ~TargetLoopIdiomRecognize() {}
+};
+
 /// \brief This pass provides access to the codegen interfaces that are needed
 /// for IR-level transformations.
 class TargetTransformInfo {
@@ -378,6 +389,12 @@
                     Type *Ty) const;
   int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
                     Type *Ty) const;
+
+  /// \brief Get a class implementing target-specific loop idiom recognition,
+  /// or nullptr if the target does not require handling of specific loop
+  /// idioms.
+  TargetLoopIdiomRecognize *getTargetLoopIdiomRecognize() const;
+
   /// @}
 
   /// \name Vector Target Information
@@ -586,6 +603,7 @@
                             Type *Ty) = 0;
   virtual int getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm,
                             Type *Ty) = 0;
+  virtual TargetLoopIdiomRecognize *getTargetLoopIdiomRecognize() = 0;
   virtual unsigned getNumberOfRegisters(bool Vector) = 0;
   virtual unsigned getRegisterBitWidth(bool Vector) = 0;
   virtual unsigned getMaxInterleaveFactor(unsigned VF) = 0;
@@ -737,6 +755,9 @@
                     Type *Ty) override {
     return Impl.getIntImmCost(IID, Idx, Imm, Ty);
   }
+  TargetLoopIdiomRecognize *getTargetLoopIdiomRecognize() override {
+    return Impl.getTargetLoopIdiomRecognize();
+  }
   unsigned getNumberOfRegisters(bool Vector) override {
     return Impl.getNumberOfRegisters(Vector);
   }
Index: include/llvm/Analysis/TargetTransformInfoImpl.h
===================================================================
--- include/llvm/Analysis/TargetTransformInfoImpl.h
+++ include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -250,6 +250,8 @@
     return TTI::TCC_Free;
   }
 
+  TargetLoopIdiomRecognize *getTargetLoopIdiomRecognize() { return nullptr; }
+
   unsigned getNumberOfRegisters(bool Vector) { return 8; }
 
   unsigned getRegisterBitWidth(bool Vector) { return 32; }
Index: lib/Analysis/TargetTransformInfo.cpp
===================================================================
--- lib/Analysis/TargetTransformInfo.cpp
+++ lib/Analysis/TargetTransformInfo.cpp
@@ -201,6 +201,11 @@
   return Cost;
 }
 
+TargetLoopIdiomRecognize *TargetTransformInfo::getTargetLoopIdiomRecognize()
+      const {
+  return TTIImpl->getTargetLoopIdiomRecognize();
+}
+
 unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const {
   return TTIImpl->getNumberOfRegisters(Vector);
 }
Index: lib/Target/Hexagon/CMakeLists.txt
===================================================================
--- lib/Target/Hexagon/CMakeLists.txt
+++ lib/Target/Hexagon/CMakeLists.txt
@@ -30,6 +30,7 @@
   HexagonInstrInfo.cpp
   HexagonISelDAGToDAG.cpp
   HexagonISelLowering.cpp
+  HexagonLoopIdiomRecognize.cpp
   HexagonMachineFunctionInfo.cpp
   HexagonMachineScheduler.cpp
   HexagonMCInstLower.cpp
Index: lib/Target/Hexagon/HexagonLoopIdiomRecognize.h
===================================================================
--- /dev/null
+++ lib/Target/Hexagon/HexagonLoopIdiomRecognize.h
@@ -0,0 +1,12 @@
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
+#include "llvm/Pass.h"
+
+using namespace llvm;
+
+namespace llvm {
+  class HexagonLoopIdiomRecognize : public TargetLoopIdiomRecognize {
+  public:
+    bool run(Pass *P, Loop *L) override;
+  };
+}
Index: lib/Target/Hexagon/HexagonLoopIdiomRecognize.cpp
===================================================================
--- /dev/null
+++ lib/Target/Hexagon/HexagonLoopIdiomRecognize.cpp
@@ -0,0 +1,38 @@
+#define DEBUG_TYPE "hexidiom"
+
+#include "HexagonLoopIdiomRecognize.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Utils/Local.h"
+
+using namespace llvm;
+
+bool llvm::HexagonLoopIdiomRecognize::run(Pass *P, Loop *L) {
+  BasicBlock *Header = L->getHeader();
+  if (!Header)
+    return false;
+
+  auto *DL = &Header->getParent()->getParent()->getDataLayout();
+  auto *DTW = P->getAnalysisIfAvailable<DominatorTreeWrapperPass>();
+  auto *TLIW = P->getAnalysisIfAvailable<TargetLibraryInfoWrapperPass>();
+  auto *SE = P->getAnalysisIfAvailable<ScalarEvolution>();
+
+  (void)DL;
+  if (!DTW || !TLIW || !SE)
+    return false;
+
+  dbgs() << "Hello, all is in order\n";
+  return false;
+}
+
Index: lib/Target/Hexagon/HexagonTargetMachine.cpp
===================================================================
--- lib/Target/Hexagon/HexagonTargetMachine.cpp
+++ lib/Target/Hexagon/HexagonTargetMachine.cpp
@@ -138,9 +138,11 @@
   return I.get();
 }
 
+static HexagonLoopIdiomRecognize HLIR;
+
 TargetIRAnalysis HexagonTargetMachine::getTargetIRAnalysis() {
   return TargetIRAnalysis([this](Function &F) {
-    return TargetTransformInfo(HexagonTTIImpl(this, F));
+    return TargetTransformInfo(HexagonTTIImpl(this, F, &HLIR));
   });
 }
 
Index: lib/Target/Hexagon/HexagonTargetTransformInfo.h
===================================================================
--- lib/Target/Hexagon/HexagonTargetTransformInfo.h
+++ lib/Target/Hexagon/HexagonTargetTransformInfo.h
@@ -18,6 +18,7 @@
 
 #include "Hexagon.h"
 #include "HexagonTargetMachine.h"
+#include "HexagonLoopIdiomRecognize.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/CodeGen/BasicTTIImpl.h"
 #include "llvm/Target/TargetLowering.h"
@@ -31,21 +32,24 @@
 
   const HexagonSubtarget *ST;
   const HexagonTargetLowering *TLI;
+  HexagonLoopIdiomRecognize *HLIR;
 
   const HexagonSubtarget *getST() const { return ST; }
   const HexagonTargetLowering *getTLI() const { return TLI; }
 
 public:
-  explicit HexagonTTIImpl(const HexagonTargetMachine *TM, Function &F)
+  explicit HexagonTTIImpl(const HexagonTargetMachine *TM, Function &F,
+                          HexagonLoopIdiomRecognize *LIR)
       : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
-        TLI(ST->getTargetLowering()) {}
+        TLI(ST->getTargetLowering()), HLIR(LIR) {}
 
   // Provide value semantics. MSVC requires that we spell all of these out.
   HexagonTTIImpl(const HexagonTTIImpl &Arg)
-      : BaseT(static_cast<const BaseT &>(Arg)), ST(Arg.ST), TLI(Arg.TLI) {}
+      : BaseT(static_cast<const BaseT &>(Arg)), ST(Arg.ST), TLI(Arg.TLI),
+        HLIR(Arg.HLIR) {}
   HexagonTTIImpl(HexagonTTIImpl &&Arg)
       : BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
-        TLI(std::move(Arg.TLI)) {}
+        TLI(std::move(Arg.TLI)), HLIR(std::move(Arg.HLIR)) {}
 
   /// \name Scalar TTI Implementations
   /// @{
@@ -55,6 +59,10 @@
   // The Hexagon target can unroll loops with run-time trip counts.
   void getUnrollingPreferences(Loop *L, TTI::UnrollingPreferences &UP);
 
+  HexagonLoopIdiomRecognize *getTargetLoopIdiomRecognize() const {
+    return HLIR;
+  }
+
   /// @}
 
   /// \name Vector TTI Implementations
Index: lib/Transforms/Scalar/LoopIdiomRecognize.cpp
===================================================================
--- lib/Transforms/Scalar/LoopIdiomRecognize.cpp
+++ lib/Transforms/Scalar/LoopIdiomRecognize.cpp
@@ -674,9 +674,14 @@
     return false;
 
   SE = &getAnalysis<ScalarEvolution>();
-  if (SE->hasLoopInvariantBackedgeTakenCount(L))
-    return runOnCountableLoop();
-  return runOnNoncountableLoop();
+  bool HasInvCount = SE->hasLoopInvariantBackedgeTakenCount(L);
+  bool Changed = HasInvCount ? runOnCountableLoop()
+                             : runOnNoncountableLoop();
+
+  if (auto *TLIR = getTargetTransformInfo()->getTargetLoopIdiomRecognize())
+    Changed |= TLIR->run(this, L);
+
+  return Changed;
 }
 
 /// runOnLoopBlock - Process the specified block, which lives in a counted loop