isKnownNonNull needs to consider globals in non-zero address spaces.
authorPete Cooper <peter_cooper@apple.com>
Thu, 27 Aug 2015 03:16:29 +0000 (03:16 +0000)
committerPete Cooper <peter_cooper@apple.com>
Thu, 27 Aug 2015 03:16:29 +0000 (03:16 +0000)
Globals in address spaces other than one may have 0 as a valid address,
so we should not assume that they can be null.

Reviewed by Philip Reames.

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

lib/Analysis/ValueTracking.cpp
test/Transforms/InstCombine/nonnull-attribute.ll [new file with mode: 0644]

index 9b930d7d2eb9a4790345f4342cd4907fd3986bb2..352b0fbd4dcb25a815fd7b6f06a7562d50f2cd89 100644 (file)
@@ -3226,9 +3226,12 @@ bool llvm::isKnownNonNull(const Value *V, const TargetLibraryInfo *TLI) {
   if (const Argument *A = dyn_cast<Argument>(V))
     return A->hasByValOrInAllocaAttr() || A->hasNonNullAttr();
 
-  // Global values are not null unless extern weak.
+  // A global variable in address space 0 is non null unless extern weak.
+  // Other address spaces may have null as a valid address for a global,
+  // so we can't assume anything.
   if (const GlobalValue *GV = dyn_cast<GlobalValue>(V))
-    return !GV->hasExternalWeakLinkage();
+    return !GV->hasExternalWeakLinkage() &&
+           GV->getType()->getAddressSpace() == 0;
 
   // A Load tagged w/nonnull metadata is never null. 
   if (const LoadInst *LI = dyn_cast<LoadInst>(V))
diff --git a/test/Transforms/InstCombine/nonnull-attribute.ll b/test/Transforms/InstCombine/nonnull-attribute.ll
new file mode 100644 (file)
index 0000000..74fb091
--- /dev/null
@@ -0,0 +1,19 @@
+; RUN: opt < %s -instcombine -S | FileCheck %s
+
+; This test makes sure that we do not assume globals in address spaces other
+; than 0 are able to be null.
+
+@as0 = external global i32
+@as1 = external addrspace(1) global i32
+
+declare void @addrspace0(i32*)
+declare void @addrspace1(i32 addrspace(1)*)
+
+; CHECK: call void @addrspace0(i32* nonnull @as0)
+; CHECK: call void @addrspace1(i32 addrspace(1)* @as1)
+
+define void @test() {
+  call void @addrspace0(i32* @as0)
+  call void @addrspace1(i32 addrspace(1)* @as1)
+  ret void
+}