diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
index ec7549d4535cc80c2047c957e9bdf40bfe8087f8..cc08e05822d41138a0162578d198d1c8fbda3c1a 100644
--- a/include/clang/Analysis/AnalysisContext.h
+++ b/include/clang/Analysis/AnalysisContext.h
@@ -427,6 +427,7 @@ public:
                              bool addInitializers = false,
                              bool addTemporaryDtors = false,
                              bool addLifetime = false,
+                             bool addLoopExit = false,
                              bool synthesizeBodies = false,
                              bool addStaticInitBranches = false,
                              bool addCXXNewAllocator = true,
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 97639bbfade206aa1b51b129723f8386c38cb3a2..8cdd782671603fb9f9485cb851d2a823734ae5e0 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -59,6 +59,7 @@ public:
     Initializer,
     NewAllocator,
     LifetimeEnds,
+    LoopExit,
     // dtor kind
     AutomaticObjectDtor,
     DeleteDtor,
@@ -168,6 +169,29 @@ private:
   }
 };
 
+/// Represents the point where a loop ends.
+/// This element is is only produced when building the CFG for the static
+/// analyzer and hidden behind the 'cfg-loopexit' analyzer config flag.
+///
+/// Note: a loop exit element can be reached even when the loop body was never
+/// entered.
+class CFGLoopExit : public CFGElement {
+public:
+    explicit CFGLoopExit(const Stmt *stmt)
+            : CFGElement(LoopExit, stmt) {}
+
+    const Stmt *getLoopStmt() const {
+      return static_cast<Stmt *>(Data1.getPointer());
+    }
+
+private:
+    friend class CFGElement;
+    CFGLoopExit() {}
+    static bool isKind(const CFGElement &elem) {
+      return elem.getKind() == LoopExit;
+    }
+};
+
 /// Represents the point where the lifetime of an automatic object ends
 class CFGLifetimeEnds : public CFGElement {
 public:
@@ -728,6 +752,10 @@ public:
     Elements.push_back(CFGLifetimeEnds(VD, S), C);
   }
 
+  void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C) {
+    Elements.push_back(CFGLoopExit(LoopStmt), C);
+  }
+
   void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
     Elements.push_back(CFGDeleteDtor(RD, DE), C);
   }
@@ -794,6 +822,7 @@ public:
     bool AddInitializers;
     bool AddImplicitDtors;
     bool AddLifetime;
+    bool AddLoopExit;
     bool AddTemporaryDtors;
     bool AddStaticInitBranches;
     bool AddCXXNewAllocator;
@@ -818,7 +847,7 @@ public:
         PruneTriviallyFalseEdges(true),
         AddEHEdges(false),
         AddInitializers(false), AddImplicitDtors(false),
-        AddLifetime(false),
+        AddLifetime(false), AddLoopExit(false),
         AddTemporaryDtors(false), AddStaticInitBranches(false),
         AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
   };
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 66e1a746ffa0a697ba7e0d03e47211e2075acfef..ce50cc582d1e00389140abd881875f85a8be9bba 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -214,6 +214,9 @@ private:
   /// \sa IncludeLifetimeInCFG
   Optional<bool> IncludeLifetimeInCFG;
 
+  /// \sa IncludeLoopExitInCFG
+  Optional<bool> IncludeLoopExitInCFG;
+
   /// \sa mayInlineCXXStandardLibrary
   Optional<bool> InlineCXXStandardLibrary;
   
@@ -418,6 +421,13 @@ public:
   /// the values "true" and "false".
   bool includeLifetimeInCFG();
 
+  /// Returns whether or not the end of the loop information should be included
+  /// in the CFG.
+  ///
+  /// This is controlled by the 'cfg-loopexit' config option, which accepts
+  /// the values "true" and "false".
+  bool includeLoopExitInCFG();
+
   /// Returns whether or not C++ standard library functions may be considered
   /// for inlining.
   ///
diff --git a/lib/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp
index ec15f34fb231d259641340da0f9ce3ca27e40739..0f123fdc4b32708630ce84df6ffcba6197529d80 100644
--- a/lib/Analysis/AnalysisDeclContext.cpp
+++ b/lib/Analysis/AnalysisDeclContext.cpp
@@ -68,6 +68,7 @@ AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
                                                        bool addInitializers,
                                                        bool addTemporaryDtors,
                                                        bool addLifetime,
+                                                       bool addLoopExit,
                                                        bool synthesizeBodies,
                                                        bool addStaticInitBranch,
                                                        bool addCXXNewAllocator,
