diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Analysis/ValueTracking.cpp | 5 | ||||
| -rw-r--r-- | llvm/unittests/Analysis/ValueTrackingTest.cpp | 3 | 
2 files changed, 8 insertions, 0 deletions
| diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index e49f28513b8..ebd214586d6 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -4285,6 +4285,11 @@ bool llvm::isGuaranteedToTransferExecutionToSuccessor(const Instruction *I) {      if (!CS.doesNotThrow())        return false; +    // A function which doens't throw and has "willreturn" attribute will +    // always return. +    if (CS.hasFnAttr(Attribute::WillReturn)) +      return true; +      // Non-throwing call sites can loop infinitely, call exit/pthread_exit      // etc. and thus not return.  However, LLVM already assumes that      // diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index df32287dbff..fbb07a9ac11 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -464,6 +464,7 @@ TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {        "declare void @nounwind_argmemonly(i32*) nounwind argmemonly "        "declare void @throws_but_readonly(i32*) readonly "        "declare void @throws_but_argmemonly(i32*) argmemonly " +      "declare void @nounwind_willreturn(i32*) nounwind willreturn"        " "        "declare void @unknown(i32*) "        " " @@ -476,6 +477,7 @@ TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {        "  call void @unknown(i32* %p) nounwind argmemonly "        "  call void @unknown(i32* %p) readonly "        "  call void @unknown(i32* %p) argmemonly " +      "  call void @nounwind_willreturn(i32* %p)"        "  ret void "        "} "; @@ -497,6 +499,7 @@ TEST(ValueTracking, GuaranteedToTransferExecutionToSuccessor) {        true,  // call void @unknown(i32* %p) nounwind argmemonly        false, // call void @unknown(i32* %p) readonly        false, // call void @unknown(i32* %p) argmemonly +      true,  // call void @nounwind_willreturn(i32* %p)        false, // ret void    }; | 

