[llvm] r302238 - [LoopIdiom] check for safety while expanding

Aditya Kumar via llvm-commits llvm-commits at lists.llvm.org
Fri May 5 07:49:46 PDT 2017


Author: hiraditya
Date: Fri May  5 09:49:45 2017
New Revision: 302238

URL: http://llvm.org/viewvc/llvm-project?rev=302238&view=rev
Log:
[LoopIdiom] check for safety while expanding

Loop Idiom recognition was generating memset in a case that
would result generating a division operation to an unsafe location.

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

Added:
    llvm/trunk/test/Transforms/LoopIdiom/unsafe.ll
Modified:
    llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=302238&r1=302237&r2=302238&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Fri May  5 09:49:45 2017
@@ -783,6 +783,11 @@ bool LoopIdiomRecognize::processLoopStri
   if (NegStride)
     Start = getStartForNegStride(Start, BECount, IntPtr, StoreSize, SE);
 
+  // TODO: ideally we should still be able to generate memset if SCEV expander
+  // is taught to generate the dependencies at the latest point.
+  if (!isSafeToExpand(Start, *SE))
+    return false;
+
   // Okay, we have a strided store "p[i]" of a splattable value.  We can turn
   // this into a memset in the loop preheader now if we want.  However, this
   // would be unsafe to do if there is anything else in the loop that may read
@@ -814,6 +819,11 @@ bool LoopIdiomRecognize::processLoopStri
                                SCEV::FlagNUW);
   }
 
+  // TODO: ideally we should still be able to generate memset if SCEV expander
+  // is taught to generate the dependencies at the latest point.
+  if (!isSafeToExpand(NumBytesS, *SE))
+    return false;
+
   Value *NumBytes =
       Expander.expandCodeFor(NumBytesS, IntPtr, Preheader->getTerminator());
 

Added: llvm/trunk/test/Transforms/LoopIdiom/unsafe.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopIdiom/unsafe.ll?rev=302238&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LoopIdiom/unsafe.ll (added)
+++ llvm/trunk/test/Transforms/LoopIdiom/unsafe.ll Fri May  5 09:49:45 2017
@@ -0,0 +1,55 @@
+; RUN: opt -S < %s -loop-idiom | FileCheck %s
+; CHECK-NOT: memset
+; check that memset is not generated (for stores) because that will result
+; in udiv hoisted out of the loop by the SCEV Expander
+; TODO: ideally we should be able to generate memset
+; if SCEV expander is taught to generate the dependencies
+; at the right point.
+
+ at a = global i32 0, align 4
+ at b = global i32 0, align 4
+ at c = external local_unnamed_addr global [1 x i8], align 1
+
+define void @e() local_unnamed_addr {
+entry:
+  %d0 = load i32, i32* @a, align 4
+  %d1 = load i32, i32* @b, align 4
+  br label %for.cond1thread-pre-split
+
+for.cond1thread-pre-split:                        ; preds = %for.body5, %entry
+  %div = udiv i32 %d0, %d1
+  br label %for.body5
+
+for.body5:                                        ; preds = %for.body5, %for.cond1thread-pre-split
+  %indvars.iv = phi i64 [ 0, %for.cond1thread-pre-split ], [ %indvars.iv.next, %for.body5 ]
+  %divx = sext i32 %div to i64
+  %0 = add nsw i64 %divx, %indvars.iv
+  %arrayidx = getelementptr inbounds [1 x i8], [1 x i8]* @c, i64 0, i64 %0
+  store i8 0, i8* %arrayidx, align 1
+  %indvars.iv.next = add nsw i64 %indvars.iv, 1
+  %1 = trunc i64 %indvars.iv.next to i32
+  %tobool4 = icmp eq i32 %1, 0
+  br i1 %tobool4, label %for.cond1thread-pre-split, label %for.body5
+}
+
+; The loop's trip count is depending on an unsafe operation
+; udiv. SCEV expander hoists it out of the loop, so loop-idiom
+; should check that the memset is not generated in this case.
+define void @f(i32 %a, i32 %b, i8* nocapture %x) local_unnamed_addr {
+entry:
+  br label %for.body
+
+for.body:                                         ; preds = %for.body6, %entry
+  %div = udiv i32 %a, %b
+  %conv = zext i32 %div to i64
+  br label %for.body6
+
+for.body6:                                        ; preds = %for.body6, %for.body
+  %i.09 = phi i64 [ %inc, %for.body6 ], [ 0, %for.body ]
+  %arrayidx = getelementptr inbounds i8, i8* %x, i64 %i.09
+  store i8 0, i8* %arrayidx, align 1
+  %inc = add nuw nsw i64 %i.09, 1
+  %cmp3 = icmp slt i64 %inc, %conv
+  br i1 %cmp3, label %for.body6, label %for.body
+}
+




More information about the llvm-commits mailing list