[llvm] dee812a - [StackSafety] Fix union which produces wrapped sets
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Sun Aug 9 23:20:33 PDT 2020
Author: Vitaly Buka
Date: 2020-08-09T23:20:17-07:00
New Revision: dee812a297c2a5810be7674680314ba9150fe50c
URL: https://github.com/llvm/llvm-project/commit/dee812a297c2a5810be7674680314ba9150fe50c
DIFF: https://github.com/llvm/llvm-project/commit/dee812a297c2a5810be7674680314ba9150fe50c.diff
LOG: [StackSafety] Fix union which produces wrapped sets
Added:
Modified:
llvm/lib/Analysis/StackSafetyAnalysis.cpp
llvm/test/Analysis/StackSafetyAnalysis/local.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp
index 2629a633a38e..44eace4212b8 100644
--- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp
+++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp
@@ -61,6 +61,32 @@ static cl::opt<bool> StackSafetyRun("stack-safety-run", cl::init(false),
namespace {
+// Check if we should bailout for such ranges.
+bool isUnsafe(const ConstantRange &R) {
+ return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
+}
+
+ConstantRange addOverflowNever(const ConstantRange &L, const ConstantRange &R) {
+ assert(!L.isSignWrappedSet());
+ assert(!R.isSignWrappedSet());
+ if (L.signedAddMayOverflow(R) !=
+ ConstantRange::OverflowResult::NeverOverflows)
+ return ConstantRange::getFull(L.getBitWidth());
+ ConstantRange Result = L.add(R);
+ assert(!Result.isSignWrappedSet());
+ return Result;
+}
+
+ConstantRange unionNoWrap(const ConstantRange &L, const ConstantRange &R) {
+ assert(!L.isSignWrappedSet());
+ assert(!R.isSignWrappedSet());
+ auto Result = L.unionWith(R);
+ // Two non-wrapped sets can produce wrapped.
+ if (Result.isSignWrappedSet())
+ Result = ConstantRange::getFull(Result.getBitWidth());
+ return Result;
+}
+
/// Describes use of address in as a function call argument.
template <typename CalleeTy> struct CallInfo {
/// Function being called.
@@ -93,11 +119,7 @@ template <typename CalleeTy> struct UseInfo {
UseInfo(unsigned PointerSize) : Range{PointerSize, false} {}
- void updateRange(const ConstantRange &R) {
- assert(!R.isUpperSignWrapped());
- Range = Range.unionWith(R);
- assert(!Range.isUpperSignWrapped());
- }
+ void updateRange(const ConstantRange &R) { Range = unionNoWrap(Range, R); }
};
template <typename CalleeTy>
@@ -108,18 +130,6 @@ raw_ostream &operator<<(raw_ostream &OS, const UseInfo<CalleeTy> &U) {
return OS;
}
-// Check if we should bailout for such ranges.
-bool isUnsafe(const ConstantRange &R) {
- return R.isEmptySet() || R.isFullSet() || R.isUpperSignWrapped();
-}
-
-ConstantRange addOverflowNever(const ConstantRange &L, const ConstantRange &R) {
- if (L.signedAddMayOverflow(R) !=
- ConstantRange::OverflowResult::NeverOverflows)
- return ConstantRange(L.getBitWidth(), true);
- return L.add(R);
-}
-
/// Calculate the allocation size of a given alloca. Returns empty range
// in case of confution.
ConstantRange getStaticAllocaSizeRange(const AllocaInst &AI) {
@@ -515,7 +525,7 @@ bool StackSafetyDataFlowAnalysis<CalleeTy>::updateOneUse(UseInfo<CalleeTy> &US,
if (UpdateToFullSet)
US.Range = UnknownRange;
else
- US.Range = US.Range.unionWith(CalleeRange);
+ US.updateRange(CalleeRange);
}
}
return Changed;
diff --git a/llvm/test/Analysis/StackSafetyAnalysis/local.ll b/llvm/test/Analysis/StackSafetyAnalysis/local.ll
index 89542a8d72bb..f7973108a1da 100644
--- a/llvm/test/Analysis/StackSafetyAnalysis/local.ll
+++ b/llvm/test/Analysis/StackSafetyAnalysis/local.ll
@@ -11,6 +11,7 @@ target triple = "x86_64-unknown-linux-gnu"
declare void @llvm.memset.p0i8.i32(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
declare void @llvm.memmove.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
+declare void @llvm.memset.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile)
; Address leaked.
define void @LeakAddress() {
@@ -81,6 +82,33 @@ entry:
ret void
}
+define dso_local void @WriteMinMax(i8* %p) {
+; CHECK-LABEL: @WriteMinMax{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: p[]: full-set
+; CHECK-NEXT: allocas uses:
+; CHECK-EMPTY:
+entry:
+ %p1 = getelementptr i8, i8* %p, i64 9223372036854775805
+ store i8 0, i8* %p1, align 1
+ %p2 = getelementptr i8, i8* %p, i64 -9223372036854775805
+ store i8 0, i8* %p2, align 1
+ ret void
+}
+
+define dso_local void @WriteMax(i8* %p) {
+; CHECK-LABEL: @WriteMax{{$}}
+; CHECK-NEXT: args uses:
+; CHECK-NEXT: p[]: [-9223372036854775807,9223372036854775806)
+; CHECK-NEXT: allocas uses:
+; CHECK-EMPTY:
+entry:
+ call void @llvm.memset.p0i8.i64(i8* %p, i8 1, i64 9223372036854775806, i1 0)
+ %p2 = getelementptr i8, i8* %p, i64 -9223372036854775807
+ call void @llvm.memset.p0i8.i64(i8* %p2, i8 1, i64 9223372036854775806, i1 0)
+ ret void
+}
+
define void @StoreOutOfBounds() {
; CHECK-LABEL: @StoreOutOfBounds dso_preemptable{{$}}
; CHECK-NEXT: args uses:
More information about the llvm-commits
mailing list