[polly] r295846 - [DeLICM] Add regression tests for DeLICM reject cases.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 22 07:14:09 PST 2017


Author: meinersbur
Date: Wed Feb 22 09:14:08 2017
New Revision: 295846

URL: http://llvm.org/viewvc/llvm-project?rev=295846&view=rev
Log:
[DeLICM] Add regression tests for DeLICM reject cases.

These tests were not included in the main DeLICM commit. These check the
cases where zone analysis cannot be successful because of assumption
violations.

We use the LLVM optimization remark infrastructure as it seems to be the
best fit for this kind of messages. I tried to make use if the
OptimizationRemarkEmitter. However, it would insert additional function
passes into the pass manager to get the hotness information. The pass
manager would insert them between the flatten pass and delicm, causing
the ScopInfo with the flattened schedule being thrown away.

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

Added:
    polly/trunk/test/DeLICM/reject_loadafterstore.ll
    polly/trunk/test/DeLICM/reject_outofquota.ll
    polly/trunk/test/DeLICM/reject_storeafterstore.ll
    polly/trunk/test/DeLICM/reject_storeinsubregion.ll
    polly/trunk/test/DeLICM/reject_unusualstore.ll
Modified:
    polly/trunk/include/polly/Support/GICHelper.h
    polly/trunk/lib/Transform/DeLICM.cpp

Modified: polly/trunk/include/polly/Support/GICHelper.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/GICHelper.h?rev=295846&r1=295845&r2=295846&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/GICHelper.h (original)
+++ polly/trunk/include/polly/Support/GICHelper.h Wed Feb 22 09:14:08 2017
@@ -15,6 +15,7 @@
 #define POLLY_SUPPORT_GIC_HELPER_H
 
 #include "llvm/ADT/APInt.h"
+#include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/Support/raw_ostream.h"
 #include "isl/aff.h"
 #include "isl/ctx.h"
@@ -318,6 +319,13 @@ llvm::raw_ostream &operator<<(llvm::raw_
   OS << IslObjTraits<T>::to_str(Obj.keep());
   return OS;
 }
+
+template <typename T>
+llvm::DiagnosticInfoOptimizationBase &
+operator<<(llvm::DiagnosticInfoOptimizationBase &OS, const IslPtr<T> &Obj) {
+  OS << IslObjTraits<T>::to_str(Obj.keep());
+  return OS;
+}
 
 /// Smart pointer to an ISL object, but does not release it when destroyed.
 ///

Modified: polly/trunk/lib/Transform/DeLICM.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/DeLICM.cpp?rev=295846&r1=295845&r2=295846&view=diff
==============================================================================
--- polly/trunk/lib/Transform/DeLICM.cpp (original)
+++ polly/trunk/lib/Transform/DeLICM.cpp Wed Feb 22 09:14:08 2017
@@ -641,6 +641,17 @@ public:
   }
 };
 
+std::string printIntruction(Instruction *Instr, bool IsForDebug = false) {
+  std::string Result;
+  raw_string_ostream OS(Result);
+  Instr->print(OS, IsForDebug);
+  OS.flush();
+  size_t i = 0;
+  while (i < Result.size() && Result[i] == ' ')
+    i += 1;
+  return Result.substr(i);
+}
+
 /// Base class for algorithms based on zones, like DeLICM.
 class ZoneAlgorithm {
 protected:
@@ -724,8 +735,15 @@ private:
 
       if (MA->isRead()) {
         // Reject load after store to same location.
-        if (!isl_union_map_is_disjoint(Stores.keep(), AccRel.keep()))
+        if (!isl_union_map_is_disjoint(Stores.keep(), AccRel.keep())) {
+          OptimizationRemarkMissed R(DEBUG_TYPE, "LoadAfterStore",
+                                     MA->getAccessInstruction());
+          R << "load after store of same element in same statement";
+          R << " (previous stores: " << Stores;
+          R << ", loading: " << AccRel << ")";
+          S->getFunction().getContext().diagnose(R);
           return false;
+        }
 
         Loads = give(isl_union_map_union(Loads.take(), AccRel.take()));
 
@@ -734,18 +752,35 @@ private:
 
       if (!isa<StoreInst>(MA->getAccessInstruction())) {
         DEBUG(dbgs() << "WRITE that is not a StoreInst not supported\n");
+        OptimizationRemarkMissed R(DEBUG_TYPE, "UnusualStore",
+                                   MA->getAccessInstruction());
+        R << "encountered write that is not a StoreInst: "
+          << printIntruction(MA->getAccessInstruction());
+        S->getFunction().getContext().diagnose(R);
         return false;
       }
 
       // In region statements the order is less clear, eg. the load and store
       // might be in a boxed loop.
       if (Stmt->isRegionStmt() &&
-          !isl_union_map_is_disjoint(Loads.keep(), AccRel.keep()))
+          !isl_union_map_is_disjoint(Loads.keep(), AccRel.keep())) {
+        OptimizationRemarkMissed R(DEBUG_TYPE, "StoreInSubregion",
+                                   MA->getAccessInstruction());
+        R << "store is in a non-affine subregion";
+        S->getFunction().getContext().diagnose(R);
         return false;
+      }
 
       // Do not allow more than one store to the same location.
-      if (!isl_union_map_is_disjoint(Stores.keep(), AccRel.keep()))
+      if (!isl_union_map_is_disjoint(Stores.keep(), AccRel.keep())) {
+        OptimizationRemarkMissed R(DEBUG_TYPE, "StoreAfterStore",
+                                   MA->getAccessInstruction());
+        R << "store after store of same element in same statement";
+        R << " (previous stores: " << Stores;
+        R << ", storing: " << AccRel << ")";
+        S->getFunction().getContext().diagnose(R);
         return false;
+      }
 
       Stores = give(isl_union_map_union(Stores.take(), AccRel.take()));
     }
