diff --git a/llvm/lib/Transforms/Utils/VNCoercion.cpp b/llvm/lib/Transforms/Utils/VNCoercion.cpp --- a/llvm/lib/Transforms/Utils/VNCoercion.cpp +++ b/llvm/lib/Transforms/Utils/VNCoercion.cpp @@ -34,17 +34,22 @@ if (StoreSize < DL.getTypeSizeInBits(LoadTy)) return false; + bool StoredNI = DL.isNonIntegralPointerType(StoredTy->getScalarType()); + bool LoadNI = DL.isNonIntegralPointerType(LoadTy->getScalarType()); // Don't coerce non-integral pointers to integers or vice versa. - if (DL.isNonIntegralPointerType(StoredVal->getType()->getScalarType()) != - DL.isNonIntegralPointerType(LoadTy->getScalarType())) { + if (StoredNI != LoadNI) { // As a special case, allow coercion of memset used to initialize // an array w/null. Despite non-integral pointers not generally having a // specific bit pattern, we do assume null is zero. if (auto *CI = dyn_cast(StoredVal)) return CI->isNullValue(); return false; + } else if (StoredNI && LoadNI && + cast(StoredTy)->getAddressSpace() != + cast(LoadTy)->getAddressSpace()) { + return false; } - + return true; } diff --git a/llvm/test/Transforms/GVN/non-integral-pointers.ll b/llvm/test/Transforms/GVN/non-integral-pointers.ll --- a/llvm/test/Transforms/GVN/non-integral-pointers.ll +++ b/llvm/test/Transforms/GVN/non-integral-pointers.ll @@ -1,7 +1,7 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -gvn -S < %s | FileCheck %s -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4:5" target triple = "x86_64-unknown-linux-gnu" define void @f0(i1 %alwaysFalse, i64 %val, i64* %loc) { @@ -285,3 +285,21 @@ %ref = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %loc.off ret i8 addrspace(4)* %ref } + + define i8 addrspace(5)* @multini(i1 %alwaysFalse, i8 addrspace(4)* %val, i8 addrspace(4)** %loc) { + ; CHECK-LABEL: @multini( + ; CHECK-NOT: inttoptr + ; CHECK-NOT: ptrtoint + ; CHECK-NOT: addrspacecast + entry: + store i8 addrspace(4)* %val, i8 addrspace(4)** %loc + br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken + + neverTaken: + %loc.bc = bitcast i8 addrspace(4)** %loc to i8 addrspace(5)** + %differentas = load i8 addrspace(5)*, i8 addrspace(5)** %loc.bc + ret i8 addrspace(5)* %differentas + + alwaysTaken: + ret i8 addrspace(5)* null + }