diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Transforms/IPO/Attributor.cpp | 19 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll | 14 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionAttrs/internal-noalias.ll | 2 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionAttrs/liveness.ll | 2 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionAttrs/norecurse.ll | 2 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionAttrs/noreturn_async.ll | 2 | ||||
| -rw-r--r-- | llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll | 2 |
7 files changed, 29 insertions, 14 deletions
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp index 7dfc802179c..ce720e4aff7 100644 --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -2859,6 +2859,14 @@ struct AAAlignCallSiteReturned final : AAAlignImpl { struct AANoReturnImpl : public AANoReturn { AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {} + /// See AbstractAttribute::initialize(...). + void initialize(Attributor &A) override { + AANoReturn::initialize(A); + Function *F = getAssociatedFunction(); + if (!F || F->hasFnAttribute(Attribute::WillReturn)) + indicatePessimisticFixpoint(); + } + /// See AbstractAttribute::getAsStr(). const std::string getAsStr() const override { return getAssumed() ? "noreturn" : "may-return"; @@ -2866,6 +2874,9 @@ struct AANoReturnImpl : public AANoReturn { /// See AbstractAttribute::updateImpl(Attributor &A). virtual ChangeStatus updateImpl(Attributor &A) override { + const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, getIRPosition()); + if (WillReturnAA.isKnownWillReturn()) + return indicatePessimisticFixpoint(); auto CheckForNoReturn = [](Instruction &) { return false; }; if (!A.checkForAllInstructions(CheckForNoReturn, *this, {(unsigned)Instruction::Ret})) @@ -2885,14 +2896,6 @@ struct AANoReturnFunction final : AANoReturnImpl { struct AANoReturnCallSite final : AANoReturnImpl { AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {} - /// See AbstractAttribute::initialize(...). - void initialize(Attributor &A) override { - AANoReturnImpl::initialize(A); - Function *F = getAssociatedFunction(); - if (!F) - indicatePessimisticFixpoint(); - } - /// See AbstractAttribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { // TODO: Once we have call site specific value information we can provide diff --git a/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll b/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll index e3a0f0b2504..b9139c5571a 100644 --- a/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll +++ b/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll @@ -1,4 +1,4 @@ -; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 -S < %s | FileCheck %s +; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 -S < %s | FileCheck %s ; ; Test cases specifically designed for the "no-return" function attribute. ; We use FIXME's to indicate problems and missing attributes. @@ -124,4 +124,16 @@ cond.end: ; preds = %cond.false, %cond.t ret i32 %cond } + +; TEST 6: willreturn means *not* no-return +; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn +; CHECK-NEXT: define i32 @endless_loop_but_willreturn +define i32 @endless_loop_but_willreturn(i32 %a) willreturn { +entry: + br label %while.body + +while.body: ; preds = %entry, %while.body + br label %while.body +} + attributes #0 = { noinline nounwind uwtable } diff --git a/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll b/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll index 9c4158acebf..30667ef13f6 100644 --- a/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll +++ b/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll @@ -1,4 +1,4 @@ -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=5 < %s | FileCheck %s +; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 < %s | FileCheck %s define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 { entry: diff --git a/llvm/test/Transforms/FunctionAttrs/liveness.ll b/llvm/test/Transforms/FunctionAttrs/liveness.ll index b6a4900d2af..e1bcb31d288 100644 --- a/llvm/test/Transforms/FunctionAttrs/liveness.ll +++ b/llvm/test/Transforms/FunctionAttrs/liveness.ll @@ -1,4 +1,4 @@ -; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 -S < %s | FileCheck %s +; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 -S < %s | FileCheck %s declare void @no_return_call() nofree noreturn nounwind readnone diff --git a/llvm/test/Transforms/FunctionAttrs/norecurse.ll b/llvm/test/Transforms/FunctionAttrs/norecurse.ll index 1b22d4858e0..6a4d1180231 100644 --- a/llvm/test/Transforms/FunctionAttrs/norecurse.ll +++ b/llvm/test/Transforms/FunctionAttrs/norecurse.ll @@ -1,6 +1,6 @@ ; RUN: opt < %s -basicaa -functionattrs -rpo-functionattrs -S | FileCheck %s --check-prefixes=CHECK,BOTH ; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs),rpo-functionattrs' -S | FileCheck %s --check-prefixes=CHECK,BOTH -; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,BOTH +; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,BOTH ; CHECK: Function Attrs ; CHECK-SAME: norecurse nounwind readnone diff --git a/llvm/test/Transforms/FunctionAttrs/noreturn_async.ll b/llvm/test/Transforms/FunctionAttrs/noreturn_async.ll index e06a13f40c5..b7e9b0f4058 100644 --- a/llvm/test/Transforms/FunctionAttrs/noreturn_async.ll +++ b/llvm/test/Transforms/FunctionAttrs/noreturn_async.ll @@ -1,4 +1,4 @@ -; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 -S < %s | FileCheck %s +; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 -S < %s | FileCheck %s ; ; This file is the same as noreturn_sync.ll but with a personality which ; indicates that the exception handler *can* catch asynchronous exceptions. As diff --git a/llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll b/llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll index 423a369f704..8e583cf9bc4 100644 --- a/llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll +++ b/llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll @@ -1,4 +1,4 @@ -; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=2 -S < %s | FileCheck %s +; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=3 -S < %s | FileCheck %s ; ; This file is the same as noreturn_async.ll but with a personality which ; indicates that the exception handler *cannot* catch asynchronous exceptions. |

