[polly] r219077 - Introduce the ScopArrayInfo class.

Johannes Doerfert doerfert at cs.uni-saarland.de
Sun Oct 5 04:32:19 PDT 2014


Author: jdoerfert
Date: Sun Oct  5 06:32:18 2014
New Revision: 219077

URL: http://llvm.org/viewvc/llvm-project?rev=219077&view=rev
Log:
Introduce the ScopArrayInfo class.

  This class allows to store information about the arrays in the SCoP.
  For each base pointer in the SCoP one object is created storing the
  type and dimension sizes of the array. The objects can be obtained via
  the SCoP, a MemoryAccess or the isl_id associated with the output
  dimension of a MemoryAccess (the description of what is accessed).

  So far we use the information in the IslExprBuilder to create the
  right base type before indexing into the base array. This fixes the
  bug http://llvm.org/bugs/show_bug.cgi?id=21113 (both test cases are
  included). On top of that we can now build runtime alias checks for
  delinearized arrays as the dimension sizes are also part of the
  ScopArrayInfo objects.

Differential Revision: http://reviews.llvm.org/D5613

Added:
    polly/trunk/test/Isl/CodeGen/aliasing_different_base_and_access_type.ll
    polly/trunk/test/Isl/CodeGen/aliasing_struct_element.ll
Modified:
    polly/trunk/include/polly/ScopInfo.h
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/lib/CodeGen/IslCodeGeneration.cpp
    polly/trunk/lib/CodeGen/IslExprBuilder.cpp
    polly/trunk/lib/Exchange/JSONExporter.cpp
    polly/trunk/test/Isl/CodeGen/MemAccess/codegen_constant_offset.ll
    polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple.ll
    polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_float.ll
    polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md.ll
    polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll

Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Sun Oct  5 06:32:18 2014
@@ -59,7 +59,70 @@ class TempScop;
 class SCEVAffFunc;
 class Comparison;
 
-//===----------------------------------------------------------------------===//
+/// @brief A class to store information about arrays in the SCoP.
+///
+/// Objects are accessible via the ScoP, MemoryAccess or the id associated with
+/// the MemoryAccess access function.
+///
+class ScopArrayInfo {
+public:
+  /// @brief Construct a ScopArrayInfo object.
+  ///
+  /// @param BasePtr        The array base pointer.
+  /// @param AccessType     The type used to access this array.
+  /// @param IslCtx         The isl context used to create the base pointer id.
+  /// @param DimensionSizes A vector containing the size of each dimension.
+  ScopArrayInfo(Value *BasePtr, Type *AccessType, isl_ctx *IslCtx,
+                const SmallVector<const SCEV *, 4> &DimensionSizes);
+
+  /// @brief Destructor to free the isl id of the base pointer.
+  ~ScopArrayInfo();
+
+  /// @brief Return the base pointer.
+  Value *getBasePtr() const { return BasePtr; }
+
+  /// @brief Return the number of dimensions.
+  unsigned getNumberOfDimensions() const { return DimensionSizes.size(); }
+
+  /// @brief Return the size of dimension @p dim.
+  const SCEV *getDimensionSize(unsigned dim) const {
+    assert(dim < getNumberOfDimensions() && "Invalid dimension");
+    return DimensionSizes[dim];
+  }
+
+  /// @brief Return the type used to access this array in the SCoP.
+  Type *getType() const { return AccessType; }
+
+  /// @brief Return the isl id for the base pointer.
+  __isl_give isl_id *getBasePtrId() const;
+
+  /// @brief Dump a readable representation to stderr.
+  void dump() const;
+
+  /// @brief Print a readable representation to @p OS.
+  void print(raw_ostream &OS) const;
+
+  /// @brief Access the ScopArrayInfo associated with an access function.
+  static const ScopArrayInfo *
+  getFromAccessFunction(__isl_keep isl_pw_multi_aff *PMA);
+
+  /// @brief Access the ScopArrayInfo associated with an isl Id.
+  static const ScopArrayInfo *getFromId(__isl_take isl_id *Id);
+
+private:
+  /// @brief The base pointer.
+  Value *BasePtr;
+
+  /// @brief The type used to access this array.
+  Type *AccessType;
+
+  /// @brief The isl id for the base pointer.
+  isl_id *Id;
+
+  /// @brief The sizes of each dimension.
+  SmallVector<const SCEV *, 4> DimensionSizes;
+};
+
 /// @brief Represent memory accesses in statements.
 class MemoryAccess {
 public:
@@ -148,11 +211,12 @@ private:
 public:
   /// @brief Create a memory access from an access in LLVM-IR.
   ///
-  /// @param Access     The memory access.
-  /// @param Statement  The statement that contains the access.
-  /// @param SE         The ScalarEvolution analysis.
+  /// @param Access    The memory access.
+  /// @param AccInst   The access instruction.
+  /// @param Statement The statement that contains the access.
+  /// @param SAI       The ScopArrayInfo object for this base pointer.
   MemoryAccess(const IRAccess &Access, Instruction *AccInst,
-               ScopStmt *Statement);
+               ScopStmt *Statement, const ScopArrayInfo *SAI);
 
   ~MemoryAccess();
 
