[polly] r303517 - [CodeGen] Support partial write accesses.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Sun May 21 15:46:57 PDT 2017


Author: meinersbur
Date: Sun May 21 17:46:57 2017
New Revision: 303517

URL: http://llvm.org/viewvc/llvm-project?rev=303517&view=rev
Log:
[CodeGen] Support partial write accesses.

Allow the BlockGenerator to generate memory writes that are not defined
over the complete statement domain, but only over a subset of it. It
generates a condition that evaluates to 1 if executing the subdomain,
and only then execute the access.

Only write accesses are supported. Read accesses would require a PHINode
which has a value if the access is not executed.

Partial write makes DeLICM able to apply mappings that are not defined
over the entire domain (for instance, a branch that leaves a loop with
a PHINode in its header; a MemoryKind::PHI write when leaving is never
read by its PHI read).

Differential Revision: https://reviews.llvm.org/D33255

Added:
    polly/trunk/test/Isl/CodeGen/partial_write_array.ll
    polly/trunk/test/Isl/CodeGen/partial_write_array___%for---%return.jscop
    polly/trunk/test/Isl/CodeGen/partial_write_array___%for---%return.jscop.transformed
    polly/trunk/test/Isl/CodeGen/partial_write_emptyset.ll
    polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%for---%return.jscop
    polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%for---%return.jscop.transformed
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar.ll
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%for---%return.jscop
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%for---%return.jscop.transformed
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion.ll
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%for---%return.jscop
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%for---%return.jscop.transformed
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector.ll
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%for---%return.jscop
    polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%for---%return.jscop.transformed
Modified:
    polly/trunk/include/polly/CodeGen/BlockGenerators.h
    polly/trunk/include/polly/ScopInfo.h
    polly/trunk/lib/Analysis/ScopInfo.cpp
    polly/trunk/lib/CodeGen/BlockGenerators.cpp
    polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
    polly/trunk/lib/Exchange/JSONExporter.cpp

Modified: polly/trunk/include/polly/CodeGen/BlockGenerators.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/BlockGenerators.h?rev=303517&r1=303516&r2=303517&view=diff
==============================================================================
--- polly/trunk/include/polly/CodeGen/BlockGenerators.h (original)
+++ polly/trunk/include/polly/CodeGen/BlockGenerators.h Sun May 21 17:46:57 2017
@@ -17,6 +17,7 @@
 #define POLLY_BLOCK_GENERATORS_H
 
 #include "polly/CodeGen/IRBuilder.h"
+#include "polly/Support/GICHelper.h"
 #include "polly/Support/ScopHelper.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
@@ -328,6 +329,33 @@ protected:
                            ValueMapT &BBMap,
                            __isl_keep isl_id_to_ast_expr *NewAccesses);
 
+  /// Generate instructions that compute whether one instance of @p Set is
+  /// executed.
+  ///
+  /// @param Stmt      The statement we generate code for.
+  /// @param Subdomain A set in the space of @p Stmt's domain. Elements not in
+  ///                  @p Stmt's domain are ignored.
+  ///
+  /// @return An expression of type i1, generated into the current builder
+  ///         position, that evaluates to 1 if the executed instance is part of
+  ///         @p Set.
+  Value *buildContainsCondition(ScopStmt &Stmt, const isl::set &Subdomain);
+
+  /// Generate code that executes in a subset of @p Stmt's domain.
+  ///
+  /// @param Stmt        The statement we generate code for.
+  /// @param Subdomain   The condition for some code to be executed.
+  /// @param Subject     A name for the code that is executed
+  ///                    conditionally. Used to name new basic blocks and
+  ///                    instructions.
+  /// @param GenThenFunc Callback which generates the code to be executed
+  ///                    when the current executed instance is in @p Set. The
+  ///                    IRBuilder's position is moved to within the block that
+  ///                    executes conditionally for this callback.
+  void generateConditionalExecution(ScopStmt &Stmt, const isl::set &Subdomain,
+                                    StringRef Subject,
+                                    const std::function<void()> &GenThenFunc);
+
   /// Generate the scalar stores for the given statement.
   ///
   /// After the statement @p Stmt was copied all inner-SCoP scalar dependences

Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=303517&r1=303516&r2=303517&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Sun May 21 17:46:57 2017
@@ -1043,6 +1043,10 @@ public:
   /// Set the updated access relation read from JSCOP file.
   void setNewAccessRelation(__isl_take isl_map *NewAccessRelation);
 