@@ -1537,6 +1572,12 @@ public:
     if (isl_ctx_last_error(IslCtx.get()) == isl_error_quota) {
       DeLICMOutOfQuota++;
       DEBUG(dbgs() << "DeLICM analysis exceeded max_operations\n");
+      DebugLoc Begin, End;
+      getDebugLocations(getBBPairForRegion(&S->getRegion()), Begin, End);
+      OptimizationRemarkAnalysis R(DEBUG_TYPE, "OutOfQuota", Begin,
+                                   S->getEntry());
+      R << "maximal number of operations exceeded during zone analysis";
+      S->getFunction().getContext().diagnose(R);
     }
 
     DeLICMAnalyzed++;

Added: polly/trunk/test/DeLICM/reject_loadafterstore.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DeLICM/reject_loadafterstore.ll?rev=295846&view=auto
==============================================================================
--- polly/trunk/test/DeLICM/reject_loadafterstore.ll (added)
+++ polly/trunk/test/DeLICM/reject_loadafterstore.ll Wed Feb 22 09:14:08 2017
@@ -0,0 +1,67 @@
+; RUN: opt %loadPolly -polly-delicm -analyze -pass-remarks-missed=polly-delicm < %s 2>&1 | FileCheck %s
+;
+;    void func(double *A) {
+;      for (int j = 0; j < 2; j += 1) { /* outer */
+;        double phi = 0.0;
+;        for (int i = 0; i < 4; i += 1) /* reduction */
+;          phi += 4.2;
+;        A[j] = phi;
+;        (void)A[j];
+;      }
+;    }
+;
+define void @func(double* noalias nonnull %A) {
+entry:
+  br label %outer.preheader
+
+outer.preheader:
+  br label %outer.for
+
+outer.for:
+  %j = phi i32 [0, %outer.preheader], [%j.inc, %outer.inc]
+  %j.cmp = icmp slt i32 %j, 2
+  br i1 %j.cmp, label %reduction.preheader, label %outer.exit
+
+
+    reduction.preheader:
+      br label %reduction.for
+
+    reduction.for:
+      %i = phi i32 [0, %reduction.preheader], [%i.inc, %reduction.inc]
+      %phi = phi double [0.0, %reduction.preheader], [%add, %reduction.inc]
+      %i.cmp = icmp slt i32 %i, 4
+      br i1 %i.cmp, label %body, label %reduction.exit
+
+
+
+        body:
+          %add = fadd double %phi, 4.2
+          br label %reduction.inc
+
+
+
+    reduction.inc:
+      %i.inc = add nuw nsw i32 %i, 1
+      br label %reduction.for
+
+    reduction.exit:
+      %A_idx = getelementptr inbounds double, double* %A, i32 %j
+      store double %phi, double* %A_idx
+      %dummy = load double, double* %A_idx
+      br label %outer.inc
+
+
+
+outer.inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %outer.for
+
+outer.exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK: load after store of same element in same statement

Added: polly/trunk/test/DeLICM/reject_outofquota.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DeLICM/reject_outofquota.ll?rev=295846&view=auto
==============================================================================
--- polly/trunk/test/DeLICM/reject_outofquota.ll (added)
+++ polly/trunk/test/DeLICM/reject_outofquota.ll Wed Feb 22 09:14:08 2017
@@ -0,0 +1,65 @@
+; RUN: opt %loadPolly -polly-delicm -analyze -pass-remarks-analysis=polly-delicm -polly-delicm-max-ops=1 < %s 2>&1 | FileCheck %s
+;
+;    void func(double *A) {
+;      for (int j = 0; j < 2; j += 1) { /* outer */
+;        double phi = 0.0;
+;        for (int i = 0; i < 4; i += 1) /* reduction */
+;          phi += 4.2;
+;        A[j] = phi;
+;      }
+;    }
+;
+define void @func(double* noalias nonnull %A) {
+entry:
+  br label %outer.preheader
+
+outer.preheader:
+  br label %outer.for
+
+outer.for:
+  %j = phi i32 [0, %outer.preheader], [%j.inc, %outer.inc]
+  %j.cmp = icmp slt i32 %j, 2
+  br i1 %j.cmp, label %reduction.preheader, label %outer.exit
+
+
+    reduction.preheader:
+      br label %reduction.for
+
+    reduction.for:
+      %i = phi i32 [0, %reduction.preheader], [%i.inc, %reduction.inc]
+      %phi = phi double [0.0, %reduction.preheader], [%add, %reduction.inc]
+      %i.cmp = icmp slt i32 %i, 4
+      br i1 %i.cmp, label %body, label %reduction.exit
+
+
+
+        body:
+          %add = fadd double %phi, 4.2
+          br label %reduction.inc
+
+
+
+    reduction.inc:
+      %i.inc = add nuw nsw i32 %i, 1
+      br label %reduction.for
+
+    reduction.exit:
+      %A_idx = getelementptr inbounds double, double* %A, i32 %j
+      store double %phi, double* %A_idx
+      br label %outer.inc
+
+
+
+outer.inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %outer.for
+
+outer.exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK: maximal number of operations exceeded during zone analysis

Added: polly/trunk/test/DeLICM/reject_storeafterstore.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DeLICM/reject_storeafterstore.ll?rev=295846&view=auto
==============================================================================
--- polly/trunk/test/DeLICM/reject_storeafterstore.ll (added)
+++ polly/trunk/test/DeLICM/reject_storeafterstore.ll Wed Feb 22 09:14:08 2017
@@ -0,0 +1,67 @@
+; RUN: opt %loadPolly -polly-delicm -analyze -pass-remarks-missed=polly-delicm < %s 2>&1 | FileCheck %s
+;
+;    void func(double *A) {
+;      for (int j = 0; j < 2; j += 1) { /* outer */
+;        double phi = 0.0;
+;        for (int i = 0; i < 4; i += 1) /* reduction */
+;          phi += 4.2;
+;        A[j] = 0.0;
+;        A[j] = phi;
+;      }
+;    }
+;
+define void @func(double* noalias nonnull %A) {
+entry:
+  br label %outer.preheader
+
+outer.preheader:
+  br label %outer.for
+
+outer.for:
+  %j = phi i32 [0, %outer.preheader], [%j.inc, %outer.inc]
+  %j.cmp = icmp slt i32 %j, 2
+  br i1 %j.cmp, label %reduction.preheader, label %outer.exit
+
+
+    reduction.preheader:
+      br label %reduction.for
+
+    reduction.for:
+      %i = phi i32 [0, %reduction.preheader], [%i.inc, %reduction.inc]
+      %phi = phi double [0.0, %reduction.preheader], [%add, %reduction.inc]
+      %i.cmp = icmp slt i32 %i, 4
+      br i1 %i.cmp, label %body, label %reduction.exit
+
+
+
+        body:
+          %add = fadd double %phi, 4.2
+          br label %reduction.inc
+
+
+
+    reduction.inc:
+      %i.inc = add nuw nsw i32 %i, 1
+      br label %reduction.for
+
+    reduction.exit:
+      %A_idx = getelementptr inbounds double, double* %A, i32 %j
+      store double 0.0, double* %A_idx
+      store double %phi, double* %A_idx
+      br label %outer.inc
+
+
+
+outer.inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %outer.for
+
+outer.exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK: store after store of same element in same statement

Added: polly/trunk/test/DeLICM/reject_storeinsubregion.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DeLICM/reject_storeinsubregion.ll?rev=295846&view=auto
==============================================================================
--- polly/trunk/test/DeLICM/reject_storeinsubregion.ll (added)
+++ polly/trunk/test/DeLICM/reject_storeinsubregion.ll Wed Feb 22 09:14:08 2017
@@ -0,0 +1,79 @@
+; RUN: opt %loadPolly -polly-delicm -analyze -pass-remarks-missed=polly-delicm < %s 2>&1 | FileCheck %s
+;
+;    void func(double *A) {
+;      for (int j = 0; j < 2; j += 1) { /* outer */
+;        double phi = 0.0;
+;        for (int i = 0; i < 4; i += 1) /* reduction */
+;          phi += 4.2;
+;          if (phi > 42.0)
+;            (void)A[j];
+;          else
+;            A[j] = 0.0;
+;        A[j] = phi;
+;      }
+;    }
+;
+define void @func(double* noalias nonnull %A) {
+entry:
+  br label %outer.preheader
+
+outer.preheader:
+  br label %outer.for
+
+outer.for:
+  %j = phi i32 [0, %outer.preheader], [%j.inc, %outer.inc]
+  %j.cmp = icmp slt i32 %j, 2
+  br i1 %j.cmp, label %reduction.preheader, label %outer.exit
+
+
+    reduction.preheader:
+      br label %reduction.for
+
+    reduction.for:
+      %i = phi i32 [0, %reduction.preheader], [%i.inc, %reduction.inc]
+      %phi = phi double [0.0, %reduction.preheader], [%add, %reduction.inc]
+      %i.cmp = icmp slt i32 %i, 4
+      br i1 %i.cmp, label %body, label %reduction.exit
+
+
+
+        body:
+          %add = fadd double %phi, 4.2
+          %A_idxp = getelementptr inbounds double, double* %A, i32 %j
+          %add.cmp = fcmp ogt double %add, 42.0
+          br i1 %add.cmp , label %body_true, label %body_false
+
+        body_true:
+          %dummy = load double, double* %A_idxp
+          br label %reduction.inc
+
+        body_false:
+          store double 0.0, double* %A_idxp
+          br label %reduction.inc
+
+
+
+    reduction.inc:
+      %i.inc = add nuw nsw i32 %i, 1
+      br label %reduction.for
+
+    reduction.exit:
+      %A_idx = getelementptr inbounds double, double* %A, i32 %j
+      store double %phi, double* %A_idx
+      br label %outer.inc
+
+
+
+outer.inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %outer.for
+
+outer.exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK: store is in a non-affine subregion

Added: polly/trunk/test/DeLICM/reject_unusualstore.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DeLICM/reject_unusualstore.ll?rev=295846&view=auto
==============================================================================
--- polly/trunk/test/DeLICM/reject_unusualstore.ll (added)
+++ polly/trunk/test/DeLICM/reject_unusualstore.ll Wed Feb 22 09:14:08 2017
@@ -0,0 +1,71 @@
+; RUN: opt %loadPolly -polly-delicm -analyze -pass-remarks-missed=polly-delicm < %s 2>&1 | FileCheck %s
+;
+;    void func(double *A) {
+;      for (int j = 0; j < 2; j += 1) { /* outer */
+;        memset(A[j], 0, sizeof(double));
+;        double phi = 0.0;
+;        for (int i = 0; i < 4; i += 1) /* reduction */
+;          phi += 4.2;
+;        A[j] = phi;
+;      }
+;    }
+;
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
+
+define void @func(double* noalias nonnull %A) {
+entry:
+  br label %outer.preheader
+
+outer.preheader:
+  br label %outer.for
+
+outer.for:
+  %j = phi i32 [0, %outer.preheader], [%j.inc, %outer.inc]
+  %j.cmp = icmp slt i32 %j, 2
+  br i1 %j.cmp, label %reduction.preheader, label %outer.exit
+
+
+    reduction.preheader:
+      %A_idx = getelementptr inbounds double, double* %A, i32 %j
+      %tmp = bitcast double* %A_idx to i8*
+      call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 8, i32 1, i1 false)
+      br label %reduction.for
+
+    reduction.for:
+      %i = phi i32 [0, %reduction.preheader], [%i.inc, %reduction.inc]
+      %phi = phi double [0.0, %reduction.preheader], [%add, %reduction.inc]
+      %i.cmp = icmp slt i32 %i, 4
+      br i1 %i.cmp, label %body, label %reduction.exit
+
+
+
+        body:
+          %add = fadd double %phi, 4.2
+          br label %reduction.inc
+
+
+
+    reduction.inc:
+      %i.inc = add nuw nsw i32 %i, 1
+      br label %reduction.for
+
+    reduction.exit:
+      store double %phi, double* %A_idx
+      br label %outer.inc
+
+
+
+outer.inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %outer.for
+
+outer.exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK: encountered write that is not a StoreInst: call void @llvm.memset.p0i8.i64(i8* %tmp, i8 0, i64 8, i32 1, i1 false)




More information about the llvm-commits mailing list