forked from OSchip/llvm-project
				
			Support SCoPs with multiple entry edges.
Regions that have multiple entry edges are very common. A simple if condition yields e.g. such a region: if / \ then else \ / for_region This for_region contains two entry edges 'then' -> 'for_region' and 'else' -> 'for_region'. Previously we scheduled the RegionSimplify pass to translate such regions into simple regions. With this patch, we now support them natively when the region is in -loop-simplify form, which means the entry block should not be a loop header. Contributed by: Star Tan <tanmx_star@yeah.net> llvm-svn: 179586
This commit is contained in:
		
							parent
							
								
									5e77d76c95
								
							
						
					
					
						commit
						8edce4ee62
					
				| 
						 | 
					@ -28,6 +28,7 @@ class BasicBlock;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace polly {
 | 
					namespace polly {
 | 
				
			||||||
 | 
					class Scop;
 | 
				
			||||||
/// Temporary Hack for extended regiontree.
 | 
					/// Temporary Hack for extended regiontree.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
/// @brief Cast the region to loop.
 | 
					/// @brief Cast the region to loop.
 | 
				
			||||||
| 
						 | 
					@ -51,6 +52,14 @@ bool hasInvokeEdge(const llvm::PHINode *PN);
 | 
				
			||||||
llvm::Value *getPointerOperand(llvm::Instruction &Inst);
 | 
					llvm::Value *getPointerOperand(llvm::Instruction &Inst);
 | 
				
			||||||
llvm::BasicBlock *createSingleExitEdge(llvm::Region *R, llvm::Pass *P);
 | 
					llvm::BasicBlock *createSingleExitEdge(llvm::Region *R, llvm::Pass *P);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// @brief Simplify the region in a scop to have a single entry edge
 | 
				
			||||||
 | 
					///        and a single exit edge.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					/// @param S  The scop that is simplified.
 | 
				
			||||||
 | 
					/// @param P  The pass that is currently running.
 | 
				
			||||||
 | 
					///
 | 
				
			||||||
 | 
					void simplifyRegion(polly::Scop *S, llvm::Pass *P);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// @brief Split the entry block of a function to store the newly inserted
 | 
					/// @brief Split the entry block of a function to store the newly inserted
 | 
				
			||||||
///        allocations outside of all Scops.
 | 
					///        allocations outside of all Scops.
 | 
				
			||||||
///
 | 
					///
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -133,7 +133,7 @@ BADSCOP_STAT(FuncCall, "Function call with side effects appeared");
 | 
				
			||||||
BADSCOP_STAT(AffFunc, "Expression not affine");
 | 
					BADSCOP_STAT(AffFunc, "Expression not affine");
 | 
				
			||||||
BADSCOP_STAT(Scalar, "Found scalar dependency");
 | 
					BADSCOP_STAT(Scalar, "Found scalar dependency");
 | 
				
			||||||
BADSCOP_STAT(Alias, "Found base address alias");
 | 
					BADSCOP_STAT(Alias, "Found base address alias");
 | 
				
			||||||
BADSCOP_STAT(SimpleRegion, "Region not simple");
 | 
					BADSCOP_STAT(SimpleLoop, "Loop not in -loop-simplify form");
 | 
				
			||||||
BADSCOP_STAT(Other, "Others");
 | 
					BADSCOP_STAT(Other, "Others");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//===----------------------------------------------------------------------===//
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
| 
						 | 
					@ -549,15 +549,17 @@ bool ScopDetection::isValidRegion(DetectionContext &Context) const {
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!R.getEnteringBlock()){
 | 
				
			||||||
 | 
					    Loop *L = LI->getLoopFor(R.getEntry());
 | 
				
			||||||
 | 
					    if (L && !L->isLoopSimplifyForm())
 | 
				
			||||||
 | 
					      INVALID(SimpleLoop, "Loop not in simplify form is invalid!");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // SCoP cannot contain the entry block of the function, because we need
 | 
					  // SCoP cannot contain the entry block of the function, because we need
 | 
				
			||||||
  // to insert alloca instruction there when translate scalar to array.
 | 
					  // to insert alloca instruction there when translate scalar to array.
 | 
				
			||||||
  if (R.getEntry() == &(R.getEntry()->getParent()->getEntryBlock()))
 | 
					  if (R.getEntry() == &(R.getEntry()->getParent()->getEntryBlock()))
 | 
				
			||||||
    INVALID(Other, "Region containing entry block of function is invalid!");
 | 
					    INVALID(Other, "Region containing entry block of function is invalid!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Only regions that have a single entry are allowed.
 | 
					 | 
				
			||||||
  if (!R.getEnteringBlock())
 | 
					 | 
				
			||||||
    INVALID(SimpleRegion, "Region has multiple entries: " << R.getNameStr());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!isValidExit(Context))
 | 
					  if (!isValidExit(Context))
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -986,16 +986,10 @@ public:
 | 
				
			||||||
  bool runOnScop(Scop &S) {
 | 
					  bool runOnScop(Scop &S) {
 | 
				
			||||||
    ParallelLoops.clear();
 | 
					    ParallelLoops.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Region &R = S.getRegion();
 | 
					    assert(!S.getRegion().isTopLevelRegion()
 | 
				
			||||||
 | 
					           && "Top level regions are not supported");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(!R.isTopLevelRegion() && "Top level regions are not supported");
 | 
					    simplifyRegion(&S, this);
 | 
				
			||||||
    assert(R.getEnteringBlock() && "Only support regions with a single entry");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!R.getExitingBlock()) {
 | 
					 | 
				
			||||||
      BasicBlock *newExit = createSingleExitEdge(&R, this);
 | 
					 | 
				
			||||||
      for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI)
 | 
					 | 
				
			||||||
        (*RI)->replaceExitRecursive(newExit);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BasicBlock *StartBlock = executeScopConditionally(S, this);
 | 
					    BasicBlock *StartBlock = executeScopConditionally(S, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1026,16 +1026,10 @@ public:
 | 
				
			||||||
  bool runOnScop(Scop &S) {
 | 
					  bool runOnScop(Scop &S) {
 | 
				
			||||||
    IslAstInfo &AstInfo = getAnalysis<IslAstInfo>();
 | 
					    IslAstInfo &AstInfo = getAnalysis<IslAstInfo>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Region &R = S.getRegion();
 | 
					    assert(!S.getRegion().isTopLevelRegion()
 | 
				
			||||||
 | 
					           && "Top level regions are not supported");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert(!R.isTopLevelRegion() && "Top level regions are not supported");
 | 
					    simplifyRegion(&S, this);
 | 
				
			||||||
    assert(R.getEnteringBlock() && "Only support regions with a single entry");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (!R.getExitingBlock()) {
 | 
					 | 
				
			||||||
      BasicBlock *newExit = createSingleExitEdge(&R, this);
 | 
					 | 
				
			||||||
      for (Region::const_iterator RI = R.begin(), RE = R.end(); RI != RE; ++RI)
 | 
					 | 
				
			||||||
        (*RI)->replaceExitRecursive(newExit);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BasicBlock *StartBlock = executeScopConditionally(S, this);
 | 
					    BasicBlock *StartBlock = executeScopConditionally(S, this);
 | 
				
			||||||
    isl_ast_node *Ast = AstInfo.getAst();
 | 
					    isl_ast_node *Ast = AstInfo.getAst();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,7 @@
 | 
				
			||||||
//===----------------------------------------------------------------------===//
 | 
					//===----------------------------------------------------------------------===//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "polly/Support/ScopHelper.h"
 | 
					#include "polly/Support/ScopHelper.h"
 | 
				
			||||||
 | 
					#include "polly/ScopInfo.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "llvm/Analysis/LoopInfo.h"
 | 
					#include "llvm/Analysis/LoopInfo.h"
 | 
				
			||||||
#include "llvm/Analysis/RegionInfo.h"
 | 
					#include "llvm/Analysis/RegionInfo.h"
 | 
				
			||||||
| 
						 | 
					@ -86,6 +87,32 @@ BasicBlock *polly::createSingleExitEdge(Region *R, Pass *P) {
 | 
				
			||||||
  return SplitBlockPredecessors(BB, Preds, ".region", P);
 | 
					  return SplitBlockPredecessors(BB, Preds, ".region", P);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void polly::simplifyRegion(Scop *S, Pass *P){
 | 
				
			||||||
 | 
					  Region *R = &S->getRegion();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create single entry edge if the region has multiple entry edges.
 | 
				
			||||||
 | 
					  if (!R->getEnteringBlock()){
 | 
				
			||||||
 | 
					    BasicBlock *OldEntry = R->getEntry();
 | 
				
			||||||
 | 
					    BasicBlock *NewEntry = SplitBlock (OldEntry, OldEntry->begin(), P);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (Scop::iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
 | 
				
			||||||
 | 
					      if ((*SI)->getBasicBlock() == OldEntry) {
 | 
				
			||||||
 | 
					        (*SI)->setBasicBlock(NewEntry);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    R->replaceEntryRecursive(NewEntry);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create single exit edge if the region has multiple exit edges.
 | 
				
			||||||
 | 
					  if (!R->getExitingBlock()) {
 | 
				
			||||||
 | 
					    BasicBlock *NewExit = createSingleExitEdge(R, P);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (Region::const_iterator RI = R->begin(), RE = R->end(); RI != RE; ++RI)
 | 
				
			||||||
 | 
					      (*RI)->replaceExitRecursive(NewExit);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) {
 | 
					void polly::splitEntryBlockForAlloca(BasicBlock *EntryBlock, Pass *P) {
 | 
				
			||||||
  // Find first non-alloca instruction. Every basic block has a non-alloc
 | 
					  // Find first non-alloca instruction. Every basic block has a non-alloc
 | 
				
			||||||
  // instruction, as every well formed basic block has a terminator.
 | 
					  // instruction, as every well formed basic block has a terminator.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,71 @@
 | 
				
			||||||
 | 
					; RUN: opt %loadPolly -polly-codegen-isl -analyze < %s | FileCheck %s
 | 
				
			||||||
 | 
					; RUN: opt %loadPolly -polly-codegen-isl -S < %s | FileCheck %s -check-prefix=CHECK-CODE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; void f(long A[], long N) {
 | 
				
			||||||
 | 
					;   long i;
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;  if (true){
 | 
				
			||||||
 | 
					;    i = 0;
 | 
				
			||||||
 | 
					;    goto next;
 | 
				
			||||||
 | 
					;  }else{
 | 
				
			||||||
 | 
					;    i = 1;
 | 
				
			||||||
 | 
					;    goto next;
 | 
				
			||||||
 | 
					; }
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; next:
 | 
				
			||||||
 | 
					;  if (true)
 | 
				
			||||||
 | 
					;    goto for.i;
 | 
				
			||||||
 | 
					;  else
 | 
				
			||||||
 | 
					;    goto for.i;
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; for.i:
 | 
				
			||||||
 | 
					;   for (i = 0; i < N; ++i)
 | 
				
			||||||
 | 
					;     A[i] = i;
 | 
				
			||||||
 | 
					; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
 | 
				
			||||||
 | 
					target triple = "x86_64-unknown-linux-gnu"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define void @f(i64* %A, i64 %N) nounwind {
 | 
				
			||||||
 | 
					entry:
 | 
				
			||||||
 | 
					  fence seq_cst
 | 
				
			||||||
 | 
					  br i1 true, label %then1, label %else1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					then1:
 | 
				
			||||||
 | 
					  br label %next
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					else1:
 | 
				
			||||||
 | 
					  br label %next
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					next:
 | 
				
			||||||
 | 
					  br i1 true, label %then, label %else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					then:
 | 
				
			||||||
 | 
					  br label %for.i.head
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					  br label %for.i.head
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.i.head:
 | 
				
			||||||
 | 
					  br label %for.i.head1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.i.head1:
 | 
				
			||||||
 | 
					  br label %for.i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.i:
 | 
				
			||||||
 | 
					  %indvar = phi i64 [ 0, %for.i.head1], [ %indvar.next, %for.i ]
 | 
				
			||||||
 | 
					  fence seq_cst
 | 
				
			||||||
 | 
					  %scevgep = getelementptr i64* %A, i64 %indvar
 | 
				
			||||||
 | 
					  store i64 %indvar, i64* %scevgep
 | 
				
			||||||
 | 
					  %indvar.next = add nsw i64 %indvar, 1
 | 
				
			||||||
 | 
					  %exitcond = icmp eq i64 %indvar.next, %N
 | 
				
			||||||
 | 
					  br i1 %exitcond, label %return, label %for.i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return:
 | 
				
			||||||
 | 
					  fence seq_cst
 | 
				
			||||||
 | 
					  ret void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; CHECK: Create LLVM-IR from SCoPs' for region: 'next.split => polly.merge_new_and_old'
 | 
				
			||||||
 | 
					; CHECK-CODE: polly.split_new_and_old
 | 
				
			||||||
 | 
					; CHECK-CODE: polly.merge_new_and_old
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,5 @@
 | 
				
			||||||
; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
 | 
					; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
 | 
				
			||||||
; RUN: opt %loadPolly -polly-region-simplify -polly-detect -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
 | 
					 | 
				
			||||||
; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
 | 
					; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
 | 
				
			||||||
; RUN: opt %loadPolly -polly-region-simplify -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s -check-prefix=CHECK-SIMPLIFY
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
; void f(long A[], long N) {
 | 
					; void f(long A[], long N) {
 | 
				
			||||||
;   long i;
 | 
					;   long i;
 | 
				
			||||||
| 
						 | 
					@ -16,6 +14,8 @@
 | 
				
			||||||
;     A[i] = i;
 | 
					;     A[i] = i;
 | 
				
			||||||
; }
 | 
					; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; We will not detect this scop, as the loop is not in -loop-simplify form.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
 | 
					target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
 | 
				
			||||||
target triple = "x86_64-unknown-linux-gnu"
 | 
					target triple = "x86_64-unknown-linux-gnu"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,4 +44,3 @@ return:
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; CHECK-NOT: Valid Region for Scop
 | 
					; CHECK-NOT: Valid Region for Scop
 | 
				
			||||||
; CHECK-SIMPLIFY: Valid Region for Scop: for.i => return
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,69 @@
 | 
				
			||||||
 | 
					; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s
 | 
				
			||||||
 | 
					; RUN: opt %loadPolly -polly-detect -polly-codegen-scev -analyze < %s | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; void f(long A[], long N) {
 | 
				
			||||||
 | 
					;   long i;
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					;  if (true){
 | 
				
			||||||
 | 
					;    i = 0;
 | 
				
			||||||
 | 
					;    goto next;
 | 
				
			||||||
 | 
					;  }else{
 | 
				
			||||||
 | 
					;    i = 1;
 | 
				
			||||||
 | 
					;    goto next;
 | 
				
			||||||
 | 
					; }
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; next:
 | 
				
			||||||
 | 
					;  if (true)
 | 
				
			||||||
 | 
					;    goto for.i;
 | 
				
			||||||
 | 
					;  else
 | 
				
			||||||
 | 
					;    goto for.i;
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					; for.i:
 | 
				
			||||||
 | 
					;   for (i = 0; i < N; ++i)
 | 
				
			||||||
 | 
					;     A[i] = i;
 | 
				
			||||||
 | 
					; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
 | 
				
			||||||
 | 
					target triple = "x86_64-unknown-linux-gnu"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					define void @f(i64* %A, i64 %N) nounwind {
 | 
				
			||||||
 | 
					entry:
 | 
				
			||||||
 | 
					  fence seq_cst
 | 
				
			||||||
 | 
					  br i1 true, label %then1, label %else1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					then1:
 | 
				
			||||||
 | 
					  br label %next
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					else1:
 | 
				
			||||||
 | 
					  br label %next
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					next:
 | 
				
			||||||
 | 
					  br i1 true, label %then, label %else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					then:
 | 
				
			||||||
 | 
					  br label %for.i.head
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					  br label %for.i.head
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.i.head:
 | 
				
			||||||
 | 
					  br label %for.i.head1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.i.head1:
 | 
				
			||||||
 | 
					  br label %for.i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for.i:
 | 
				
			||||||
 | 
					  %indvar = phi i64 [ 0, %for.i.head1], [ %indvar.next, %for.i ]
 | 
				
			||||||
 | 
					  fence seq_cst
 | 
				
			||||||
 | 
					  %scevgep = getelementptr i64* %A, i64 %indvar
 | 
				
			||||||
 | 
					  store i64 %indvar, i64* %scevgep
 | 
				
			||||||
 | 
					  %indvar.next = add nsw i64 %indvar, 1
 | 
				
			||||||
 | 
					  %exitcond = icmp eq i64 %indvar.next, %N
 | 
				
			||||||
 | 
					  br i1 %exitcond, label %return, label %for.i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return:
 | 
				
			||||||
 | 
					  fence seq_cst
 | 
				
			||||||
 | 
					  ret void
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; CHECK: Valid Region for Scop: next => for.i.head1
 | 
				
			||||||
		Loading…
	
		Reference in New Issue