@@ -79,6 +80,7 @@ AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
   cfgBuildOptions.AddInitializers = addInitializers;
   cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
   cfgBuildOptions.AddLifetime = addLifetime;
+  cfgBuildOptions.AddLoopExit = addLoopExit;
   cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
   cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
 }
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 6a77455edeef670e8f54735130a59daac054fec0..c47a917bef63dec4f66ed7d4094b4763c8393fbe 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -602,6 +602,7 @@ private:
     return Visit(S, AddStmtChoice::AlwaysAdd);
   }
   CFGBlock *addInitializer(CXXCtorInitializer *I);
+  void addLoopExit(const Stmt *LoopStmt);
   void addAutomaticObjDtors(LocalScope::const_iterator B,
                             LocalScope::const_iterator E, Stmt *S);
   void addLifetimeEnds(LocalScope::const_iterator B,
@@ -652,6 +653,10 @@ private:
     B->appendLifetimeEnds(VD, S, cfg->getBumpVectorContext());
   }
 
+  void appendLoopExit(CFGBlock *B, const Stmt *LoopStmt) {
+    B->appendLoopExit(LoopStmt, cfg->getBumpVectorContext());
+  }
+
   void appendDeleteDtor(CFGBlock *B, CXXRecordDecl *RD, CXXDeleteExpr *DE) {
     B->appendDeleteDtor(RD, DE, cfg->getBumpVectorContext());
   }
@@ -1253,6 +1258,16 @@ static QualType getReferenceInitTemporaryType(ASTContext &Context,
   return Init->getType();
 }
 
