Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -1912,6 +1912,7 @@ } } + // Try to infer inbounds on GEPs of allocas. if (!GEP.isInBounds()) { unsigned PtrWidth = DL.getPointerSizeInBits(PtrOp->getType()->getPointerAddressSpace()); @@ -1924,8 +1925,13 @@ BasePtrOffset.isNonNegative()) { APInt AllocSize(PtrWidth, DL.getTypeAllocSize(AI->getAllocatedType())); if (BasePtrOffset.ule(AllocSize)) { - return GetElementPtrInst::CreateInBounds( + Instruction *NewGEP = GetElementPtrInst::CreateInBounds( PtrOp, makeArrayRef(Ops).slice(1), GEP.getName()); + + if (PtrOp->getType()->getPointerAddressSpace() == + GEP.getAddressSpace()) + return NewGEP; + return new AddrSpaceCastInst(Builder->Insert(NewGEP), GEP.getType()); } } } Index: test/Transforms/InstCombine/getelementptr.ll =================================================================== --- test/Transforms/InstCombine/getelementptr.ll +++ test/Transforms/InstCombine/getelementptr.ll @@ -942,4 +942,17 @@ ret <2 x i32*> %tmp1 } +; Test that inbounds inference works in the presence of addrspacecasts. +define i8 addrspace(42)* @gep_inbounds_addrspace() { +; CHECK-LABEL: @gep_inbounds_addrspace +; CHECK: getelementptr inbounds +; CHECK-NEXT: addrspacecast +; CHECK: ret + %A = alloca <8 x half>, align 16 + %B = bitcast <8 x half>* %A to i8* + %C = addrspacecast i8* %B to i8 addrspace(42)* + %gep = getelementptr i8, i8 addrspace(42)* %C, i64 12 + ret i8 addrspace(42)* %gep +} + ; CHECK: attributes [[NUW]] = { nounwind }