GlobalsAA: Functions with the argmemonly attribute won't read arbitrary globals
authorTom Stellard <thomas.stellard@amd.com>
Thu, 14 Jul 2016 15:50:27 +0000 (15:50 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Thu, 14 Jul 2016 15:50:27 +0000 (15:50 +0000)
Summary:
In preparation for changing GlobalsAA to stop assuming that intrinsics
can't read arbitrary globals, we need to make sure GlobalsAA is querying
function attributes rather than relying on this assumption.

This patch was inspired by: http://reviews.llvm.org/D20206

Reviewers: jmolloy, hfinkel

Subscribers: eli.friedman, llvm-commits

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

llvm-svn: 275433

llvm/lib/Analysis/GlobalsModRef.cpp
llvm/test/Analysis/GlobalsModRef/func-memattributes.ll [new file with mode: 0644]

index 0dc0078..a7d1e04 100644 (file)
@@ -498,7 +498,7 @@ void GlobalsAAResult::AnalyzeCallGraph(CallGraph &CG, Module &M) {
           // Can't do better than that!
         } else if (F->onlyReadsMemory()) {
           FI.addModRefInfo(MRI_Ref);
-          if (!F->isIntrinsic())
+          if (!F->isIntrinsic() && !F->onlyAccessesArgMemory())
             // This function might call back into the module and read a global -
             // consider every global as possibly being read by this function.
             FI.setMayReadAnyGlobal();
diff --git a/llvm/test/Analysis/GlobalsModRef/func-memattributes.ll b/llvm/test/Analysis/GlobalsModRef/func-memattributes.ll
new file mode 100644 (file)
index 0000000..5494512
--- /dev/null
@@ -0,0 +1,31 @@
+; RUN: opt < %s -disable-basicaa -globals-aa -dse -S | FileCheck %s
+
+@X = internal global i32 4
+
+define void @test0() {
+; CHECK-LABEL: @test0
+; CHECK: store i32 0, i32* @X
+; CHECK-NEXT: call void @func_readonly() #0
+; CHECK-NEXT: store i32 1, i32* @X
+  store i32 0, i32* @X
+  call void @func_readonly() #0
+  store i32 1, i32* @X
+  ret void
+}
+
+define void @test1() {
+; CHECK-LABEL: @test1
+; CHECK-NOT: store
+; CHECK: call void @func_read_argmem_only() #1
+; CHECK-NEXT: store i32 3, i32* @X
+  store i32 2, i32* @X
+  call void @func_read_argmem_only() #1
+  store i32 3, i32* @X
+  ret void
+}
+
+declare void @func_readonly() #0
+declare void @func_read_argmem_only() #1
+
+attributes #0 = { readonly }
+attributes #1 = { readonly argmemonly }