+
+// TODO: Support adding LoopExit element to the CFG in case where the loop is
+// ended by ReturnStmt, GotoStmt or ThrowExpr.
+void CFGBuilder::addLoopExit(const Stmt *LoopStmt){
+  if(!BuildOpts.AddLoopExit)
+    return;
+  autoCreateBlock();
+  appendLoopExit(Block, LoopStmt);
+}
+
 void CFGBuilder::addAutomaticObjHandling(LocalScope::const_iterator B,
                                          LocalScope::const_iterator E,
                                          Stmt *S) {
@@ -2543,6 +2558,8 @@ CFGBlock *CFGBuilder::VisitForStmt(ForStmt *F) {
 
   addAutomaticObjHandling(ScopePos, save_scope_pos.get(), F);
 
+  addLoopExit(F);
+
   // "for" is a control-flow statement.  Thus we stop processing the current
   // block.
   if (Block) {
@@ -2882,6 +2899,7 @@ CFGBlock *CFGBuilder::VisitWhileStmt(WhileStmt *W) {
     addLocalScopeForVarDecl(VD);
     addAutomaticObjHandling(ScopePos, LoopBeginScopePos, W);
   }
+  addLoopExit(W);
 
   // "while" is a control-flow statement.  Thus we stop processing the current
   // block.
@@ -3045,6 +3063,8 @@ CFGBlock *CFGBuilder::VisitCXXThrowExpr(CXXThrowExpr *T) {
 CFGBlock *CFGBuilder::VisitDoStmt(DoStmt *D) {
   CFGBlock *LoopSuccessor = nullptr;
 
+  addLoopExit(D);
+
   // "do...while" is a control-flow statement.  Thus we stop processing the
   // current block.
   if (Block) {
@@ -4025,6 +4045,7 @@ CFGImplicitDtor::getDestructorDecl(ASTContext &astContext) const {
     case CFGElement::Statement:
     case CFGElement::Initializer:
     case CFGElement::NewAllocator:
+    case CFGElement::LoopExit:
     case CFGElement::LifetimeEnds:
       llvm_unreachable("getDestructorDecl should only be used with "
                        "ImplicitDtors");
@@ -4442,6 +4463,9 @@ static void print_elem(raw_ostream &OS, StmtPrinterHelper &Helper,
 
     OS << " (Lifetime ends)\n";
 
+  } else if (Optional<CFGLoopExit> LE = E.getAs<CFGLoopExit>()) {
+    const Stmt *LoopStmt = LE->getLoopStmt();
+    OS << LoopStmt->getStmtClassName() << " (LoopExit)\n";
   } else if (Optional<CFGNewAllocator> NE = E.getAs<CFGNewAllocator>()) {
     OS << "CFGNewAllocator(";
     if (const CXXNewExpr *AllocExpr = NE->getAllocatorExpr())
diff --git a/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index 83e67662e614c322af8af595d06f90541fbc4e2c..10cf079b3462625188214d4d25c74734d1b24a69 100644
--- a/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -26,7 +26,8 @@ AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
               Options.includeImplicitDtorsInCFG(),
               /*AddInitializers=*/true,
               Options.includeTemporaryDtorsInCFG(),
-	      Options.includeLifetimeInCFG(),
+	            Options.includeLifetimeInCFG(),
+              Options.includeLoopExitInCFG(),
               Options.shouldSynthesizeBodies(),
               Options.shouldConditionalizeStaticInitializers(),
               /*addCXXNewAllocator=*/true,
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index d5d6527f4fc5645d110fd39144ffa1d6a1f3e06f..48e3e22af04ab6b0cf8022eb67d958a520e8a934 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -183,6 +183,11 @@ bool AnalyzerOptions::includeLifetimeInCFG() {
                           /* Default = */ false);
 }
 
+bool AnalyzerOptions::includeLoopExitInCFG() {
+  return getBooleanOption(IncludeLoopExitInCFG, "cfg-loopexit",
+          /* Default = */ false);
+}
+
 bool AnalyzerOptions::mayInlineCXXStandardLibrary() {
   return getBooleanOption(InlineCXXStandardLibrary,
                           "c++-stdlib-inlining",
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 835b3536865215504ebe91163d1f8901e0dc412e..547978ad43c7d8d6ad0978314ab30f1b7c8ed056 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -365,6 +365,7 @@ void ExprEngine::processCFGElement(const CFGElement E, ExplodedNode *Pred,
       ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred);
       return;
     case CFGElement::LifetimeEnds:
+    case CFGElement::LoopExit:
       return;
   }
 }
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index d91786f749198d2b2f5f92e30400edcc294b595b..907755683f47c60c8e94a38f2da0f1e47e60802b 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -578,8 +578,10 @@ getLocationForCaller(const StackFrameContext *SFC,
   }
   case CFGElement::TemporaryDtor:
   case CFGElement::NewAllocator:
-  case CFGElement::LifetimeEnds:
     llvm_unreachable("not yet implemented!");
+  case CFGElement::LifetimeEnds:
+  case CFGElement::LoopExit:
+    llvm_unreachable("CFGElement kind should not be on callsite!");
   }
 
   llvm_unreachable("Unknown CFGElement kind");
diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c
index 7bed7cb5e3bade742a72114b2af32ea9cc412b1a..4daea898ecd0d4388e56971988024847e5ee6884 100644
--- a/test/Analysis/analyzer-config.c
+++ b/test/Analysis/analyzer-config.c
@@ -14,6 +14,7 @@ void foo() {
 // CHECK-NEXT: cfg-conditional-static-initializers = true
 // CHECK-NEXT: cfg-implicit-dtors = true
 // CHECK-NEXT: cfg-lifetime = false
+// CHECK-NEXT: cfg-loopexit = false
 // CHECK-NEXT: cfg-temporary-dtors = false
 // CHECK-NEXT: faux-bodies = true
 // CHECK-NEXT: graph-trim-interval = 1000
@@ -30,4 +31,4 @@ void foo() {
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 18
+// CHECK-NEXT: num-entries = 19
diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp
index 155ee02e839ee2c839fc0e4cfb7c30d9d27ceb0c..a08e85e53e48b0bd83f63e8ebf43099ad771ee64 100644
--- a/test/Analysis/analyzer-config.cpp
+++ b/test/Analysis/analyzer-config.cpp
@@ -25,6 +25,7 @@ public:
 // CHECK-NEXT: cfg-conditional-static-initializers = true
 // CHECK-NEXT: cfg-implicit-dtors = true
 // CHECK-NEXT: cfg-lifetime = false
+// CHECK-NEXT: cfg-loopexit = false
 // CHECK-NEXT: cfg-temporary-dtors = false
 // CHECK-NEXT: faux-bodies = true
 // CHECK-NEXT: graph-trim-interval = 1000
@@ -41,4 +42,4 @@ public:
 // CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 23
+// CHECK-NEXT: num-entries = 24
diff --git a/test/Analysis/loopexit-cfg-output.cpp b/test/Analysis/loopexit-cfg-output.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8e53ce3066b7f7ab0e78eaaba5ca72e65562c09e
--- /dev/null
+++ b/test/Analysis/loopexit-cfg-output.cpp
@@ -0,0 +1,476 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-loopexit=true %s > %t 2>&1
+// RUN: FileCheck --input-file=%t %s
+
+// CHECK:       [B6 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   2: return;
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B2.1]++
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B3.1]++
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B4.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 12
+// CHECK-NEXT:   4: [B4.2] < [B4.3]
+// CHECK-NEXT:   T: for (...; [B4.4]; ...)
+// CHECK-NEXT:   Preds (2): B2 B5
+// CHECK-NEXT:   Succs (2): B3 B1
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: 0
+// CHECK-NEXT:   2: int i = 0;
+// CHECK-NEXT:   Preds (1): B6
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_forloop1() {
+  for (int i = 0; i < 12; i++) {
+    i++;
+  }
+  return;
+}
+
+// CHECK:       [B4 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B3]
+// CHECK-NEXT:   T: for (; ; )
+// CHECK-NEXT:   Preds (2): B2 B4
+// CHECK-NEXT:   Succs (2): B2 NULL
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_forloop2() {
+  for (;;)
+    ;
+}
+
+// CHECK:       [B5 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: int i;
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: true
+// CHECK-NEXT:   T: while [B4.1]
+// CHECK-NEXT:   Preds (2): B2 B5
+// CHECK-NEXT:   Succs (2): B3 NULL
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_while1() {
+  while (true) {
+    int i;
+  }
+}
+
+// CHECK:       [B5 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   2: 2
+// CHECK-NEXT:   3: int k = 2;
+// CHECK-NEXT:   4: return;
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: l
+// CHECK-NEXT:   2: [B3.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 42
+// CHECK-NEXT:   4: [B3.2] < [B3.3]
+// CHECK-NEXT:   T: while [B3.4]
+// CHECK-NEXT:   Preds (2): B2 B4
+// CHECK-NEXT:   Succs (2): B2 B1
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: int l;
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_while2() {
+  int l;
+  while (l < 42)
+    ;
+  int k = 2;
+  return;
+}
+
+// CHECK:       [B4 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: false
+// CHECK-NEXT:   T: while [B3.1]
+// CHECK-NEXT:   Preds (2): B2 B4
+// CHECK-NEXT:   Succs (2): NULL B1
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_while3() {
+  while (false) {
+    ;
+  }
+}
+
+// CHECK:       [B4 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: DoStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B2
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   1: false
+// CHECK-NEXT:   T: do ... while [B2.1]
+// CHECK-NEXT:   Preds (2): B3 B4
+// CHECK-NEXT:   Succs (2): NULL B1
+
+// CHECK:       [B3]
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_dowhile1() {
+  do {
+  } while (false);
+}
+
+// CHECK:       [B6 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: DoStmt (LoopExit)
+// CHECK-NEXT:   2: j
+// CHECK-NEXT:   3: [B1.2]--
+// CHECK-NEXT:   4: return;
+// CHECK-NEXT:   Preds (1): B2
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B2.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 20
+// CHECK-NEXT:   4: [B2.2] < [B2.3]
+// CHECK-NEXT:   T: do ... while [B2.4]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (2): B4 B1
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: 2
+// CHECK-NEXT:   3: [B3.1] += [B3.2]
+// CHECK-NEXT:   Preds (2): B4 B5
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   Preds (1): B2
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: 2
+// CHECK-NEXT:   2: int j = 2;
+// CHECK-NEXT:   Preds (1): B6
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_dowhile2() {
+  int j = 2;
+  do {
+    j += 2;
+  } while (j < 20);
+  j--;
+  return;
+}
+
+// CHECK:       [B10 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B9
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B8
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B8
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B6
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B4.1]++
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (1): B6
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B5.1]++
+// CHECK-NEXT:   Preds (1): B6
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B6]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B6.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 6
+// CHECK-NEXT:   4: [B6.2] < [B6.3]
+// CHECK-NEXT:   T: for (...; [B6.4]; ...)
+// CHECK-NEXT:   Preds (2): B4 B7
+// CHECK-NEXT:   Succs (2): B5 B3
+
+// CHECK:       [B7]
+// CHECK-NEXT:   1: 1
+// CHECK-NEXT:   2: int j = 1;
+// CHECK-NEXT:   Preds (1): B8
+// CHECK-NEXT:   Succs (1): B6
+
+// CHECK:       [B8]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B8.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 2
+// CHECK-NEXT:   4: [B8.2] < [B8.3]
+// CHECK-NEXT:   T: while [B8.4]
+// CHECK-NEXT:   Preds (2): B2 B9
+// CHECK-NEXT:   Succs (2): B7 B1
+
+// CHECK:       [B9]
+// CHECK-NEXT:   1: 40
+// CHECK-NEXT:   2: -[B9.1]
+// CHECK-NEXT:   3: int i = -40;
+// CHECK-NEXT:   Preds (1): B10
+// CHECK-NEXT:   Succs (1): B8
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void nested_loops1() {
+  int i = -40;
+  while (i < 2) {
+    for (int j = 1; j < 6; j++)
+      i++;
+  }
+}
+
+// CHECK:       [B9 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B8
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B7
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B2.1]++
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B7
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: DoStmt (LoopExit)
+// CHECK-NEXT:   2: i
+// CHECK-NEXT:   3: [B3.2]--
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B4.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 2
+// CHECK-NEXT:   4: [B4.2] < [B4.3]
+// CHECK-NEXT:   T: do ... while [B4.4]
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (2): B6 B3
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B5.1]++
+// CHECK-NEXT:   Preds (2): B6 B7
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B6]
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B7]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B7.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 6
+// CHECK-NEXT:   4: [B7.2] < [B7.3]
+// CHECK-NEXT:   T: for (...; [B7.4]; ...)
+// CHECK-NEXT:   Preds (2): B2 B8
+// CHECK-NEXT:   Succs (2): B5 B1
+
+// CHECK:       [B8]
+// CHECK-NEXT:   1: 40
+// CHECK-NEXT:   2: -[B8.1]
+// CHECK-NEXT:   3: int i = -40;
+// CHECK-NEXT:   4: 1
+// CHECK-NEXT:   5: int j = 1;
+// CHECK-NEXT:   Preds (1): B9
+// CHECK-NEXT:   Succs (1): B7
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void nested_loops2() {
+  int i = -40;
+  for (int j = 1; j < 6; j++) {
+    do {
+      i++;
+    } while (i < 2);
+    i--;
+  }
+}
+
+// CHECK:       [B12 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B11
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   2: return;
+// CHECK-NEXT:   Preds (2): B3 B5
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B3]
+// CHECK-NEXT:   T: break;
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B1
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B4.1]++
+// CHECK-NEXT:   3: i
+// CHECK-NEXT:   4: [B4.3] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   5: 2
+// CHECK-NEXT:   6: [B4.4] % [B4.5]
+// CHECK-NEXT:   7: [B4.6] (ImplicitCastExpr, IntegralToBoolean, _Bool)
+// CHECK-NEXT:   T: if [B4.7]
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (2): B3 B2
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B5.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 5
+// CHECK-NEXT:   4: [B5.2] < [B5.3]
+// CHECK-NEXT:   T: while [B5.4]
+// CHECK-NEXT:   Preds (2): B2 B6
+// CHECK-NEXT:   Succs (2): B4 B1
+
+// CHECK:       [B6]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   2: 1
+// CHECK-NEXT:   3: int i = 1;
+// CHECK-NEXT:   Preds (2): B8 B10
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B7]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B7.1]++
+// CHECK-NEXT:   Preds (1): B9
+// CHECK-NEXT:   Succs (1): B10
+
+// CHECK:       [B8]
+// CHECK-NEXT:   T: break;
+// CHECK-NEXT:   Preds (1): B9
+// CHECK-NEXT:   Succs (1): B6
+
+// CHECK:       [B9]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B9.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 4
+// CHECK-NEXT:   4: [B9.2] == [B9.3]
+// CHECK-NEXT:   T: if [B9.4]
+// CHECK-NEXT:   Preds (1): B10
+// CHECK-NEXT:   Succs (2): B8 B7
+
+// CHECK:       [B10]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B10.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 6
+// CHECK-NEXT:   4: [B10.2] < [B10.3]
+// CHECK-NEXT:   T: for (...; [B10.4]; ...)
+// CHECK-NEXT:   Preds (2): B7 B11
+// CHECK-NEXT:   Succs (2): B9 B6
+
+// CHECK:       [B11]
+// CHECK-NEXT:   1: 2
+// CHECK-NEXT:   2: int i = 2;
+// CHECK-NEXT:   Preds (1): B12
+// CHECK-NEXT:   Succs (1): B10
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_break()
+{
+  for(int i = 2; i < 6; i++) {
+    if(i == 4)
+      break;
+  }
+
+  int i = 1;
+  while(i<5){
+    i++;
+    if(i%2)
+      break;
+  }
+  
+  return;
+}