diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/SROA.cpp')
-rw-r--r-- | llvm/lib/Transforms/Scalar/SROA.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp index eaf73ee5e68..f69c750f3f9 100644 --- a/llvm/lib/Transforms/Scalar/SROA.cpp +++ b/llvm/lib/Transforms/Scalar/SROA.cpp @@ -4153,8 +4153,13 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { for (auto &P : AS.partitions()) { if (AllocaInst *NewAI = rewritePartition(AI, AS, P)) { Changed = true; - if (NewAI != &AI) - Pieces.push_back(Piece(NewAI, P.beginOffset(), P.size())); + if (NewAI != &AI) { + uint64_t SizeOfByte = 8; + uint64_t AllocaSize = DL->getTypeSizeInBits(NewAI->getAllocatedType()); + // Don't include any padding. + uint64_t Size = std::min(AllocaSize, P.size() * SizeOfByte); + Pieces.push_back(Piece(NewAI, P.beginOffset() * SizeOfByte, Size)); + } } ++NumPartitions; } @@ -4178,12 +4183,17 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) { if (IsSplit || Expr.isBitPiece()) { // If this alloca is already a scalar replacement of a larger aggregate, // Piece.Offset describes the offset inside the scalar. - unsigned Offset = Expr.isBitPiece() ? Expr.getBitPieceOffset() : 0; - assert((Offset == 0 || - Offset+Piece.Offset+Piece.Size*8 <= - Expr.getBitPieceOffset()+Expr.getBitPieceSize()) && - "inner piece is not inside original alloca"); - PieceExpr = DIB.createBitPieceExpression(Offset+Piece.Offset*8, Piece.Size*8); + uint64_t Offset = Expr.isBitPiece() ? Expr.getBitPieceOffset() : 0; + uint64_t Start = Offset + Piece.Offset; + uint64_t Size = Piece.Size; + if (Expr.isBitPiece()) { + uint64_t AbsEnd = Expr.getBitPieceOffset() + Expr.getBitPieceSize(); + if (Start >= AbsEnd) + // No need to describe a SROAed padding. + continue; + Size = std::min(Size, AbsEnd - Start); + } + PieceExpr = DIB.createBitPieceExpression(Start, Size); } // Remove any existing dbg.declare intrinsic describing the same alloca. |