diff --git a/llvm/lib/Analysis/StackSafetyAnalysis.cpp b/llvm/lib/Analysis/StackSafetyAnalysis.cpp index 853707e9c23dd..3fb5c294acf64 100644 --- a/llvm/lib/Analysis/StackSafetyAnalysis.cpp +++ b/llvm/lib/Analysis/StackSafetyAnalysis.cpp @@ -98,6 +98,13 @@ 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) { @@ -237,10 +244,7 @@ StackSafetyLocalAnalysis::getAccessRange(Value *Addr, Value *Base, if (isUnsafe(Offsets)) return UnknownRange; - if (Offsets.signedAddMayOverflow(SizeRange) != - ConstantRange::OverflowResult::NeverOverflows) - return UnknownRange; - Offsets = Offsets.add(SizeRange); + Offsets = addOverflowNever(Offsets, SizeRange); if (isUnsafe(Offsets)) return UnknownRange; return Offsets; @@ -453,10 +457,7 @@ ConstantRange StackSafetyDataFlowAnalysis::getArgumentAccessRange( return Access; if (Access.isFullSet()) return UnknownRange; - if (Offsets.signedAddMayOverflow(Access) != - ConstantRange::OverflowResult::NeverOverflows) - return UnknownRange; - return Access.add(Offsets); + return addOverflowNever(Access, Offsets); } template diff --git a/llvm/test/Analysis/StackSafetyAnalysis/local.ll b/llvm/test/Analysis/StackSafetyAnalysis/local.ll index 75cf64fb17770..e0f450a975abc 100644 --- a/llvm/test/Analysis/StackSafetyAnalysis/local.ll +++ b/llvm/test/Analysis/StackSafetyAnalysis/local.ll @@ -459,4 +459,29 @@ entry: %z3 = bitcast i8* %z2 to [100000 x i64]* call void @ByValArray([100000 x i64]* byval %z3) ret void +} + +define dso_local i8 @LoadMinInt64(i8* %p) { + ; CHECK-LABEL: @LoadMinInt64{{$}} + ; CHECK-NEXT: args uses: + ; CHECK-NEXT: p[]: [-9223372036854775808,-9223372036854775807){{$}} + ; CHECK-NEXT: allocas uses: + ; CHECK-NOT: ]: + %p2 = getelementptr i8, i8* %p, i64 -9223372036854775808 + %v = load i8, i8* %p2, align 1 + ret i8 %v +} + +define void @Overflow() { +; CHECK-LABEL: @Overflow dso_preemptable{{$}} +; CHECK-NEXT: args uses: +; CHECK-NEXT: allocas uses: +; LOCAL: x[1]: empty-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}} +; GLOBAL: x[1]: full-set, @LoadMinInt64(arg0, [-9223372036854775808,-9223372036854775807)){{$}} +; CHECK-NOT: ]: +entry: + %x = alloca i8, align 4 + %x2 = getelementptr i8, i8* %x, i64 -9223372036854775808 + %v = call i8 @LoadMinInt64(i8* %x2) + ret void } \ No newline at end of file diff --git a/llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll b/llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll index 4d55de5b631a8..70135a3a1875a 100644 --- a/llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll +++ b/llvm/test/Analysis/StackSafetyAnalysis/memintrin.ll @@ -6,6 +6,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu" +declare void @llvm.memset.p0i8.i64(i8* %dest, i8 %val, i64 %len, i1 %isvolatile) 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)