@@ -188,6 +252,9 @@ public:
   /// @brief Get the base array isl_id for this access.
   __isl_give isl_id *getArrayId() const;
 
+  /// @brief Get the ScopArrayInfo object for the base address.
+  const ScopArrayInfo *getScopArrayInfo() const;
+
   /// @brief Return a string representation of the accesse's reduction type.
   const std::string getReductionOperatorStr() const;
 
@@ -534,6 +601,9 @@ private:
   /// Constraints on parameters.
   isl_set *Context;
 
+  /// @brief A map to remember ScopArrayInfo objects for all base pointers.
+  DenseMap<const Value *, const ScopArrayInfo *> ScopArrayInfoMap;
+
   /// @brief The assumptions under which this scop was built.
   ///
   /// When constructing a scop sometimes the exact representation of a statement
@@ -728,6 +798,13 @@ public:
   const_reverse_iterator rend() const { return Stmts.rend(); }
   //@}
 
+  /// @brief Return the (possibly new) ScopArrayInfo object for @p Access.
+  const ScopArrayInfo *getOrCreateScopArrayInfo(const IRAccess &Access,
+                                                Instruction *AccessInst);
+
+  /// @brief Return the cached ScopArrayInfo object for @p BasePtr.
+  const ScopArrayInfo *getScopArrayInfo(Value *BasePtr);
+
   void setContext(isl_set *NewContext);
 
   /// @brief Align the parameters in the statement to the scop context

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Sun Oct  5 06:32:18 2014
@@ -278,6 +278,43 @@ int SCEVAffinator::getLoopDepth(const Lo
   return L->getLoopDepth() - outerLoop->getLoopDepth();
 }
 
