[StackSafety] Use SCEV to find mem operation length

This commit is contained in:
Vitaly Buka 2020-05-26 23:20:12 -07:00
parent d0f1f5adfa
commit 32a1f60d11
3 changed files with 19 additions and 12 deletions

View File

@ -247,9 +247,8 @@ StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
ConstantRange StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base,
TypeSize Size) {
ConstantRange SizeRange = Size.isScalable()
? ConstantRange::getFull(PointerSize)
: getRange(0, Size.getFixedSize());
ConstantRange SizeRange =
Size.isScalable() ? UnknownRange : getRange(0, Size.getFixedSize());
return getAccessRange(Addr, Base, SizeRange);
}
@ -262,13 +261,21 @@ ConstantRange StackSafetyLocalAnalysis::getMemIntrinsicAccessRange(
if (MI->getRawDest() != U)
return getRange(0, 1);
}
const auto *Len = dyn_cast<ConstantInt>(MI->getLength());
// Non-constant size => unsafe. FIXME: try SCEV getRange.
if (!Len)
auto *CalculationTy = IntegerType::getIntNTy(SE.getContext(), PointerSize);
if (!SE.isSCEVable(MI->getLength()->getType()))
return UnknownRange;
ConstantRange AccessRange =
getAccessRange(U, Base, getRange(0, Len->getZExtValue()));
return AccessRange;
const SCEV *Expr =
SE.getTruncateOrZeroExtend(SE.getSCEV(MI->getLength()), CalculationTy);
ConstantRange LenRange = SE.getSignedRange(Expr);
assert(!LenRange.isEmptySet());
if (LenRange.isSignWrappedSet() || LenRange.isFullSet() ||
LenRange.getUpper().isNegative())
return UnknownRange;
LenRange = LenRange.sextOrTrunc(PointerSize);
ConstantRange SizeRange(APInt::getNullValue(PointerSize),
LenRange.getUpper() - 1);
return getAccessRange(U, Base, SizeRange);
}
/// The function analyzes all local uses of Ptr (alloca or argument) and

View File

@ -362,7 +362,7 @@ define dso_local void @SizeCheck(i32 %sz) {
; CHECK-NEXT: args uses:
; CHECK-NEXT: sz[]: [0,1){{$}}
; CHECK-NEXT: allocas uses:
; CHECK-NEXT: x1[128]: full-set{{$}}
; CHECK-NEXT: x1[128]: [0,4294967295){{$}}
; CHECK-NOT: ]:
entry:
%x1 = alloca [128 x i8], align 16

View File

@ -55,7 +55,7 @@ define void @MemsetNonConst(i32 %size) {
; CHECK-NEXT: args uses:
; CHECK-NEXT: size[]: [0,1){{$}}
; CHECK-NEXT: allocas uses:
; CHECK-NEXT: x[4]: full-set{{$}}
; CHECK-NEXT: x[4]: [0,4294967295){{$}}
; CHECK-NOT: ]:
entry:
%x = alloca i32, align 4
@ -71,7 +71,7 @@ define void @MemsetNonConstInBounds(i1 zeroext %z) {
; CHECK-NEXT: args uses:
; CHECK-NEXT: z[]: [0,1){{$}}
; CHECK-NEXT: allocas uses:
; CHECK-NEXT: x[4]: full-set{{$}}
; CHECK-NEXT: x[4]: [0,4294967295){{$}}
; CHECK-NOT: ]:
entry:
%x = alloca i32, align 4