diff options
-rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 9 | ||||
-rw-r--r-- | llvm/test/Transforms/CorrelatedValuePropagation/pointer.ll | 35 |
2 files changed, 40 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 5f5d1be9baa..8cff7a696b2 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -1943,6 +1943,10 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { } } + // Some of the tests below are recursive, so bail out if we hit the limit. + if (Depth++ >= MaxDepth) + return false; + // Check for pointer simplifications. if (V->getType()->isPointerTy()) { // Alloca never returns null, malloc might. @@ -1963,13 +1967,10 @@ bool isKnownNonZero(const Value *V, unsigned Depth, const Query &Q) { if (CS.isReturnNonNull()) return true; if (const auto *RP = getArgumentAliasingToReturnedPointer(CS)) - return isKnownNonZero(RP, Depth + 1, Q); + return isKnownNonZero(RP, Depth, Q); } } - // The remaining tests are all recursive, so bail out if we hit the limit. - if (Depth++ >= MaxDepth) - return false; // Check for recursive pointer simplifications. if (V->getType()->isPointerTy()) { diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/pointer.ll b/llvm/test/Transforms/CorrelatedValuePropagation/pointer.ll new file mode 100644 index 00000000000..9242d7b8aff --- /dev/null +++ b/llvm/test/Transforms/CorrelatedValuePropagation/pointer.ll @@ -0,0 +1,35 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -correlated-propagation -S -o - %s | FileCheck %s + +; Testcase that checks that we don't end in a neverending recursion resulting in +; a segmentation fault. The checks below verify that nothing is changed. + +declare dso_local i16* @f2(i16* readnone returned) local_unnamed_addr + +define dso_local void @f3() local_unnamed_addr { +; CHECK-LABEL: @f3( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.end: +; CHECK-NEXT: [[CALL6:%.*]] = call i16* @f2(i16* [[CALL6]]) +; CHECK-NEXT: br i1 false, label [[FOR_COND]], label [[FOR_COND3:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[C_0:%.*]] = phi i16* [ undef, [[ENTRY:%.*]] ], [ [[CALL6]], [[FOR_END:%.*]] ] +; CHECK-NEXT: br label [[FOR_COND3]] +; CHECK: for.cond3: +; CHECK-NEXT: ret void +; +entry: + br label %for.cond + +for.end: + %call6 = call i16* @f2(i16* %call6) + br i1 false, label %for.cond, label %for.cond3 + +for.cond: + %c.0 = phi i16* [ undef, %entry ], [ %call6, %for.end ] + br label %for.cond3 + +for.cond3: + ret void +} |