[polly] r312455 - [IslAst] Do not assert in case of empty min/max alias locations

Tobias Grosser via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 3 12:47:19 PDT 2017


Author: grosser
Date: Sun Sep  3 12:47:19 2017
New Revision: 312455

URL: http://llvm.org/viewvc/llvm-project?rev=312455&view=rev
Log:
[IslAst] Do not assert in case of empty min/max alias locations

In certain situations, the context in the isl_ast_build could result for the
min/max locations of our alias sets to become empty, which would cause an
internal error in isl, which is then unable to derive a value for these
expressions. Check these conditions before code generating expressions and
instead assume that alias check succeeded. This is valid, as the corresponding
memory accesses will not be executed under any valid context.

This fixed llvm.org/PR34432. Thanks to Qirun Zhang for reporting.

Added:
    polly/trunk/test/Isl/Ast/alias_checks_with_empty_context.ll
Modified:
    polly/trunk/lib/CodeGen/IslAst.cpp

Modified: polly/trunk/lib/CodeGen/IslAst.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/IslAst.cpp?rev=312455&r1=312454&r2=312455&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/IslAst.cpp (original)
+++ polly/trunk/lib/CodeGen/IslAst.cpp Sun Sep  3 12:47:19 2017
@@ -347,7 +347,7 @@ static __isl_give isl_ast_node *AtEachDo
 }
 
 // Build alias check condition given a pair of minimal/maximal access.
-static isl::ast_expr buildCondition(isl::ast_build Build,
+static isl::ast_expr buildCondition(Scop &S, isl::ast_build Build,
                                     const Scop::MinMaxAccessTy *It0,
                                     const Scop::MinMaxAccessTy *It1) {
 
@@ -359,21 +359,49 @@ static isl::ast_expr buildCondition(isl:
   isl::id Left = AFirst.get_tuple_id(isl::dim::set);
   isl::id Right = BFirst.get_tuple_id(isl::dim::set);
 
+  isl::ast_expr True =
+      isl::ast_expr::from_val(isl::val::int_from_ui(Build.get_ctx(), 1));
+  isl::ast_expr False =
+      isl::ast_expr::from_val(isl::val::int_from_ui(Build.get_ctx(), 0));
+
   const ScopArrayInfo *BaseLeft =
       ScopArrayInfo::getFromId(Left)->getBasePtrOriginSAI();
   const ScopArrayInfo *BaseRight =
       ScopArrayInfo::getFromId(Right)->getBasePtrOriginSAI();
   if (BaseLeft && BaseLeft == BaseRight)
-    return isl::ast_expr::from_val(isl::val::int_from_ui(Build.get_ctx(), 1));
+    return True;
+
+  isl::set Params = S.getContext();
 
   isl::ast_expr NonAliasGroup, MinExpr, MaxExpr;
-  MinExpr = Build.access_from(AFirst).address_of();
-  MaxExpr = Build.access_from(BSecond).address_of();
-  NonAliasGroup = MaxExpr.le(MinExpr);
-  MinExpr = Build.access_from(BFirst).address_of();
-  MaxExpr = Build.access_from(ASecond).address_of();
-  NonAliasGroup = isl::manage(
-      isl_ast_expr_or(NonAliasGroup.release(), MaxExpr.le(MinExpr).release()));
+
+  // In the following, we first check if any accesses will be empty under
+  // the execution context of the scop and do not code generate them if this
+  // is the case as isl will fail to derive valid AST expressions for such
+  // accesses.
+
+  if (!AFirst.intersect_params(Params).domain().is_empty() &&
+      !BSecond.intersect_params(Params).domain().is_empty()) {
+    MinExpr = Build.access_from(AFirst).address_of();
+    MaxExpr = Build.access_from(BSecond).address_of();
+    NonAliasGroup = MaxExpr.le(MinExpr);
+  }
+
+  if (!BFirst.intersect_params(Params).domain().is_empty() &&
+      !ASecond.intersect_params(Params).domain().is_empty()) {
+    MinExpr = Build.access_from(BFirst).address_of();
+    MaxExpr = Build.access_from(ASecond).address_of();
+
+    isl::ast_expr Result = MaxExpr.le(MinExpr);
+    if (!NonAliasGroup.is_null())
+      NonAliasGroup = isl::manage(
+          isl_ast_expr_or(NonAliasGroup.release(), Result.release()));
+    else
+      NonAliasGroup = Result;
+  }
+
+  if (NonAliasGroup.is_null())
+    NonAliasGroup = True;
 
   return NonAliasGroup;
 }
@@ -410,14 +438,16 @@ IslAst::buildRunCondition(Scop &S, __isl
          ++RWAccIt0) {
       for (auto RWAccIt1 = RWAccIt0 + 1; RWAccIt1 != RWAccEnd; ++RWAccIt1)
         RunCondition = isl_ast_expr_and(
-            RunCondition, buildCondition(isl::manage(isl_ast_build_copy(Build)),
-                                         RWAccIt0, RWAccIt1)
-                              .release());
+            RunCondition,
+            buildCondition(S, isl::manage(isl_ast_build_copy(Build)), RWAccIt0,
+                           RWAccIt1)
+                .release());
       for (const Scop::MinMaxAccessTy &ROAccIt : MinMaxReadOnly)
         RunCondition = isl_ast_expr_and(
-            RunCondition, buildCondition(isl::manage(isl_ast_build_copy(Build)),
-                                         RWAccIt0, &ROAccIt)
-                              .release());
+            RunCondition,
+            buildCondition(S, isl::manage(isl_ast_build_copy(Build)), RWAccIt0,
+                           &ROAccIt)
+                .release());
     }
   }
 

