diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-04-22 15:22:33 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-04-22 15:22:33 +0000 |
commit | 52968a1c765e43000f904ecb27a6353b0185bcd6 (patch) | |
tree | 86c5c79552c9e9815697ffb465a30b3181f98d95 /lib/CodeGen/CGRecordLayoutBuilder.cpp | |
parent | 4651efb5ba5710c91b58c8b86872b264dd71f464 (diff) |
IRgen: Fix another case where we generated an invalid access component when we
immediately narrowed the access size. Fix this (and previous case) by just
choosing a better access size up-front.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102068 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGRecordLayoutBuilder.cpp')
-rw-r--r-- | lib/CodeGen/CGRecordLayoutBuilder.cpp | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/lib/CodeGen/CGRecordLayoutBuilder.cpp b/lib/CodeGen/CGRecordLayoutBuilder.cpp index ee8ae5224f..6302cf8d1f 100644 --- a/lib/CodeGen/CGRecordLayoutBuilder.cpp +++ b/lib/CodeGen/CGRecordLayoutBuilder.cpp @@ -191,7 +191,14 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, // Round down from the field offset to find the first access position that is // at an aligned offset of the initial access type. - uint64_t AccessStart = FieldOffset - (FieldOffset % TypeSizeInBits); + uint64_t AccessStart = FieldOffset - (FieldOffset % AccessWidth); + + // Adjust initial access size to fit within record. + while (AccessWidth > 8 && + AccessStart + AccessWidth > ContainingTypeSizeInBits) { + AccessWidth >>= 1; + AccessStart = FieldOffset - (FieldOffset % AccessWidth); + } while (AccessedTargetBits < FieldSize) { // Check that we can access using a type of this size, without reading off @@ -210,20 +217,12 @@ static CGBitFieldInfo ComputeBitFieldInfo(CodeGenTypes &Types, // target. We are reading bits [AccessStart, AccessStart + AccessWidth); the // intersection with [FieldOffset, FieldOffset + FieldSize) gives the bits // in the target that we are reading. + assert(FieldOffset < AccessStart + AccessWidth && "Invalid access start!"); + assert(AccessStart < FieldOffset + FieldSize && "Invalid access start!"); uint64_t AccessBitsInFieldStart = std::max(AccessStart, FieldOffset); uint64_t AccessBitsInFieldSize = - std::min(AccessWidth - (AccessBitsInFieldStart - AccessStart), - FieldSize - (AccessBitsInFieldStart-FieldOffset)); - - // If we haven't accessed any target bits yet and narrowed the access size, - // we might not have reached any target bits yet. - // - // FIXME: This test is unnecessarily once we choose the initial acccess size - // more intelligently. - if (!AccessedTargetBits && AccessBitsInFieldSize == 0) { - AccessStart += AccessWidth; - continue; - } + std::min(AccessWidth + AccessStart, + FieldOffset + FieldSize) - AccessBitsInFieldStart; assert(NumComponents < 3 && "Unexpected number of components!"); CGBitFieldInfo::AccessInfo &AI = Components[NumComponents++]; |