Skip to content

Commit

Permalink
Unpack array of all sizes in InstCombine
Browse files Browse the repository at this point in the history
Summary: This is another step toward improving fca support. This unpack load of array in a series of load to array's elements.

Reviewers: chandlerc, joker.eph, majnemer, reames, hfinkel

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D15890

llvm-svn: 262521
  • Loading branch information
deadalnix committed Mar 2, 2016
1 parent dce8d8b commit 7cd3fe7
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 5 deletions.
43 changes: 38 additions & 5 deletions llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
Expand Up @@ -574,13 +574,46 @@ static Instruction *unpackLoadToAggregate(InstCombiner &IC, LoadInst &LI) {
}

if (auto *AT = dyn_cast<ArrayType>(T)) {
// If the array only have one element, we unpack.
if (AT->getNumElements() == 1) {
LoadInst *NewLoad = combineLoadToNewType(IC, LI, AT->getElementType(),
".unpack");
auto *ET = AT->getElementType();
auto NumElements = AT->getNumElements();
if (NumElements == 1) {
LoadInst *NewLoad = combineLoadToNewType(IC, LI, ET, ".unpack");
return IC.replaceInstUsesWith(LI, IC.Builder->CreateInsertValue(
UndefValue::get(T), NewLoad, 0, LI.getName()));
UndefValue::get(T), NewLoad, 0, Name));
}

const DataLayout &DL = IC.getDataLayout();
auto EltSize = DL.getTypeAllocSize(ET);
auto Align = LI.getAlignment();
if (!Align)
Align = DL.getABITypeAlignment(T);

SmallString<16> LoadName = Name;
LoadName += ".unpack";
SmallString<16> EltName = Name;
EltName += ".elt";

auto *Addr = LI.getPointerOperand();
auto *IdxType = Type::getInt64Ty(T->getContext());
auto *Zero = ConstantInt::get(IdxType, 0);

Value *V = UndefValue::get(T);
uint64_t Offset = 0;
for (uint64_t i = 0; i < NumElements; i++) {
Value *Indices[2] = {
Zero,
ConstantInt::get(IdxType, i),
};
auto *Ptr = IC.Builder->CreateInBoundsGEP(AT, Addr, makeArrayRef(Indices),
EltName);
auto *L = IC.Builder->CreateAlignedLoad(Ptr, MinAlign(Align, Offset),
LoadName);
V = IC.Builder->CreateInsertValue(V, L, i);
Offset += EltSize;
}

V->setName(Name);
return IC.replaceInstUsesWith(LI, V);
}

return nullptr;
Expand Down
21 changes: 21 additions & 0 deletions llvm/test/Transforms/InstCombine/unpack-fca.ll
Expand Up @@ -137,6 +137,27 @@ define %B @structB(%B* %b.ptr) {
ret %B %1
}

define [2 x %B] @loadArrayOfB([2 x %B]* %ab.ptr) {
; CHECK-LABEL: loadArrayOfB
; CHECK-NEXT: [[GEP1:%[a-z0-9\.]+]] = getelementptr inbounds [2 x %B], [2 x %B]* %ab.ptr, i64 0, i64 0, i32 0
; CHECK-NEXT: [[LOAD1:%[a-z0-9\.]+]] = load i8*, i8** [[GEP1]], align 8
; CHECK-NEXT: [[IV1:%[a-z0-9\.]+]] = insertvalue %B undef, i8* [[LOAD1]], 0
; CHECK-NEXT: [[GEP2:%[a-z0-9\.]+]] = getelementptr inbounds [2 x %B], [2 x %B]* %ab.ptr, i64 0, i64 0, i32 1
; CHECK-NEXT: [[LOAD2:%[a-z0-9\.]+]] = load i64, i64* [[GEP2]], align 8
; CHECK-NEXT: [[IV2:%[a-z0-9\.]+]] = insertvalue %B [[IV1]], i64 [[LOAD2]], 1
; CHECK-NEXT: [[IV3:%[a-z0-9\.]+]] = insertvalue [2 x %B] undef, %B [[IV2]], 0
; CHECK-NEXT: [[GEP3:%[a-z0-9\.]+]] = getelementptr inbounds [2 x %B], [2 x %B]* %ab.ptr, i64 0, i64 1, i32 0
; CHECK-NEXT: [[LOAD3:%[a-z0-9\.]+]] = load i8*, i8** [[GEP3]], align 8
; CHECK-NEXT: [[IV4:%[a-z0-9\.]+]] = insertvalue %B undef, i8* [[LOAD3]], 0
; CHECK-NEXT: [[GEP4:%[a-z0-9\.]+]] = getelementptr inbounds [2 x %B], [2 x %B]* %ab.ptr, i64 0, i64 1, i32 1
; CHECK-NEXT: [[LOAD4:%[a-z0-9\.]+]] = load i64, i64* [[GEP4]], align 8
; CHECK-NEXT: [[IV5:%[a-z0-9\.]+]] = insertvalue %B [[IV4]], i64 [[LOAD4]], 1
; CHECK-NEXT: [[IV6:%[a-z0-9\.]+]] = insertvalue [2 x %B] [[IV3]], %B [[IV5]], 1
; CHECK-NEXT: ret [2 x %B] [[IV6]]
%1 = load [2 x %B], [2 x %B]* %ab.ptr, align 8
ret [2 x %B] %1
}

%struct.S = type <{ i8, %struct.T }>
%struct.T = type { i32, i32 }

Expand Down

0 comments on commit 7cd3fe7

Please sign in to comment.