Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -896,6 +896,9 @@ /// @return True if the basic block is trivial, otherwise false. static bool isTrivialBB(BasicBlock *BB, TempScop &tempScop); + /// @brief Add parameter constraints to @p C that imply a non-empty domain. + __isl_give isl_set *addNonEmptyDomainConstraints(__isl_take isl_set *C) const; + /// @brief Build the Context of the Scop. void buildContext(); @@ -1053,8 +1056,13 @@ /// @return The runtime check context of this Scop. __isl_give isl_set *getRuntimeCheckContext() const; - /// @brief Return true if the runtime check context is feasible. - bool hasFeasibleRuntimeCheckContext() const; + /// @brief Return true if the optimized SCoP can be executed. + /// + /// In addition to the runtime check context this will also utilize the domain + /// constraints to decide it the optimized version can actually be executed. + /// + /// @returns True if the optimized SCoP can be executed. + bool hasFeasibleRuntimeContext() const; /// @brief Add assumptions to assumed context. /// Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -1113,6 +1113,11 @@ const_cast((const void *)Parameter)); } +isl_set *Scop::addNonEmptyDomainConstraints(isl_set *C) const { + isl_set *DomainContext = isl_union_set_params(getDomains()); + return isl_set_intersect_params(C, DomainContext); +} + void Scop::addUserContext() { if (UserContextStr.empty()) return; @@ -1598,8 +1603,9 @@ return RuntimeCheckContext; } -bool Scop::hasFeasibleRuntimeCheckContext() const { +bool Scop::hasFeasibleRuntimeContext() const { isl_set *RuntimeCheckContext = getRuntimeCheckContext(); + RuntimeCheckContext = addNonEmptyDomainConstraints(RuntimeCheckContext); bool IsFeasible = !isl_set_is_empty(RuntimeCheckContext); isl_set_free(RuntimeCheckContext); return IsFeasible; @@ -2033,7 +2039,7 @@ DEBUG(scop->print(dbgs())); - if (!scop->hasFeasibleRuntimeCheckContext()) { + if (!scop->hasFeasibleRuntimeContext()) { delete scop; scop = nullptr; return false; Index: test/Isl/CodeGen/20150328-SCEVExpanderIntroducesNewIV.ll =================================================================== --- test/Isl/CodeGen/20150328-SCEVExpanderIntroducesNewIV.ll +++ test/Isl/CodeGen/20150328-SCEVExpanderIntroducesNewIV.ll @@ -1,5 +1,7 @@ ; RUN: opt %loadPolly -polly-detect-unprofitable -polly-no-early-exit -polly-codegen -S < %s | FileCheck %s +@A = common global [1536 x float] zeroinitializer + ; CHECK: polly target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" @@ -25,6 +27,8 @@ for.body121: %indvar = phi i32 [ 0, %switchbb ], [ %indvar.next, %for.body121 ] + %ptr = getelementptr [1536 x float], [1536 x float]* @A, i64 0, i32 %indvar + store float undef, float* %ptr %indvar.next = add nsw i32 %indvar, 1 br i1 false, label %for.body121, label %while.cond.loopexit3 Index: test/Isl/CodeGen/create-conditional-scop.ll =================================================================== --- test/Isl/CodeGen/create-conditional-scop.ll +++ test/Isl/CodeGen/create-conditional-scop.ll @@ -2,6 +2,8 @@ target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-a0:0-n32" +@A = common global [1536 x float] zeroinitializer + ; This test case used to fail, because we did not add the newly generated basic ; block %polly.start as a basic block to the surrounding loop. define void @foo() nounwind { @@ -16,8 +18,10 @@ while.body: ; preds = %while.body, %for.body7.single_entry.single_entry %indvar35 = phi i32 [ %0, %while.body ], [ 0, %for.body7.single_entry.single_entry ] + %ptr = getelementptr [1536 x float], [1536 x float]* @A, i64 0, i32 %indvar35 + store float undef, float* %ptr %0 = add i32 %indvar35, 1 - %exitcond2 = icmp eq i32 %0, 0 + %exitcond2 = icmp eq i32 %0, 42 br i1 %exitcond2, label %for.inc02, label %while.body for.inc02: ; preds = %while.body Index: test/Isl/CodeGen/simple_non_single_entry.ll =================================================================== --- test/Isl/CodeGen/simple_non_single_entry.ll +++ test/Isl/CodeGen/simple_non_single_entry.ll @@ -37,6 +37,8 @@ br label %next next: + %sg = getelementptr i64, i64* %A, i64 42 + store i64 undef, i64* %sg br i1 true, label %then, label %else then: Index: test/Isl/CodeGen/split_edges.ll =================================================================== --- test/Isl/CodeGen/split_edges.ll +++ test/Isl/CodeGen/split_edges.ll @@ -1,6 +1,8 @@ ; RUN: opt %loadPolly -polly-detect-unprofitable -polly-no-early-exit -polly-codegen -verify-region-info -verify-dom-info -S < %s | FileCheck %s 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-n8:16:32:64" +@A = common global [1536 x float] zeroinitializer + define void @loop_with_condition() nounwind { bb0: fence seq_cst @@ -11,6 +13,8 @@ bb2: %ind1 = phi i32 [0, %bb1], [ %inc0, %bb2] + %ptr = getelementptr [1536 x float], [1536 x float]* @A, i64 0, i32 %ind1 + store float undef, float* %ptr %inc0 = add i32 %ind1, 1 %cond1 = icmp eq i32 %ind1, 32 br i1 %cond1, label %bb4, label %bb2 Index: test/Isl/CodeGen/split_edges_2.ll =================================================================== --- test/Isl/CodeGen/split_edges_2.ll +++ test/Isl/CodeGen/split_edges_2.ll @@ -2,6 +2,8 @@ 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-n8:16:32:64" +@A = common global [1536 x float] zeroinitializer + define void @loop_with_condition() nounwind { bb0: fence seq_cst @@ -12,6 +14,8 @@ bb2: %ind1 = phi i32 [0, %bb1], [ %inc0, %bb2] + %ptr = getelementptr [1536 x float], [1536 x float]* @A, i64 0, i32 %ind1 + store float undef, float* %ptr %inc0 = add i32 %ind1, 1 %cond1 = icmp eq i32 %ind1, 32 br i1 %cond1, label %bb4, label %bb2 Index: test/ScheduleOptimizer/2012-10-14-Zero-Bands.ll =================================================================== --- test/ScheduleOptimizer/2012-10-14-Zero-Bands.ll +++ /dev/null @@ -1,26 +0,0 @@ -; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect-scops-in-regions-without-loops -polly-detect-scops-in-functions-without-loops -polly-opt-isl -analyze < %s | FileCheck %s -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-n8:16:32:64-S128" - -@A = common global [1536 x float] zeroinitializer - -define void @read_nres() { -entry: - br label %if.cond - -if.cond: - br i1 false, label %if.then, label %if.end - -if.then: - %ptr = getelementptr [1536 x float], [1536 x float]* @A, i64 0, i32 23 - store float undef, float* %ptr - br label %if.end - -if.end: - br label %return - -return: - ret void -} - -; CHECK: Calculated schedule: -; CHECK-NOT: Stmt_if_then Index: test/ScopInfo/aliasing_dead_access.ll =================================================================== --- test/ScopInfo/aliasing_dead_access.ll +++ test/ScopInfo/aliasing_dead_access.ll @@ -1,8 +1,8 @@ ; RUN: opt %loadPolly -polly-detect-unprofitable -polly-code-generator=isl -analyze -polly-scops < %s | FileCheck %s ; -; Check that RTC generation does not die when accesses are dead. +; Check that we do not create a SCoP if there is no statement executed. ; -; CHECK: Alias Groups (0): +; CHECK-NOT: Context ; ; void jd(int *A, int *B) { ; for (int i = 0; i < 1024; i++)