Skip to content

Commit a568222

Browse files
committedMay 14, 2019
[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 llvm-svn: 360656
1 parent b1f213c commit a568222

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed
 

‎llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -461,9 +461,12 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
461461
ArrayRef<uint64_t> Offsets = *VMap.getOffsets(LI);
462462
unsigned Base = getOrCreateVReg(*LI.getPointerOperand());
463463

464+
Type *OffsetIRTy = DL->getIntPtrType(LI.getPointerOperandType());
465+
LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
466+
464467
for (unsigned i = 0; i < Regs.size(); ++i) {
465468
unsigned Addr = 0;
466-
MIRBuilder.materializeGEP(Addr, Base, LLT::scalar(64), Offsets[i] / 8);
469+
MIRBuilder.materializeGEP(Addr, Base, OffsetTy, Offsets[i] / 8);
467470

468471
MachinePointerInfo Ptr(LI.getPointerOperand(), Offsets[i] / 8);
469472
unsigned BaseAlign = getMemOpAlignment(LI);
@@ -490,9 +493,12 @@ bool IRTranslator::translateStore(const User &U, MachineIRBuilder &MIRBuilder) {
490493
ArrayRef<uint64_t> Offsets = *VMap.getOffsets(*SI.getValueOperand());
491494
unsigned Base = getOrCreateVReg(*SI.getPointerOperand());
492495

496+
Type *OffsetIRTy = DL->getIntPtrType(SI.getPointerOperandType());
497+
LLT OffsetTy = getLLTForType(*OffsetIRTy, *DL);
498+
493499
for (unsigned i = 0; i < Vals.size(); ++i) {
494500
unsigned Addr = 0;
495-
MIRBuilder.materializeGEP(Addr, Base, LLT::scalar(64), Offsets[i] / 8);
501+
MIRBuilder.materializeGEP(Addr, Base, OffsetTy, Offsets[i] / 8);
496502

497503
MachinePointerInfo Ptr(SI.getPointerOperand(), Offsets[i] / 8);
498504
unsigned BaseAlign = getMemOpAlignment(SI);

‎llvm/test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll

+17
Original file line numberDiff line numberDiff line change
@@ -544,3 +544,20 @@ define i32 @test_constantstruct_v2s32_s32_s32() {
544544
%elt = extractelement <2 x i32> %vec, i32 0
545545
ret i32 %elt
546546
}
547+
548+
define void @test_load_store_struct({i32, i32} *%addr) {
549+
; Make sure the IRTranslator doesn't use an unnecessarily large GEP index type
550+
; when breaking up loads and stores of aggregates.
551+
; CHECK-LABEL: name: test_load_store_struct
552+
; CHECK: [[ADDR1:%[0-9]+]]:_(p0) = COPY $r0
553+
; CHECK-DAG: [[VAL1:%[0-9]+]]:_(s32) = G_LOAD [[ADDR1]](p0) :: (load 4 from %ir.addr)
554+
; CHECK-DAG: [[OFFSET:%[0-9]+]]:_(s32) = G_CONSTANT i32 4
555+
; CHECK-DAG: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFFSET]](s32)
556+
; CHECK-DAG: [[VAL2:%[0-9]+]]:_(s32) = G_LOAD [[ADDR2]](p0) :: (load 4 from %ir.addr + 4)
557+
; CHECK-DAG: G_STORE [[VAL1]](s32), [[ADDR1]](p0) :: (store 4 into %ir.addr)
558+
; CHECK-DAG: [[ADDR2:%[0-9]+]]:_(p0) = G_GEP [[ADDR1]], [[OFFSET]](s32)
559+
; CHECK-DAG: G_STORE [[VAL2]](s32), [[ADDR2]](p0) :: (store 4 into %ir.addr + 4)
560+
%val = load {i32, i32}, {i32, i32} *%addr, align 4
561+
store {i32, i32} %val, {i32, i32} *%addr, align 4
562+
ret void
563+
}

0 commit comments

Comments
 (0)
Please sign in to comment.