Index: lib/Analysis/ScopDetection.cpp =================================================================== --- lib/Analysis/ScopDetection.cpp +++ lib/Analysis/ScopDetection.cpp @@ -532,7 +532,7 @@ if (IntToPtrInst *Inst = dyn_cast(BaseValue)) return invalid(Context, /*Assert=*/true, Inst); - if (PollyUseRuntimeAliasChecks || IgnoreAliasing) + if (IgnoreAliasing) return true; // Check if the base pointer of the memory access does alias with @@ -548,8 +548,27 @@ // alias, if -basicaa is not available. They actually do not, but as we can // not proof this without -basicaa we would fail. We disable this check to // not cause irrelevant verification failures. - if (!AS.isMustAlias()) + if (!AS.isMustAlias()) { + if (PollyUseRuntimeAliasChecks) { + bool CanBuildRunTimeCheck = true; + // The run-time alias check places code that involves the base pointer at + // the beginning of the SCoP. This breaks if the base pointer is defined + // inside the scop. Hence, we can only use it if we are sure the base + // pointer is not an instruction defined inside the scop. + for (const auto &Ptr : AS) { + Instruction *Inst = dyn_cast(Ptr.getValue()); + BaseValue->dump(); + if (Inst && Context.CurRegion.contains(Inst)) { + CanBuildRunTimeCheck = false; + break; + } + } + + if (CanBuildRunTimeCheck) + return true; + } return invalid(Context, /*Assert=*/false, &Inst, AS); + } return true; } Index: test/ScopDetect/run_time_alias_check.ll =================================================================== --- /dev/null +++ test/ScopDetect/run_time_alias_check.ll @@ -0,0 +1,36 @@ +; RUN: opt %loadPolly -polly-detect -polly-code-generator=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" +target triple = "x86_64-unknown-linux-gnu" + +declare float* @getNextBasePtr(float*) readnone nounwind + +define void @base_pointer_is_inst_inside_invariant_1(i64 %n, float* %A, float* %B) { +entry: + br label %for.i + +for.i: + %indvar.i = phi i64 [ %indvar.i.next, %for.i.inc ], [ 0, %entry ] + br label %S1 + +S1: +; To get an instruction inside a region, we use a function without side +; effects on which SCEV blocks, but for which it is still clear that the +; return value remains invariant throughout the whole loop. + %ptr = call float* @getNextBasePtr(float* %A) + %conv = sitofp i64 %indvar.i to float + %arrayidx5 = getelementptr float* %ptr, i64 %indvar.i + store float %conv, float* %arrayidx5, align 4 + store float 1.0, float* %B + br label %for.i.inc + +for.i.inc: + %indvar.i.next = add i64 %indvar.i, 1 + %exitcond.i = icmp ne i64 %indvar.i.next, %n + br i1 %exitcond.i, label %for.i, label %exit + +exit: + ret void +} + +; CHECK-NOT: Valid Region for Scop