forked from OSchip/llvm-project
Unpack array of all sizes in InstCombine
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
This commit is contained in:
parent
dce8d8b3f1
commit
7cd3fe7db6
|
@ -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;
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
Loading…
Reference in New Issue