diff --git a/hpvm/projects/hetero-c++/include/HCCVerifier.h b/hpvm/projects/hetero-c++/include/HCCVerifier.h
index 899a1623b8e19bd7d876a0122e2acf7a90678294..92a7baf41ac511d4d408cf0a4b10f6ddd2d02b97 100644
--- a/hpvm/projects/hetero-c++/include/HCCVerifier.h
+++ b/hpvm/projects/hetero-c++/include/HCCVerifier.h
@@ -95,7 +95,9 @@ private:
   void verifyNesting();
   bool verifyUses(RegionTree& region, std::set<Value*> inputs,
                   std::set<Value*>* outerInputs);
+
   bool isLoopCondition(RegionTree const& region, Instruction* instr);
+  bool allUsesLoopCondition(RegionTree const& region, Instruction* instr);
 };
 
 }
diff --git a/hpvm/projects/hetero-c++/lib/HCCVerifier.cpp b/hpvm/projects/hetero-c++/lib/HCCVerifier.cpp
index 12c761d587e3754ee603afce736aa5f41e0b9a91..0e4cd756b3853e43f26c82bcb474c6b37a36f89b 100644
--- a/hpvm/projects/hetero-c++/lib/HCCVerifier.cpp
+++ b/hpvm/projects/hetero-c++/lib/HCCVerifier.cpp
@@ -477,6 +477,24 @@ bool HCCVerifier::isLoopCondition(RegionTree const& region, Instruction* instr)
   return false;
 }
 
+bool HCCVerifier::allUsesLoopCondition(RegionTree const& region, Instruction* instr) {
+  // Don't handle phi's since they can lead to infinite recursion of this
+  // analysis (since they can depend on themselves or otherwise have circular
+  // dependences
+  if (dyn_cast<PHINode>(instr)) return false;
+
+  bool hasUse = false; // Handles branches which don't have uses
+  for (User* user : instr->users()) {
+    hasUse = true;
+    Instruction* useInst = dyn_cast<Instruction>(user);
+    if (!useInst) return false;
+    if (!isLoopCondition(region, useInst)
+      && !allUsesLoopCondition(region, useInst))
+      return false;
+  }
+  return hasUse;
+}
+
 // Verifies that a well-nested region does not use any values it is not allowed
 // to access (so does not use arguments not included in the region) and
 // identifies uses of values calculated outside of the region and verifies that
