Index: include/llvm/IR/DataLayout.h =================================================================== --- include/llvm/IR/DataLayout.h +++ include/llvm/IR/DataLayout.h @@ -338,6 +338,11 @@ NonIntegralSpaces.end(); } + bool isNonIntegralPointerType(Type *Ty) const { + auto *PTy = dyn_cast(Ty); + return PTy && isNonIntegralPointerType(PTy); + } + /// Layout pointer size, in bits /// FIXME: The defaults need to be removed once all of /// the backends/clients are updated. Index: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -475,7 +475,8 @@ // size is a legal integer type. if (!Ty->isIntegerTy() && Ty->isSized() && DL.isLegalInteger(DL.getTypeStoreSizeInBits(Ty)) && - DL.getTypeStoreSizeInBits(Ty) == DL.getTypeSizeInBits(Ty)) { + DL.getTypeStoreSizeInBits(Ty) == DL.getTypeSizeInBits(Ty) && + !DL.isNonIntegralPointerType(Ty)) { if (std::all_of(LI.user_begin(), LI.user_end(), [&LI](User *U) { auto *SI = dyn_cast(U); return SI && SI->getPointerOperand() != &LI; Index: test/Transforms/InstCombine/non-integral-pointers.ll =================================================================== --- test/Transforms/InstCombine/non-integral-pointers.ll +++ test/Transforms/InstCombine/non-integral-pointers.ll @@ -18,3 +18,31 @@ %result = getelementptr i8, i8 addrspace(3)* null, i64 50 ret i8 addrspace(3)* %result } + +define void @f_2(i8 addrspace(4)** %ptr0, i8 addrspace(4)** %ptr1) { +; It is not okay to convert the load/store pair to load and store +; integers, since pointers in address space 4 are non-integral. + +; CHECK-LABEL: @f_2( +entry: +; CHECK: %val = load i8 addrspace(4)*, i8 addrspace(4)** %ptr0, align 8 +; CHECK: store i8 addrspace(4)* %val, i8 addrspace(4)** %ptr1, align 8 +; CHECK-NOT: load i64 +; CHECK-NOT: store i64 + %val = load i8 addrspace(4)*, i8 addrspace(4)** %ptr0 + store i8 addrspace(4)* %val, i8 addrspace(4)** %ptr1 + ret void +} + +define void @f_3(i8 addrspace(3)** %ptr0, i8 addrspace(3)** %ptr1) { +; It *is* okay to convert the load/store pair to load and store +; integers, since pointers in address space 3 are integral. + +; CHECK-LABEL: @f_3( +entry: +; CHECK: load i64 +; CHECK: store i64 + %val = load i8 addrspace(3)*, i8 addrspace(3)** %ptr0 + store i8 addrspace(3)* %val, i8 addrspace(3)** %ptr1 + ret void +}