[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