+  /// Return whether the MemoryyAccess is a partial access. That is, the access
+  /// is not executed in some instances of the parent statement's domain.
+  bool isLatestPartialAccess() const;
+
   /// Mark this a reduction like access
   void markAsReductionLike(ReductionType RT) { RedType = RT; }
 

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=303517&r1=303516&r2=303517&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Sun May 21 17:46:57 2017
@@ -1204,15 +1204,19 @@ void MemoryAccess::setNewAccessRelation(
   isl_space_free(NewDomainSpace);
   isl_space_free(OriginalDomainSpace);
 
-  // Check whether there is an access for every statement instance.
-  auto *StmtDomain = getStatement()->getDomain();
-  StmtDomain = isl_set_intersect_params(
-      StmtDomain, getStatement()->getParent()->getContext());
-  auto *NewDomain = isl_map_domain(isl_map_copy(NewAccess));
-  assert(isl_set_is_subset(StmtDomain, NewDomain) &&
-         "Partial accesses not supported");
-  isl_set_free(NewDomain);
-  isl_set_free(StmtDomain);
+  // Reads must be executed unconditionally. Writes might be executed in a
+  // subdomain only.
+  if (isRead()) {
+    // Check whether there is an access for every statement instance.
+    auto *StmtDomain = getStatement()->getDomain();
+    StmtDomain = isl_set_intersect_params(
+        StmtDomain, getStatement()->getParent()->getContext());
+    auto *NewDomain = isl_map_domain(isl_map_copy(NewAccess));
+    assert(isl_set_is_subset(StmtDomain, NewDomain) &&
+           "Partial READ accesses not supported");
+    isl_set_free(NewDomain);
+    isl_set_free(StmtDomain);
+  }
 
   auto *NewAccessSpace = isl_space_range(NewSpace);
   assert(isl_space_has_tuple_id(NewAccessSpace, isl_dim_set) &&
@@ -1243,6 +1247,13 @@ void MemoryAccess::setNewAccessRelation(
   NewAccessRelation = NewAccess;
 }
 
+bool MemoryAccess::isLatestPartialAccess() const {
+  isl::set StmtDom = give(getStatement()->getDomain());
+  isl::set AccDom = give(isl_map_domain(getLatestAccessRelation()));
+
+  return isl_set_is_subset(StmtDom.keep(), AccDom.keep()) == isl_bool_false;
+}
+
 //===----------------------------------------------------------------------===//
 
 __isl_give isl_map *ScopStmt::getSchedule() const {

Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=303517&r1=303516&r2=303517&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Sun May 21 17:46:57 2017
@@ -318,16 +318,22 @@ Value *BlockGenerator::generateArrayLoad
 void BlockGenerator::generateArrayStore(ScopStmt &Stmt, StoreInst *Store,
                                         ValueMapT &BBMap, LoopToScevMapT &LTS,
                                         isl_id_to_ast_expr *NewAccesses) {
-  Value *NewPointer =
-      generateLocationAccessed(Stmt, Store, BBMap, LTS, NewAccesses);
-  Value *ValueOperand = getNewValue(Stmt, Store->getValueOperand(), BBMap, LTS,
-                                    getLoopForStmt(Stmt));
-
-  if (PollyDebugPrinting)
-    RuntimeDebugBuilder::createCPUPrinter(Builder, "Store to  ", NewPointer,
-                                          ": ", ValueOperand, "\n");
+  MemoryAccess &MA = Stmt.getArrayAccessFor(Store);
+  isl::set AccDom = give(isl_map_domain(MA.getAccessRelation()));
+  const char *Subject = isl_id_get_name(give(MA.getId()).keep());
+
+  generateConditionalExecution(Stmt, AccDom, Subject, [&, this]() {
+    Value *NewPointer =
+        generateLocationAccessed(Stmt, Store, BBMap, LTS, NewAccesses);
+    Value *ValueOperand = getNewValue(Stmt, Store->getValueOperand(), BBMap,
+                                      LTS, getLoopForStmt(Stmt));
+
+    if (PollyDebugPrinting)
+      RuntimeDebugBuilder::createCPUPrinter(Builder, "Store to  ", NewPointer,
+                                            ": ", ValueOperand, "\n");
 
-  Builder.CreateAlignedStore(ValueOperand, NewPointer, Store->getAlignment());
+    Builder.CreateAlignedStore(ValueOperand, NewPointer, Store->getAlignment());
+  });
 }
 
 bool BlockGenerator::canSyntheziseInStmt(ScopStmt &Stmt, Instruction *Inst) {
@@ -553,6 +559,79 @@ void BlockGenerator::generateScalarLoads
   }
 }
 
+Value *BlockGenerator::buildContainsCondition(ScopStmt &Stmt,
+                                              const isl::set &Subdomain) {
+  isl::ast_build AstBuild = give(isl_ast_build_copy(Stmt.getAstBuild()));
+  isl::set Domain = give(Stmt.getDomain());
+  isl::union_set UDomain = give(isl_union_set_from_set(Domain.copy()));
+
+  isl::union_map USchedule = give(isl_ast_build_get_schedule(AstBuild.keep()));
+  USchedule =
+      give(isl_union_map_intersect_domain(USchedule.take(), UDomain.copy()));
+  assert(isl_union_map_is_empty(USchedule.keep()) == isl_bool_false);
+  isl::map Schedule = give(isl_map_from_union_map(USchedule.copy()));
+
+  isl::set ScheduledDomain = give(isl_map_range(Schedule.copy()));
+  isl::set ScheduledSet =
+      give(isl_set_apply(Subdomain.copy(), Schedule.copy()));
+
+  isl::ast_build RestrictedBuild =
+      give(isl_ast_build_restrict(AstBuild.copy(), ScheduledDomain.copy()));
+
+  isl::ast_expr IsInSet = give(
+      isl_ast_build_expr_from_set(RestrictedBuild.keep(), ScheduledSet.copy()));
+  Value *IsInSetExpr = ExprBuilder->create(IsInSet.copy());
+  IsInSetExpr = Builder.CreateICmpNE(
+      IsInSetExpr, ConstantInt::get(IsInSetExpr->getType(), 0));
+
+  return IsInSetExpr;
+}
+
+void BlockGenerator::generateConditionalExecution(
+    ScopStmt &Stmt, const isl::set &Subdomain, StringRef Subject,
+    const std::function<void()> &GenThenFunc) {
+  isl::set StmtDom = give(Stmt.getDomain());
+
+  // Don't call GenThenFunc if it is never executed. An ast index expression
+  // might not be defined in this case.
+  bool IsEmpty = isl_set_is_empty(Subdomain.keep()) == isl_bool_true;
+  if (IsEmpty)
+    return;
+
+  // If the condition is a tautology, don't generate a condition around the
+  // code.
+  bool IsPartial =
+      isl_set_is_subset(StmtDom.keep(), Subdomain.keep()) == isl_bool_false;
+  if (!IsPartial) {
+    GenThenFunc();
+    return;
+  }
+
+  // Generate the condition.
+  Value *Cond = buildContainsCondition(Stmt, Subdomain);
+  BasicBlock *HeadBlock = Builder.GetInsertBlock();
+  StringRef BlockName = HeadBlock->getName();
+
+  // Generate the conditional block.
+  SplitBlockAndInsertIfThen(Cond, &*Builder.GetInsertPoint(), false, nullptr,
+                            &DT, &LI);
+  BranchInst *Branch = cast<BranchInst>(HeadBlock->getTerminator());
+  BasicBlock *ThenBlock = Branch->getSuccessor(0);
+  BasicBlock *TailBlock = Branch->getSuccessor(1);
+
+  // Assign descriptive names.
+  if (auto *CondInst = dyn_cast<Instruction>(Cond))
+    CondInst->setName("polly." + Subject + ".cond");
+  ThenBlock->setName(BlockName + "." + Subject + ".partial");
+  TailBlock->setName(BlockName + ".cont");
+
+  // Put the client code into the conditional block and continue in the merge
+  // block afterwards.
+  Builder.SetInsertPoint(ThenBlock, ThenBlock->getFirstInsertionPt());
+  GenThenFunc();
+  Builder.SetInsertPoint(TailBlock, TailBlock->getFirstInsertionPt());
+}
+
 void BlockGenerator::generateScalarStores(
     ScopStmt &Stmt, LoopToScevMapT &LTS, ValueMapT &BBMap,
     __isl_keep isl_id_to_ast_expr *NewAccesses) {
@@ -566,40 +645,38 @@ void BlockGenerator::generateScalarStore
     if (MA->isOriginalArrayKind() || MA->isRead())
       continue;
 
-#ifndef NDEBUG
-    auto *StmtDom = Stmt.getDomain();
-    auto *AccDom = isl_map_domain(MA->getAccessRelation());
-    assert(isl_set_is_subset(StmtDom, AccDom) &&
-           "Scalar must be stored in all statement instances");
-    isl_set_free(StmtDom);
-    isl_set_free(AccDom);
-#endif
+    isl::set AccDom = give(isl_map_domain(MA->getAccessRelation()));
+    const char *Subject = isl_id_get_name(give(MA->getId()).keep());
 
-    Value *Val = MA->getAccessValue();
-    if (MA->isAnyPHIKind()) {
-      assert(MA->getIncoming().size() >= 1 &&
-             "Block statements have exactly one exiting block, or multiple but "
-             "with same incoming block and value");
-      assert(std::all_of(MA->getIncoming().begin(), MA->getIncoming().end(),
-                         [&](std::pair<BasicBlock *, Value *> p) -> bool {
-                           return p.first == Stmt.getBasicBlock();
-                         }) &&
-             "Incoming block must be statement's block");
-      Val = MA->getIncoming()[0].second;
-    }
-    auto Address =
-        getImplicitAddress(*MA, getLoopForStmt(Stmt), LTS, BBMap, NewAccesses);
+    generateConditionalExecution(Stmt, AccDom, Subject, [&, this, MA]() {
+      Value *Val = MA->getAccessValue();
+      if (MA->isAnyPHIKind()) {
+        assert(
+            MA->getIncoming().size() >= 1 &&
+            "Block statements have exactly one exiting block, or multiple but "
+            "with same incoming block and value");
+        assert(std::all_of(MA->getIncoming().begin(), MA->getIncoming().end(),
+                           [&](std::pair<BasicBlock *, Value *> p) -> bool {
+                             return p.first == Stmt.getBasicBlock();
+                           }) &&
+               "Incoming block must be statement's block");
+        Val = MA->getIncoming()[0].second;
+      }
+      auto Address = getImplicitAddress(*MA, getLoopForStmt(Stmt), LTS, BBMap,
+                                        NewAccesses);
 
-    Val = getNewValue(Stmt, Val, BBMap, LTS, L);
-    assert((!isa<Instruction>(Val) ||
-            DT.dominates(cast<Instruction>(Val)->getParent(),
-                         Builder.GetInsertBlock())) &&
-           "Domination violation");
-    assert((!isa<Instruction>(Address) ||
-            DT.dominates(cast<Instruction>(Address)->getParent(),
-                         Builder.GetInsertBlock())) &&
-           "Domination violation");
-    Builder.CreateStore(Val, Address);
+      Val = getNewValue(Stmt, Val, BBMap, LTS, L);
+      assert((!isa<Instruction>(Val) ||
+              DT.dominates(cast<Instruction>(Val)->getParent(),
+                           Builder.GetInsertBlock())) &&
+             "Domination violation");
+      assert((!isa<Instruction>(Address) ||
+              DT.dominates(cast<Instruction>(Address)->getParent(),
+                           Builder.GetInsertBlock())) &&
+             "Domination violation");
+      Builder.CreateStore(Val, Address);
+
+    });
   }
 }
 
@@ -1470,18 +1547,23 @@ void RegionGenerator::generateScalarStor
     if (MA->isOriginalArrayKind() || MA->isRead())
       continue;
 
-    Value *NewVal = getExitScalar(MA, LTS, BBMap);
-    Value *Address =
-        getImplicitAddress(*MA, getLoopForStmt(Stmt), LTS, BBMap, NewAccesses);
-    assert((!isa<Instruction>(NewVal) ||
-            DT.dominates(cast<Instruction>(NewVal)->getParent(),
-                         Builder.GetInsertBlock())) &&
-           "Domination violation");
-    assert((!isa<Instruction>(Address) ||
-            DT.dominates(cast<Instruction>(Address)->getParent(),
-                         Builder.GetInsertBlock())) &&
-           "Domination violation");
-    Builder.CreateStore(NewVal, Address);
+    isl::set AccDom = give(isl_map_domain(MA->getAccessRelation()));
+    const char *Subject = isl_id_get_name(give(MA->getId()).keep());
+    generateConditionalExecution(Stmt, AccDom, Subject, [&, this, MA]() {
+
+      Value *NewVal = getExitScalar(MA, LTS, BBMap);
+      Value *Address = getImplicitAddress(*MA, getLoopForStmt(Stmt), LTS, BBMap,
+                                          NewAccesses);
+      assert((!isa<Instruction>(NewVal) ||
+              DT.dominates(cast<Instruction>(NewVal)->getParent(),
+                           Builder.GetInsertBlock())) &&
+             "Domination violation");
+      assert((!isa<Instruction>(Address) ||
+              DT.dominates(cast<Instruction>(Address)->getParent(),
+                           Builder.GetInsertBlock())) &&
+             "Domination violation");
+      Builder.CreateStore(NewVal, Address);
+    });
   }
 }
 

