[polly] r179148 - scop detection: properly instantiate SCEVs to the place where they are used

Sebastian Pop spop at codeaurora.org
Tue Apr 9 21:05:19 PDT 2013


Author: spop
Date: Tue Apr  9 23:05:18 2013
New Revision: 179148

URL: http://llvm.org/viewvc/llvm-project?rev=179148&view=rev
Log:
scop detection: properly instantiate SCEVs to the place where they are used

Fix inspired from c2d4a0627e95c34a819b9d4ffb4db62daa78dade.

    Given the following code

        for (i = 0; i < 10; i++) {
          ;
        }

    S:  A[i] = 0

    When translate the data reference A[i] in statement S using scev, we need to
    retrieve the scev of 'i' at the location of 'S'. If we do not do this the
    scev that we obtain will be expressed as {0,+,1}_for and will reference loop
    iterators that do not surround 'S'. What we really want is the scev to be
    instantiated to the value of 'i' after the loop. This value is {10}.

This used to crash in:

    int loopDimension = getLoopDepth(Expr->getLoop());

    isl_aff *LAff = isl_aff_set_coefficient_si(
        isl_aff_zero_on_domain(LocalSpace), isl_dim_in, loopDimension, 1);

(gdb) p Expr->dump()
{8,+,8}<nw><%do.body>

(gdb) p getLoopDepth(Expr->getLoop())
$5 = 0

    isl_space *Space = isl_space_set_alloc(Ctx, 0, NbLoopSpaces);
    isl_local_space *LocalSpace = isl_local_space_from_space(Space);

As we are trying to create a memory access in a stmt that is outside all loops,
LocalSpace has 0 dimensions:

(gdb) p NbLoopSpaces
$12 = 0

(gdb) p Statement.BB->dump()

if.then:                                          ; preds = %do.end
  %0 = load float* %add.ptr, align 4
  store float %0, float* %q.1.reg2mem, align 4
  br label %if.end.single_exit

and so the scev for %add.ptr should be taken at the place where it is used,
i.e., it should be the value on the last iteration of the do.body loop, and not
"{8,+,8}<nw><%do.body>".

Added:
    polly/trunk/test/ScopDetect/isl_aff_out_of_bounds.ll
Modified:
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/Analysis/TempScopInfo.cpp

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=179148&r1=179147&r2=179148&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Tue Apr  9 23:05:18 2013
@@ -196,8 +196,9 @@ bool ScopDetection::isValidCFG(BasicBloc
         isa<UndefValue>(ICmp->getOperand(1)))
       INVALID(AffFunc, "undef operand in branch at BB: " + BB.getName());
 
-    const SCEV *LHS = SE->getSCEV(ICmp->getOperand(0));
-    const SCEV *RHS = SE->getSCEV(ICmp->getOperand(1));
+    Loop *L = LI->getLoopFor(ICmp->getParent());
+    const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
+    const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
 
     if (!isAffineExpr(&Context.CurRegion, LHS, *SE) ||
         !isAffineExpr(&Context.CurRegion, RHS, *SE))
@@ -239,7 +240,8 @@ bool ScopDetection::isValidCallInst(Call
 bool ScopDetection::isValidMemoryAccess(Instruction &Inst,
                                         DetectionContext &Context) const {
   Value *Ptr = getPointerOperand(Inst);
-  const SCEV *AccessFunction = SE->getSCEV(Ptr);
+  Loop *L = LI->getLoopFor(Inst.getParent());
+  const SCEV *AccessFunction = SE->getSCEVAtScope(Ptr, L);
   const SCEVUnknown *BasePointer;
   Value *BaseValue;
 

Modified: polly/trunk/lib/Analysis/TempScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/TempScopInfo.cpp?rev=179148&r1=179147&r2=179148&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/TempScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/TempScopInfo.cpp Tue Apr  9 23:05:18 2013
@@ -77,6 +77,7 @@ void TempScop::printDetail(llvm::raw_ost
 
 void TempScopInfo::buildAccessFunctions(Region &R, BasicBlock &BB) {
   AccFuncSetType Functions;
+  Loop *L = LI->getLoopFor(&BB);
 
   for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) {
     Instruction &Inst = *I;
@@ -93,7 +94,8 @@ void TempScopInfo::buildAccessFunctions(
         Type = IRAccess::WRITE;
       }
 
-      const SCEV *AccessFunction = SE->getSCEV(getPointerOperand(Inst));
+      const SCEV *AccessFunction =
+          SE->getSCEVAtScope(getPointerOperand(Inst), L);
       const SCEVUnknown *BasePointer =
           dyn_cast<SCEVUnknown>(SE->getPointerBase(AccessFunction));
 
@@ -163,8 +165,9 @@ void TempScopInfo::buildAffineCondition(
   ICmpInst *ICmp = dyn_cast<ICmpInst>(&V);
   assert(ICmp && "Only ICmpInst of constant as condition supported!");
 
-  const SCEV *LHS = SE->getSCEV(ICmp->getOperand(0)),
-              *RHS = SE->getSCEV(ICmp->getOperand(1));
+  Loop *L = LI->getLoopFor(ICmp->getParent());
+  const SCEV *LHS = SE->getSCEVAtScope(ICmp->getOperand(0), L);
+  const SCEV *RHS = SE->getSCEVAtScope(ICmp->getOperand(1), L);
 
   ICmpInst::Predicate Pred = ICmp->getPredicate();
 

Added: polly/trunk/test/ScopDetect/isl_aff_out_of_bounds.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopDetect/isl_aff_out_of_bounds.ll?rev=179148&view=auto
==============================================================================
--- polly/trunk/test/ScopDetect/isl_aff_out_of_bounds.ll (added)
+++ polly/trunk/test/ScopDetect/isl_aff_out_of_bounds.ll Tue Apr  9 23:05:18 2013
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -basicaa -polly-codegen-isl -polly-codegen-scev %s
+
+; Used to fail with:
+; ../../isl/isl_aff.c:591: position out of bounds
+
+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"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare double @frexp(double)
+
+define void @vorbis_lsp_to_curve(float* %lsp, i32 %m) {
+entry:
+  %q.1.reg2mem = alloca float, align 4
+  br i1 undef, label %do.body, label %while.end
+
+do.body:                                          ; preds = %do.body, %entry
+  %ftmp.0 = phi float* [ %add.ptr, %do.body ], [ %lsp, %entry ]
+  %add.ptr = getelementptr inbounds float* %ftmp.0, i64 2
+  br i1 true, label %do.end, label %do.body
+
+do.end:                                           ; preds = %do.body
+  br i1 false, label %if.end.single_exit, label %if.then
+
+if.then:                                          ; preds = %do.end
+  %0 = load float* %add.ptr, align 4
+  store float %0, float* %q.1.reg2mem, align 4
+  br label %if.end.single_exit
+
+if.end.single_exit:                               ; preds = %do.end, %if.then
+  br label %if.end
+
+if.end:                                           ; preds = %if.end.single_exit
+  %q.1.reload = load float* %q.1.reg2mem, align 4
+  %conv31 = fpext float %q.1.reload to double
+  %call32 = call double @frexp(double %conv31)
+  unreachable
+
+while.end:                                        ; preds = %entry
+  ret void
+}





More information about the llvm-commits mailing list