Index: llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp =================================================================== --- llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -461,9 +461,12 @@ ArrayRef Offsets = *VMap.getOffsets(LI); unsigned Base = getOrCreateVReg(*LI.getPointerOperand()); + Type *OffsetIRTy = DL->getIntPtrType(LI.getPointerOperandType()); + LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL); + for (unsigned i = 0; i < Regs.size(); ++i) { unsigned Addr = 0; - MIRBuilder.materializeGEP(Addr, Base, LLT::scalar(64), Offsets[i] / 8); + MIRBuilder.materializeGEP(Addr, Base, OffsetTy, Offsets[i] / 8); MachinePointerInfo Ptr(LI.getPointerOperand(), Offsets[i] / 8); unsigned BaseAlign = getMemOpAlignment(LI); @@ -490,9 +493,12 @@ ArrayRef Offsets = *VMap.getOffsets(*SI.getValueOperand()); unsigned Base = getOrCreateVReg(*SI.getPointerOperand()); + Type *OffsetIRTy = DL->getIntPtrType(SI.getPointerOperandType()); + LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL); + for (unsigned i = 0; i < Vals.size(); ++i) { unsigned Addr = 0; - MIRBuilder.materializeGEP(Addr, Base, LLT::scalar(64), Offsets[i] / 8); + MIRBuilder.materializeGEP(Addr, Base, OffsetTy, Offsets[i] / 8); MachinePointerInfo Ptr(SI.getPointerOperand(), Offsets[i] / 8); unsigned BaseAlign = getMemOpAlignment(SI); Index: llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll =================================================================== --- llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll +++ llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll @@ -544,3 +544,20 @@ %elt = extractelement <2 x i32> %vec, i32 0 ret i32 %elt } + +define void @test_load_store_struct({i32, i32} *%addr) { +; Make sure the IRTranslator doesn't use an unnecessarily large GEP index type +; when breaking up loads and stores of aggregates. +; CHECK-LABEL: name: test_load_store_struct +; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $r0 +; CHECK-DAG: [[VAL1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load 4 from %ir.addr) +; CHECK-DAG: [[OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 4 +; CHECK-DAG: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFFSET]](s32) +; CHECK-DAG: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[ADDR2]](p0) :: (load 4 from %ir.addr + 4) +; CHECK-DAG: G_STORE [[VAL1]](s32), [[ADDR1]](p0) :: (store 4 into %ir.addr) +; CHECK-DAG: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFFSET]](s32) +; CHECK-DAG: G_STORE [[VAL2]](s32), [[ADDR2]](p0) :: (store 4 into %ir.addr + 4) + %val = load {i32, i32}, {i32, i32} *%addr, align 4 + store {i32, i32} %val, {i32, i32} *%addr, align 4 + ret void +}