]> granicus.if.org Git - llvm/commitdiff
[IRTranslator] Don't hardcode GEP index type
authorDiana Picus <diana.picus@linaro.org>
Tue, 14 May 2019 09:25:17 +0000 (09:25 +0000)
committerDiana Picus <diana.picus@linaro.org>
Tue, 14 May 2019 09:25:17 +0000 (09:25 +0000)
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
test/CodeGen/ARM/GlobalISel/arm-irtranslator.ll

index ba5605448671f298bf8d1eff3371583e3ce1b914..939a9a92cc01d900cc2fda50ba89cafea25fecad 100644 (file)
@@ -461,9 +461,12 @@ bool IRTranslator::translateLoad(const User &U, MachineIRBuilder &MIRBuilder) {
   ArrayRef<uint64_t> 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<uint64_t> 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 175673740cddc73252be7c88e8b09029d5de9d7b..1d7ca322ce9be32627dfb626b0944a715be63077 100644 (file)
@@ -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
+}