mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-16 23:38:40 +00:00
[SROA] Fix a bug which could cause the common type finding to return
inconsistent results for different orderings of alloca slices. The fundamental issue is that it is just always a mistake to return early from this function. There is no effective early exit to leverage. This patch stops trynig to do so and simplifies the code a bit as a consequence. Original diagnosis and patch by James Molloy with some name tweaks by me in part reflecting feedback from Duncan Smith on the mailing list. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199771 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3d218156f8
commit
c04f2c99ab
@ -957,7 +957,11 @@ static Type *findCommonType(AllocaSlices::const_iterator B,
|
|||||||
AllocaSlices::const_iterator E,
|
AllocaSlices::const_iterator E,
|
||||||
uint64_t EndOffset) {
|
uint64_t EndOffset) {
|
||||||
Type *Ty = 0;
|
Type *Ty = 0;
|
||||||
bool IgnoreNonIntegralTypes = false;
|
bool TyIsCommon = true;
|
||||||
|
IntegerType *ITy = 0;
|
||||||
|
|
||||||
|
// Note that we need to look at *every* alloca slice's Use to ensure we
|
||||||
|
// always get consistent results regardless of the order of slices.
|
||||||
for (AllocaSlices::const_iterator I = B; I != E; ++I) {
|
for (AllocaSlices::const_iterator I = B; I != E; ++I) {
|
||||||
Use *U = I->getUse();
|
Use *U = I->getUse();
|
||||||
if (isa<IntrinsicInst>(*U->getUser()))
|
if (isa<IntrinsicInst>(*U->getUser()))
|
||||||
@ -970,37 +974,30 @@ static Type *findCommonType(AllocaSlices::const_iterator B,
|
|||||||
UserTy = LI->getType();
|
UserTy = LI->getType();
|
||||||
} else if (StoreInst *SI = dyn_cast<StoreInst>(U->getUser())) {
|
} else if (StoreInst *SI = dyn_cast<StoreInst>(U->getUser())) {
|
||||||
UserTy = SI->getValueOperand()->getType();
|
UserTy = SI->getValueOperand()->getType();
|
||||||
} else {
|
|
||||||
IgnoreNonIntegralTypes = true; // Give up on anything but an iN type.
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IntegerType *ITy = dyn_cast<IntegerType>(UserTy)) {
|
if (!UserTy || (Ty && Ty != UserTy))
|
||||||
|
TyIsCommon = false; // Give up on anything but an iN type.
|
||||||
|
else
|
||||||
|
Ty = UserTy;
|
||||||
|
|
||||||
|
if (IntegerType *UserITy = dyn_cast_or_null<IntegerType>(UserTy)) {
|
||||||
// If the type is larger than the partition, skip it. We only encounter
|
// If the type is larger than the partition, skip it. We only encounter
|
||||||
// this for split integer operations where we want to use the type of the
|
// this for split integer operations where we want to use the type of the
|
||||||
// entity causing the split. Also skip if the type is not a byte width
|
// entity causing the split. Also skip if the type is not a byte width
|
||||||
// multiple.
|
// multiple.
|
||||||
if (ITy->getBitWidth() % 8 != 0 ||
|
if (UserITy->getBitWidth() % 8 != 0 ||
|
||||||
ITy->getBitWidth() / 8 > (EndOffset - B->beginOffset()))
|
UserITy->getBitWidth() / 8 > (EndOffset - B->beginOffset()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// If we have found an integer type use covering the alloca, use that
|
// Track the largest bitwidth integer type used in this way in case there
|
||||||
// regardless of the other types, as integers are often used for
|
// is no common type.
|
||||||
// a "bucket of bits" type.
|
if (!ITy || ITy->getBitWidth() < UserITy->getBitWidth())
|
||||||
//
|
ITy = UserITy;
|
||||||
// NB: This *must* be the only return from inside the loop so that the
|
|
||||||
// order of slices doesn't impact the computed type.
|
|
||||||
return ITy;
|
|
||||||
} else if (IgnoreNonIntegralTypes) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Ty && Ty != UserTy)
|
|
||||||
IgnoreNonIntegralTypes = true; // Give up on anything but an iN type.
|
|
||||||
|
|
||||||
Ty = UserTy;
|
|
||||||
}
|
}
|
||||||
return Ty;
|
|
||||||
|
return TyIsCommon ? Ty : ITy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// PHI instructions that use an alloca and are subsequently loaded can be
|
/// PHI instructions that use an alloca and are subsequently loaded can be
|
||||||
|
Loading…
x
Reference in New Issue
Block a user