]> granicus.if.org Git - llvm/commitdiff
[Attributor] Deduce "noalias" attribute
authorHideto Ueno <uenoku.tokotoko@gmail.com>
Thu, 29 Aug 2019 05:52:00 +0000 (05:52 +0000)
committerHideto Ueno <uenoku.tokotoko@gmail.com>
Thu, 29 Aug 2019 05:52:00 +0000 (05:52 +0000)
Summary:
This patch adds very basic deduction for noalias.

Reviewers: jdoerfert, sstefan1

Reviewed By: jdoerfert

Tags: LLVM

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370295 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/Attributor.cpp
test/Transforms/FunctionAttrs/internal-noalias.ll [new file with mode: 0644]
test/Transforms/FunctionAttrs/noalias_returned.ll

index 2d386ae036565d51443797eb5f516cff41952c6d..c882f8ccf01d6fff218b1a4a7a123cb779ea958c 100644 (file)
@@ -1559,6 +1559,12 @@ struct AANoAliasImpl : AANoAlias {
 struct AANoAliasFloating final : AANoAliasImpl {
   AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
 
+  /// See AbstractAttribute::initialize(...).
+  void initialize(Attributor &A) override {
+    // TODO: It isn't sound to initialize as the same with `AANoAliasImpl`
+    // because `noalias` may not be valid in the current position.
+  }
+
   /// See AbstractAttribute::updateImpl(...).
   ChangeStatus updateImpl(Attributor &A) override {
     // TODO: Implement this.
@@ -1572,14 +1578,10 @@ struct AANoAliasFloating final : AANoAliasImpl {
 };
 
 /// NoAlias attribute for an argument.
-struct AANoAliasArgument final : AANoAliasImpl {
-  AANoAliasArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
-
-  /// See AbstractAttribute::updateImpl(...).
-  ChangeStatus updateImpl(Attributor &A) override {
-    // TODO: Implement this.
-    return indicatePessimisticFixpoint();
-  }
+struct AANoAliasArgument final
+    : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
+  AANoAliasArgument(const IRPosition &IRP)
+      : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
 
   /// See AbstractAttribute::trackStatistics()
   void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
@@ -1588,6 +1590,12 @@ struct AANoAliasArgument final : AANoAliasImpl {
 struct AANoAliasCallSiteArgument final : AANoAliasImpl {
   AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
 
+  /// See AbstractAttribute::initialize(...).
+  void initialize(Attributor &A) override {
+    // TODO: It isn't sound to initialize as the same with `AANoAliasImpl`
+    // because `noalias` may not be valid in the current position.
+  }
+
   /// See AbstractAttribute::updateImpl(...).
   ChangeStatus updateImpl(Attributor &A) override {
     // TODO: Implement this.
@@ -2814,6 +2822,9 @@ void Attributor::identifyDefaultAbstractAttributes(
       // Every argument with pointer type might be marked nonnull.
       checkAndRegisterAA<AANonNullArgument>(ArgPos, *this, Whitelist);
 
+      // Every argument with pointer type might be marked noalias.
+      checkAndRegisterAA<AANoAliasArgument>(ArgPos, *this, Whitelist);
+
       // Every argument with pointer type might be marked dereferenceable.
       checkAndRegisterAA<AADereferenceableArgument>(ArgPos, *this, Whitelist);
 
@@ -2879,6 +2890,10 @@ void Attributor::identifyDefaultAbstractAttributes(
         checkAndRegisterAA<AANonNullCallSiteArgument>(CSArgPos, *this,
                                                       Whitelist);
 
+        // Call site argument attribute "no-alias".
+        checkAndRegisterAA<AANoAliasCallSiteArgument>(CSArgPos, *this,
+                                                      Whitelist);
+
         // Call site argument attribute "dereferenceable".
         checkAndRegisterAA<AADereferenceableCallSiteArgument>(CSArgPos, *this,
                                                               Whitelist);
diff --git a/test/Transforms/FunctionAttrs/internal-noalias.ll b/test/Transforms/FunctionAttrs/internal-noalias.ll
new file mode 100644 (file)
index 0000000..b580c5a
--- /dev/null
@@ -0,0 +1,49 @@
+; RUN: opt -S -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=9 < %s | FileCheck %s
+
+define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 {
+entry:
+  %call1 = call i32 @noalias_args(i32* %A, i32* %B)
+  %call2 = call i32 @noalias_args_argmem(i32* %A, i32* %B)
+  %add = add nsw i32 %call1, %call2
+  ret i32 %add
+}
+
+; FIXME: Should be something like this.
+; define internal i32 @noalias_args(i32* nocapture readonly %A, i32* noalias nocapture readonly %B)
+; CHECK: define internal i32 @noalias_args(i32* %A, i32* %B)
+
+define internal i32 @noalias_args(i32* %A, i32* %B) #0 {
+entry:
+  %0 = load i32, i32* %A, align 4
+  %1 = load i32, i32* %B, align 4
+  %add = add nsw i32 %0, %1
+  %call = call i32 @noalias_args_argmem(i32* %A, i32* %B)
+  %add2 = add nsw i32 %add, %call
+  ret i32 %add2
+}
+
+
+; FIXME: Should be something like this.
+; define internal i32 @noalias_args_argmem(i32* noalias nocapture readonly %A, i32* noalias nocapture readonly %B)
+; CHECK: define internal i32 @noalias_args_argmem(i32* %A, i32* %B)
+;
+define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 {
+entry:
+  %0 = load i32, i32* %A, align 4
+  %1 = load i32, i32* %B, align 4
+  %add = add nsw i32 %0, %1
+  ret i32 %add
+}
+
+define dso_local i32 @visible_local(i32* %A) #0 {
+entry:
+  %B = alloca i32, align 4
+  store i32 5, i32* %B, align 4
+  %call1 = call i32 @noalias_args(i32* %A, i32* nonnull %B)
+  %call2 = call i32 @noalias_args_argmem(i32* %A, i32* nonnull %B)
+  %add = add nsw i32 %call1, %call2
+  ret i32 %add
+}
+
+attributes #0 = { noinline nounwind uwtable willreturn }
+attributes #1 = { argmemonly noinline nounwind uwtable willreturn}
index c1d802fd1e3b2a56e3ac8fa22b972b1882b1ceee..d7c4eadb983687a3e0661ad2bbe5344315c3dfc3 100644 (file)
@@ -138,3 +138,40 @@ define i8* @test8(i32* %0) nounwind uwtable {
 5:                                                ; preds = %1, %4
   ret i8* %2
 }
+
+; TEST 9
+; Simple Argument Test
+define internal void @test9(i8* %a, i8* %b) {
+; FIXME: missing noalias
+; CHECK: define internal void @test9(i8* %a, i8* %b)
+  ret void
+}
+define void @test9_helper(i8* %a, i8* %b) {
+  tail call void @test9(i8* noalias %a, i8* %b)
+  tail call void @test9(i8* noalias %b, i8* noalias %a)
+  ret void
+}
+
+
+; TEST 10
+; Simple CallSite Test
+
+declare void @test10_helper(i8* %a)
+define void @test10(i8* noalias %a) {
+; CHECK: define void @test10(i8* noalias %a)
+; FIXME: missing noalias
+; CHECK-NEXT:   tail call void @test10_helper(i8* %a)
+  tail call void @test10_helper(i8* %a)
+  ret void
+}
+
+; TEST 11
+; CallSite Test
+
+declare void @test11_helper(i8* %a, i8 *%b)
+define void @test11(i8* noalias %a) {
+; CHECK: define void @test11(i8* noalias %a)
+; CHECK-NEXT:   tail call void @test11_helper(i8* %a, i8* %a)
+  tail call void @test11_helper(i8* %a, i8* %a)
+  ret void
+}