From: Johannes Doerfert Date: Sun, 3 May 2015 16:03:01 +0000 (+0000) Subject: [FIX] Invalid recognition of multidimensional access X-Git-Tag: llvmorg-3.7.0-rc1~5472 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8983031b5edd81f67504d81a7d693e5ee79baee6;p=platform%2Fupstream%2Fllvm.git [FIX] Invalid recognition of multidimensional access In the lnt benchmark MultiSource/Benchmarks/MallocBench/gs/gs with scalar and PHI modeling we detected the multidimensional accesses with sizes variant in the SCoP. This will check the sizes for validity. llvm-svn: 236395 --- diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp index db04f0b..f7ea6c4 100644 --- a/polly/lib/Analysis/ScopDetection.cpp +++ b/polly/lib/Analysis/ScopDetection.cpp @@ -488,6 +488,13 @@ bool ScopDetection::hasAffineMemoryAccesses(DetectionContext &Context) const { SE->findArrayDimensions(Terms, Shape->DelinearizedSizes, Context.ElementSize[BasePointer]); + if (!AllowNonAffine) + for (const SCEV *DelinearizedSize : Shape->DelinearizedSizes) + if (hasScalarDepsInsideRegion(DelinearizedSize, &CurRegion)) + invalid( + Context, /*Assert=*/true, DelinearizedSize, + Context.Accesses[BasePointer].front().first, BaseValue); + // No array shape derived. if (Shape->DelinearizedSizes.empty()) { if (AllowNonAffine) diff --git a/polly/lib/Support/SCEVValidator.cpp b/polly/lib/Support/SCEVValidator.cpp index 80c2249..f1d9443 100644 --- a/polly/lib/Support/SCEVValidator.cpp +++ b/polly/lib/Support/SCEVValidator.cpp @@ -559,6 +559,7 @@ std::vector getParamsInAffineExpr(const Region *R, SCEVValidator Validator(R, SE, BaseAddress); ValidatorResult Result = Validator.visit(Expr); + assert(Result.isValid() && "Requested parameters for an invalid SCEV!"); return Result.getParameters(); } diff --git a/polly/test/ScopDetect/multidim_indirect_access.ll b/polly/test/ScopDetect/multidim_indirect_access.ll new file mode 100644 index 0000000..b3edecb --- /dev/null +++ b/polly/test/ScopDetect/multidim_indirect_access.ll @@ -0,0 +1,58 @@ +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect -analyze < %s | FileCheck %s --check-prefix=INDEPENDENT +; RUN: opt %loadPolly -polly-detect-unprofitable -polly-detect -analyze -polly-model-phi-nodes -disable-polly-intra-scop-scalar-to-array < %s | FileCheck %s --check-prefix=NON_INDEPENDENT +; +; With the IndependentBlocks and PollyPrepare passes this will __correctly__ +; not be recognized as a SCoP and the debug states: +; +; SCEV of PHI node refers to SSA names in region +; +; Without IndependentBlocks and PollyPrepare the access A[x] is mistakenly +; treated as a multidimensional access with dimension size x. This test will +; check that we correctly invalidate the region and do not detect a outer SCoP. +; +; FIXME: +; We should detect the inner region but the PHI node in the exit blocks that. +; +; void f(int *A, long N) { +; int j = 0; +; while (N > j) { +; int x = A[0]; +; int i = 1; +; do { +; A[x] = 42; +; A += x; +; } while (i++ < N); +; } +; } +; +; INDEPENDENT-NOT: Valid +; NON_INDEPENDENT-NOT: Valid +; +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @f(i32* %A, i64 %N) { +bb: + br label %bb0 + +bb0: + %j = phi i64 [ %j.next, %bb1 ], [ 1, %bb ] + %tmp = load i32, i32* %A, align 4 + %exitcond0 = icmp sgt i64 %N, %j + %j.next = add nuw nsw i64 %j, 1 + br i1 %exitcond0, label %bb1, label %bb13 + +bb1: ; preds = %bb7, %bb0 + %i = phi i64 [ %i.next, %bb1 ], [ 1, %bb0 ] + %.0 = phi i32* [ %A, %bb0 ], [ %tmp12, %bb1 ] + %tmp8 = sext i32 %tmp to i64 + %tmp9 = getelementptr inbounds i32, i32* %.0, i64 %tmp8 + store i32 42, i32* %tmp9, align 4 + %tmp11 = sext i32 %tmp to i64 + %tmp12 = getelementptr inbounds i32, i32* %.0, i64 %tmp11 + %i.next = add nuw nsw i64 %i, 1 + %exitcond = icmp ne i64 %i, %N + br i1 %exitcond, label %bb1, label %bb0 + +bb13: ; preds = %bb1 + ret void +}