[GlobalsAA] An indirect global that is initialized is not fair game
authorJames Molloy <james.molloy@arm.com>
Wed, 28 Oct 2015 10:41:29 +0000 (10:41 +0000)
committerJames Molloy <james.molloy@arm.com>
Wed, 28 Oct 2015 10:41:29 +0000 (10:41 +0000)
When checking if an indirect global (a global with pointer type) is only assigned by allocation functions, first check if the global is itself initialized. If it is, it's not only assigned by allocation functions.

This fixes PR25309. Thanks to David Majnemer for reducing the test case!

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

include/llvm/Analysis/GlobalsModRef.h
lib/Analysis/GlobalsModRef.cpp
test/Analysis/GlobalsModRef/pr25309.ll [new file with mode: 0644]

index d45e4d430aed5c464e84eeb27f67ba0b73ea39b5..bcd102e7ded2ad7b7b7e251a551b5fd2a0c9fff0 100644 (file)
@@ -107,7 +107,7 @@ private:
                             SmallPtrSetImpl<Function *> *Readers = nullptr,
                             SmallPtrSetImpl<Function *> *Writers = nullptr,
                             GlobalValue *OkayStoreDest = nullptr);
-  bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
+  bool AnalyzeIndirectGlobalMemory(GlobalVariable *GV);
   void CollectSCCMembership(CallGraph &CG);
 
   bool isNonEscapingGlobalNoAlias(const GlobalValue *GV, const Value *V);
index 3b808e371dbcce268c5100f3bc0e231021252633..c809ff83457b4b8b8dbcd6d191a7d2b8f29574bc 100644 (file)
@@ -395,11 +395,16 @@ bool GlobalsAAResult::AnalyzeUsesOfPointer(Value *V,
 /// Further, all loads out of GV must directly use the memory, not store the
 /// pointer somewhere.  If this is true, we consider the memory pointed to by
 /// GV to be owned by GV and can disambiguate other pointers from it.
-bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
+bool GlobalsAAResult::AnalyzeIndirectGlobalMemory(GlobalVariable *GV) {
   // Keep track of values related to the allocation of the memory, f.e. the
   // value produced by the malloc call and any casts.
   std::vector<Value *> AllocRelatedValues;
 
+  // If the initializer is a valid pointer, bail.
+  if (Constant *C = GV->getInitializer())
+    if (!C->isNullValue())
+      return false;
+    
   // Walk the user list of the global.  If we find anything other than a direct
   // load or store, bail out.
   for (User *U : GV->users()) {
diff --git a/test/Analysis/GlobalsModRef/pr25309.ll b/test/Analysis/GlobalsModRef/pr25309.ll
new file mode 100644 (file)
index 0000000..ce3b498
--- /dev/null
@@ -0,0 +1,27 @@
+; RUN: opt -globals-aa -gvn < %s -S | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; @o and @m are initialized to @i, so they should not be classed as
+; indirect globals referring only to allocation functions.
+@o = internal global i32* @i, align 8
+@m = internal global i32* @i, align 8
+@i = internal global i32 0, align 4
+
+; CHECK-LABEL: @f
+define i1 @f() {
+entry:
+  %0 = load i32*, i32** @o, align 8
+  store i32 0, i32* %0, align 4
+  %1 = load volatile i32*, i32** @m, align 8
+  store i32 1, i32* %1, align 4
+  ; CHECK: %[[a:.*]] = load i32*
+  %2 = load i32*, i32** @o, align 8
+  ; CHECK: %[[b:.*]] = load i32, i32* %[[a]]
+  %3 = load i32, i32* %2, align 4
+  ; CHECK: %[[c:.*]] = icmp ne i32 %[[b]], 0
+  %tobool.i = icmp ne i32 %3, 0
+  ; CHECK: ret i1 %[[c]]
+  ret i1 %tobool.i
+}
\ No newline at end of file