From: Johannes Doerfert Date: Thu, 27 Jun 2019 19:29:48 +0000 (+0000) Subject: Use "willreturn" in isGuaranteedToTransferExecutionToSuccessor X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=775fc9548c93fb5b91346e0ba352e3d83f796015;p=llvm Use "willreturn" in isGuaranteedToTransferExecutionToSuccessor The `willreturn` function attribute guarantees that a function call will come back to the call site if the call is also known not to throw. Therefore, this attribute can be used in `isGuaranteedToTransferExecutionToSuccessor`. Patch by Hideto Ueno (@uenoku) Reviewers: jdoerfert, sstefan1 Reviewed By: jdoerfert Subscribers: hiraditya, jfb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D63372 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@364580 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index e49f28513b8..ebd214586d6 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/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/unittests/Analysis/ValueTrackingTest.cpp b/unittests/Analysis/ValueTrackingTest.cpp index df32287dbff..fbb07a9ac11 100644 --- a/unittests/Analysis/ValueTrackingTest.cpp +++ b/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 };