[polly] r252942 - [FIX] Bail if access function is not divisible by element size.

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 12 12:15:32 PST 2015


Author: jdoerfert
Date: Thu Nov 12 14:15:32 2015
New Revision: 252942

URL: http://llvm.org/viewvc/llvm-project?rev=252942&view=rev
Log:
[FIX] Bail if access function is not divisible by element size.

Modified:
    polly/trunk/include/polly/ScopInfo.h
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/test/Isl/CodeGen/invariant_cannot_handle_void.ll

Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=252942&r1=252941&r2=252942&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Thu Nov 12 14:15:32 2015
@@ -72,6 +72,7 @@ enum AssumptionKind {
   ALIASING,
   INBOUNDS,
   WRAPPING,
+  ALIGNMENT,
   ERRORBLOCK,
   INFINITELOOP,
   INVARIANTLOAD,

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=252942&r1=252941&r2=252942&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Thu Nov 12 14:15:32 2015
@@ -601,6 +601,32 @@ __isl_give isl_map *MemoryAccess::foldAc
   return AccessRelation;
 }
 
+/// @brief Check if @p Expr is divisible by @p Size.
+static bool isDivisible(const SCEV *Expr, unsigned Size, ScalarEvolution &SE) {
+
+  // Only one factor needs to be divisible.
+  if (auto *MulExpr = dyn_cast<SCEVMulExpr>(Expr)) {
+    for (auto *FactorExpr : MulExpr->operands())
+      if (isDivisible(FactorExpr, Size, SE))
+        return true;
+    return false;
+  }
+
+  // For other n-ary expressions (Add, AddRec, Max,...) all operands need
+  // to be divisble.
+  if (auto *NAryExpr = dyn_cast<SCEVNAryExpr>(Expr)) {
+    for (auto *OpExpr : NAryExpr->operands())
+      if (!isDivisible(OpExpr, Size, SE))
+        return false;
+    return true;
+  }
+
+  auto *SizeSCEV = SE.getConstant(Expr->getType(), Size);
+  auto *UDivSCEV = SE.getUDivExpr(Expr, SizeSCEV);
+  auto *MulSCEV = SE.getMulExpr(UDivSCEV, SizeSCEV);
+  return MulSCEV == Expr;
+}
+
 void MemoryAccess::buildAccessRelation(const ScopArrayInfo *SAI) {
   assert(!AccessRelation && "AccessReltation already built");
 
@@ -620,6 +646,7 @@ void MemoryAccess::buildAccessRelation(c
     return;
   }
 
+  Scop &S = *getStatement()->getParent();
   isl_space *Space = isl_space_alloc(Ctx, 0, Statement->getNumIterators(), 0);
   AccessRelation = isl_map_universe(Space);
 
@@ -634,9 +661,14 @@ void MemoryAccess::buildAccessRelation(c
       // LLVM-IR as something like A[i * elementsize]. This hides the fact that
       // two subsequent values of 'i' index two values that are stored next to
       // each other in memory. By this division we make this characteristic
-      // obvious again.
+      // obvious again. However, if the index is not divisible by the element
+      // size we will bail out.
       isl_val *v = isl_val_int_from_si(Ctx, getElemSizeInBytes());
       Affine = isl_pw_aff_scale_down_val(Affine, v);
+
+      if (!isDivisible(Subscripts[0], getElemSizeInBytes(), *S.getSE()))
+        S.addAssumption(ALIGNMENT, isl_set_empty(S.getParamSpace()),
+                        AccessInstruction->getDebugLoc());
     }
 
     isl_map *SubscriptMap = isl_map_from_pw_aff(Affine);
@@ -2941,6 +2973,8 @@ static std::string toString(AssumptionKi
     return "Inbounds";
   case WRAPPING:
     return "No-overflows";
+  case ALIGNMENT:
+    return "Alignment";
   case ERRORBLOCK:
     return "No-error";
   case INFINITELOOP:

Modified: polly/trunk/test/Isl/CodeGen/invariant_cannot_handle_void.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/invariant_cannot_handle_void.ll?rev=252942&r1=252941&r2=252942&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/invariant_cannot_handle_void.ll (original)
+++ polly/trunk/test/Isl/CodeGen/invariant_cannot_handle_void.ll Thu Nov 12 14:15:32 2015
@@ -1,11 +1,9 @@
 ; RUN: opt %loadPolly -S -polly-codegen %s | FileCheck %s
 ;
 ; The offset of the %tmp1 load wrt. to %buff (62 bytes) is not divisible
-; by the type size (i32 = 4 bytes), thus the access function build for
-; %tmp1 is empty. As a result the code generation crashed when hoisting
-; %tmp1. This test verifies we do not crash anymore.
+; by the type size (i32 = 4 bytes), thus we will bail out.
 ;
-; CHECK: polly.start
+; CHECK-NOT: polly.start
 ;
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 




More information about the llvm-commits mailing list