@@ -521,7 +539,8 @@ bool HCCVerifier::verifyUses(RegionTree& region, std::set<Value*> inputs,
       // Instructions that control loop execution iterations are allowed to
       // access values that are accessible to the outer region
       bool isLoopCond = region.type == RegionTree::Loop
-                      && isLoopCondition(region, current);
+                      && (isLoopCondition(region, current)
+                          || allUsesLoopCondition(region, current));
 
       // Valid operands are in the list of inputs, instructions dominated by
       // the start of the region, a Constant, or a BasicBlock
@@ -533,7 +552,8 @@ bool HCCVerifier::verifyUses(RegionTree& region, std::set<Value*> inputs,
           BasicBlock* block = dyn_cast<BasicBlock>(op);
           MetadataAsValue* meta = dyn_cast<MetadataAsValue>(op);
 
-          if (const_ || (inst && DTCache.dominates(region.start, inst))
+          if (const_ || (inst && (inst == region.start
+                                  || DTCache.dominates(region.start, inst)))
               || block || meta) {
             continue;
           } else if (inst && !inst->mayHaveSideEffects()
@@ -673,7 +693,15 @@ bool HCCVerifier::verifyUses(RegionTree& region, std::set<Value*> inputs,
       }
 
       bool extraInstructions = false;
+      std::set<BasicBlock*> reached;
+      std::set<BasicBlock*> toSearch;
       while (current != end) {
+        reached.insert(current->getParent());
+        auto f = toSearch.find(current->getParent());
+        if (f != toSearch.end()) {
+          toSearch.erase(f);
+        }
+
         if (current == region.marker) {
           current = current->getNextNonDebugInstruction();
         } else {
@@ -689,7 +717,36 @@ bool HCCVerifier::verifyUses(RegionTree& region, std::set<Value*> inputs,
                                 current);
               extraInstructions = true;
             }
-            current = next;
+            if (next) {
+              current = next;
+            } else {
+              BranchInst* branch = dyn_cast<BranchInst>(current);
+              if (!branch) {
+                errors = true;
+                reportErrorOnInst("Encountered non-branch terminator in "
+                                  "marked region", current);
+                extraInstructions = true;
+              } else {
+                // Add the basic blocks we can reach from this branch to the
+                // list to explore (if we haven't already). We also don't add
+                // back-edges since they should already have been processed
+                // (and if not, only because we skipped over the body because
+                // it was a parallel loop)
+                for (BasicBlock* succ : branch->successors()) {
+                  if (reached.find(succ) == reached.end()
+                    && (succ != branch->getParent() 
+                       && !DTCache.dominates(succ, branch->getParent()))) {
+                    toSearch.insert(succ);
+                  }
+                }
+                // And then pick some unprocessed basic block to process
+                assert(!toSearch.empty()
+                  && "Cannot explore further but have not located region end");
+                BasicBlock* bb = *(toSearch.begin());
+                toSearch.erase(toSearch.begin());
+                current = getFirstNonDebug(bb);
+              }
+            }
           }
         }
       }
@@ -737,14 +794,18 @@ void HCCVerifier::verifyNesting() {
     for (auto it : loops) {
       Loop* loop = std::get<0>(it);
       BasicBlock* preheader = loop->getLoopPreheader();
-      BasicBlock* pred = preheader->getSinglePredecessor();
-      if (!pred) {
-        errors = true;
-        reportErrorOnInst("Parallel loop is only allowed one predecessor",
-                          std::get<2>(it));
-        continue;
+
+      // Beginning of this region is the first instruction in the pre-header
+      // that isn' the marker for some other HeteroC++ region
+      Instruction* begins = preheader->getFirstNonPHIOrDbg();
+      while (!begins->isTerminator()) {
+        CallInst* call = dyn_cast<CallInst>(begins);
+        if (!call) break;
+        if (markerFunctions.find(call->getCalledFunction())
+            != markerFunctions.end()) {
+          begins = begins->getNextNonDebugInstruction();
+        }
       }
-      Instruction* begins = pred->getTerminator();
 
       if (!loop->getExitingBlock() || !std::get<1>(it)->getExitingBlock()) {
         errors = true;
@@ -753,12 +814,7 @@ void HCCVerifier::verifyNesting() {
         continue;
       }
 
-      Instruction* ends = getFirstNonDebug(loop->getExitBlock());
-      BranchInst* branch;
-      while ((branch = dyn_cast<BranchInst>(ends))
-           && branch->isUnconditional()) {
-        ends = getFirstNonDebug(branch->getSuccessor(0));
-      }
+      Instruction* ends = loop->getExitingBlock()->getTerminator();
       allRegions.push_back(std::make_tuple(begins, ends, std::get<2>(it)));
     }
 
diff --git a/hpvm/projects/hetero-c++/lib/HPVMExtractTask.cpp b/hpvm/projects/hetero-c++/lib/HPVMExtractTask.cpp
index 11d4a1a8caf58a53feceda5c29261e1db6eaf9f0..b0640c0036b40b6c4036578a8e47facc0aec2683 100644
--- a/hpvm/projects/hetero-c++/lib/HPVMExtractTask.cpp
+++ b/hpvm/projects/hetero-c++/lib/HPVMExtractTask.cpp
@@ -3591,6 +3591,10 @@ void HPVMProgram::removeParallelLoopGuard(BasicBlock* Preheader, BasicBlock* Dir
     if(GuardBB){
         BranchInst* Br = dyn_cast<BranchInst>(GuardBB->getTerminator());
 
+        if(Br->isUnconditional()){
+            return;
+        }
+
         BasicBlock* LeftSucc = Br->getSuccessor(0);
         BasicBlock* RightSucc = Br->getSuccessor(1);
 
diff --git a/hpvm/projects/hetero-c++/test/integration/src/all_const.cc b/hpvm/projects/hetero-c++/test/integration/src/all_const.cc
new file mode 100644
index 0000000000000000000000000000000000000000..34f6cc1d83f7055ecfa751e031788f40d7416dc8
--- /dev/null
+++ b/hpvm/projects/hetero-c++/test/integration/src/all_const.cc
@@ -0,0 +1,35 @@
+#include "heterocc.h"
+
+void root(int* A, size_t sizeA, int* B, size_t sizeB) {
+  auto s = __hetero_section_begin();
+
+  for (int i = 0; i < 10; i++) {
+    __hetero_parallel_loop(1, 1, A, sizeA, 1, A, sizeA);
+    A[i] = i * i;
+  }
+
+  for (int i = 0; i < 15; i++) {
+    __hetero_parallel_loop(1, 2, A, sizeA, B, sizeB, 1, B, sizeB);
+    B[i] = i + A[i];
+  }
+
+  __hetero_section_end(s);
+}
+
+int main() {
+  int* A = new int[15];
+  for (int i = 0; i < 15; i++) A[i] = i;
+
+  int* B = new int[15];
+
+  size_t sizeA = sizeof(int) * 15;
+  size_t sizeB = sizeof(int) * 15;
+
+  auto l = __hetero_launch((void*)root, 2, A, sizeA, B, sizeB, 2, A, sizeA, B, sizeB);
+  __hetero_wait(l);
+
+  delete [] A;
+  delete [] B;
+
+  return 0;
+}
diff --git a/hpvm/projects/hetero-c++/test/integration/src/mixed_const.cc b/hpvm/projects/hetero-c++/test/integration/src/mixed_const.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9457bc2cd6d8066427b840aee5d748e472537cb8
--- /dev/null
+++ b/hpvm/projects/hetero-c++/test/integration/src/mixed_const.cc
@@ -0,0 +1,37 @@
+#include "heterocc.h"
+
+void root(int* A, size_t sizeA, int n, int* B, size_t sizeB) {
+  auto s = __hetero_section_begin();
+
+  for (int i = 0; i < n; i++) {
+    __hetero_parallel_loop(1, 1, A, sizeA, 1, A, sizeA);
+    A[i] = i * i;
+  }
+
+  for (int i = 0; i < 15; i++) {
+    __hetero_parallel_loop(1, 2, A, sizeA, B, sizeB, 1, B, sizeB);
+    B[i] = i + A[i];
+  }
+
+  __hetero_section_end(s);
+}
+
+int main() {
+  int* A = new int[15];
+  for (int i = 0; i < 15; i++) A[i] = i;
+
+  int* B = new int[15];
+
+  size_t sizeA = sizeof(int) * 15;
+  size_t sizeB = sizeof(int) * 15;
+
+  int n = 15;
+
+  auto l = __hetero_launch((void*)root, 3, A, sizeA, n, B, sizeB, 2, A, sizeA, B, sizeB);
+  __hetero_wait(l);
+
+  delete [] A;
+  delete [] B;
+
+  return 0;
+}
diff --git a/hpvm/projects/hetero-c++/test/integration/src/simple_const.cc b/hpvm/projects/hetero-c++/test/integration/src/simple_const.cc
new file mode 100644
index 0000000000000000000000000000000000000000..5d4750c431075832c4d08dcba17932a5ff08f9c2
--- /dev/null
+++ b/hpvm/projects/hetero-c++/test/integration/src/simple_const.cc
@@ -0,0 +1,32 @@
+#include "heterocc.h"
+
+void root(int* A, size_t sizeA, int n, int* B, size_t sizeB) {
+  auto s = __hetero_section_begin();
+
+  for (int i = 0; i < 15; i++) {
+    __hetero_parallel_loop(1, 2, A, sizeA, B, sizeB, 1, B, sizeB);
+    B[i] = i + A[i];
+  }
+
+  __hetero_section_end(s);
+}
+
+int main() {
+  int* A = new int[15];
+  for (int i = 0; i < 15; i++) A[i] = i;
+
+  int* B = new int[15];
+
+  size_t sizeA = sizeof(int) * 15;
+  size_t sizeB = sizeof(int) * 15;
+
+  int n = 15;
+
+  auto l = __hetero_launch((void*)root, 3, A, sizeA, n, B, sizeB, 2, A, sizeA, B, sizeB);
+  __hetero_wait(l);
+
+  delete [] A;
+  delete [] B;
+
+  return 0;
+}