aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-01-11 20:15:20 +0000
committerChris Lattner <sabre@nondot.org>2009-01-11 20:15:20 +0000
commitdbc3bc258576672c26d32a0fb56437d87409dec1 (patch)
tree5385b9abbb864703f03bafdc53783cc18a070467
parent1ed86d74a87baca2e42b90873345c63811647b1d (diff)
Make a couple of cleanups to the instcombine bitcast/gep
canonicalization transform based on duncan's comments: 1) improve the comment about %. 2) within our index loop make sure the offset stays within the *type size*, instead of within the *abi size*. This allows us to reason explicitly about landing in tail padding and means that issues like non-zero offsets into [0 x foo] types don't occur anymore. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62045 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/Scalar/InstructionCombining.cpp25
1 files changed, 13 insertions, 12 deletions
diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp
index a183c14ba5..fd15f2e1ca 100644
--- a/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -7712,7 +7712,7 @@ static bool FindElementAtOffset(const Type *Ty, int64_t Offset,
FirstIdx = Offset/TySize;
Offset %= TySize;
- // Handle silly modulus not returning values [0..TySize).
+ // Handle hosts where % returns negative instead of values [0..TySize).
if (Offset < 0) {
--FirstIdx;
Offset += TySize;
@@ -7725,12 +7725,15 @@ static bool FindElementAtOffset(const Type *Ty, int64_t Offset,
// Index into the types. If we fail, set OrigBase to null.
while (Offset) {
+ // Indexing into tail padding between struct/array elements.
+ if (uint64_t(Offset*8) >= TD->getTypeSizeInBits(Ty))
+ return false;
+
if (const StructType *STy = dyn_cast<StructType>(Ty)) {
const StructLayout *SL = TD->getStructLayout(STy);
- if (Offset >= (int64_t)SL->getSizeInBytes()) {
- // We can't index into this, bail out.
- return false;
- }
+ assert(Offset < (int64_t)SL->getSizeInBytes() &&
+ "Offset must stay within the indexed type");
+
unsigned Elt = SL->getElementContainingOffset(Offset);
NewIndices.push_back(ConstantInt::get(Type::Int32Ty, Elt));
@@ -7738,15 +7741,13 @@ static bool FindElementAtOffset(const Type *Ty, int64_t Offset,
Ty = STy->getElementType(Elt);
} else if (isa<ArrayType>(Ty) || isa<VectorType>(Ty)) {
const SequentialType *STy = cast<SequentialType>(Ty);
- if (uint64_t EltSize = TD->getABITypeSize(STy->getElementType())) {
- NewIndices.push_back(ConstantInt::get(IntPtrTy,Offset/EltSize));
- Offset %= EltSize;
- } else {
- NewIndices.push_back(ConstantInt::get(IntPtrTy, 0));
- }
+ uint64_t EltSize = TD->getABITypeSize(STy->getElementType());
+ assert(EltSize && "Cannot index into a zero-sized array");
+ NewIndices.push_back(ConstantInt::get(IntPtrTy,Offset/EltSize));
+ Offset %= EltSize;
Ty = STy->getElementType();
} else {
- // Otherwise, we can't index into this, bail out.
+ // Otherwise, we can't index into the middle of this atomic type, bail.
return false;
}
}