Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -197,6 +197,14 @@ " disjunction sets that only have one instance"), cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::cat(PollyCategory)); + +static cl::opt + CleanRTC("polly-clean-rtc", + cl::desc("Propagate parameter restrictions form Trip count" + " assumptions to overflow and alaias checks"), + cl::Hidden, cl::ZeroOrMore, cl::init(false), + cl::cat(PollyCategory)); + //===----------------------------------------------------------------------===// // Create a sequence of two schedules. Either argument may be null and is @@ -2258,6 +2266,12 @@ if (InvolvedParams > RunTimeChecksMaxParameters) return false; } + // Simplify the Alias conditon by intersecting with the + // trip count asumption that makes trip count always >= 1. + if (CleanRTC && !S.getRestrictDomainParams().plain_is_universe()) + Set = Set.intersect_params(S.getRestrictDomainParams()) + .coalesce() + .gist_params(S.getRestrictDomainParams()); MinPMA = Set.lexmin_pw_multi_aff(); MaxPMA = Set.lexmax_pw_multi_aff(); @@ -3026,6 +3040,10 @@ Stmt.updateDomain(NewDom); } Schedule = Schedule.gist_domain_params(RestrictDomainParams); + if (CleanRTC) + InvalidContext = InvalidContext.intersect_params(RestrictDomainParams) + .coalesce() + .gist_params(RestrictDomainParams); } } Index: test/ScopDetect/model-dowhile-update-rtc.ll =================================================================== --- /dev/null +++ test/ScopDetect/model-dowhile-update-rtc.ll @@ -0,0 +1,63 @@ +; REQUIRES: asserts +; Original C code: +;void foo(int* A, int* B, unsigned n) { +; +; unsigned idx =5; +; do { +; A[idx] += B[idx]; +; idx++; +; } while (idx <= n); +;} + +; This test checks that assumptions for the Trip Count added by modeling +; do-while like loops can be used to simplify the runtime check for the Scop. + +; In the example below we were able to get rid of "n <= -1" in the RTC +; since we added the assumption "n >= 5". + +; RUN: opt -S -polly -O3 -debug-only=polly-ast -debug-only=polly-scops\ +; RUN: -polly-process-unprofitable %s -polly-model-do-while=true\ +; RUN: -polly-clean-rtc=false &> %t1 + +; RUN: opt -S -polly -O3 -debug-only=polly-ast -debug-only=polly-scops\ +; RUN: -polly-process-unprofitable %s -polly-model-do-while=true\ +; RUN: -polly-clean-rtc=true &> %t2 + +; RUN: FileCheck %s < %t1 --check-prefix=NOFIXRTC +; RUN: FileCheck %s < %t2 --check-prefix=FIXRTC + +; NOFIXTRC: Invalid Context: +; NOFIXRTC: p_0 < 0 +; NOFIXRTC: :: isl ast :: foo +; NOFIXRTC: [p_0] -> { : -2147483648 <= p_0 <= 2147483647 } +; NOFIXRTC: if (p_0 >= 5 && 0 == (p_0 <= -1 || p_0 == 2147483647) && (&MemRef0[p_0 + 1] <= &MemRef1[5] || &MemRef1[p_0 + 1] <= &MemRef0[5])) + +; FIXTRC: Invalid Context: +; FIXRTC-NOT: p_0 < 0 +; FIXRTC: :: isl ast :: foo :: %do.body---%do.end +; FIXRTC: [p_0] -> { : -2147483648 <= p_0 <= 2147483647 } +; FIXRTC: if (p_0 >= 5 && 0 == (p_0 == 2147483647) && (&MemRef0[p_0 + 1] <= &MemRef1[5] || &MemRef1[p_0 + 1] <= &MemRef0[5])) + +; Function Attrs: norecurse nounwind +define dso_local void @foo(i32* nocapture %A, i32* nocapture readonly %B, i32 %n) local_unnamed_addr { +entry: + br label %entry.split + +entry.split: ; preds = %entry + br label %do.body + +do.body: ; preds = %do.body, %entry.split + %idx.0 = phi i32 [ 5, %entry.split ], [ %inc, %do.body ] + %arrayidx = getelementptr inbounds i32, i32* %B, i32 %idx.0 + %0 = load i32, i32* %arrayidx, align 4 + %arrayidx1 = getelementptr inbounds i32, i32* %A, i32 %idx.0 + %1 = load i32, i32* %arrayidx1, align 4 + %add = add nsw i32 %1, %0 + store i32 %add, i32* %arrayidx1, align 4 + %inc = add i32 %idx.0, 1 + %cmp = icmp ugt i32 %inc, %n + br i1 %cmp, label %do.end, label %do.body + +do.end: ; preds = %do.body + ret void +}