From 5e300846b97b36ec72245f05599808179345c5b0 Mon Sep 17 00:00:00 2001 From: Diana Picus Date: Tue, 14 May 2019 09:25:17 +0000 Subject: [PATCH] [IRTranslator] Don't hardcode GEP index type When breaking up loads and stores of aggregates, the IRTranslator uses LLT::scalar(64) for the index type of the G_GEP instructions that compute the addresses. This is unnecessarily large for 32-bit targets. Use the int ptr type provided by the DataLayout instead. Note that we're already doing the right thing when translating getelementptr instructions from the IR. This is just an oversight when generating new ones while translating loads/stores. Both x86 and AArch64 already have tests confirming that the old behaviour is preserved for 64-bit targets. Differential Revision: https://reviews.llvm.org/D61852 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@360656 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/GlobalISel/IRTranslator.cpp | 10 ++++++++-- test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/CodeGen/GlobalISel/IRTranslator.cpp b/lib/CodeGen/GlobalISel/IRTranslator.cpp index ba560544867..939a9a92cc0 100644 --- a/lib/CodeGen/GlobalISel/IRTranslator.cpp +++ b/lib/CodeGen/GlobalISel/IRTranslator.cpp @@ -461,9 +461,12 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) { 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 @@ bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) { 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); diff --git a/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll b/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll index 175673740cd..1d7ca322ce9 100644 --- a/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll +++ b/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll @@ -544,3 +544,20 @@ define i32 @test_constantstruct_v2s32_s32_s32() { %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 +} -- 2.11.0