Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -3574,7 +3574,9 @@ auto *PartPtrTy = PartTy->getPointerTo(LI->getPointerAddressSpace()); LoadInst *PLoad = IRB.CreateAlignedLoad( getAdjustedPtr(IRB, DL, BasePtr, - APInt(DL.getPointerSizeInBits(), PartOffset), + APInt(DL.getPointerSizeInBits( + PartPtrTy->getPointerAddressSpace()), + PartOffset), PartPtrTy, BasePtr->getName() + "."), getAdjustedAlignment(LI, PartOffset, DL), /*IsVolatile*/ false, LI->getName()); @@ -3698,7 +3700,7 @@ int Idx = 0, Size = Offsets.Splits.size(); for (;;) { auto *PartTy = Type::getIntNTy(Ty->getContext(), PartSize * 8); - auto *PartPtrTy = PartTy->getPointerTo(SI->getPointerAddressSpace()); + auto *PartPtrTy = PartTy->getPointerTo(); // Either lookup a split load or create one. LoadInst *PLoad; @@ -3707,9 +3709,12 @@ } else { IRB.SetInsertPoint(LI); PLoad = IRB.CreateAlignedLoad( - getAdjustedPtr(IRB, DL, LoadBasePtr, - APInt(DL.getPointerSizeInBits(), PartOffset), - PartPtrTy, LoadBasePtr->getName() + "."), + getAdjustedPtr( + IRB, DL, LoadBasePtr, + APInt(DL.getPointerSizeInBits(LI->getPointerAddressSpace()), + PartOffset), + PartTy->getPointerTo(LI->getPointerAddressSpace()), + LoadBasePtr->getName() + "."), getAdjustedAlignment(LI, PartOffset, DL), /*IsVolatile*/ false, LI->getName()); } Index: test/Transforms/SROA/address-spaces.ll =================================================================== --- test/Transforms/SROA/address-spaces.ll +++ test/Transforms/SROA/address-spaces.ll @@ -83,3 +83,33 @@ store i32 addrspace(3)* @l, i32 addrspace(3)** %3, align 8 ret void } + +%pr26154.S = type { <4 x i32>, <3 x i8> } + +; Just check that we don't crash due to using the wrong address space when +; splitting the load or store. +; CHECK-LABEL: pr26154 +; CHECK: ret i8 + +define i8 @pr26154(%pr26154.S addrspace(1)* %arg) { +bb: + %a = alloca %pr26154.S, align 16 + %b = alloca %pr26154.S, align 16 + + %arg_ptr = getelementptr inbounds %pr26154.S, %pr26154.S addrspace(1)* %arg, i16 0, i32 1 + %arg_bc = bitcast <3 x i8> addrspace(1)* %arg_ptr to i32 addrspace(1)* + %arg_val = load i32, i32 addrspace(1)* %arg_bc, align 4 + + %a_ptr = getelementptr inbounds %pr26154.S, %pr26154.S* %a, i64 0, i32 1 + %a_bc = bitcast <3 x i8>* %a_ptr to i32* + store i32 %arg_val, i32* %a_bc, align 16 + + %amem = bitcast %pr26154.S* %a to i8* + %bmem = bitcast %pr26154.S* %b to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %bmem, i8* %amem, i32 20, i32 16, i1 false) + + %b_ptr = getelementptr %pr26154.S, %pr26154.S* %b, i64 0, i32 1 + %b_val = load <3 x i8>, <3 x i8>* %b_ptr, align 16 + %x = extractelement <3 x i8> %b_val, i32 0 + ret i8 %x +}