Added: polly/trunk/test/Isl/Ast/alias_checks_with_empty_context.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/Ast/alias_checks_with_empty_context.ll?rev=312455&view=auto
==============================================================================
--- polly/trunk/test/Isl/Ast/alias_checks_with_empty_context.ll (added)
+++ polly/trunk/test/Isl/Ast/alias_checks_with_empty_context.ll Sun Sep  3 12:47:19 2017
@@ -0,0 +1,72 @@
+; RUN: opt %loadPolly -polly-ast -analyze < %s \
+; RUN:     | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+ at global = external local_unnamed_addr global i32, align 4
+ at global.1 = external local_unnamed_addr global i32, align 4
+
+define void @hoge() local_unnamed_addr {
+bb:
+  %tmp = alloca i8, align 8
+  br label %bb1
+
+bb1:                                              ; preds = %bb19, %bb
+  %tmp2 = phi i32 [ undef, %bb ], [ %tmp5, %bb19 ]
+  %tmp3 = phi i32* [ @global, %bb ], [ %tmp20, %bb19 ]
+  %tmp4 = icmp ugt i32 %tmp2, 5
+  %tmp5 = select i1 %tmp4, i32 %tmp2, i32 5
+  br label %bb6
+
+bb6:                                              ; preds = %bb1
+  br label %bb7
+
+bb7:                                              ; preds = %bb10, %bb6
+  %tmp8 = phi i8 [ 7, %bb6 ], [ %tmp11, %bb10 ]
+  store i32 2, i32* %tmp3, align 4
+  %tmp9 = load i8, i8* %tmp, align 8
+  br label %bb10
+
+bb10:                                             ; preds = %bb7
+  store i32 undef, i32* @global.1, align 4
+  %tmp11 = add nuw nsw i8 %tmp8, 1
+  %tmp12 = icmp eq i8 %tmp11, 72
+  br i1 %tmp12, label %bb13, label %bb7
+
+bb13:                                             ; preds = %bb10
+  %tmp14 = icmp eq i32 %tmp5, 0
+  br i1 %tmp14, label %bb15, label %bb16
+
+bb15:                                             ; preds = %bb13
+  store i8 0, i8* %tmp, align 8
+  br label %bb16
+
+bb16:                                             ; preds = %bb15, %bb13
+  br label %bb17
+
+bb17:                                             ; preds = %bb16
+  br i1 undef, label %bb19, label %bb18
+
+bb18:                                             ; preds = %bb17
+  br label %bb19
+
+bb19:                                             ; preds = %bb18, %bb17
+  %tmp20 = phi i32* [ %tmp3, %bb17 ], [ bitcast (void ()* @hoge to i32*), %bb18 ]
+  br label %bb1
+}
+
+; CHECK: if (1 && (&MemRef_global_1[1] <= &MemRef_tmp3[0] || &MemRef_tmp3[1] <= &MemRef_global_1[0]) && 1 && 1)
+
+; CHECK:     {
+; CHECK-NEXT:       for (int c0 = 0; c0 <= 64; c0 += 1) {
+; CHECK-NEXT:         Stmt_bb7(c0);
+; CHECK-NEXT:         Stmt_bb10(c0);
+; CHECK-NEXT:       }
+; CHECK-NEXT:       if (p_0 == 0)
+; CHECK-NEXT:         Stmt_bb15();
+; CHECK-NEXT:     }
+
+; CHECK: else
+; CHECK-NEXT:     {  /* original code */ }
+




More information about the llvm-commits mailing list