forked from OSchip/llvm-project
[StackSafety] Bailout more aggressively
Many edge cases, e.g. wrapped ranges, can be processed precisely without bailout. However it's very unlikely that memory access with min/max integer offsets will be classified as safe anyway. Early bailout may help with ThinLTO where we can drop unsafe parameters from summaries.
This commit is contained in:
parent
b277382311
commit
14f3357586
|
@ -85,7 +85,11 @@ struct UseInfo {
|
||||||
|
|
||||||
explicit UseInfo(unsigned PointerSize) : Range{PointerSize, false} {}
|
explicit UseInfo(unsigned PointerSize) : Range{PointerSize, false} {}
|
||||||
|
|
||||||
void updateRange(ConstantRange R) { Range = Range.unionWith(R); }
|
void updateRange(const ConstantRange &R) {
|
||||||
|
assert(!R.isUpperSignWrapped());
|
||||||
|
Range = Range.unionWith(R);
|
||||||
|
assert(!Range.isUpperSignWrapped());
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
raw_ostream &operator<<(raw_ostream &OS, const UseInfo &U) {
|
raw_ostream &operator<<(raw_ostream &OS, const UseInfo &U) {
|
||||||
|
@ -189,6 +193,11 @@ StackSafetyInfo makeSSI(FunctionInfo Info) {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// Check if we should bailout for such ranges.
|
||||||
|
bool isUnsafe(const ConstantRange &R) {
|
||||||
|
return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
|
||||||
|
}
|
||||||
|
|
||||||
class StackSafetyLocalAnalysis {
|
class StackSafetyLocalAnalysis {
|
||||||
Function &F;
|
Function &F;
|
||||||
const DataLayout &DL;
|
const DataLayout &DL;
|
||||||
|
@ -227,7 +236,7 @@ ConstantRange StackSafetyLocalAnalysis::offsetFrom(Value *Addr, Value *Base) {
|
||||||
AllocaOffsetRewriter Rewriter(SE, Base);
|
AllocaOffsetRewriter Rewriter(SE, Base);
|
||||||
const SCEV *Expr = Rewriter.visit(SE.getSCEV(Addr));
|
const SCEV *Expr = Rewriter.visit(SE.getSCEV(Addr));
|
||||||
ConstantRange Offset = SE.getSignedRange(Expr);
|
ConstantRange Offset = SE.getSignedRange(Expr);
|
||||||
if (Offset.isEmptySet() || Offset.isFullSet() || Offset.isSignWrappedSet())
|
if (isUnsafe(Offset))
|
||||||
return UnknownRange;
|
return UnknownRange;
|
||||||
return Offset.sextOrTrunc(PointerSize);
|
return Offset.sextOrTrunc(PointerSize);
|
||||||
}
|
}
|
||||||
|
@ -238,18 +247,26 @@ StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
|
||||||
// Zero-size loads and stores do not access memory.
|
// Zero-size loads and stores do not access memory.
|
||||||
if (SizeRange.isEmptySet())
|
if (SizeRange.isEmptySet())
|
||||||
return ConstantRange::getEmpty(PointerSize);
|
return ConstantRange::getEmpty(PointerSize);
|
||||||
|
assert(!isUnsafe(SizeRange));
|
||||||
|
|
||||||
ConstantRange AccessStartRange = offsetFrom(Addr, Base);
|
ConstantRange AccessRange = offsetFrom(Addr, Base);
|
||||||
ConstantRange AccessRange = AccessStartRange.add(SizeRange);
|
if (isUnsafe(AccessRange))
|
||||||
assert(!AccessRange.isEmptySet());
|
return UnknownRange;
|
||||||
|
|
||||||
|
if (AccessRange.signedAddMayOverflow(SizeRange) !=
|
||||||
|
ConstantRange::OverflowResult::NeverOverflows)
|
||||||
|
return UnknownRange;
|
||||||
|
AccessRange = AccessRange.add(SizeRange);
|
||||||
|
if (isUnsafe(AccessRange))
|
||||||
|
return UnknownRange;
|
||||||
return AccessRange;
|
return AccessRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantRange StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
|
ConstantRange StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
|
||||||
TypeSize Size) {
|
TypeSize Size) {
|
||||||
ConstantRange SizeRange =
|
if (Size.isScalable())
|
||||||
Size.isScalable() ? UnknownRange : getRange(0, Size.getFixedSize());
|
return UnknownRange;
|
||||||
return getAccessRange(Addr, Base, SizeRange);
|
return getAccessRange(Addr, Base, getRange(0, Size.getFixedSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
|
ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
|
||||||
|
@ -268,9 +285,8 @@ ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
|
||||||
const SCEV *Expr =
|
const SCEV *Expr =
|
||||||
SE.getTruncateOrZeroExtend(SE.getSCEV(MI->getLength()), CalculationTy);
|
SE.getTruncateOrZeroExtend(SE.getSCEV(MI->getLength()), CalculationTy);
|
||||||
ConstantRange LenRange = SE.getSignedRange(Expr);
|
ConstantRange LenRange = SE.getSignedRange(Expr);
|
||||||
assert(!LenRange.isEmptySet());
|
assert(!isUnsafe(LenRange));
|
||||||
if (LenRange.isSignWrappedSet() || LenRange.isFullSet() ||
|
if (LenRange.getUpper().isNegative())
|
||||||
LenRange.getUpper().isNegative())
|
|
||||||
return UnknownRange;
|
return UnknownRange;
|
||||||
LenRange = LenRange.sextOrTrunc(PointerSize);
|
LenRange = LenRange.sextOrTrunc(PointerSize);
|
||||||
ConstantRange SizeRange(APInt::getNullValue(PointerSize),
|
ConstantRange SizeRange(APInt::getNullValue(PointerSize),
|
||||||
|
|
Loading…
Reference in New Issue