Index: lib/Transforms/Scalar/SROA.cpp =================================================================== --- lib/Transforms/Scalar/SROA.cpp +++ lib/Transforms/Scalar/SROA.cpp @@ -1206,6 +1206,9 @@ if (Ty == TargetTy) return buildGEP(IRB, BasePtr, Indices); + // Pointer size to use for the indices. + unsigned PtrSize = DL.getPointerTypeSizeInBits(BasePtr->getType()); + // See if we can descend into a struct and locate a field with the correct // type. unsigned NumLayers = 0; @@ -1213,11 +1216,13 @@ do { if (ElementTy->isPointerTy()) break; - if (SequentialType *SeqTy = dyn_cast(ElementTy)) { - ElementTy = SeqTy->getElementType(); - // Note that we use the default address space as this index is over an - // array or a vector, not a pointer. - Indices.push_back(IRB.getInt(APInt(DL.getPointerSizeInBits(0), 0))); + + if (ArrayType *ArrayTy = dyn_cast(ElementTy)) { + ElementTy = ArrayTy->getElementType(); + Indices.push_back(IRB.getInt(APInt(PtrSize, 0))); + } else if (VectorType *VectorTy = dyn_cast(ElementTy)) { + ElementTy = VectorTy->getElementType(); + Indices.push_back(IRB.getInt(APInt(32, 0))); } else if (StructType *STy = dyn_cast(ElementTy)) { if (STy->element_begin() == STy->element_end()) break; // Nothing left to descend into. @@ -2016,8 +2021,9 @@ Value *getAdjustedAllocaPtr(IRBuilderTy &IRB, uint64_t Offset, Type *PointerTy) { assert(Offset >= NewAllocaBeginOffset); - return getAdjustedPtr(IRB, DL, &NewAI, APInt(DL.getPointerSizeInBits(), - Offset - NewAllocaBeginOffset), + return getAdjustedPtr(IRB, DL, &NewAI, + APInt(DL.getPointerTypeSizeInBits(PointerTy), + Offset - NewAllocaBeginOffset), PointerTy); } @@ -2420,8 +2426,10 @@ assert(II.getRawSource() == OldPtr || II.getRawDest() == OldPtr); bool IsDest = II.getRawDest() == OldPtr; + unsigned AS = IsDest ? II.getSourceAddressSpace() : II.getDestAddressSpace(); + // Compute the relative offset within the transfer. - unsigned IntPtrWidth = DL.getPointerSizeInBits(); + unsigned IntPtrWidth = DL.getPointerSizeInBits(AS); APInt RelOffset(IntPtrWidth, NewBeginOffset - BeginOffset); unsigned Align = II.getAlignment(); Index: test/Transforms/SROA/address-spaces.ll =================================================================== --- test/Transforms/SROA/address-spaces.ll +++ test/Transforms/SROA/address-spaces.ll @@ -49,3 +49,29 @@ ret void } +define void @test_address_space_gep_index(i8 addrspace(1)* %out) { +; CHECK-LABEL: @test_address_space_gep_index( +; CHECK-NOT: alloca + %a = alloca [16 x i8] + %raw1 = getelementptr inbounds [16 x i8]* %a, i32 0, i32 0 + %ptr1 = bitcast i8* %raw1 to double* + %raw2 = getelementptr inbounds [16 x i8]* %a, i32 0, i32 8 + %ptr2 = bitcast i8* %raw2 to double* + + call void @llvm.memcpy.p0i8.p1i8.i32(i8* %raw1, i8 addrspace(1)* %out, i32 16, i32 0, i1 false) +; CHECK: %[[val2:.*]] = load double addrspace(1)* %{{.*}}, align 1 +; CHECK: getelementptr inbounds i8 addrspace(1)* %out, i16 8 +; CHECK: %[[val1:.*]] = load double addrspace(1)* %{{.*}}, align 1 + %val1 = load double* %ptr2, align 1 + %val2 = load double* %ptr1, align 1 + + store double %val1, double* %ptr1, align 1 + store double %val2, double* %ptr2, align 1 + call void @llvm.memcpy.p1i8.p0i8.i32(i8 addrspace(1)* %out, i8* %raw1, i32 16, i32 0, i1 false) +; CHECK: store double %[[val1]], double addrspace(1)* %{{.*}}, align 1 +; CHECK: getelementptr inbounds i8 addrspace(1)* %out, i16 8 +; CHECK: store double %[[val2]], double addrspace(1)* %{{.*}}, align 1 + ret void +; CHECK: ret void +} +