forked from OSchip/llvm-project
[SROA] Handle over-large loads during presplitting
When a load extends past the extent of the alloca, SROA will restrict the slice size to extend to the end of the alloca only. However, presplitting was asserting that the load size and the slice size match exactly, which does not hold in this case. Relax the assertion to only require that the load size is greater or equal than the slice size.
This commit is contained in:
parent
d58ef6df0d
commit
d7cf7ec05d
|
@ -3965,16 +3965,15 @@ bool SROAPass::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
|
|||
for (LoadInst *LI : Loads) {
|
||||
SplitLoads.clear();
|
||||
|
||||
IntegerType *Ty = cast<IntegerType>(LI->getType());
|
||||
assert(Ty->getBitWidth() % 8 == 0);
|
||||
uint64_t LoadSize = Ty->getBitWidth() / 8;
|
||||
assert(LoadSize > 0 && "Cannot have a zero-sized integer load!");
|
||||
|
||||
auto &Offsets = SplitOffsetsMap[LI];
|
||||
assert(LoadSize == Offsets.S->endOffset() - Offsets.S->beginOffset() &&
|
||||
"Slice size should always match load size exactly!");
|
||||
unsigned SliceSize = Offsets.S->endOffset() - Offsets.S->beginOffset();
|
||||
assert(LI->getType()->getIntegerBitWidth() % 8 == 0 &&
|
||||
"Load must have type size equal to store size");
|
||||
assert(LI->getType()->getIntegerBitWidth() / 8 >= SliceSize &&
|
||||
"Load must be >= slice size");
|
||||
|
||||
uint64_t BaseOffset = Offsets.S->beginOffset();
|
||||
assert(BaseOffset + LoadSize > BaseOffset &&
|
||||
assert(BaseOffset + SliceSize > BaseOffset &&
|
||||
"Cannot represent alloca access size using 64-bit integers!");
|
||||
|
||||
Instruction *BasePtr = cast<Instruction>(LI->getPointerOperand());
|
||||
|
@ -3985,7 +3984,7 @@ bool SROAPass::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
|
|||
uint64_t PartOffset = 0, PartSize = Offsets.Splits.front();
|
||||
int Idx = 0, Size = Offsets.Splits.size();
|
||||
for (;;) {
|
||||
auto *PartTy = Type::getIntNTy(Ty->getContext(), PartSize * 8);
|
||||
auto *PartTy = Type::getIntNTy(LI->getContext(), PartSize * 8);
|
||||
auto AS = LI->getPointerAddressSpace();
|
||||
auto *PartPtrTy = PartTy->getPointerTo(AS);
|
||||
LoadInst *PLoad = IRB.CreateAlignedLoad(
|
||||
|
@ -4018,7 +4017,7 @@ bool SROAPass::presplitLoadsAndStores(AllocaInst &AI, AllocaSlices &AS) {
|
|||
// Setup the next partition.
|
||||
PartOffset = Offsets.Splits[Idx];
|
||||
++Idx;
|
||||
PartSize = (Idx < Size ? Offsets.Splits[Idx] : LoadSize) - PartOffset;
|
||||
PartSize = (Idx < Size ? Offsets.Splits[Idx] : SliceSize) - PartOffset;
|
||||
}
|
||||
|
||||
// Now that we have the split loads, do the slow walk over all uses of the
|
||||
|
|
|
@ -158,3 +158,19 @@ define void @PR50910() {
|
|||
call void @llvm.memset.p0i8.i64(i8* align 8 %t1, i8 0, i64 4294967296, i1 false)
|
||||
ret void
|
||||
}
|
||||
|
||||
define i1 @presplit_overlarge_load() {
|
||||
; CHECK-LABEL: @presplit_overlarge_load(
|
||||
; CHECK-NEXT: [[A_SROA_0:%.*]] = alloca i8, align 2
|
||||
; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_L11:%.*]] = load i8, i8* [[A_SROA_0]], align 2
|
||||
; CHECK-NEXT: [[A_SROA_0_0_A_1_SROA_CAST3:%.*]] = bitcast i8* [[A_SROA_0]] to i1*
|
||||
; CHECK-NEXT: [[A_SROA_0_0_A_SROA_0_0_L2:%.*]] = load i1, i1* [[A_SROA_0_0_A_1_SROA_CAST3]], align 2
|
||||
; CHECK-NEXT: ret i1 [[A_SROA_0_0_A_SROA_0_0_L2]]
|
||||
;
|
||||
%A = alloca i16
|
||||
%A.32 = bitcast i16* %A to i32*
|
||||
%A.1 = bitcast i16* %A to i1*
|
||||
%L1 = load i32, i32* %A.32
|
||||
%L2 = load i1, i1* %A.1
|
||||
ret i1 %L2
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue