Index: lib/Transforms/Utils/VNCoercion.cpp =================================================================== --- lib/Transforms/Utils/VNCoercion.cpp +++ lib/Transforms/Utils/VNCoercion.cpp @@ -20,7 +20,8 @@ StoredVal->getType()->isStructTy() || StoredVal->getType()->isArrayTy()) return false; - uint64_t StoreSize = DL.getTypeSizeInBits(StoredVal->getType()); + Type *StoredValTy = StoredVal->getType(); + uint64_t StoreSize = DL.getTypeSizeInBits(StoredValTy); // The store size must be byte-aligned to support future type casts. if (llvm::alignTo(StoreSize, 8) != StoreSize) @@ -30,10 +31,15 @@ if (StoreSize < DL.getTypeSizeInBits(LoadTy)) return false; - // Don't coerce non-integral pointers to integers or vice versa. - if (DL.isNonIntegralPointerType(StoredVal->getType()) != - DL.isNonIntegralPointerType(LoadTy)) + bool StoredNI = DL.isNonIntegralPointerType(StoredValTy); + bool LoadNI = DL.isNonIntegralPointerType(LoadTy); + if (StoredNI != LoadNI) { + return false; + } else if (StoredNI && LoadNI && + cast(StoredValTy)->getAddressSpace() != + cast(LoadTy)->getAddressSpace()) { return false; + } return true; } Index: test/Transforms/GVN/non-integral-pointers.ll =================================================================== --- test/Transforms/GVN/non-integral-pointers.ll +++ test/Transforms/GVN/non-integral-pointers.ll @@ -1,6 +1,6 @@ ; 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) { @@ -37,3 +37,21 @@ alwaysTaken: ret i64 42 } + + 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 + }