[polly] r264284 - [FIX] Handle accesses to "null" in MemIntrinsics

Johannes Doerfert via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 24 06:50:04 PDT 2016


Author: jdoerfert
Date: Thu Mar 24 08:50:04 2016
New Revision: 264284

URL: http://llvm.org/viewvc/llvm-project?rev=264284&view=rev
Log:
[FIX] Handle accesses to "null" in MemIntrinsics

  This fixes PR27035. While we now exclude MemIntrinsics from the
  polyhedral model if they would access "null" we could exploit this
  even more, e.g., remove all parameter combinations that would lead to
  the execution of this statement from the context.


Added:
    polly/trunk/test/ScopInfo/memset_null.ll
Modified:
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/Analysis/ScopInfo.cpp

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=264284&r1=264283&r2=264284&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Thu Mar 24 08:50:04 2016
@@ -533,17 +533,21 @@ bool ScopDetection::isValidIntrinsicInst
   case llvm::Intrinsic::memmove:
   case llvm::Intrinsic::memcpy:
     AF = SE->getSCEVAtScope(cast<MemTransferInst>(II).getSource(), L);
-    BP = dyn_cast<SCEVUnknown>(SE->getPointerBase(AF));
-    // Bail if the source pointer is not valid.
-    if (!isValidAccess(&II, AF, BP, Context))
-      return false;
+    if (!AF->isZero()) {
+      BP = dyn_cast<SCEVUnknown>(SE->getPointerBase(AF));
+      // Bail if the source pointer is not valid.
+      if (!isValidAccess(&II, AF, BP, Context))
+        return false;
+    }
   // Fall through
   case llvm::Intrinsic::memset:
     AF = SE->getSCEVAtScope(cast<MemIntrinsic>(II).getDest(), L);
-    BP = dyn_cast<SCEVUnknown>(SE->getPointerBase(AF));
-    // Bail if the destination pointer is not valid.
-    if (!isValidAccess(&II, AF, BP, Context))
-      return false;
+    if (!AF->isZero()) {
+      BP = dyn_cast<SCEVUnknown>(SE->getPointerBase(AF));
+      // Bail if the destination pointer is not valid.
+      if (!isValidAccess(&II, AF, BP, Context))
+        return false;
+    }
 
     // Bail if the length is not affine.
     if (!isAffine(SE->getSCEVAtScope(cast<MemIntrinsic>(II).getLength(), L), L,

Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=264284&r1=264283&r2=264284&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Thu Mar 24 08:50:04 2016
@@ -3942,8 +3942,17 @@ bool ScopInfo::buildAccessMemIntrinsic(
 
   auto *DestPtrVal = MemIntr->getDest();
   assert(DestPtrVal);
+
   auto *DestAccFunc = SE->getSCEVAtScope(DestPtrVal, L);
   assert(DestAccFunc);
+  // Ignore accesses to "NULL".
+  // TODO: We could use this to optimize the region further, e.g., intersect
+  //       the context with
+  //          isl_set_complement(isl_set_params(getDomain()))
+  //       as we know it would be undefined to execute this instruction anyway.
+  if (DestAccFunc->isZero())
+    return true;
+
   auto *DestPtrSCEV = dyn_cast<SCEVUnknown>(SE->getPointerBase(DestAccFunc));
   assert(DestPtrSCEV);
   DestAccFunc = SE->getMinusSCEV(DestAccFunc, DestPtrSCEV);
@@ -3957,8 +3966,14 @@ bool ScopInfo::buildAccessMemIntrinsic(
 
   auto *SrcPtrVal = MemTrans->getSource();
   assert(SrcPtrVal);
+
   auto *SrcAccFunc = SE->getSCEVAtScope(SrcPtrVal, L);
   assert(SrcAccFunc);
+  // Ignore accesses to "NULL".
+  // TODO: See above TODO
+  if (SrcAccFunc->isZero())
+    return true;
+
   auto *SrcPtrSCEV = dyn_cast<SCEVUnknown>(SE->getPointerBase(SrcAccFunc));
   assert(SrcPtrSCEV);
   SrcAccFunc = SE->getMinusSCEV(SrcAccFunc, SrcPtrSCEV);

Added: polly/trunk/test/ScopInfo/memset_null.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/memset_null.ll?rev=264284&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/memset_null.ll (added)
+++ polly/trunk/test/ScopInfo/memset_null.ll Thu Mar 24 08:50:04 2016
@@ -0,0 +1,37 @@
+; RUN: opt %loadPolly -polly-allow-modref-calls -polly-scops -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-allow-modref-calls -S -polly-codegen < %s
+;
+; Verify we can handle a memset to "null" and that we do not model it.
+; TODO: FIXME: We could use the undefined memset to optimize the code further,
+;              see the TODOs in the ScopInfo.cpp.
+;
+; CHECK:         Statements {
+; CHECK-NEXT:        Stmt_for_cond5_preheader_us221
+; CHECK-NEXT:            Domain :=
+; CHECK-NEXT:                { Stmt_for_cond5_preheader_us221[0] };
+; CHECK-NEXT:            Schedule :=
+; CHECK-NEXT:                { Stmt_for_cond5_preheader_us221[i0] -> [0] };
+; CHECK-NEXT:            MustWriteAccess :=	[Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT:                { Stmt_for_cond5_preheader_us221[i0] -> MemRef_A[0] };
+; CHECK-NEXT:    }
+
+;
+target datalayout = "e-m:e-i64:64-i128:128-n8:16:32:64-S128"
+
+define void @test(i32* %A) {
+entry:
+  br i1 undef, label %for.end68, label %for.cond5.preheader.lr.ph
+
+for.cond5.preheader.lr.ph:                        ; preds = %entry
+  br label %for.cond5.preheader.us221
+
+for.cond5.preheader.us221:                        ; preds = %for.cond5.preheader.us221, %for.cond5.preheader.lr.ph
+  store i32 0, i32* %A
+  call void @llvm.memset.p0i8.i64(i8* null, i8 0, i64 undef, i32 1, i1 false)
+  br i1 true, label %for.end68, label %for.cond5.preheader.us221
+
+for.end68:                                        ; preds = %for.cond5.preheader.us221, %entry
+  ret void
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)




More information about the llvm-commits mailing list