Index: lib/Analysis/ScopDetection.cpp =================================================================== --- lib/Analysis/ScopDetection.cpp +++ lib/Analysis/ScopDetection.cpp @@ -192,6 +192,12 @@ cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); +static cl::opt + AllowNonAffineRead("polly-allow-nonaffine-read", + cl::desc("Allow non-affine read functions in arrays"), + cl::Hidden, cl::init(true), cl::ZeroOrMore, + cl::cat(PollyCategory)); + static cl::opt AllowModrefCall("polly-allow-modref-calls", cl::desc("Allow functions with known modref behavior"), @@ -958,7 +964,8 @@ const Instruction *Insn = Pair.first; const SCEV *AF = Pair.second; - if (!isAffine(AF, Scope, Context)) { + if (!isAffine(AF, Scope, Context) && + (Insn->mayWriteToMemory() || !AllowNonAffineRead)) { invalid(Context, /*Assert=*/true, AF, Insn, BaseValue); if (!KeepGoing) @@ -1013,10 +1020,13 @@ // (Possibly) report non affine access if (IsNonAffine) { BasePtrHasNonAffine = true; - if (!AllowNonAffine) + bool AllowThisNonAffine = + AllowNonAffine || (!Insn->mayWriteToMemory() && AllowNonAffineRead); + + if (!AllowThisNonAffine) invalid(Context, /*Assert=*/true, Pair.second, Insn, BaseValue); - if (!KeepGoing && !AllowNonAffine) + if (!KeepGoing && !AllowThisNonAffine) return false; } } @@ -1124,7 +1134,8 @@ if (!IsAffine || hasIVParams(AF)) Context.NonAffineAccesses.insert( std::make_pair(BP, LI.getLoopFor(Inst->getParent()))); - } else if (!AllowNonAffine && !IsAffine) { + } else if (!IsAffine && !AllowNonAffine && + (Inst->mayWriteToMemory() || !AllowNonAffineRead)) { return invalid(Context, /*Assert=*/true, AF, Inst, BV); } Index: test/Isl/CodeGen/two-loops-right-after-each-other-2.ll =================================================================== --- test/Isl/CodeGen/two-loops-right-after-each-other-2.ll +++ test/Isl/CodeGen/two-loops-right-after-each-other-2.ll @@ -1,4 +1,4 @@ -; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s +; RUN: opt %loadPolly -polly-codegen -polly-allow-nonaffine-read=0 -S < %s | FileCheck %s ; CHECK: polly.merge_new_and_old: ; CHECK-NEXT: merge = phi Index: test/ScopDetect/allow-nonaffine-read.ll =================================================================== --- /dev/null +++ test/ScopDetect/allow-nonaffine-read.ll @@ -0,0 +1,40 @@ +; RUN: opt %loadPolly -polly-detect -polly-allow-nonaffine-read=1 -analyze < %s | FileCheck %s -match-full-lines +; +; The non-affine lookup in the loop body must be allowed. +; +; for (int j = 0; j < n; j += 1) { +; int idx = A[j]; +; double val = B[idx]; +; C[0] = val; +; } +; +define void @func(i32 %n, i32* noalias nonnull %A, double* noalias nonnull %B, double* noalias nonnull %C) { +entry: + br label %for + +for: + %j = phi i32 [0, %entry], [%j.inc, %inc] + %j.cmp = icmp slt i32 %j, %n + br i1 %j.cmp, label %body, label %exit + + body: + %idxidx = getelementptr inbounds i32, i32* %A, i32 %j + %idx = load i32, i32* %idxidx + %validx = getelementptr inbounds double, double* %B, i32 %idx + %val = load double, double* %validx + store double %val, double* %C + br label %inc + +inc: + %j.inc = add nuw nsw i32 %j, 1 + br label %for + +exit: + br label %return + +return: + ret void +} + + +; CHECK: Valid Region for Scop: for => return Index: test/ScopDetect/multidim.ll =================================================================== --- test/ScopDetect/multidim.ll +++ test/ScopDetect/multidim.ll @@ -1,4 +1,4 @@ -; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-detect -polly-allow-nonaffine-read=0 -analyze < %s | FileCheck %s target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" ; CHECK: Valid Region for Scop: bb19 => bb20 Index: test/ScopDetect/non-affine-loop.ll =================================================================== --- test/ScopDetect/non-affine-loop.ll +++ test/ScopDetect/non-affine-loop.ll @@ -2,7 +2,7 @@ ; RUN: -polly-allow-nonaffine-loops=false \ ; RUN: -analyze < %s | FileCheck %s --check-prefix=REJECTNONAFFINELOOPS ; RUN: opt %loadPolly -polly-detect -polly-allow-nonaffine-branches \ -; RUN: -polly-allow-nonaffine-loops=true \ +; RUN: -polly-allow-nonaffine-loops=true -polly-allow-nonaffine-read=0 \ ; RUN: -analyze < %s | FileCheck %s --check-prefix=ALLOWNONAFFINELOOPS ; RUN: opt %loadPolly -polly-detect -polly-allow-nonaffine-branches \ ; RUN: -polly-allow-nonaffine-loops=false -polly-allow-nonaffine \ Index: test/ScopDetect/parametric-multiply-in-scev-2.ll =================================================================== --- test/ScopDetect/parametric-multiply-in-scev-2.ll +++ test/ScopDetect/parametric-multiply-in-scev-2.ll @@ -1,4 +1,4 @@ -; RUN: opt %loadPolly -polly-detect -analyze < %s | FileCheck %s +; RUN: opt %loadPolly -polly-detect -polly-allow-nonaffine-read=0 -analyze < %s | FileCheck %s ; CHECK-NOT: Valid Region Index: test/ScopDetectionDiagnostics/ReportMultipleNonAffineAccesses.ll =================================================================== --- test/ScopDetectionDiagnostics/ReportMultipleNonAffineAccesses.ll +++ test/ScopDetectionDiagnostics/ReportMultipleNonAffineAccesses.ll @@ -1,9 +1,9 @@ -; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -analyze < %s 2>&1| FileCheck %s -; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -polly-delinearize=false -polly-detect-keep-going -analyze < %s 2>&1| FileCheck %s -check-prefix=ALL -; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -analyze < %s 2>&1| FileCheck %s -check-prefix=DELIN -; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -polly-detect-keep-going -analyze < %s 2>&1| FileCheck %s -check-prefix=DELIN-ALL -; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -polly-allow-nonaffine -analyze < %s 2>&1| FileCheck %s -check-prefix=NONAFFINE -; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-detect-track-failures -polly-detect -polly-allow-nonaffine -analyze < %s 2>&1| FileCheck %s -check-prefix=NONAFFINE +; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-allow-nonaffine-read=0 -polly-detect-track-failures -polly-detect -analyze < %s 2>&1| FileCheck %s +; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-allow-nonaffine-read=0 -polly-detect-track-failures -polly-detect -polly-delinearize=false -polly-detect-keep-going -analyze < %s 2>&1| FileCheck %s -check-prefix=ALL +; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-allow-nonaffine-read=0 -polly-detect-track-failures -polly-detect -analyze < %s 2>&1| FileCheck %s -check-prefix=DELIN +; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-allow-nonaffine-read=0 -polly-detect-track-failures -polly-detect -polly-detect-keep-going -analyze < %s 2>&1| FileCheck %s -check-prefix=DELIN-ALL +; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-allow-nonaffine-read=0 -polly-detect-track-failures -polly-detect -polly-allow-nonaffine -analyze < %s 2>&1| FileCheck %s -check-prefix=NONAFFINE +; RUN: opt %loadPolly -basicaa -pass-remarks-missed="polly-detect" -polly-allow-nonaffine-read=0 -polly-detect-track-failures -polly-detect -polly-allow-nonaffine -analyze < %s 2>&1| FileCheck %s -check-prefix=NONAFFINE ; 1 void manyaccesses(float A[restrict], long n, float B[restrict][n]) ; 2 {