[PATCH] llvm.noalias - don't prevent loop vectorization

hfinkel at anl.gov hfinkel at anl.gov
Thu Apr 30 08:27:38 PDT 2015


Hi chandlerc, reames, aschwaighofer,

This is part of the series started by D9375, and teaches the loop vectorizer enough about llvm.noalias that it should not interfere with vectorization when it happens to appear inside a loop we might otherwise vectorize.

http://reviews.llvm.org/D9382

Files:
  include/llvm/Analysis/TargetTransformInfoImpl.h
  include/llvm/Transforms/Utils/VectorUtils.h
  lib/Transforms/Vectorize/LoopVectorize.cpp
  test/Transforms/LoopVectorize/noalias.ll

Index: include/llvm/Analysis/TargetTransformInfoImpl.h
===================================================================
--- include/llvm/Analysis/TargetTransformInfoImpl.h
+++ include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -149,6 +149,7 @@
     case Intrinsic::invariant_end:
     case Intrinsic::lifetime_start:
     case Intrinsic::lifetime_end:
+    case Intrinsic::noalias:
     case Intrinsic::objectsize:
     case Intrinsic::ptr_annotation:
     case Intrinsic::var_annotation:
Index: include/llvm/Transforms/Utils/VectorUtils.h
===================================================================
--- include/llvm/Transforms/Utils/VectorUtils.h
+++ include/llvm/Transforms/Utils/VectorUtils.h
@@ -101,7 +101,8 @@
   if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CI)) {
     Intrinsic::ID ID = II->getIntrinsicID();
     if (isTriviallyVectorizable(ID) || ID == Intrinsic::lifetime_start ||
-        ID == Intrinsic::lifetime_end || ID == Intrinsic::assume)
+        ID == Intrinsic::lifetime_end || ID == Intrinsic::assume ||
+        ID == Intrinsic::noalias)
       return ID;
     else
       return Intrinsic::not_intrinsic;
Index: lib/Transforms/Vectorize/LoopVectorize.cpp
===================================================================
--- lib/Transforms/Vectorize/LoopVectorize.cpp
+++ lib/Transforms/Vectorize/LoopVectorize.cpp
@@ -3144,20 +3144,21 @@
       Module *M = BB->getParent()->getParent();
       CallInst *CI = cast<CallInst>(it);
 
+      Intrinsic::ID ID = getIntrinsicIDForCall(CI, TLI);
+      if (ID &&
+          (ID == Intrinsic::assume || ID == Intrinsic::lifetime_end ||
+           ID == Intrinsic::lifetime_start || ID == Intrinsic::noalias)) {
+        scalarizeInstruction(it);
+        break;
+      }
+
       StringRef FnName = CI->getCalledFunction()->getName();
       Function *F = CI->getCalledFunction();
       Type *RetTy = ToVectorTy(CI->getType(), VF);
       SmallVector<Type *, 4> Tys;
       for (unsigned i = 0, ie = CI->getNumArgOperands(); i != ie; ++i)
         Tys.push_back(ToVectorTy(CI->getArgOperand(i)->getType(), VF));
 
-      Intrinsic::ID ID = getIntrinsicIDForCall(CI, TLI);
-      if (ID &&
-          (ID == Intrinsic::assume || ID == Intrinsic::lifetime_end ||
-           ID == Intrinsic::lifetime_start)) {
-        scalarizeInstruction(it);
-        break;
-      }
       // The flag shows whether we use Intrinsic or a usual Call for vectorized
       // version of the instruction.
       // Is it beneficial to perform intrinsic call compared to lib call?
Index: test/Transforms/LoopVectorize/noalias.ll
===================================================================
--- /dev/null
+++ test/Transforms/LoopVectorize/noalias.ll
@@ -0,0 +1,34 @@
+; RUN: opt -S -loop-vectorize -force-vector-width=2 -force-vector-interleave=1 < %s | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+; Make sure we can vectorize loops which contain lifetime markers.
+
+; CHECK-LABEL: @test(
+; CHECK: @llvm.noalias.p0i32
+; CHECK: store <2 x i32>
+
+define void @test(i32 *%d) {
+entry:
+  br label %for.body
+
+for.body:
+  %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ]
+  %d2 = call i32* @llvm.noalias.p0i32(i32* %d, metadata !1)
+  %arrayidx = getelementptr inbounds i32, i32* %d2, i64 %indvars.iv
+  %v1 = load i32, i32* %arrayidx, align 8
+  store i32 100, i32* %arrayidx, align 8
+  %indvars.iv.next = add i64 %indvars.iv, 1
+  %lftr.wideiv = trunc i64 %indvars.iv.next to i32
+  %exitcond = icmp ne i32 %lftr.wideiv, 128
+  br i1 %exitcond, label %for.body, label %for.end
+
+for.end:
+  ret void
+}
+
+declare i32* @llvm.noalias.p0i32(i32*, metadata) nounwind
+
+!0 = !{!0, !"some domain"}
+!1 = !{!1, !0, !"some scope"}
+

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9382.24716.patch
Type: text/x-patch
Size: 3871 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150430/005ff0e3/attachment.bin>


More information about the llvm-commits mailing list