Modified: polly/trunk/lib/CodeGen/IslNodeBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslNodeBuilder.cpp?rev=303517&r1=303516&r2=303517&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslNodeBuilder.cpp (original)
+++ polly/trunk/lib/CodeGen/IslNodeBuilder.cpp Sun May 21 17:46:57 2017
@@ -667,13 +667,40 @@ void IslNodeBuilder::createForParallel(_
   isl_id_free(IteratorID);
 }
 
+/// Return whether any of @p Node's statements contain partial accesses.
+///
+/// Partial accesses are not supported by Polly's vector code generator.
+static bool hasPartialAccesses(__isl_take isl_ast_node *Node) {
+  return isl_ast_node_foreach_descendant_top_down(
+             Node,
+             [](isl_ast_node *Node, void *User) -> isl_bool {
+               if (isl_ast_node_get_type(Node) != isl_ast_node_user)
+                 return isl_bool_true;
+
+               isl::ast_expr Expr = give(isl_ast_node_user_get_expr(Node));
+               isl::ast_expr StmtExpr =
+                   give(isl_ast_expr_get_op_arg(Expr.keep(), 0));
+               isl::id Id = give(isl_ast_expr_get_id(StmtExpr.keep()));
+
+               ScopStmt *Stmt =
+                   static_cast<ScopStmt *>(isl_id_get_user(Id.keep()));
+               isl::set StmtDom = give(Stmt->getDomain());
+               for (auto *MA : *Stmt) {
+                 if (MA->isLatestPartialAccess())
+                   return isl_bool_error;
+               }
+               return isl_bool_true;
+             },
+             nullptr) == isl_stat_error;
+}
+
 void IslNodeBuilder::createFor(__isl_take isl_ast_node *For) {
   bool Vector = PollyVectorizerChoice == VECTORIZER_POLLY;
 
   if (Vector && IslAstInfo::isInnermostParallel(For) &&
       !IslAstInfo::isReductionParallel(For)) {
     int VectorWidth = getNumberOfIterations(For);
-    if (1 < VectorWidth && VectorWidth <= 16) {
+    if (1 < VectorWidth && VectorWidth <= 16 && !hasPartialAccesses(For)) {
       createForVector(For, VectorWidth);
       return;
     }
@@ -765,24 +792,34 @@ IslNodeBuilder::createNewAccesses(ScopSt
     auto Schedule = isl_ast_build_get_schedule(Build);
 
 #ifndef NDEBUG
-    auto Dom = Stmt->getDomain();
-    auto SchedDom = isl_set_from_union_set(
-        isl_union_map_domain(isl_union_map_copy(Schedule)));
-    auto AccDom = isl_map_domain(MA->getAccessRelation());
-    Dom = isl_set_intersect_params(Dom, Stmt->getParent()->getContext());
-    SchedDom =
-        isl_set_intersect_params(SchedDom, Stmt->getParent()->getContext());
-    assert(isl_set_is_subset(SchedDom, AccDom) &&
-           "Access relation not defined on full schedule domain");
-    assert(isl_set_is_subset(Dom, AccDom) &&
-           "Access relation not defined on full domain");
-    isl_set_free(AccDom);
-    isl_set_free(SchedDom);
-    isl_set_free(Dom);
+    if (MA->isRead()) {
+      auto Dom = Stmt->getDomain();
+      auto SchedDom = isl_set_from_union_set(
+          isl_union_map_domain(isl_union_map_copy(Schedule)));
+      auto AccDom = isl_map_domain(MA->getAccessRelation());
+      Dom = isl_set_intersect_params(Dom, Stmt->getParent()->getContext());
+      SchedDom =
+          isl_set_intersect_params(SchedDom, Stmt->getParent()->getContext());
+      assert(isl_set_is_subset(SchedDom, AccDom) &&
+             "Access relation not defined on full schedule domain");
+      assert(isl_set_is_subset(Dom, AccDom) &&
+             "Access relation not defined on full domain");
+      isl_set_free(AccDom);
+      isl_set_free(SchedDom);
+      isl_set_free(Dom);
+    }
 #endif
 
     auto PWAccRel = MA->applyScheduleToAccessRelation(Schedule);
 
+    // isl cannot generate an index expression for access-nothing accesses.
+    isl::set AccDomain =
+        give(isl_pw_multi_aff_domain(isl_pw_multi_aff_copy(PWAccRel)));
+    if (isl_set_is_empty(AccDomain.keep()) == isl_bool_true) {
+      isl_pw_multi_aff_free(PWAccRel);
+      continue;
+    }
+
     auto AccessExpr = isl_ast_build_access_from_pw_multi_aff(Build, PWAccRel);
     NewAccesses = isl_id_to_ast_expr_set(NewAccesses, MA->getId(), AccessExpr);
   }

Modified: polly/trunk/lib/Exchange/JSONExporter.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Exchange/JSONExporter.cpp?rev=303517&r1=303516&r2=303517&view=diff
==============================================================================
--- polly/trunk/lib/Exchange/JSONExporter.cpp (original)
+++ polly/trunk/lib/Exchange/JSONExporter.cpp Sun May 21 17:46:57 2017
@@ -446,8 +446,9 @@ bool JSONImporter::importAccesses(Scop &
       CurrentAccessDomain =
           isl_set_intersect_params(CurrentAccessDomain, S.getContext());
 
-      if (isl_set_is_subset(CurrentAccessDomain, NewAccessDomain) ==
-          isl_bool_false) {
+      if (MA->isRead() &&
+          isl_set_is_subset(CurrentAccessDomain, NewAccessDomain) ==
+              isl_bool_false) {
         errs() << "Mapping not defined for all iteration domain elements\n";
         isl_set_free(CurrentAccessDomain);
         isl_set_free(NewAccessDomain);

Added: polly/trunk/test/Isl/CodeGen/partial_write_array.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_array.ll?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_array.ll (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_array.ll Sun May 21 17:46:57 2017
@@ -0,0 +1,44 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-codegen -S < %s | FileCheck %s
+;
+; Partial write of an array access.
+;
+; for (int j = 0; j < n; j += 1)
+;   A[0] = 42.0
+;
+
+define void @partial_write_array(i32 %n, double* noalias nonnull %A) {
+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:
+      store double 42.0, double* %A
+      br label %inc
+
+inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %for
+
+exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK:      polly.stmt.body:
+; CHECK-NEXT:   %1 = icmp sge i64 %polly.indvar, 5
+; CHECK-NEXT:   %polly.Stmt_body_Write0.cond = icmp ne i1 %1, false
+; CHECK-NEXT:   br i1 %polly.Stmt_body_Write0.cond, label %polly.stmt.body.Stmt_body_Write0.partial, label %polly.stmt.body.cont
+
+; CHECK:      polly.stmt.body.Stmt_body_Write0.partial:
+; CHECK-NEXT:   %polly.access.A = getelementptr double, double* %A, i64 0
+; CHECK-NEXT:   store double 4.200000e+01, double* %polly.access.A, !alias.scope !0, !noalias !2
+; CHECK-NEXT:   br label %polly.stmt.body.cont
+
+; CHECK:      polly.stmt.body.cont:

Added: polly/trunk/test/Isl/CodeGen/partial_write_array___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_array___%25for---%25return.jscop?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_array___%for---%return.jscop (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_array___%for---%return.jscop Sun May 21 17:46:57 2017
@@ -0,0 +1,24 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "[n] -> {  : -2147483648 <= n <= 2147483647 }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+         "name" : "Stmt_body",
+         "schedule" : "[n] -> { Stmt_body[i0] -> [i0] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_array___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_array___%25for---%25return.jscop.transformed?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_array___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_array___%for---%return.jscop.transformed Sun May 21 17:46:57 2017
@@ -0,0 +1,24 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "[n] -> {  : -2147483648 <= n <= 2147483647 }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_body[j] -> MemRef_A[0] : j >= 5 }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+         "name" : "Stmt_body",
+         "schedule" : "[n] -> { Stmt_body[i0] -> [i0] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_emptyset.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_emptyset.ll?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_emptyset.ll (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_emptyset.ll Sun May 21 17:46:57 2017
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-codegen -S < %s | FileCheck %s
+;
+; Partial write, where "partial" is the empty set.
+; The store is never executed in this case and we do generate it in the
+; first place.
+;
+; for (int j = 0; j < n; j += 1)
+;   A[0] = 42.0
+;
+
+define void @partial_write_emptyset(i32 %n, double* noalias nonnull %A) {
+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:
+      store double 42.0, double* %A
+      br label %inc
+
+inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %for
+
+exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK-LABEL: polly.stmt.body:
+; CHECK-NOT:     store

Added: polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%25for---%25return.jscop?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%for---%return.jscop (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%for---%return.jscop Sun May 21 17:46:57 2017
@@ -0,0 +1,24 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "[n] -> {  : -2147483648 <= n <= 2147483647 }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+         "name" : "Stmt_body",
+         "schedule" : "[n] -> { Stmt_body[i0] -> [i0] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%25for---%25return.jscop.transformed?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_emptyset___%for---%return.jscop.transformed Sun May 21 17:46:57 2017
@@ -0,0 +1,24 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "[n] -> {  : -2147483648 <= n <= 2147483647 }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_body[j] -> MemRef_A[0] : 1 = 0 }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+         "name" : "Stmt_body",
+         "schedule" : "[n] -> { Stmt_body[i0] -> [i0] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar.ll?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar.ll (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar.ll Sun May 21 17:46:57 2017
@@ -0,0 +1,57 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-codegen -S < %s | FileCheck %s
+;
+; Partial write of a (mapped) scalar.
+;
+; for (int j = 0; j < n; j += 1) {
+;body:
+;   val = 21.0 + 21.0;
+;   if (j >= 5)
+;user:
+;     A[0] = val;
+; }
+
+define void @partial_write_mapped_scalar(i32 %n, double* noalias nonnull %A) {
+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:
+      %val = fadd double 21.0, 21.0
+      %if.cond = icmp sgt i32 %j, 5
+      br i1 %if.cond, label %user, label %inc
+
+    user:
+      store double %val, double* %A
+      br label %inc
+
+inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %for
+
+exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK:      polly.stmt.body:
+; CHECK-NEXT:   %p_val = fadd double 2.100000e+01, 2.100000e+01
+; CHECK-NEXT:   %1 = trunc i64 %polly.indvar to i32
+; CHECK-NEXT:   %p_if.cond = icmp sgt i32 %1, 5
+; CHECK-NEXT:   %2 = icmp sge i64 %polly.indvar, 5
+; CHECK-NEXT:   %polly.Stmt_body_Write0.cond = icmp ne i1 %2, false
+; CHECK-NEXT:   br i1 %polly.Stmt_body_Write0.cond, label %polly.stmt.body.Stmt_body_Write0.partial, label %polly.stmt.body.cont
+
+; CHECK:      polly.stmt.body.Stmt_body_Write0.partial:
+; CHECK-NEXT:   %polly.access.A = getelementptr double, double* %A, i64 1
+; CHECK-NEXT:   store double %p_val, double* %polly.access.A
+; CHECK-NEXT:   br label %polly.stmt.body.cont
+
+; CHECK:      polly.stmt.body.cont:
+; CHECK-NEXT:   br label %polly.cond

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%25for---%25return.jscop?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%for---%return.jscop (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%for---%return.jscop Sun May 21 17:46:57 2017
@@ -0,0 +1,39 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "[n] -> {  : -2147483648 <= n <= 2147483647 }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_body[i0] -> MemRef_val[] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+         "name" : "Stmt_body",
+         "schedule" : "[n] -> { Stmt_body[i0] -> [i0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_user[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_user[i0] -> MemRef_val[] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_user[i0] : 6 <= i0 < n }",
+         "name" : "Stmt_user",
+         "schedule" : "[n] -> { Stmt_user[i0] -> [i0, 1] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%25for---%25return.jscop.transformed?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar___%for---%return.jscop.transformed Sun May 21 17:46:57 2017
@@ -0,0 +1,39 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "[n] -> {  : -2147483648 <= n <= 2147483647 }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_body[j] -> MemRef_A[1] : j >= 5 }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+         "name" : "Stmt_body",
+         "schedule" : "[n] -> { Stmt_body[i0] -> [i0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_user[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_user[j] -> MemRef_A[1] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_user[i0] : 6 <= i0 < n }",
+         "name" : "Stmt_user",
+         "schedule" : "[n] -> { Stmt_user[i0] -> [i0, 1] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion.ll?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion.ll (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion.ll Sun May 21 17:46:57 2017
@@ -0,0 +1,64 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-codegen -S < %s | FileCheck %s
+;
+; Partial write of a (mapped) scalar in a non-affine subregion.
+;
+; for (int j = 0; j < n; j += 1) {
+;subregion:
+;   val = 21.0 + 21.0;
+;   if (undef > undef)
+;subregion_true: ;
+;
+;subregion_exit:
+;   if (j >= 5)
+;user:
+;     A[0] = val;
+; }
+
+define void @partial_write_mapped_scalar_subregion(i32 %n, double* noalias nonnull %A) {
+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 %subregion, label %exit
+
+    subregion:
+      %val = fadd double 21.0, 21.0
+      %nonaffine.cond = fcmp ogt double undef, undef
+      br i1 %nonaffine.cond, label %subregion_true, label %subregion_exit
+
+    subregion_true:
+      br label %subregion_exit
+
+    subregion_exit:
+      %if.cond = icmp sgt i32 %j, 5
+      br i1 %if.cond, label %user, label %inc
+
+    user:
+      store double %val, double* %A
+      br label %inc
+
+inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %for
+
+exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK-LABEL: polly.stmt.subregion_exit.exit:
+; CHECK-NEXT:    %1 = icmp sge i64 %polly.indvar, 5
+; CHECK-NEXT:    %polly.Stmt_subregion__TO__subregion_exit_Write0.cond = icmp ne i1 %1, false
+; CHECK-NEXT:    br i1 %polly.Stmt_subregion__TO__subregion_exit_Write0.cond, label %polly.stmt.subregion_exit.exit.Stmt_subregion__TO__subregion_exit_Write0.partial, label %polly.stmt.subregion_exit.exit.cont
+
+; CHECK-LABEL: polly.stmt.subregion_exit.exit.Stmt_subregion__TO__subregion_exit_Write0.partial:
+; CHECK-NEXT:    %polly.access.A = getelementptr double, double* %A, i64 1
+; CHECK-NEXT:    store double %p_val, double* %polly.access.A
+; CHECK-NEXT:    br label %polly.stmt.subregion_exit.exit.cont
+
+; CHECK-LABEL: polly.stmt.subregion_exit.exit.cont:

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%25for---%25return.jscop?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%for---%return.jscop (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%for---%return.jscop Sun May 21 17:46:57 2017
@@ -0,0 +1,39 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "[n] -> {  : -2147483648 <= n <= 2147483647 }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_body__TO__subregion_exit[i0] -> MemRef_val[] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_body__TO__subregion_exit[i0] : 0 <= i0 < n }",
+         "name" : "Stmt_body__TO__subregion_exit",
+         "schedule" : "[n] -> { Stmt_body__TO__subregion_exit[i0] -> [i0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_user[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_user[i0] -> MemRef_val[] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_user[i0] : 6 <= i0 < n }",
+         "name" : "Stmt_user",
+         "schedule" : "[n] -> { Stmt_user[i0] -> [i0, 1] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%25for---%25return.jscop.transformed?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_scalar_subregion___%for---%return.jscop.transformed Sun May 21 17:46:57 2017
@@ -0,0 +1,39 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "[n] -> {  : -2147483648 <= n <= 2147483647 }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_body__TO__subregion_exit[j] -> MemRef_A[1] : j >= 5 }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_body__TO__subregion_exit[i0] : 0 <= i0 < n }",
+         "name" : "Stmt_body__TO__subregion_exit",
+         "schedule" : "[n] -> { Stmt_body__TO__subregion_exit[i0] -> [i0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "[n] -> { Stmt_user[i0] -> MemRef_A[0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "[n] -> { Stmt_user[i0] -> MemRef_A[1] }"
+            }
+         ],
+         "domain" : "[n] -> { Stmt_user[i0] : 6 <= i0 < n }",
+         "name" : "Stmt_user",
+         "schedule" : "[n] -> { Stmt_user[i0] -> [i0, 1] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector.ll?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector.ll (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector.ll Sun May 21 17:46:57 2017
@@ -0,0 +1,57 @@
+; RUN: opt %loadPolly -basicaa -polly-import-jscop -polly-import-jscop-dir=%S -polly-import-jscop-postfix=transformed -polly-vectorizer=polly -polly-opt-isl -polly-ast -polly-codegen -S < %s | FileCheck %s
+;
+; Polly's vectorizer does not support partial accesses.
+;
+; for (int j = 0; j < 4; j += 1) {
+;body:
+;   val = 21.0 + 21.0;
+;   if (j > 1)
+;user:
+;     A[0] = val;
+; }
+
+define void @partial_write_mapped_vector(double* noalias nonnull %A) {
+entry:
+  br label %for
+
+for:
+  %j = phi i32 [0, %entry], [%j.inc, %inc]
+  %j.cmp = icmp slt i32 %j, 4
+  br i1 %j.cmp, label %body, label %exit
+
+    body:
+      %val = fadd double 21.0, 21.0
+      %if.cond = icmp sgt i32 %j, 1
+      br i1 %if.cond, label %user, label %inc
+
+    user:
+      %elt= getelementptr inbounds double, double* %A, i32 %j
+      store double %val, double* %elt
+      br label %inc
+
+inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %for
+
+exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK-LABEL: polly.stmt.body:
+; CHECK-NEXT:    %p_val = fadd double 2.100000e+01, 2.100000e+01
+; CHECK-NEXT:    %0 = trunc i64 %polly.indvar to i32
+; CHECK-NEXT:    %p_if.cond = icmp sgt i32 %0, 1
+; CHECK-NEXT:    %1 = icmp sge i64 %polly.indvar, 2
+; CHECK-NEXT:    %polly.Stmt_body_Write0.cond = icmp ne i1 %1, false
+; CHECK-NEXT:    br i1 %polly.Stmt_body_Write0.cond, label %polly.stmt.body.Stmt_body_Write0.partial, label %polly.stmt.body.cont
+
+; CHECK-LABEL:  polly.stmt.body.Stmt_body_Write0.partial:
+; CHECK-NEXT:    %polly.access.A = getelementptr double, double* %A, i64 1
+; CHECK-NEXT:    store double %p_val, double* %polly.access.A
+; CHECK-NEXT:    br label %polly.stmt.body.cont
+
+; CHECK-LABEL:  polly.stmt.body.cont:

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%25for---%25return.jscop?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%for---%return.jscop (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%for---%return.jscop Sun May 21 17:46:57 2017
@@ -0,0 +1,39 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "{  :  }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_body[i0] -> MemRef_val[] }"
+            }
+         ],
+         "domain" : "{ Stmt_body[i0] : 0 <= i0 <= 3 }",
+         "name" : "Stmt_body",
+         "schedule" : "{ Stmt_body[i0] -> [i0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_user[i0] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_user[i0] -> MemRef_val[] }"
+            }
+         ],
+         "domain" : "{ Stmt_user[i0] : 2 <= i0 <= 3 }",
+         "name" : "Stmt_user",
+         "schedule" : "{ Stmt_user[i0] -> [i0, 1] }"
+      }
+   ]
+}

Added: polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%25for---%25return.jscop.transformed?rev=303517&view=auto
==============================================================================
--- polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Isl/CodeGen/partial_write_mapped_vector___%for---%return.jscop.transformed Sun May 21 17:46:57 2017
@@ -0,0 +1,39 @@
+{
+   "arrays" : [
+      {
+         "name" : "MemRef_A",
+         "sizes" : [ "*" ],
+         "type" : "double"
+      }
+   ],
+   "context" : "{  :  }",
+   "name" : "%for---%return",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_body[j] -> MemRef_A[1] : j > 1 }"
+            }
+         ],
+         "domain" : "{ Stmt_body[i0] : 0 <= i0 <= 3 }",
+         "name" : "Stmt_body",
+         "schedule" : "{ Stmt_body[i0] -> [i0, 0] }"
+      },
+      {
+         "accesses" : [
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_user[i0] -> MemRef_A[i0] }"
+            },
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_user[j] -> MemRef_A[1] }"
+            }
+         ],
+         "domain" : "{ Stmt_user[i0] : 2 <= i0 <= 3 }",
+         "name" : "Stmt_user",
+         "schedule" : "{ Stmt_user[i0] -> [i0, 1] }"
+      }
+   ]
+}




More information about the llvm-commits mailing list