+ScopArrayInfo::ScopArrayInfo(Value *BasePtr, Type *AccessType, isl_ctx *Ctx,
+                             const SmallVector<const SCEV *, 4> &DimensionSizes)
+    : BasePtr(BasePtr), AccessType(AccessType), DimensionSizes(DimensionSizes) {
+  const std::string BasePtrName = getIslCompatibleName("MemRef_", BasePtr, "");
+  Id = isl_id_alloc(Ctx, BasePtrName.c_str(), this);
+}
+
+ScopArrayInfo::~ScopArrayInfo() { isl_id_free(Id); }
+
+isl_id *ScopArrayInfo::getBasePtrId() const { return isl_id_copy(Id); }
+
+void ScopArrayInfo::dump() const { print(errs()); }
+
+void ScopArrayInfo::print(raw_ostream &OS) const {
+  OS << "ScopArrayInfo:\n";
+  OS << "  Base: " << *getBasePtr() << "\n";
+  OS << "  Type: " << *getType() << "\n";
+  OS << "  Dimension Sizes:\n";
+  for (unsigned u = 0; u < getNumberOfDimensions(); u++)
+    OS << "    " << u << ") " << *DimensionSizes[u] << "\n";
+  OS << "\n";
+}
+
+const ScopArrayInfo *
+ScopArrayInfo::getFromAccessFunction(__isl_keep isl_pw_multi_aff *PMA) {
+  isl_id *Id = isl_pw_multi_aff_get_tuple_id(PMA, isl_dim_out);
+  assert(Id && "Output dimension didn't have an ID");
+  return getFromId(Id);
+}
+
+const ScopArrayInfo *ScopArrayInfo::getFromId(isl_id *Id) {
+  void *User = isl_id_get_user(Id);
+  const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
+  isl_id_free(Id);
+  return SAI;
+}
+
 const std::string
 MemoryAccess::getReductionOperatorStr(MemoryAccess::ReductionType RT) {
   switch (RT) {
@@ -348,6 +385,14 @@ static MemoryAccess::AccessType getMemor
   llvm_unreachable("Unknown IRAccess type!");
 }
 
+const ScopArrayInfo *MemoryAccess::getScopArrayInfo() const {
+  isl_id *ArrayId = getArrayId();
+  void *User = isl_id_get_user(ArrayId);
+  const ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(User);
+  isl_id_free(ArrayId);
+  return SAI;
+}
+
 isl_id *MemoryAccess::getArrayId() const {
   return isl_map_get_tuple_id(AccessRelation, isl_dim_out);
 }
@@ -433,14 +478,15 @@ void MemoryAccess::assumeNoOutOfBound(co
 }
 
 MemoryAccess::MemoryAccess(const IRAccess &Access, Instruction *AccInst,
-                           ScopStmt *Statement)
+                           ScopStmt *Statement, const ScopArrayInfo *SAI)
     : Type(getMemoryAccessType(Access)), Statement(Statement), Inst(AccInst),
       newAccessRelation(nullptr) {
 
   isl_ctx *Ctx = Statement->getIslCtx();
   BaseAddr = Access.getBase();
   BaseName = getIslCompatibleName("MemRef_", getBaseAddr(), "");
-  isl_id *BaseAddrId = isl_id_alloc(Ctx, getBaseName().c_str(), nullptr);
+
+  isl_id *BaseAddrId = SAI->getBasePtrId();
 
   if (!Access.isAffine()) {
     // We overapproximate non-affine accesses with a possible access to the
@@ -666,18 +712,23 @@ void ScopStmt::buildScattering(SmallVect
 }
 
 void ScopStmt::buildAccesses(TempScop &tempScop, const Region &CurRegion) {
-  for (auto &&Access : *tempScop.getAccessFunctions(BB)) {
-    MemAccs.push_back(new MemoryAccess(Access.first, Access.second, this));
+  for (const auto &AccessPair : *tempScop.getAccessFunctions(BB)) {
+    const IRAccess &Access = AccessPair.first;
+    Instruction *AccessInst = AccessPair.second;
+
+    const ScopArrayInfo *SAI =
+        getParent()->getOrCreateScopArrayInfo(Access, AccessInst);
+    MemAccs.push_back(new MemoryAccess(Access, AccessInst, this, SAI));
 
     // We do not track locations for scalar memory accesses at the moment.
     //
     // We do not have a use for this information at the moment. If we need this
     // at some point, the "instruction -> access" mapping needs to be enhanced
     // as a single instruction could then possibly perform multiple accesses.
-    if (!Access.first.isScalar()) {
-      assert(!InstructionToAccess.count(Access.second) &&
+    if (!Access.isScalar()) {
+      assert(!InstructionToAccess.count(AccessInst) &&
              "Unexpected 1-to-N mapping on instruction to access map!");
-      InstructionToAccess[Access.second] = MemAccs.back();
+      InstructionToAccess[AccessInst] = MemAccs.back();
     }
   }
 }
@@ -1373,6 +1424,10 @@ Scop::~Scop() {
   for (ScopStmt *Stmt : *this)
     delete Stmt;
 
+  // Free the ScopArrayInfo objects.
+  for (auto &ScopArrayInfoPair : ScopArrayInfoMap)
+    delete ScopArrayInfoPair.second;
+
   // Free the alias groups
   for (MinMaxVectorTy *MinMaxAccesses : MinMaxAliasGroups) {
     for (MinMaxAccessTy &MMA : *MinMaxAccesses) {
@@ -1383,6 +1438,26 @@ Scop::~Scop() {
   }
 }
 
+const ScopArrayInfo *Scop::getOrCreateScopArrayInfo(const IRAccess &Access,
+                                                    Instruction *AccessInst) {
+  Value *BasePtr = Access.getBase();
+  const ScopArrayInfo *&SAI = ScopArrayInfoMap[BasePtr];
+  if (!SAI) {
+    Type *AccessType = getPointerOperand(*AccessInst)->getType();
+    SAI = new ScopArrayInfo(BasePtr, AccessType, getIslCtx(), Access.Sizes);
+  }
+  return SAI;
+}
+
+const ScopArrayInfo *Scop::getScopArrayInfo(Value *BasePtr) {
+  const SCEV *PtrSCEV = SE->getSCEV(BasePtr);
+  const SCEVUnknown *PtrBaseSCEV =
+      cast<SCEVUnknown>(SE->getPointerBase(PtrSCEV));
+  const ScopArrayInfo *SAI = ScopArrayInfoMap[PtrBaseSCEV->getValue()];
+  assert(SAI && "No ScopArrayInfo available for this base pointer");
+  return SAI;
+}
+
 std::string Scop::getContextStr() const { return stringFromIslObj(Context); }
 std::string Scop::getAssumedContextStr() const {
   return stringFromIslObj(AssumedContext);

Modified: polly/trunk/lib/CodeGen/IslCodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslCodeGeneration.cpp?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslCodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/IslCodeGeneration.cpp Sun Oct  5 06:32:18 2014
@@ -23,7 +23,6 @@
 #include "polly/CodeGen/BlockGenerators.h"
 #include "polly/CodeGen/CodeGeneration.h"
 #include "polly/CodeGen/IslAst.h"
-#include "polly/CodeGen/IslExprBuilder.h"
 #include "polly/CodeGen/LoopGenerators.h"
 #include "polly/CodeGen/Utils.h"
 #include "polly/Dependences.h"

Modified: polly/trunk/lib/CodeGen/IslExprBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslExprBuilder.cpp?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslExprBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslExprBuilder.cpp Sun Oct  5 06:32:18 2014
@@ -11,6 +11,7 @@
 
 #include "polly/CodeGen/IslExprBuilder.h"
 
+#include "polly/ScopInfo.h"
 #include "polly/Support/GICHelper.h"
 
 #include "llvm/Support/Debug.h"
@@ -103,39 +104,28 @@ Value *IslExprBuilder::createAccessAddre
   assert(isl_ast_expr_get_op_n_arg(Expr) == 2 &&
          "Multidimensional access functions are not supported yet");
 
-  Value *Base, *IndexOp, *Zero, *Access;
-  SmallVector<Value *, 4> Indices;
-  Type *PtrElTy;
+  Value *Base, *IndexOp, *Access;
+  isl_ast_expr *BaseExpr;
+  isl_id *BaseId;
+
+  BaseExpr = isl_ast_expr_get_op_arg(Expr, 0);
+  BaseId = isl_ast_expr_get_id(BaseExpr);
+  isl_ast_expr_free(BaseExpr);
 
-  Base = create(isl_ast_expr_get_op_arg(Expr, 0));
+  const ScopArrayInfo *SAI = ScopArrayInfo::getFromId(BaseId);
+  Base = SAI->getBasePtr();
   assert(Base->getType()->isPointerTy() && "Access base should be a pointer");
+  const Twine &BaseName = Base->getName();
+
+  if (Base->getType() != SAI->getType())
+    Base = Builder.CreateBitCast(Base, SAI->getType(),
+                                 "polly.access.cast." + BaseName);
 
   IndexOp = create(isl_ast_expr_get_op_arg(Expr, 1));
   assert(IndexOp->getType()->isIntegerTy() &&
          "Access index should be an integer");
-  Zero = ConstantInt::getNullValue(IndexOp->getType());
-
-  // If base is a array type like,
-  //   int A[N][M][K];
-  // we have to adjust the GEP. The easiest way is to transform accesses like,
-  //   A[i][j][k]
-  // into equivalent ones like,
-  //   A[0][0][ i*N*M + j*M + k]
-  // because SCEV already folded the "peudo dimensions" into one. Thus our index
-  // operand will be 'i*N*M + j*M + k' anyway.
-  PtrElTy = Base->getType()->getPointerElementType();
-  while (PtrElTy->isArrayTy()) {
-    Indices.push_back(Zero);
-    PtrElTy = PtrElTy->getArrayElementType();
-  }
-
-  Indices.push_back(IndexOp);
-  assert((PtrElTy->isIntOrIntVectorTy() || PtrElTy->isFPOrFPVectorTy() ||
-          PtrElTy->isPtrOrPtrVectorTy()) &&
-         "We do not yet change the type of the access base during code "
-         "generation.");
 
-  Access = Builder.CreateGEP(Base, Indices, "polly.access." + Base->getName());
+  Access = Builder.CreateGEP(Base, IndexOp, "polly.access." + BaseName);
 
   isl_ast_expr_free(Expr);
   return Access;

Modified: polly/trunk/lib/Exchange/JSONExporter.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Exchange/JSONExporter.cpp?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/lib/Exchange/JSONExporter.cpp (original)
+++ polly/trunk/lib/Exchange/JSONExporter.cpp Sun Oct  5 06:32:18 2014
@@ -277,6 +277,9 @@ bool JSONImporter::runOnScop(Scop &scop)
         return false;
       }
 
+      isl_id *OutId = isl_map_get_tuple_id(currentAccessMap, isl_dim_out);
+      newAccessMap = isl_map_set_tuple_id(newAccessMap, isl_dim_out, OutId);
+
       // We keep the old alignment, thus we cannot allow accesses to memory
       // locations that were not accessed before.
       isl_set *newAccessSet = isl_map_range(isl_map_copy(newAccessMap));

Modified: polly/trunk/test/Isl/CodeGen/MemAccess/codegen_constant_offset.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/codegen_constant_offset.ll?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/codegen_constant_offset.ll (original)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/codegen_constant_offset.ll Sun Oct  5 06:32:18 2014
@@ -40,4 +40,4 @@ for.inc:
 for.end:                                          ; preds = %for.cond
   ret i32 0
 }
-; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i64 0, i64 10)
+; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i{{(32|64)}} 0, i{{(32|64)}} 10)

Modified: polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple.ll?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple.ll (original)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple.ll Sun Oct  5 06:32:18 2014
@@ -40,4 +40,4 @@ for.inc:
 for.end:                                          ; preds = %for.cond
   ret i32 0
 }
-; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i64 0, i64 0)
+; CHECK: load i32* getelementptr inbounds ([100 x i32]* @A, i{{(32|64)}} 0, i{{(32|64)}} 0)

Modified: polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_float.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_float.ll?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_float.ll (original)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_float.ll Sun Oct  5 06:32:18 2014
@@ -38,4 +38,4 @@ for.inc:
 for.end:                                          ; preds = %for.cond
   ret i32 0
 }
-; CHECK: load float* getelementptr inbounds ([100 x float]* @A, i64 0, i64 0)
+; CHECK: load float* getelementptr inbounds ([100 x float]* @A, i{{(32|64)}} 0, i{{(32|64)}} 0)

Modified: polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md.ll?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md.ll (original)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md.ll Sun Oct  5 06:32:18 2014
@@ -63,7 +63,7 @@ for.end6:
 ; WITHCONST:  %[[MUL2:[._a-zA-Z0-9]+]] = mul nsw i64 2, %[[IVIn]]
 ; WITHCONST:  %[[SUM1:[._a-zA-Z0-9]+]] = add nsw i64 %[[MUL1]], %[[MUL2]]
 ; WITHCONST:  %[[SUM2:[._a-zA-Z0-9]+]] = add nsw i64 %[[SUM1]], 5
-; WITHCONST:  %[[ACC:[._a-zA-Z0-9]*]] = getelementptr [1040 x i32]* @A, i64 0, i64 %[[SUM2]]
+; WITHCONST:  %[[ACC:[._a-zA-Z0-9]*]] = getelementptr i32* getelementptr inbounds ([1040 x i32]* @A, i{{(32|64)}} 0, i{{(32|64)}} 0), i64 %[[SUM2]]
 ; WITHCONST:  store i32 100, i32* %[[ACC]]
 
 ; WITHOUTCONST:  %[[IVOut:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ]
@@ -71,5 +71,5 @@ for.end6:
 ; WITHOUTCONST:  %[[MUL1:[._a-zA-Z0-9]+]] = mul nsw i64 16, %[[IVOut]]
 ; WITHOUTCONST:  %[[MUL2:[._a-zA-Z0-9]+]] = mul nsw i64 2, %[[IVIn]]
 ; WITHOUTCONST:  %[[SUM1:[._a-zA-Z0-9]+]] = add nsw i64 %[[MUL1]], %[[MUL2]]
-; WITHOUTCONST:  %[[ACC:[._a-zA-Z0-9]*]] = getelementptr [1040 x i32]* @A, i64 0, i64 %[[SUM1]]
+; WITHOUTCONST:  %[[ACC:[._a-zA-Z0-9]*]] = getelementptr i32* getelementptr inbounds ([1040 x i32]* @A, i{{(32|64)}} 0, i{{(32|64)}} 0), i64 %[[SUM1]]
 ; WITHOUTCONST:  store i32 100, i32* %[[ACC]]

Modified: polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll?rev=219077&r1=219076&r2=219077&view=diff
==============================================================================
--- polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll (original)
+++ polly/trunk/test/Isl/CodeGen/MemAccess/codegen_simple_md_float.ll Sun Oct  5 06:32:18 2014
@@ -59,7 +59,7 @@ for.end6:
 ; WITHCONST:  %[[MUL2:[._a-zA-Z0-9]+]] = mul nsw i64 2, %[[IVIn]]
 ; WITHCONST:  %[[SUM1:[._a-zA-Z0-9]+]] = add nsw i64 %[[MUL1]], %[[MUL2]]
 ; WITHCONST:  %[[SUM2:[._a-zA-Z0-9]+]] = add nsw i64 %[[SUM1]], 5
-; WITHCONST:  %[[ACC:[._a-zA-Z0-9]*]] = getelementptr [1040 x float]* @A, i64 0, i64 %[[SUM2]]
+; WITHCONST:  %[[ACC:[._a-zA-Z0-9]*]] = getelementptr float* getelementptr inbounds ([1040 x float]* @A, i{{(32|64)}} 0, i{{(32|64)}} 0), i64 %[[SUM2]]
 ; WITHCONST:  store float 1.000000e+02, float* %[[ACC]]
 
 ; WITHOUTCONST:  %[[IVOut:polly.indvar[0-9]*]] = phi i64 [ 0, %polly.loop_preheader{{[0-9]*}} ], [ %polly.indvar_next{{[0-9]*}}, %polly.{{[._a-zA-Z0-9]*}} ]
@@ -67,5 +67,5 @@ for.end6:
 ; WITHOUTCONST:  %[[MUL1:[._a-zA-Z0-9]+]] = mul nsw i64 16, %[[IVOut]]
 ; WITHOUTCONST:  %[[MUL2:[._a-zA-Z0-9]+]] = mul nsw i64 2, %[[IVIn]]
 ; WITHOUTCONST:  %[[SUM1:[._a-zA-Z0-9]+]] = add nsw i64 %[[MUL1]], %[[MUL2]]
-; WITHOUTCONST:  %[[ACC:[._a-zA-Z0-9]*]] = getelementptr [1040 x float]* @A, i64 0, i64 %[[SUM1]]
+; WITHOUTCONST:  %[[ACC:[._a-zA-Z0-9]*]] = getelementptr float* getelementptr inbounds ([1040 x float]* @A, i{{(32|64)}} 0, i{{(32|64)}} 0), i64 %[[SUM1]]
 ; WITHOUTCONST:  store float 1.000000e+02, float* %[[ACC]]

Added: polly/trunk/test/Isl/CodeGen/aliasing_different_base_and_access_type.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/aliasing_different_base_and_access_type.ll?rev=219077&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/aliasing_different_base_and_access_type.ll (added)
+++ polly/trunk/test/Isl/CodeGen/aliasing_different_base_and_access_type.ll Sun Oct  5 06:32:18 2014
@@ -0,0 +1,44 @@
+; RUN: opt %loadPolly -S -polly-code-generator=isl -polly-codegen-isl < %s | FileCheck %s
+;
+; We have to cast %B to "short *" before we create RTCs.
+;
+; CHECK:      entry:
+; CHECK-NEXT:   %polly.access.cast.B = bitcast i32* %B to i16*
+; CHECK-NEXT:   %polly.access.B = getelementptr i16* %polly.access.cast.B, i64 1024
+;
+; We should never access %B as an i32 pointer:
+;
+; CHECK-NOT: getelementptr i32* %B
+;
+;    void jd(int *A, int *B) {
+;      for (int i = 0; i < 1024; i++)
+;        A[i] = ((short *)B)[i];
+;    }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @jd(i32* %A, i32* %B) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvars.iv, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %tmp = bitcast i32* %B to i16*
+  %arrayidx = getelementptr inbounds i16* %tmp, i64 %indvars.iv
+  %tmp1 = load i16* %arrayidx, align 2
+  %conv = sext i16 %tmp1 to i32
+  %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv
+  store i32 %conv, i32* %arrayidx2, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}

Added: polly/trunk/test/Isl/CodeGen/aliasing_struct_element.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/aliasing_struct_element.ll?rev=219077&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/aliasing_struct_element.ll (added)
+++ polly/trunk/test/Isl/CodeGen/aliasing_struct_element.ll Sun Oct  5 06:32:18 2014
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -S -polly-code-generator=isl -polly-codegen-isl < %s | FileCheck %s
+;
+; We should only access (or compute the address of) "the first element" of %S
+; as it is a single struct not a struct array. The maximal access to S, thus
+; S->B[1023] is for ScalarEvolution an access with offset of 1423, 1023 for the
+; index inside the B part of S and 400 to skip the Dummy array in S. Note that
+; these numbers are relative to the actual type of &S->B[i] (char*) not to the
+; type of S (struct st *) or something else.
+;
+; Verify that we do not use the offset 1423 into a non existent S array when we
+; compute runtime alias checks but treat it as if it was a char array.
+;
+; CHECK: %polly.access.cast.S = bitcast %struct.st* %S to i8*
+; CHECK: %polly.access.S = getelementptr i8* %polly.access.cast.S, i64 1424
+;
+;    struct st {
+;      int Dummy[100];
+;      char B[100];
+;    };
+;
+;    void jd(int *A, struct st *S) {
+;      for (int i = 0; i < 1024; i++)
+;        A[i] = S->B[i];
+;    }
+;
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+%struct.st = type { [100 x i32], [100 x i8] }
+
+define void @jd(i32* %A, %struct.st* %S) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.inc, %entry
+  %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc ], [ 0, %entry ]
+  %exitcond = icmp ne i64 %indvars.iv, 1024
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds %struct.st* %S, i64 0, i32 1, i64 %indvars.iv
+  %tmp = load i8* %arrayidx, align 1
+  %conv = sext i8 %tmp to i32
+  %arrayidx2 = getelementptr inbounds i32* %A, i64 %indvars.iv
+  store i32 %conv, i32* %arrayidx2, align 4
+  br label %for.inc
+
+for.inc:                                          ; preds = %for.body
+  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}





More information about the llvm-commits mailing list