[llvm] 1b6041a - [Attributor] `willreturn` + `noreturn` = UB
Johannes Doerfert via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 1 22:39:06 PDT 2019
Author: Johannes Doerfert
Date: 2019-11-02T00:35:22-05:00
New Revision: 1b6041a9e8c537894dfda998fdd3d284b1111bd2
URL: https://github.com/llvm/llvm-project/commit/1b6041a9e8c537894dfda998fdd3d284b1111bd2
DIFF: https://github.com/llvm/llvm-project/commit/1b6041a9e8c537894dfda998fdd3d284b1111bd2.diff
LOG: [Attributor] `willreturn` + `noreturn` = UB
We gave up on `noreturn` if `willreturn` was known for a while but we
now again try to always derive `noreturn`. This is useful because a
function that is `noreturn` + `willreturn` is basically dead as
executing it would lead to undefined behavior (UB).
This came up in the IPConstantProp cases where a function only contained
a unreachable but was not marked `noreturn` which caused missed
opportunities down the line.
Added:
Modified:
llvm/lib/Transforms/IPO/Attributor.cpp
llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll
llvm/test/Transforms/FunctionAttrs/internal-noalias.ll
llvm/test/Transforms/FunctionAttrs/norecurse.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index 4c8bb0f51e96..ee7166e381ae 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -3076,7 +3076,7 @@ struct AANoReturnImpl : public AANoReturn {
void initialize(Attributor &A) override {
AANoReturn::initialize(A);
Function *F = getAssociatedFunction();
- if (!F || F->hasFnAttribute(Attribute::WillReturn))
+ if (!F)
indicatePessimisticFixpoint();
}
@@ -3087,9 +3087,6 @@ 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}))
diff --git a/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll b/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll
index d0ccb87485be..2b15e0780df7 100644
--- a/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll
+++ b/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll
@@ -125,10 +125,12 @@ cond.end: ; preds = %cond.false, %cond.t
}
-; TEST 6: willreturn means *not* no-return
-; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; TEST 6a: willreturn means *not* no-return or UB
+; FIXME: we should derive "UB" as an argument and report it to the user on request.
+
+; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
; CHECK-NEXT: define i32 @endless_loop_but_willreturn
-define i32 @endless_loop_but_willreturn(i32 %a) willreturn {
+define i32 @endless_loop_but_willreturn() willreturn {
entry:
br label %while.body
@@ -136,4 +138,12 @@ while.body: ; preds = %entry, %while.body
br label %while.body
}
+; TEST 6b: willreturn means *not* no-return or UB
+; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; CHECK-NEXT: define i32 @UB_and_willreturn
+define i32 @UB_and_willreturn() willreturn {
+entry:
+ unreachable
+}
+
attributes #0 = { noinline nounwind uwtable }
diff --git a/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll b/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll
index 2ccb4b67e564..9afea1fbf8d0 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-annotate-decl-cs -attributor-max-iterations=2 < %s | FileCheck %s
+; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 < %s | FileCheck %s
define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 {
entry:
diff --git a/llvm/test/Transforms/FunctionAttrs/norecurse.ll b/llvm/test/Transforms/FunctionAttrs/norecurse.ll
index 0e67a600f344..132396fc37fb 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-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,BOTH
+; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,BOTH
; CHECK: Function Attrs
; CHECK-SAME: norecurse nounwind readnone
More information about the llvm-commits
mailing list