[Intrinsics] Add a 'NoAlias' intrinsic property; annotate llvm.memcpy
authorDavid Bolvansky <david.bolvansky@gmail.com>
Wed, 14 Aug 2019 08:33:07 +0000 (08:33 +0000)
committerDavid Bolvansky <david.bolvansky@gmail.com>
Wed, 14 Aug 2019 08:33:07 +0000 (08:33 +0000)
Reviewers: jdoerfert

Reviewed By: jdoerfert

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

llvm-svn: 368810

llvm/include/llvm/IR/Intrinsics.td
llvm/test/Bitcode/upgrade-memory-intrinsics.ll
llvm/test/Other/lint.ll
llvm/utils/TableGen/CodeGenIntrinsics.h
llvm/utils/TableGen/CodeGenTarget.cpp
llvm/utils/TableGen/IntrinsicEmitter.cpp

index 3ad1d92..b10efe3 100644 (file)
@@ -63,6 +63,12 @@ class NoCapture<int argNo> : IntrinsicProperty {
   int ArgNo = argNo;
 }
 
+// NoAlias - The specified argument pointer is not aliasing other "noalias" pointer
+// arguments of the intrinsic wrt. the intrinsic scope.
+class NoAlias<int argNo> : IntrinsicProperty {
+  int ArgNo = argNo;
+}
+
 // Returned - The specified argument is always the return value of the
 // intrinsic.
 class Returned<int argNo> : IntrinsicProperty {
@@ -494,7 +500,7 @@ def int_memcpy  : Intrinsic<[],
                              [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
                               llvm_i1_ty],
                             [IntrArgMemOnly, IntrWillReturn, NoCapture<0>, NoCapture<1>,
-                             WriteOnly<0>, ReadOnly<1>, ImmArg<3>]>;
+                             NoAlias<0>, NoAlias<1>, WriteOnly<0>, ReadOnly<1>, ImmArg<3>]>;
 def int_memmove : Intrinsic<[],
                             [llvm_anyptr_ty, llvm_anyptr_ty, llvm_anyint_ty,
                              llvm_i1_ty],
index 1bdee92..c534313 100644 (file)
@@ -28,7 +28,7 @@ define void @test2(i8* %p1, i8* %p2, i8* %p3) {
 }
 
 ; CHECK: declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg)
-; CHECK: declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1 immarg)
+; CHECK: declare void @llvm.memcpy.p0i8.p0i8.i64(i8* noalias nocapture writeonly, i8* noalias nocapture readonly, i64, i1 immarg)
 ; CHECK: declare void @llvm.memmove.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i1 immarg)
 declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1)
 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly , i8* nocapture readonly, i64, i32, i1)
index ab5df0e..415fc29 100644 (file)
@@ -9,6 +9,7 @@ declare void @has_noaliases(i32* noalias %p, i32* %q)
 declare void @one_arg(i32)
 
 @CG = constant i32 7
+@CG2 = constant i32 7
 @E = external global i8
 
 define i32 @foo() noreturn {
@@ -78,7 +79,9 @@ define i32 @foo() noreturn {
   call void (float) bitcast (void (i32)* @one_arg to void (float)*)(float 0.0)
 
 ; CHECK: Write to read-only memory
-  call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (i32* @CG to i8*), i8* bitcast (i32* @CG to i8*), i64 1, i1 0)
+call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (i32* @CG to i8*), i8* bitcast (i32* @CG2 to i8*), i64 1, i1 0)
+; CHECK: Unusual: noalias argument aliases another argument
+call void @llvm.memcpy.p0i8.p0i8.i64(i8* bitcast (i32* @CG to i8*), i8* bitcast (i32* @CG to i8*), i64 1, i1 0)
 
 ; CHECK: Undefined behavior: Buffer overflow
   %wider = bitcast i8* %buf to i16*
index 7b74bb0..0e70be2 100644 (file)
@@ -141,6 +141,7 @@ struct CodeGenIntrinsic {
 
   enum ArgAttribute {
     NoCapture,
+    NoAlias,
     Returned,
     ReadOnly,
     WriteOnly,
index b65e1b6..05f9f22 100644 (file)
@@ -733,6 +733,9 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R) {
     else if (Property->isSubClassOf("NoCapture")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
       ArgumentAttributes.push_back(std::make_pair(ArgNo, NoCapture));
+    } else if (Property->isSubClassOf("NoAlias")) {
+      unsigned ArgNo = Property->getValueAsInt("ArgNo");
+      ArgumentAttributes.push_back(std::make_pair(ArgNo, NoAlias));
     } else if (Property->isSubClassOf("Returned")) {
       unsigned ArgNo = Property->getValueAsInt("ArgNo");
       ArgumentAttributes.push_back(std::make_pair(ArgNo, Returned));
index 979af98..255d78e 100644 (file)
@@ -647,6 +647,12 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
             OS << "Attribute::NoCapture";
             addComma = true;
             break;
+          case CodeGenIntrinsic::NoAlias:
+            if (addComma)
+              OS << ",";
+            OS << "Attribute::NoAlias";
+            addComma = true;
+            break;
           case CodeGenIntrinsic::Returned:
             if (addComma)
               OS << ",";