[llvm] e3d646c - [Attributor][NFC] applying update_test_checks with --check-attributes
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jul 19 23:19:35 PDT 2020
Author: sstefan1
Date: 2020-07-20T08:17:34+02:00
New Revision: e3d646c699f158aac700e939373ea5786899cbc1
URL: https://github.com/llvm/llvm-project/commit/e3d646c699f158aac700e939373ea5786899cbc1
DIFF: https://github.com/llvm/llvm-project/commit/e3d646c699f158aac700e939373ea5786899cbc1.diff
LOG: [Attributor][NFC] applying update_test_checks with --check-attributes
Summary:
All tests are updated, except wrapper.ll since it is not working nicely
with newly created functions.
Reviewers: jdoerfert, uenoku, baziotis, homerdin
Subscribers: arphaman, jfb, kuter, bbn, okura, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D84130
Added:
Modified:
llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll
llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll
llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll
llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll
llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll
llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll
llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll
llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll
llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll
llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll
llvm/test/Transforms/Attributor/IPConstantProp/global.ll
llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll
llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll
llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll
llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll
llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll
llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll
llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll
llvm/test/Transforms/Attributor/align.ll
llvm/test/Transforms/Attributor/allow_list.ll
llvm/test/Transforms/Attributor/alwaysinline.ll
llvm/test/Transforms/Attributor/callbacks.ll
llvm/test/Transforms/Attributor/dereferenceable-1.ll
llvm/test/Transforms/Attributor/dereferenceable-2.ll
llvm/test/Transforms/Attributor/heap_to_stack.ll
llvm/test/Transforms/Attributor/internal-noalias.ll
llvm/test/Transforms/Attributor/liveness.ll
llvm/test/Transforms/Attributor/liveness_chains.ll
llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
llvm/test/Transforms/Attributor/lvi-for-ashr.ll
llvm/test/Transforms/Attributor/memory_locations.ll
llvm/test/Transforms/Attributor/misc.ll
llvm/test/Transforms/Attributor/misc_crash.ll
llvm/test/Transforms/Attributor/new_attributes.ll
llvm/test/Transforms/Attributor/noalias.ll
llvm/test/Transforms/Attributor/nocapture-1.ll
llvm/test/Transforms/Attributor/nocapture-2.ll
llvm/test/Transforms/Attributor/nofree.ll
llvm/test/Transforms/Attributor/nonnull.ll
llvm/test/Transforms/Attributor/norecurse.ll
llvm/test/Transforms/Attributor/noreturn.ll
llvm/test/Transforms/Attributor/noreturn_async.ll
llvm/test/Transforms/Attributor/noreturn_sync.ll
llvm/test/Transforms/Attributor/nosync.ll
llvm/test/Transforms/Attributor/nounwind.ll
llvm/test/Transforms/Attributor/range.ll
llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll
llvm/test/Transforms/Attributor/readattrs.ll
llvm/test/Transforms/Attributor/reduced/register_benchmark_test.ll
llvm/test/Transforms/Attributor/returned.ll
llvm/test/Transforms/Attributor/undefined_behavior.ll
llvm/test/Transforms/Attributor/value-simplify.ll
llvm/test/Transforms/Attributor/willreturn.ll
Removed:
################################################################################
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll
index b943af621940..58135b8d2270 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll
@@ -1,16 +1,18 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
define internal i32 @deref(i32* %x) nounwind {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@deref
; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]])
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4
; IS__TUNIT_OPM-NEXT: ret i32 [[TMP2]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@deref
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
@@ -19,6 +21,7 @@ define internal i32 @deref(i32* %x) nounwind {
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4
; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@deref
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -31,14 +34,16 @@ entry:
}
define i32 @f(i32 %x) {
-; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@f
-; NOT_TUNIT_NPM-SAME: (i32 [[X:%.*]])
-; NOT_TUNIT_NPM-NEXT: entry:
-; NOT_TUNIT_NPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
-; NOT_TUNIT_NPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
-; NOT_TUNIT_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X_ADDR]])
-; NOT_TUNIT_NPM-NEXT: ret i32 [[TMP1]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f
+; IS__TUNIT_OPM-SAME: (i32 [[X:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
+; IS__TUNIT_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
+; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X_ADDR]])
+; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f
; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
@@ -48,6 +53,15 @@ define i32 @f(i32 %x) {
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]])
; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@f
+; IS__CGSCC____-SAME: (i32 [[X:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
+; IS__CGSCC____-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X_ADDR]])
+; IS__CGSCC____-NEXT: ret i32 [[TMP1]]
+;
entry:
%x_addr = alloca i32
store i32 %x, i32* %x_addr, align 4
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll
index e357272536b9..d0817a05a5fd 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,17 +9,31 @@
; because there is a load of %A in the entry block
define internal i32 @callee(i1 %C, i32* %A) {
;
-; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4
-; CHECK-NEXT: br label [[F:%.*]]
-; CHECK: T:
-; CHECK-NEXT: unreachable
-; CHECK: F:
-; CHECK-NEXT: [[A_2:%.*]] = getelementptr i32, i32* [[A]], i32 2
-; CHECK-NEXT: [[R:%.*]] = load i32, i32* [[A_2]], align 4
-; CHECK-NEXT: ret i32 [[R]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@callee
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4
+; IS__TUNIT____-NEXT: br label [[F:%.*]]
+; IS__TUNIT____: T:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: F:
+; IS__TUNIT____-NEXT: [[A_2:%.*]] = getelementptr i32, i32* [[A]], i32 2
+; IS__TUNIT____-NEXT: [[R:%.*]] = load i32, i32* [[A_2]], align 4
+; IS__TUNIT____-NEXT: ret i32 [[R]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@callee
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[A_0:%.*]] = load i32, i32* [[A]], align 4
+; IS__CGSCC____-NEXT: br label [[F:%.*]]
+; IS__CGSCC____: T:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: F:
+; IS__CGSCC____-NEXT: [[A_2:%.*]] = getelementptr i32, i32* [[A]], i32 2
+; IS__CGSCC____-NEXT: [[R:%.*]] = load i32, i32* [[A_2]], align 4
+; IS__CGSCC____-NEXT: ret i32 [[R]]
;
entry:
; Unconditonally load the element at %A
@@ -37,11 +51,13 @@ F:
}
define i32 @foo(i32* %A) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[A:%.*]])
; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree readonly align 4 [[A]])
; IS__TUNIT____-NEXT: ret i32 [[X]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]])
; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]])
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll
index fb80ad91c716..68fc3d62e5d2 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll
@@ -1,10 +1,11 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
define internal fastcc i32 @hash(i32* %ts, i32 %mod) nounwind {
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@hash()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: unreachable
@@ -14,10 +15,17 @@ entry:
}
define void @encode(i32* %m, i32* %ts, i32* %new) nounwind {
-; CHECK-LABEL: define {{[^@]+}}@encode
-; CHECK-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@encode
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@encode
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[M:%.*]], i32* nocapture nofree readnone [[TS:%.*]], i32* nocapture nofree readnone [[NEW:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
%0 = call fastcc i32 @hash( i32* %ts, i32 0 ) nounwind ; <i32> [#uses=0]
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll
index 2d0c4d66aa43..5f56e670aab9 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll
@@ -1,10 +1,11 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
define internal fastcc i32 @term_SharingList(i32* %Term, i32* %List) nounwind {
+; IS__TUNIT____: Function Attrs: nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@term_SharingList
; IS__TUNIT____-SAME: (i32* [[TERM:%.*]], i32* [[LIST:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -15,6 +16,7 @@ define internal fastcc i32 @term_SharingList(i32* %Term, i32* %List) nounwind {
; IS__TUNIT____: bb5:
; IS__TUNIT____-NEXT: ret i32 0
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@term_SharingList()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: br i1 false, label [[BB:%.*]], label [[BB5:%.*]]
@@ -35,14 +37,25 @@ bb5: ; preds = %entry
}
define i32 @term_Sharing(i32* %Term) nounwind {
-; CHECK-LABEL: define {{[^@]+}}@term_Sharing
-; CHECK-SAME: (i32* nocapture nofree readnone [[TERM:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 false, label [[BB_I:%.*]], label [[BB14:%.*]]
-; CHECK: bb.i:
-; CHECK-NEXT: unreachable
-; CHECK: bb14:
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@term_Sharing
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TERM:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br i1 false, label [[BB_I:%.*]], label [[BB14:%.*]]
+; IS__TUNIT____: bb.i:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: bb14:
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@term_Sharing
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TERM:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br i1 false, label [[BB_I:%.*]], label [[BB14:%.*]]
+; IS__CGSCC____: bb.i:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: bb14:
+; IS__CGSCC____-NEXT: ret i32 0
;
entry:
br i1 false, label %bb.i, label %bb14
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
index 8196d18c0e68..7728b12af97a 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -8,14 +8,25 @@
@G = constant %T { i32 0, i32 0, i32 17, i32 25 }
define internal i32 @test(%T* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 3
-; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* @G, i64 0, i32 2
-; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
-; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
-; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
-; CHECK-NEXT: ret i32 [[V]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 3
+; IS__TUNIT____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* @G, i64 0, i32 2
+; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
+; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
+; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
+; IS__TUNIT____-NEXT: ret i32 [[V]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0, i32 3
+; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* @G, i64 0, i32 2
+; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
+; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
+; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
+; IS__CGSCC____-NEXT: ret i32 [[V]]
;
entry:
%a.gep = getelementptr %T, %T* %p, i64 0, i32 3
@@ -27,10 +38,17 @@ entry:
}
define i32 @caller() {
-; CHECK-LABEL: define {{[^@]+}}@caller()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[V:%.*]] = call i32 @test()
-; CHECK-NEXT: ret i32 [[V]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[V:%.*]] = call i32 @test()
+; IS__TUNIT____-NEXT: ret i32 [[V]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test()
+; IS__CGSCC____-NEXT: ret i32 [[V]]
;
entry:
%v = call i32 @test(%T* @G)
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
index 0367a5e42ec1..98f3a5943e37 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -55,6 +55,7 @@ declare void @z(i32)
; Test2
; Different alignemnt privatizable arguments
define internal i32 @test(i32* %X, i64* %Y) {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test
; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[Y:%.*]])
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4
@@ -68,6 +69,7 @@ define internal i32 @test(i32* %X, i64* %Y) {
; IS__TUNIT_OPM: Return2:
; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
; IS__TUNIT_NPM-NEXT: [[Y_PRIV:%.*]] = alloca i64, align 8
@@ -85,6 +87,7 @@ define internal i32 @test(i32* %X, i64* %Y) {
; IS__TUNIT_NPM: Return2:
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[Y:%.*]])
; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4
@@ -111,6 +114,7 @@ Return2:
}
define internal i32 @caller(i32* %A) {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@caller
; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]])
; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i64, align 8
@@ -118,6 +122,7 @@ define internal i32 @caller(i32* %A) {
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i64* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[B]])
; IS__TUNIT_OPM-NEXT: ret i32 [[C]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32, align 4
@@ -129,6 +134,7 @@ define internal i32 @caller(i32* %A) {
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i64 [[TMP3]])
; IS__TUNIT_NPM-NEXT: ret i32 [[C]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]])
; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i64, align 8
@@ -143,18 +149,27 @@ define internal i32 @caller(i32* %A) {
}
define i32 @callercaller() {
-; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callercaller()
-; NOT_TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 4
-; NOT_TUNIT_NPM-NEXT: store i32 2, i32* [[B]], align 4
-; NOT_TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
-; NOT_TUNIT_NPM-NEXT: ret i32 [[X]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callercaller()
+; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__TUNIT_OPM-NEXT: store i32 2, i32* [[B]], align 4
+; IS__TUNIT_OPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
+; IS__TUNIT_OPM-NEXT: ret i32 [[X]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callercaller()
; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 4
; IS__TUNIT_NPM-NEXT: store i32 2, i32* [[B]], align 4
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4
; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]])
; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller()
+; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4
+; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
+; IS__CGSCC____-NEXT: ret i32 [[X]]
;
%B = alloca i32
store i32 2, i32* %B
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
index 524b26c2b128..8ecc12b171af 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,6 +9,7 @@
; Don't drop 'byval' on %X here.
define internal i32 @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind {
;
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f
; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree nonnull byval align 4 dereferenceable(4) [[X:%.*]], i32 [[I:%.*]])
; IS__TUNIT_OPM-NEXT: entry:
@@ -21,6 +22,7 @@ define internal i32 @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind {
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32 [[I:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
@@ -40,6 +42,7 @@ define internal i32 @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind {
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree nonnull byval align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC_OPM-NEXT: entry:
@@ -52,6 +55,7 @@ define internal i32 @f(%struct.ss* byval %b, i32* byval %X, i32 %i) nounwind {
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
; IS__CGSCC_OPM-NEXT: ret i32 [[A]]
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]])
; IS__CGSCC_NPM-NEXT: entry:
@@ -87,6 +91,7 @@ entry:
; Also make sure we don't drop the call zeroext attribute.
define i32 @test(i32* %X) {
;
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]])
; IS__TUNIT_OPM-NEXT: entry:
@@ -98,6 +103,7 @@ define i32 @test(i32* %X) {
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(12) [[S]], i32* nocapture nofree readonly byval align 4 [[X]], i32 zeroext 0)
; IS__TUNIT_OPM-NEXT: ret i32 [[C]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
@@ -114,6 +120,7 @@ define i32 @test(i32* %X) {
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32 [[TMP2]], i32 zeroext 0)
; IS__TUNIT_NPM-NEXT: ret i32 [[C]]
;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test
; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC_OPM-NEXT: entry:
@@ -125,6 +132,7 @@ define i32 @test(i32* %X) {
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias nocapture nofree nonnull readnone byval align 8 dereferenceable(12) [[S]], i32* noalias nocapture nofree nonnull readnone byval align 4 dereferenceable(4) [[X]])
; IS__CGSCC_OPM-NEXT: ret i32 [[C]]
;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test
; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC_NPM-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
index 3519c96a731a..13a4187830c1 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -6,6 +6,7 @@
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
define internal i32 @test(i32* %X, i32* %Y) {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test
; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[Y:%.*]])
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4
@@ -13,6 +14,7 @@ define internal i32 @test(i32* %X, i32* %Y) {
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
; IS__TUNIT_OPM-NEXT: ret i32 [[C]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
; IS__TUNIT_NPM-NEXT: [[Y_PRIV:%.*]] = alloca i32, align 4
@@ -24,6 +26,7 @@ define internal i32 @test(i32* %X, i32* %Y) {
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
; IS__TUNIT_NPM-NEXT: ret i32 [[C]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[Y:%.*]])
; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[X]], align 4
@@ -38,6 +41,7 @@ define internal i32 @test(i32* %X, i32* %Y) {
}
define internal i32 @caller(i32* %B) {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@caller
; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32, align 4
@@ -45,6 +49,7 @@ define internal i32 @caller(i32* %B) {
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
; IS__TUNIT_OPM-NEXT: ret i32 [[C]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca i32, align 4
@@ -56,6 +61,7 @@ define internal i32 @caller(i32* %B) {
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i32 [[TMP3]])
; IS__TUNIT_NPM-NEXT: ret i32 [[C]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4
@@ -70,18 +76,27 @@ define internal i32 @caller(i32* %B) {
}
define i32 @callercaller() {
-; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@callercaller()
-; NOT_TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 4
-; NOT_TUNIT_NPM-NEXT: store i32 2, i32* [[B]], align 4
-; NOT_TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
-; NOT_TUNIT_NPM-NEXT: ret i32 [[X]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callercaller()
+; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__TUNIT_OPM-NEXT: store i32 2, i32* [[B]], align 4
+; IS__TUNIT_OPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
+; IS__TUNIT_OPM-NEXT: ret i32 [[X]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callercaller()
; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 4
; IS__TUNIT_NPM-NEXT: store i32 2, i32* [[B]], align 4
; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4
; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]])
; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller()
+; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4
+; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
+; IS__CGSCC____-NEXT: ret i32 [[X]]
;
%B = alloca i32
store i32 2, i32* %B
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll
index ccfbb9463f90..bd1dfb5a11b7 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,6 +7,7 @@
%struct.ss = type { i32, i64 }
define internal void @f(%struct.ss* byval %b, i32* byval %X) nounwind {
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]], i32* noalias nocapture nofree nonnull writeonly byval align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC_OPM-NEXT: entry:
@@ -17,6 +18,7 @@ define internal void @f(%struct.ss* byval %b, i32* byval %X) nounwind {
; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[X]], align 4
; IS__CGSCC_OPM-NEXT: ret void
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]])
; IS__CGSCC_NPM-NEXT: entry:
@@ -46,6 +48,7 @@ entry:
define i32 @test(i32* %X) {
;
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -56,6 +59,7 @@ define i32 @test(i32* %X) {
; IS__TUNIT____-NEXT: store i64 2, i64* [[TMP4]], align 4
; IS__TUNIT____-NEXT: ret i32 0
;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test
; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC_OPM-NEXT: entry:
@@ -66,6 +70,7 @@ define i32 @test(i32* %X) {
; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
; IS__CGSCC_OPM-NEXT: ret i32 0
;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test
; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC_NPM-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
index a74151b777a5..f05d8883be5b 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,28 +9,55 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
%struct.ss = type { i32, i64 }
define internal i32 @f(%struct.ss* byval %b) nounwind {
-; IS________OPM-LABEL: define {{[^@]+}}@f
-; IS________OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]])
-; IS________OPM-NEXT: entry:
-; IS________OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0
-; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
-; IS________OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
-; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
-; IS________OPM-NEXT: ret i32 [[TMP1]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f
+; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0
+; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
+; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
+; IS__TUNIT_OPM-NEXT: ret i32 [[TMP1]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f
+; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
+; IS__TUNIT_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32*
+; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 4
+; IS__TUNIT_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1
+; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
+; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
+; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
+; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
+; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]]
;
-; IS________NPM-LABEL: define {{[^@]+}}@f
-; IS________NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
-; IS________NPM-NEXT: entry:
-; IS________NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
-; IS________NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32*
-; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 4
-; IS________NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1
-; IS________NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
-; IS________NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
-; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
-; IS________NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
-; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
-; IS________NPM-NEXT: ret i32 [[TMP1]]
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
+; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 8 dereferenceable(12) [[B:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0
+; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
+; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
+; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
+; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
+; IS__CGSCC_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32*
+; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 4
+; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1
+; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
+; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
+; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
+; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
+; IS__CGSCC_NPM-NEXT: ret i32 [[TMP1]]
;
entry:
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
@@ -42,28 +69,55 @@ entry:
define internal i32 @g(%struct.ss* byval align 32 %b) nounwind {
-; IS________OPM-LABEL: define {{[^@]+}}@g
-; IS________OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(12) [[B:%.*]])
-; IS________OPM-NEXT: entry:
-; IS________OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0
-; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32
-; IS________OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
-; IS________OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32
-; IS________OPM-NEXT: ret i32 [[TMP2]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@g
+; IS__TUNIT_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(12) [[B:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0
+; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32
+; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; IS__TUNIT_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32
+; IS__TUNIT_OPM-NEXT: ret i32 [[TMP2]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@g
+; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
+; IS__TUNIT_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32*
+; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 4
+; IS__TUNIT_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1
+; IS__TUNIT_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
+; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
+; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32
+; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32
+; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]]
;
-; IS________NPM-LABEL: define {{[^@]+}}@g
-; IS________NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
-; IS________NPM-NEXT: entry:
-; IS________NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
-; IS________NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32*
-; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 4
-; IS________NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1
-; IS________NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
-; IS________NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
-; IS________NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32
-; IS________NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
-; IS________NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32
-; IS________NPM-NEXT: ret i32 [[TMP2]]
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g
+; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval align 32 dereferenceable(12) [[B:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS:%.*]], %struct.ss* [[B]], i32 0, i32 0
+; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32
+; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32
+; IS__CGSCC_OPM-NEXT: ret i32 [[TMP2]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g
+; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
+; IS__CGSCC_NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to i32*
+; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]], align 4
+; IS__CGSCC_NPM-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 1
+; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]], align 4
+; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[B_PRIV]], i32 0, i32 0
+; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32
+; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
+; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32
+; IS__CGSCC_NPM-NEXT: ret i32 [[TMP2]]
;
entry:
%tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
@@ -75,6 +129,7 @@ entry:
define i32 @main() nounwind {
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@main()
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
@@ -87,6 +142,7 @@ define i32 @main() nounwind {
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@main()
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
@@ -107,6 +163,7 @@ define i32 @main() nounwind {
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@main()
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
@@ -119,6 +176,7 @@ define i32 @main() nounwind {
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
; IS__CGSCC_OPM-NEXT: ret i32 [[A]]
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@main()
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]], align 4
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
index 823edbbd7783..75e44569407a 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,11 +9,19 @@
define internal i32 @test(i32** %x) {
;
-; CHECK-LABEL: define {{[^@]+}}@test()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[Y:%.*]] = load i32*, i32** @G2, align 8
-; CHECK-NEXT: [[Z:%.*]] = load i32, i32* [[Y]], align 4
-; CHECK-NEXT: ret i32 [[Z]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[Y:%.*]] = load i32*, i32** @G2, align 8
+; IS__TUNIT____-NEXT: [[Z:%.*]] = load i32, i32* [[Y]], align 4
+; IS__TUNIT____-NEXT: ret i32 [[Z]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[Y:%.*]] = load i32*, i32** @G2, align 8
+; IS__CGSCC____-NEXT: [[Z:%.*]] = load i32, i32* [[Y]], align 4
+; IS__CGSCC____-NEXT: ret i32 [[Z]]
;
entry:
%y = load i32*, i32** %x
@@ -22,10 +30,17 @@ entry:
}
define i32 @caller() {
-; CHECK-LABEL: define {{[^@]+}}@caller()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[X:%.*]] = call i32 @test()
-; CHECK-NEXT: ret i32 [[X]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @test()
+; IS__TUNIT____-NEXT: ret i32 [[X]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @test()
+; IS__CGSCC____-NEXT: ret i32 [[X]]
;
entry:
%x = call i32 @test(i32** @G2)
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll
index b301e226169b..cc66b88e391f 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -6,15 +6,27 @@
; Don't promote around control flow.
define internal i32 @callee(i1 %C, i32* %P) {
-; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
-; CHECK: T:
-; CHECK-NEXT: ret i32 17
-; CHECK: F:
-; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
-; CHECK-NEXT: ret i32 [[X]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@callee
+; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; IS__TUNIT____: T:
+; IS__TUNIT____-NEXT: ret i32 17
+; IS__TUNIT____: F:
+; IS__TUNIT____-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
+; IS__TUNIT____-NEXT: ret i32 [[X]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@callee
+; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
+; IS__CGSCC____: T:
+; IS__CGSCC____-NEXT: ret i32 17
+; IS__CGSCC____: F:
+; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
+; IS__CGSCC____-NEXT: ret i32 [[X]]
;
entry:
br i1 %C, label %T, label %F
@@ -28,11 +40,19 @@ F:
}
define i32 @foo(i1 %C, i32* %P) {
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 [[C]], i32* nocapture nofree readonly [[P]])
-; CHECK-NEXT: ret i32 [[X]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
+; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @callee(i1 [[C]], i32* nocapture nofree readonly [[P]])
+; IS__TUNIT____-NEXT: ret i32 [[X]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
+; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree readonly [[P:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i1 [[C]], i32* nocapture nofree readonly [[P]])
+; IS__CGSCC____-NEXT: ret i32 [[X]]
;
entry:
%X = call i32 @callee(i1 %C, i32* %P)
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll
index eaeebf14ae0a..bba3e92959d9 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,6 +7,7 @@
target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
define internal i32 @callee(i1 %C, i32* %P) {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee
; IS__TUNIT_OPM-SAME: (i1 [[C:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__TUNIT_OPM-NEXT: br label [[F:%.*]]
@@ -16,6 +17,7 @@ define internal i32 @callee(i1 %C, i32* %P) {
; IS__TUNIT_OPM-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
; IS__TUNIT_OPM-NEXT: ret i32 [[X]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee
; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]], i32 [[TMP0:%.*]])
; IS__TUNIT_NPM-NEXT: [[P_PRIV:%.*]] = alloca i32, align 4
@@ -27,6 +29,7 @@ define internal i32 @callee(i1 %C, i32* %P) {
; IS__TUNIT_NPM-NEXT: [[X:%.*]] = load i32, i32* [[P_PRIV]], align 4
; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@callee
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: br label [[F:%.*]]
@@ -47,12 +50,14 @@ F: ; preds = %0
}
define i32 @foo() {
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@foo()
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32, align 4
; IS__TUNIT_OPM-NEXT: store i32 17, i32* [[A]], align 4
; IS__TUNIT_OPM-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]])
; IS__TUNIT_OPM-NEXT: ret i32 [[X]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@foo()
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 4
; IS__TUNIT_NPM-NEXT: store i32 17, i32* [[A]], align 4
@@ -60,6 +65,7 @@ define i32 @foo() {
; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32 [[TMP1]])
; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo()
; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4
; IS__CGSCC____-NEXT: store i32 17, i32* [[A]], align 4
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
index 5a03026c2dc2..dfd40d0b32a0 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,14 +9,25 @@
; Inlining should nuke the invoke (and any inlined calls) here even with
; argument promotion running along with it.
define void @zot() personality i32 (...)* @wibble {
-; CHECK-LABEL: define {{[^@]+}}@zot() #0 personality i32 (...)* @wibble
-; CHECK-NEXT: bb:
-; CHECK-NEXT: call void @hoge()
-; CHECK-NEXT: unreachable
-; CHECK: bb1:
-; CHECK-NEXT: unreachable
-; CHECK: bb2:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@zot() #0 personality i32 (...)* @wibble
+; IS__TUNIT____-NEXT: bb:
+; IS__TUNIT____-NEXT: call void @hoge()
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: bb1:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: bb2:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@zot() #0 personality i32 (...)* @wibble
+; IS__CGSCC____-NEXT: bb:
+; IS__CGSCC____-NEXT: call void @hoge()
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: bb1:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: bb2:
+; IS__CGSCC____-NEXT: unreachable
;
bb:
invoke void @hoge()
@@ -32,9 +43,15 @@ bb2:
}
define internal void @hoge() {
-; CHECK-LABEL: define {{[^@]+}}@hoge()
-; CHECK-NEXT: bb:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@hoge()
+; IS__TUNIT____-NEXT: bb:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@hoge()
+; IS__CGSCC____-NEXT: bb:
+; IS__CGSCC____-NEXT: unreachable
;
bb:
%tmp = call fastcc i8* @spam(i1 (i8*)* @eggs)
@@ -43,6 +60,7 @@ bb:
}
define internal fastcc i8* @spam(i1 (i8*)* %arg) {
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@spam()
; IS__CGSCC____-NEXT: bb:
; IS__CGSCC____-NEXT: unreachable
@@ -58,6 +76,7 @@ bb:
}
define internal i1 @barney(i8* %arg) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@barney()
; IS__CGSCC____-NEXT: bb:
; IS__CGSCC____-NEXT: ret i1 undef
@@ -67,11 +86,13 @@ bb:
}
define i32 @test_inf_promote_caller(i32 %arg) {
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_inf_promote_caller
; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
; IS__TUNIT____-NEXT: bb:
; IS__TUNIT____-NEXT: unreachable
;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inf_promote_caller
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
; IS__CGSCC____-NEXT: bb:
@@ -88,6 +109,7 @@ bb:
}
define internal i32 @test_inf_promote_callee(%S* %arg, %S* %arg1) {
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inf_promote_callee()
; IS__CGSCC____-NEXT: bb:
; IS__CGSCC____-NEXT: unreachable
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
index bf544c09cd32..051e486ea70b 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
index 5c2ed40cf590..295907cbca0b 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; TODO: The old pass manager cgscc run is disabled as it causes a crash on windows which is under investigation: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/23151
@@ -17,9 +17,15 @@ target triple = "x86_64-unknown-linux-gnu"
@a = internal global %struct.Foo { i32 1, i64 2 }, align 8
define void @run() {
-; CHECK-LABEL: define {{[^@]+}}@run()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@run()
+; NOT_CGSCC_NPM-NEXT: entry:
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@run()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
tail call i8 @UseLongDoubleUnsafely(%union.u* byval align 16 bitcast (%struct.s* @b to %union.u*))
@@ -30,6 +36,7 @@ entry:
}
define internal i8 @UseLongDoubleUnsafely(%union.u* byval align 16 %arg) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@UseLongDoubleUnsafely()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i8 undef
@@ -42,6 +49,7 @@ entry:
}
define internal x86_fp80 @UseLongDoubleSafely(%union.u* byval align 16 %arg) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@UseLongDoubleSafely()
; IS__CGSCC____-NEXT: ret x86_fp80 undef
;
@@ -51,6 +59,7 @@ define internal x86_fp80 @UseLongDoubleSafely(%union.u* byval align 16 %arg) {
}
define internal i64 @AccessPaddingOfStruct(%struct.Foo* byval %a) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@AccessPaddingOfStruct()
; IS__CGSCC____-NEXT: ret i64 undef
;
@@ -72,6 +81,7 @@ define internal i64 @CaptureAStruct(%struct.Foo* byval %a) {
; IS__CGSCC_OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]], %struct.Foo* [[A]], i64 0
; IS__CGSCC_OPM-NEXT: br label [[LOOP]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@CaptureAStruct
; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
; IS__CGSCC____-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
index f8625b256236..ea13554f587b 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -10,6 +10,7 @@ target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:1
; Argpromote + sroa should change this to passing the two integers by value.
define internal i32 @f(%struct.ss* inalloca %s) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@f
; IS__TUNIT____-SAME: (%struct.ss* inalloca noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -20,6 +21,7 @@ define internal i32 @f(%struct.ss* inalloca %s) {
; IS__TUNIT____-NEXT: [[R:%.*]] = add i32 [[A]], [[B]]
; IS__TUNIT____-NEXT: ret i32 [[R]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@f
; IS__CGSCC____-SAME: (%struct.ss* inalloca nocapture nofree nonnull align 4 dereferenceable(8) [[S:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -40,15 +42,27 @@ entry:
}
define i32 @main() {
-; CHECK-LABEL: define {{[^@]+}}@main()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]], align 4
-; CHECK-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
-; CHECK-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
-; CHECK-NEXT: store i32 1, i32* [[F0]], align 4
-; CHECK-NEXT: store i32 2, i32* [[F1]], align 4
-; CHECK-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S]])
-; CHECK-NEXT: ret i32 [[R]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@main()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]], align 4
+; IS__TUNIT____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
+; IS__TUNIT____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
+; IS__TUNIT____-NEXT: store i32 1, i32* [[F0]], align 4
+; IS__TUNIT____-NEXT: store i32 2, i32* [[F1]], align 4
+; IS__TUNIT____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S]])
+; IS__TUNIT____-NEXT: ret i32 [[R]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@main()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]], align 4
+; IS__CGSCC____-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 0
+; IS__CGSCC____-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
+; IS__CGSCC____-NEXT: store i32 1, i32* [[F0]], align 4
+; IS__CGSCC____-NEXT: store i32 2, i32* [[F1]], align 4
+; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S]])
+; IS__CGSCC____-NEXT: ret i32 [[R]]
;
entry:
%S = alloca inalloca %struct.ss
@@ -62,6 +76,7 @@ entry:
; Argpromote can't promote %a because of the icmp use.
define internal i1 @g(%struct.ss* %a, %struct.ss* inalloca %b) nounwind {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@g
; IS__CGSCC____-SAME: (%struct.ss* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[A:%.*]], %struct.ss* inalloca nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[B:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -73,9 +88,15 @@ entry:
}
define i32 @test() {
-; CHECK-LABEL: define {{[^@]+}}@test()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 0
;
entry:
%S = alloca inalloca %struct.ss
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll
index 5f6e9d10888e..ef0064ed68c4 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/invalidation.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; Check that when argument promotion changes a function in some parent node of
; the call graph, any analyses that happened to be cached for that function are
; actually invalidated. We are using `demanded-bits` here because when printed
@@ -12,6 +12,7 @@
@G = constant i32 0
define internal i32 @a(i32* %x) {
+; CHECK: Function Attrs: nofree nosync nounwind readonly willreturn
; CHECK-LABEL: define {{[^@]+}}@a()
; CHECK-NEXT: entry:
; CHECK-NEXT: [[V:%.*]] = load i32, i32* @G, align 4
@@ -23,6 +24,7 @@ entry:
}
define i32 @b() {
+; CHECK: Function Attrs: nofree nosync nounwind readonly willreturn
; CHECK-LABEL: define {{[^@]+}}@b()
; CHECK-NEXT: entry:
; CHECK-NEXT: [[V:%.*]] = call i32 @a()
@@ -34,6 +36,7 @@ entry:
}
define i32 @c() {
+; CHECK: Function Attrs: nofree nosync nounwind readonly willreturn
; CHECK-LABEL: define {{[^@]+}}@c()
; CHECK-NEXT: entry:
; CHECK-NEXT: [[V1:%.*]] = call i32 @a()
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
index 4da401f1db29..a53ab08d60ec 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -11,6 +11,7 @@ define internal void @dead() {
}
define internal i32 @test(i32* %X, i32* %Y) {
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test
; IS__CGSCC_OPM-SAME: (i32* noalias nocapture nofree writeonly align 4 [[X:%.*]])
; IS__CGSCC_OPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
@@ -20,6 +21,7 @@ define internal i32 @test(i32* %X, i32* %Y) {
; IS__CGSCC_OPM: dead:
; IS__CGSCC_OPM-NEXT: unreachable
;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test
; IS__CGSCC_NPM-SAME: (i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC_NPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
@@ -40,12 +42,14 @@ dead:
}
define internal i32 @caller(i32* %B) {
+; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller()
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4
; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
; IS__CGSCC_OPM-NEXT: ret i32 0
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller()
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32, align 4
; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[A]], align 4
@@ -59,10 +63,17 @@ define internal i32 @caller(i32* %B) {
}
define i32 @callercaller() {
-; CHECK-LABEL: define {{[^@]+}}@callercaller()
-; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT: store i32 2, i32* [[B]], align 4
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@callercaller()
+; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__TUNIT____-NEXT: store i32 2, i32* [[B]], align 4
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller()
+; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4
+; IS__CGSCC____-NEXT: ret i32 0
;
%B = alloca i32
store i32 2, i32* %B
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll
index 9d8d5e5decc3..6b2b7def5b95 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead_2.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -11,6 +11,7 @@ define internal void @dead() {
}
define internal i32 @test(i32* %X, i32* %Y) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@test
; IS__TUNIT____-SAME: (i32* noalias nocapture nofree writeonly align 4 [[X:%.*]])
; IS__TUNIT____-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
@@ -20,6 +21,7 @@ define internal i32 @test(i32* %X, i32* %Y) {
; IS__TUNIT____: dead:
; IS__TUNIT____-NEXT: unreachable
;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test
; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 4 [[X:%.*]])
; IS__CGSCC_OPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
@@ -29,6 +31,7 @@ define internal i32 @test(i32* %X, i32* %Y) {
; IS__CGSCC_OPM: dead:
; IS__CGSCC_OPM-NEXT: unreachable
;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test
; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[X:%.*]])
; IS__CGSCC_NPM-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
@@ -49,6 +52,7 @@ dead:
}
define internal i32 @caller(i32* %B) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
; IS__TUNIT____-SAME: (i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B:%.*]])
; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4
@@ -56,6 +60,7 @@ define internal i32 @caller(i32* %B) {
; IS__TUNIT____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
; IS__TUNIT____-NEXT: ret i32 0
;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller
; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B:%.*]])
; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32, align 4
@@ -63,6 +68,7 @@ define internal i32 @caller(i32* %B) {
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
; IS__CGSCC_OPM-NEXT: ret i32 0
;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller
; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B:%.*]])
; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32, align 4
@@ -77,11 +83,19 @@ define internal i32 @caller(i32* %B) {
}
define i32 @callercaller() {
-; CHECK-LABEL: define {{[^@]+}}@callercaller()
-; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT: store i32 2, i32* [[B]], align 4
-; CHECK-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
-; CHECK-NEXT: ret i32 0
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@callercaller()
+; NOT_CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 4
+; NOT_CGSCC_NPM-NEXT: store i32 2, i32* [[B]], align 4
+; NOT_CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
+; NOT_CGSCC_NPM-NEXT: ret i32 0
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@callercaller()
+; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__CGSCC_NPM-NEXT: store i32 2, i32* [[B]], align 4
+; IS__CGSCC_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
+; IS__CGSCC_NPM-NEXT: ret i32 0
;
%B = alloca i32
store i32 2, i32* %B
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll
index b70eff3abede..4b266d8a5d17 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -10,14 +10,25 @@
%T = type { i32, i32, i32, i32 }
define internal i32 @test(%T* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test
-; CHECK-SAME: (%T* nocapture nofree readonly [[P:%.*]])
-; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
-; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2
-; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
-; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
-; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
-; CHECK-NEXT: ret i32 [[V]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test
+; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[P:%.*]])
+; IS__TUNIT____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
+; IS__TUNIT____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2
+; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
+; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
+; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
+; IS__TUNIT____-NEXT: ret i32 [[V]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test
+; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]])
+; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
+; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2
+; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
+; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
+; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
+; IS__CGSCC____-NEXT: ret i32 [[V]]
;
%a.gep = getelementptr %T, %T* %p, i64 0, i32 3
%b.gep = getelementptr %T, %T* %p, i64 0, i32 2
@@ -28,10 +39,17 @@ define internal i32 @test(%T* %p) {
}
define i32 @caller(%T* %p) {
-; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (%T* nocapture nofree readonly [[P:%.*]])
-; CHECK-NEXT: [[V:%.*]] = musttail call i32 @test(%T* nocapture nofree readonly [[P]])
-; CHECK-NEXT: ret i32 [[V]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
+; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[P:%.*]])
+; IS__TUNIT____-NEXT: [[V:%.*]] = musttail call i32 @test(%T* nocapture nofree readonly [[P]])
+; IS__TUNIT____-NEXT: ret i32 [[V]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
+; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]])
+; IS__CGSCC____-NEXT: [[V:%.*]] = musttail call i32 @test(%T* nocapture nofree readonly [[P]])
+; IS__CGSCC____-NEXT: ret i32 [[V]]
;
%v = musttail call i32 @test(%T* %p)
ret i32 %v
@@ -40,14 +58,21 @@ define i32 @caller(%T* %p) {
; Don't promote arguments of musttail caller
define i32 @foo(%T* %p, i32 %v) {
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (%T* nocapture nofree readnone [[P:%.*]], i32 [[V:%.*]])
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
+; IS__TUNIT____-SAME: (%T* nocapture nofree readnone [[P:%.*]], i32 [[V:%.*]])
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
+; IS__CGSCC____-SAME: (%T* nocapture nofree readnone [[P:%.*]], i32 [[V:%.*]])
+; IS__CGSCC____-NEXT: ret i32 0
;
ret i32 0
}
define internal i32 @test2(%T* %p, i32 %p2) {
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]])
; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
@@ -68,10 +93,12 @@ define internal i32 @test2(%T* %p, i32 %p2) {
}
define i32 @caller2(%T* %g) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2
; IS__TUNIT____-SAME: (%T* nocapture nofree readnone [[G:%.*]])
; IS__TUNIT____-NEXT: ret i32 0
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2
; IS__CGSCC____-SAME: (%T* nocapture nofree readonly align 4 [[G:%.*]])
; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2(%T* nocapture nofree readonly [[G]], i32 0)
@@ -86,11 +113,19 @@ define i32 @caller2(%T* %g) {
; is kept as well.
define i32 @bar(%T* %p, i32 %v) {
-; CHECK-LABEL: define {{[^@]+}}@bar
-; CHECK-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]])
-; CHECK-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0
-; CHECK-NEXT: store i32 [[V]], i32* [[I32PTR]], align 4
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
+; IS__TUNIT____-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]])
+; IS__TUNIT____-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0
+; IS__TUNIT____-NEXT: store i32 [[V]], i32* [[I32PTR]], align 4
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
+; IS__CGSCC____-SAME: (%T* nocapture nofree nonnull writeonly dereferenceable(4) [[P:%.*]], i32 [[V:%.*]])
+; IS__CGSCC____-NEXT: [[I32PTR:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 0
+; IS__CGSCC____-NEXT: store i32 [[V]], i32* [[I32PTR]], align 4
+; IS__CGSCC____-NEXT: ret i32 0
;
%i32ptr = getelementptr %T, %T* %p, i64 0, i32 0
store i32 %v, i32* %i32ptr
@@ -98,15 +133,27 @@ define i32 @bar(%T* %p, i32 %v) {
}
define internal i32 @test2b(%T* %p, i32 %p2) {
-; CHECK-LABEL: define {{[^@]+}}@test2b
-; CHECK-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]])
-; CHECK-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
-; CHECK-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2
-; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
-; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
-; CHECK-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
-; CHECK-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]])
-; CHECK-NEXT: ret i32 [[CA]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2b
+; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]])
+; IS__TUNIT____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
+; IS__TUNIT____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2
+; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
+; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
+; IS__TUNIT____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
+; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]])
+; IS__TUNIT____-NEXT: ret i32 [[CA]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2b
+; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[P:%.*]], i32 [[P2:%.*]])
+; IS__CGSCC____-NEXT: [[A_GEP:%.*]] = getelementptr [[T:%.*]], %T* [[P]], i64 0, i32 3
+; IS__CGSCC____-NEXT: [[B_GEP:%.*]] = getelementptr [[T]], %T* [[P]], i64 0, i32 2
+; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[A_GEP]], align 4
+; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[B_GEP]], align 4
+; IS__CGSCC____-NEXT: [[V:%.*]] = add i32 [[A]], [[B]]
+; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call i32 @bar(%T* undef, i32 [[V]])
+; IS__CGSCC____-NEXT: ret i32 [[CA]]
;
%a.gep = getelementptr %T, %T* %p, i64 0, i32 3
%b.gep = getelementptr %T, %T* %p, i64 0, i32 2
@@ -118,11 +165,13 @@ define internal i32 @test2b(%T* %p, i32 %p2) {
}
define i32 @caller2b(%T* %g) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2b
; IS__TUNIT____-SAME: (%T* nocapture nofree readonly [[G:%.*]])
; IS__TUNIT____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 undef)
; IS__TUNIT____-NEXT: ret i32 0
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2b
; IS__CGSCC____-SAME: (%T* nocapture nofree readonly align 4 [[G:%.*]])
; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree readonly [[G]], i32 0)
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll
index b952ac6dc9a2..f566358cef61 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -20,6 +20,7 @@ entry:
}
define internal i32 @foo(i32*) #0 {
+; CHECK: Function Attrs: naked
; CHECK-LABEL: define {{[^@]+}}@foo
; CHECK-SAME: (i32* [[TMP0:%.*]])
; CHECK-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
index 1e9e45ed37e8..96acd981a162 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -12,6 +12,7 @@ target datalayout = "e-P1-p:16:8-i8:8-i16:8-i32:8-i64:8-f32:8-f64:8-n8-a:8"
@g = common global i32 0, align 4
define i32 @bar() {
+; CHECK: Function Attrs: noreturn
; CHECK-LABEL: define {{[^@]+}}@bar() addrspace(1)
; CHECK-NEXT: entry:
; CHECK-NEXT: [[CALL:%.*]] = call addrspace(1) i32 @foo()
@@ -24,6 +25,7 @@ entry:
}
define internal i32 @foo(i32*) {
+; CHECK: Function Attrs: noreturn
; CHECK-LABEL: define {{[^@]+}}@foo() addrspace(1)
; CHECK-NEXT: entry:
; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll
index a60d18f5e6cb..546bd149a4f0 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll
index 0f1f7a23ec2c..40edeef6db92 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,6 +9,7 @@
@a = common local_unnamed_addr global i32 0, align 4
define i32 @fn2() local_unnamed_addr {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2() local_unnamed_addr
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
@@ -16,6 +17,7 @@ define i32 @fn2() local_unnamed_addr {
; IS__TUNIT____-NEXT: call fastcc void @fn1(i32* nocapture nofree readonly align 4 [[TMP3]])
; IS__TUNIT____-NEXT: ret i32 undef
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2() local_unnamed_addr
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
@@ -31,12 +33,21 @@ define i32 @fn2() local_unnamed_addr {
}
define internal fastcc void @fn1(i32* nocapture readonly) unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@fn1
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 [[TMP0:%.*]]) unnamed_addr
-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 -1
-; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
-; CHECK-NEXT: store i32 [[TMP3]], i32* @a, align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@fn1
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 [[TMP0:%.*]]) unnamed_addr
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 -1
+; IS__TUNIT____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
+; IS__TUNIT____-NEXT: store i32 [[TMP3]], i32* @a, align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 [[TMP0:%.*]]) unnamed_addr
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 -1
+; IS__CGSCC____-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
+; IS__CGSCC____-NEXT: store i32 [[TMP3]], i32* @a, align 4
+; IS__CGSCC____-NEXT: ret void
;
%2 = getelementptr inbounds i32, i32* %0, i64 -1
%3 = load i32, i32* %2, align 4
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll
index a372028311a6..302f0e2b3b3f 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -14,10 +14,17 @@
%fun_t = type void (%p_t)*
define void @foo() {
-; CHECK-LABEL: define {{[^@]+}}@foo()
-; CHECK-NEXT: [[TMP:%.*]] = alloca void (i16*)*, align 8
-; CHECK-NEXT: store void (i16*)* @bar, void (i16*)** [[TMP]], align 8
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo()
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = alloca void (i16*)*, align 8
+; IS__TUNIT____-NEXT: store void (i16*)* @bar, void (i16*)** [[TMP]], align 8
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo()
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = alloca void (i16*)*, align 8
+; IS__CGSCC____-NEXT: store void (i16*)* @bar, void (i16*)** [[TMP]], align 8
+; IS__CGSCC____-NEXT: ret void
;
%tmp = alloca %fun_t
store %fun_t @bar, %fun_t* %tmp
@@ -25,6 +32,7 @@ define void @foo() {
}
define internal void @bar(%p_t %p) {
+; CHECK: Function Attrs: nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@bar
; CHECK-SAME: (i16* nocapture nofree readnone [[P:%.*]])
; CHECK-NEXT: call void @llvm.dbg.value(metadata i16* [[P]], metadata !3, metadata !DIExpression()) #3, !dbg !5
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
index cacc6b95d263..bf18851fb7c2 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll
index a646b258a0fc..a64997161229 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -17,6 +17,7 @@
@d = global i8 0, align 1
define internal fastcc void @fn(i32* nocapture readonly %p1, i64* nocapture readonly %p2) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn
; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P1:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -25,6 +26,7 @@ define internal fastcc void @fn(i32* nocapture readonly %p1, i64* nocapture read
; IS__TUNIT____-NEXT: store i8 [[CONV1]], i8* @d, align 1, !tbaa !4
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa !0
@@ -42,6 +44,7 @@ entry:
}
define i32 @main() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@main()
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa !5
@@ -51,6 +54,7 @@ define i32 @main() {
; IS__TUNIT____-NEXT: call fastcc void @fn(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) @g)
; IS__TUNIT____-NEXT: ret i32 0
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@main()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa !5
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
index a84ab1f4ef4b..2c4312c6159c 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,16 +9,18 @@ target triple = "x86_64-pc-windows-msvc"
define internal void @add({i32, i32}* %this, i32* sret %r) {
;
-; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@add
-; NOT_TUNIT_NPM-SAME: ({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]])
-; NOT_TUNIT_NPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0
-; NOT_TUNIT_NPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1
-; NOT_TUNIT_NPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8
-; NOT_TUNIT_NPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4
-; NOT_TUNIT_NPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]]
-; NOT_TUNIT_NPM-NEXT: store i32 [[AB]], i32* [[R]], align 4
-; NOT_TUNIT_NPM-NEXT: ret void
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@add
+; IS__TUNIT_OPM-SAME: ({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]])
+; IS__TUNIT_OPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0
+; IS__TUNIT_OPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1
+; IS__TUNIT_OPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8
+; IS__TUNIT_OPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4
+; IS__TUNIT_OPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]]
+; IS__TUNIT_OPM-NEXT: store i32 [[AB]], i32* [[R]], align 4
+; IS__TUNIT_OPM-NEXT: ret void
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@add
; IS__TUNIT_NPM-SAME: ({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]])
; IS__TUNIT_NPM-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0
@@ -28,6 +30,17 @@ define internal void @add({i32, i32}* %this, i32* sret %r) {
; IS__TUNIT_NPM-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]]
; IS__TUNIT_NPM-NEXT: store i32 [[AB]], i32* [[R]], align 4
; IS__TUNIT_NPM-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@add
+; IS__CGSCC____-SAME: ({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[THIS:%.*]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R:%.*]])
+; IS__CGSCC____-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 0
+; IS__CGSCC____-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }* [[THIS]], i32 0, i32 1
+; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8
+; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4
+; IS__CGSCC____-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]]
+; IS__CGSCC____-NEXT: store i32 [[AB]], i32* [[R]], align 4
+; IS__CGSCC____-NEXT: ret void
;
%ap = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 0
%bp = getelementptr {i32, i32}, {i32, i32}* %this, i32 0, i32 1
@@ -39,17 +52,33 @@ define internal void @add({i32, i32}* %this, i32* sret %r) {
}
define void @f() {
-; IS________OPM-LABEL: define {{[^@]+}}@f()
-; IS________OPM-NEXT: [[R:%.*]] = alloca i32, align 4
-; IS________OPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8
-; IS________OPM-NEXT: call void @add({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]])
-; IS________OPM-NEXT: ret void
-;
-; IS________NPM-LABEL: define {{[^@]+}}@f()
-; IS________NPM-NEXT: [[R:%.*]] = alloca i32, align 4
-; IS________NPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8
-; IS________NPM-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]])
-; IS________NPM-NEXT: ret void
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f()
+; IS__TUNIT_OPM-NEXT: [[R:%.*]] = alloca i32, align 4
+; IS__TUNIT_OPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8
+; IS__TUNIT_OPM-NEXT: call void @add({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]])
+; IS__TUNIT_OPM-NEXT: ret void
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f()
+; IS__TUNIT_NPM-NEXT: [[R:%.*]] = alloca i32, align 4
+; IS__TUNIT_NPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8
+; IS__TUNIT_NPM-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]])
+; IS__TUNIT_NPM-NEXT: ret void
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f()
+; IS__CGSCC_OPM-NEXT: [[R:%.*]] = alloca i32, align 4
+; IS__CGSCC_OPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8
+; IS__CGSCC_OPM-NEXT: call void @add({ i32, i32 }* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]])
+; IS__CGSCC_OPM-NEXT: ret void
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f()
+; IS__CGSCC_NPM-NEXT: [[R:%.*]] = alloca i32, align 4
+; IS__CGSCC_NPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }, align 8
+; IS__CGSCC_NPM-NEXT: call void @add({ i32, i32 }* noalias nocapture nofree nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias nocapture nofree nonnull sret writeonly align 4 dereferenceable(4) [[R]])
+; IS__CGSCC_NPM-NEXT: ret void
;
%r = alloca i32
%pair = alloca {i32, i32}
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll
index 1920e0108f51..9d5dab8f3be0 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
index 4cc49336fa6a..df9b420d11a2 100644
--- a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
+++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll
index 8ff87ae3bf33..ebd06c15bb63 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -8,6 +8,7 @@
; PR2411
define weak i32 @foo() nounwind {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@foo()
; CHECK-NEXT: entry:
; CHECK-NEXT: ret i32 1
@@ -17,6 +18,7 @@ entry:
}
define i32 @main() nounwind {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@main()
; CHECK-NEXT: entry:
; CHECK-NEXT: [[R:%.*]] = call i32 @foo()
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll
index e7d9a63f7076..2801725d3662 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/2009-09-24-byval-ptr.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,6 +9,7 @@
%struct.MYstr = type { i8, i32 }
@mystr = internal global %struct.MYstr zeroinitializer ; <%struct.MYstr*> [#uses=3]
define internal void @vfu1(%struct.MYstr* byval align 4 %u) nounwind {
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vfu1
; IS__CGSCC_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull writeonly byval align 8 dereferenceable(8) [[U:%.*]])
; IS__CGSCC_OPM-NEXT: entry:
@@ -20,6 +21,7 @@ define internal void @vfu1(%struct.MYstr* byval align 4 %u) nounwind {
; IS__CGSCC_OPM: return:
; IS__CGSCC_OPM-NEXT: ret void
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vfu1
; IS__CGSCC_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
; IS__CGSCC_NPM-NEXT: entry:
@@ -48,6 +50,7 @@ return: ; preds = %entry
}
define internal i32 @vfu2(%struct.MYstr* byval align 4 %u) nounwind readonly {
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@vfu2
; IS__TUNIT_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull readonly byval align 8 dereferenceable(8) [[U:%.*]])
; IS__TUNIT_OPM-NEXT: entry:
@@ -59,6 +62,7 @@ define internal i32 @vfu2(%struct.MYstr* byval align 4 %u) nounwind readonly {
; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]]
; IS__TUNIT_OPM-NEXT: ret i32 [[TMP5]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@vfu2
; IS__TUNIT_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
@@ -75,6 +79,7 @@ define internal i32 @vfu2(%struct.MYstr* byval align 4 %u) nounwind readonly {
; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]]
; IS__TUNIT_NPM-NEXT: ret i32 [[TMP7]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@vfu2()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1
@@ -96,11 +101,13 @@ entry:
}
define i32 @unions() nounwind {
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions()
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(%struct.MYstr* nocapture nofree nonnull readonly byval align 8 dereferenceable(8) @mystr)
; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions()
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8*
@@ -110,6 +117,7 @@ define i32 @unions() nounwind {
; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP0]], i32 [[TMP1]])
; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@unions()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[RESULT:%.*]] = call i32 @vfu2()
@@ -122,36 +130,71 @@ entry:
}
define internal i32 @vfu2_v2(%struct.MYstr* byval align 4 %u) nounwind readonly {
-; IS________OPM-LABEL: define {{[^@]+}}@vfu2_v2
-; IS________OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull byval align 8 dereferenceable(8) [[U:%.*]])
-; IS________OPM-NEXT: entry:
-; IS________OPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1
-; IS________OPM-NEXT: store i32 99, i32* [[Z]], align 4
-; IS________OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1
-; IS________OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
-; IS________OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0
-; IS________OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8
-; IS________OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32
-; IS________OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]]
-; IS________OPM-NEXT: ret i32 [[TMP5]]
-;
-; IS________NPM-LABEL: define {{[^@]+}}@vfu2_v2
-; IS________NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
-; IS________NPM-NEXT: entry:
-; IS________NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]], align 8
-; IS________NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8*
-; IS________NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]], align 1
-; IS________NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
-; IS________NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]], align 4
-; IS________NPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
-; IS________NPM-NEXT: store i32 99, i32* [[Z]], align 4
-; IS________NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
-; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
-; IS________NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0
-; IS________NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8
-; IS________NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32
-; IS________NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]]
-; IS________NPM-NEXT: ret i32 [[TMP7]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@vfu2_v2
+; IS__TUNIT_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull byval align 8 dereferenceable(8) [[U:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1
+; IS__TUNIT_OPM-NEXT: store i32 99, i32* [[Z]], align 4
+; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1
+; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
+; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0
+; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8
+; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32
+; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]]
+; IS__TUNIT_OPM-NEXT: ret i32 [[TMP5]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@vfu2_v2
+; IS__TUNIT_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]], align 8
+; IS__TUNIT_NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8*
+; IS__TUNIT_NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]], align 1
+; IS__TUNIT_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
+; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]], align 4
+; IS__TUNIT_NPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
+; IS__TUNIT_NPM-NEXT: store i32 99, i32* [[Z]], align 4
+; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
+; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
+; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0
+; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8
+; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32
+; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]]
+; IS__TUNIT_NPM-NEXT: ret i32 [[TMP7]]
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vfu2_v2
+; IS__CGSCC_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull byval align 8 dereferenceable(8) [[U:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1
+; IS__CGSCC_OPM-NEXT: store i32 99, i32* [[Z]], align 4
+; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 1
+; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
+; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U]], i32 0, i32 0
+; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 8
+; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32
+; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]]
+; IS__CGSCC_OPM-NEXT: ret i32 [[TMP5]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vfu2_v2
+; IS__CGSCC_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]], align 8
+; IS__CGSCC_NPM-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]] to i8*
+; IS__CGSCC_NPM-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]], align 1
+; IS__CGSCC_NPM-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
+; IS__CGSCC_NPM-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]], align 4
+; IS__CGSCC_NPM-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
+; IS__CGSCC_NPM-NEXT: store i32 99, i32* [[Z]], align 4
+; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 1
+; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
+; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]], %struct.MYstr* [[U_PRIV]], i32 0, i32 0
+; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8
+; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32
+; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]]
+; IS__CGSCC_NPM-NEXT: ret i32 [[TMP7]]
;
entry:
%z = getelementptr %struct.MYstr, %struct.MYstr* %u, i32 0, i32 1
@@ -166,11 +209,13 @@ entry:
}
define i32 @unions_v2() nounwind {
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions_v2()
; IS__TUNIT_OPM-NEXT: entry:
; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(%struct.MYstr* nocapture nofree nonnull readonly byval align 8 dereferenceable(8) @mystr)
; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions_v2()
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8*
@@ -180,11 +225,13 @@ define i32 @unions_v2() nounwind {
; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP0]], i32 [[TMP1]])
; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]]
;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@unions_v2()
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(%struct.MYstr* noalias nocapture nofree nonnull readnone byval align 8 dereferenceable(8) @mystr)
; IS__CGSCC_OPM-NEXT: ret i32 [[RESULT]]
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@unions_v2()
; IS__CGSCC_NPM-NEXT: entry:
; IS__CGSCC_NPM-NEXT: [[MYSTR_CAST1:%.*]] = bitcast %struct.MYstr* @mystr to i8*
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
index 57912e749046..8e66dcf04c18 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -8,11 +8,13 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define i64 @fn2() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2()
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #0, !range !0
; IS__TUNIT____-NEXT: ret i64 [[CALL2]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef)
@@ -26,6 +28,7 @@ entry:
}
define i64 @fn2b(i32 %arg) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2b
; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -34,6 +37,7 @@ define i64 @fn2b(i32 %arg) {
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #0, !range !0
; IS__TUNIT____-NEXT: ret i64 [[CALL2]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2b
; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -50,11 +54,13 @@ entry:
}
define i64 @fn2c() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2c()
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) #0, !range !0
; IS__TUNIT____-NEXT: ret i64 [[CALL2]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2c()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: ret i64 42
@@ -67,12 +73,21 @@ entry:
}
define internal i64 @fn1(i64 %p1) {
-; CHECK-LABEL: define {{[^@]+}}@fn1
-; CHECK-SAME: (i64 returned [[P1:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0
-; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]]
-; CHECK-NEXT: ret i64 [[COND]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@fn1
+; IS__TUNIT____-SAME: (i64 returned [[P1:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0
+; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]]
+; IS__TUNIT____-NEXT: ret i64 [[COND]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
+; IS__CGSCC____-SAME: (i64 returned [[P1:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i64 [[P1]], 0
+; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i64 [[P1]], i64 [[P1]]
+; IS__CGSCC____-NEXT: ret i64 [[COND]]
;
entry:
%tobool = icmp ne i64 %p1, 0
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
index 05217a23ccf9..ae1071032e98 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -8,6 +8,7 @@ target triple = "x86_64-unknown-linux-gnu"
define void @fn2(i32* %P, i1 %C) {
;
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2
; IS__TUNIT____-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -23,6 +24,7 @@ define void @fn2(i32* %P, i1 %C) {
; IS__TUNIT____: exit:
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[P:%.*]], i1 [[C:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -55,12 +57,21 @@ exit:
}
define internal i32 @fn1(i32 %p1) {
-; CHECK-LABEL: define {{[^@]+}}@fn1
-; CHECK-SAME: (i32 returned [[P1:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
-; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
-; CHECK-NEXT: ret i32 [[COND]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@fn1
+; IS__TUNIT____-SAME: (i32 returned [[P1:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
+; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
+; IS__TUNIT____-NEXT: ret i32 [[COND]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@fn1
+; IS__CGSCC____-SAME: (i32 returned [[P1:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
+; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
+; IS__CGSCC____-NEXT: ret i32 [[COND]]
;
entry:
%tobool = icmp ne i32 %p1, 0
@@ -70,6 +81,7 @@ entry:
define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
;
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid
; IS__TUNIT____-LABEL: define {{[^@]+}}@fn_no_null_opt
; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 [[C:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -85,6 +97,7 @@ define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
; IS__TUNIT____: exit:
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fn_no_null_opt
; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]])
; IS__CGSCC_OPM-NEXT: entry:
@@ -100,6 +113,7 @@ define void @fn_no_null_opt(i32* %P, i1 %C) null_pointer_is_valid {
; IS__CGSCC_OPM: exit:
; IS__CGSCC_OPM-NEXT: ret void
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fn_no_null_opt
; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly align 4 dereferenceable_or_null(4) [[P:%.*]], i1 [[C:%.*]])
; IS__CGSCC_NPM-NEXT: entry:
@@ -132,12 +146,21 @@ exit:
}
define internal i32 @fn0(i32 %p1) {
-; CHECK-LABEL: define {{[^@]+}}@fn0
-; CHECK-SAME: (i32 returned [[P1:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
-; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
-; CHECK-NEXT: ret i32 [[COND]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@fn0
+; IS__TUNIT____-SAME: (i32 returned [[P1:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
+; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
+; IS__TUNIT____-NEXT: ret i32 [[COND]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@fn0
+; IS__CGSCC____-SAME: (i32 returned [[P1:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[P1]], 0
+; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[P1]], i32 [[P1]]
+; IS__CGSCC____-NEXT: ret i32 [[COND]]
;
entry:
%tobool = icmp ne i32 %p1, 0
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll b/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll
index c894dc9bd767..08e664239f31 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -10,21 +10,30 @@
declare dso_local fastcc float @bar(%struct.wobble* noalias, <8 x i32>) unnamed_addr
define %struct.zot @widget(<8 x i32> %arg) local_unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@widget
-; CHECK-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr
-; CHECK-NEXT: bb:
-; CHECK-NEXT: ret [[STRUCT_ZOT:%.*]] undef
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@widget
+; IS__TUNIT____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: bb:
+; IS__TUNIT____-NEXT: ret [[STRUCT_ZOT:%.*]] undef
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@widget
+; IS__CGSCC____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: bb:
+; IS__CGSCC____-NEXT: ret [[STRUCT_ZOT:%.*]] undef
;
bb:
ret %struct.zot undef
}
define void @baz(<8 x i32> %arg) local_unnamed_addr {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@baz
; IS__TUNIT____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr
; IS__TUNIT____-NEXT: bb:
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@baz
; IS__CGSCC____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr
; IS__CGSCC____-NEXT: bb:
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll
index 4f177224d314..1124b5d01280 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -36,18 +36,29 @@
; FIXME we should recognize this as UB and make it an unreachable.
define dso_local i16 @foo(i16 %a) {
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i16 [[A:%.*]])
-; CHECK-NEXT: [[CALL:%.*]] = call i16 @bar()
-; CHECK-NEXT: ret i16 [[CALL]]
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo
+; NOT_CGSCC_NPM-SAME: (i16 [[A:%.*]])
+; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 @bar()
+; NOT_CGSCC_NPM-NEXT: ret i16 [[CALL]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo
+; IS__CGSCC_NPM-SAME: (i16 [[A:%.*]])
+; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i16 @bar()
+; IS__CGSCC_NPM-NEXT: ret i16 [[CALL]]
;
%call = call i16 bitcast (i16 (i16, i16) * @bar to i16 (i16) *)(i16 %a)
ret i16 %call
}
define internal i16 @bar(i16 %p1, i16 %p2) {
-; CHECK-LABEL: define {{[^@]+}}@bar()
-; CHECK-NEXT: ret i16 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bar()
+; IS__TUNIT____-NEXT: ret i16 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bar()
+; IS__CGSCC____-NEXT: ret i16 0
;
ret i16 0
}
@@ -63,10 +74,17 @@ define dso_local i16 @foo2(i16 %a) {
}
define internal i16 @bar2(i16 %p1, i16 %p2) {
-; CHECK-LABEL: define {{[^@]+}}@bar2
-; CHECK-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]])
-; CHECK-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]]
-; CHECK-NEXT: ret i16 [[A]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bar2
+; IS__TUNIT____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]])
+; IS__TUNIT____-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]]
+; IS__TUNIT____-NEXT: ret i16 [[A]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bar2
+; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 [[P2:%.*]])
+; IS__CGSCC____-NEXT: [[A:%.*]] = add i16 [[P1]], [[P2]]
+; IS__CGSCC____-NEXT: ret i16 [[A]]
;
%a = add i16 %p1, %p2
ret i16 %a
@@ -99,6 +117,7 @@ define dso_local i16 @vararg_tests(i16 %a) {
}
define internal i16 @vararg_prop(i16 %p1, ...) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_prop
; IS__CGSCC____-SAME: (i16 returned [[P1:%.*]], ...)
; IS__CGSCC____-NEXT: ret i16 7
@@ -107,9 +126,15 @@ define internal i16 @vararg_prop(i16 %p1, ...) {
}
define internal i16 @vararg_no_prop(i16 %p1, i16 %p2, ...) {
-; CHECK-LABEL: define {{[^@]+}}@vararg_no_prop
-; CHECK-SAME: (i16 returned [[P1:%.*]], i16 [[P2:%.*]], ...)
-; CHECK-NEXT: ret i16 7
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@vararg_no_prop
+; IS__TUNIT____-SAME: (i16 returned [[P1:%.*]], i16 [[P2:%.*]], ...)
+; IS__TUNIT____-NEXT: ret i16 7
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_no_prop
+; IS__CGSCC____-SAME: (i16 returned [[P1:%.*]], i16 [[P2:%.*]], ...)
+; IS__CGSCC____-NEXT: ret i16 7
;
ret i16 %p1
}
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll b/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll
index 2d38afb5dfc9..adc52ab707d1 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -18,9 +18,15 @@ define dso_local i16 @foo(i16 %a) {
}
define internal i16 @bar(i16 %p1, i16 %p2) {
-; CHECK-LABEL: define {{[^@]+}}@bar
-; CHECK-SAME: (i16 [[P1:%.*]], i16 returned [[P2:%.*]])
-; CHECK-NEXT: ret i16 [[P2]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
+; IS__TUNIT____-SAME: (i16 [[P1:%.*]], i16 returned [[P2:%.*]])
+; IS__TUNIT____-NEXT: ret i16 [[P2]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
+; IS__CGSCC____-SAME: (i16 [[P1:%.*]], i16 returned [[P2:%.*]])
+; IS__CGSCC____-NEXT: ret i16 [[P2]]
;
ret i16 %p2
}
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll b/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll
index 9ba9f69f4e00..0a57b47508ed 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,8 +7,13 @@
; See PR26774
define i32 @baz() {
-; CHECK-LABEL: define {{[^@]+}}@baz()
-; CHECK-NEXT: ret i32 10
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@baz()
+; IS__TUNIT____-NEXT: ret i32 10
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@baz()
+; IS__CGSCC____-NEXT: ret i32 10
;
ret i32 10
}
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll b/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll
index aa1374a7c3c5..381e2d58bc79 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -15,6 +15,7 @@
@bar.l = internal constant [2 x i8*] [i8* blockaddress(@bar, %lab0), i8* blockaddress(@bar, %end)] ; <[2 x i8*]*> [#uses=1]
define internal void @foo(i32 %x) nounwind readnone {
+; IS__CGSCC____: Function Attrs: nounwind readnone
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
; IS__CGSCC____-SAME: (i32 [[X:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -29,6 +30,7 @@ entry:
}
define internal void @bar(i32* nocapture %pc) nounwind readonly {
+; IS__CGSCC_OPM: Function Attrs: nounwind readonly
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar
; IS__CGSCC_OPM-SAME: (i32* nocapture [[PC:%.*]])
; IS__CGSCC_OPM-NEXT: entry:
@@ -66,9 +68,15 @@ indirectgoto: ; preds = %lab0, %entry
}
define i32 @main() nounwind readnone {
-; CHECK-LABEL: define {{[^@]+}}@main()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@main()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@main()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 0
;
entry:
ret i32 0
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll b/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll
index c46e9d103d28..4d78ab0906d3 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll b/llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll
index 4cd030b408f5..c45c48d50234 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/fp-bc-icmp-const-fold.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,32 +7,61 @@ target datalayout = "E-m:e-i64:64-n32:64"
target triple = "powerpc64-bgq-linux"
define void @test(i32 signext %n) {
-; CHECK-LABEL: define {{[^@]+}}@test
-; CHECK-SAME: (i32 signext [[N:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
-; CHECK: if.then:
-; CHECK-NEXT: unreachable
-; CHECK: if.end:
-; CHECK-NEXT: unreachable
-; CHECK: if.then2:
-; CHECK-NEXT: unreachable
-; CHECK: if.end4:
-; CHECK-NEXT: unreachable
-; CHECK: if.then9:
-; CHECK-NEXT: unreachable
-; CHECK: if.then12:
-; CHECK-NEXT: unreachable
-; CHECK: if.else14:
-; CHECK-NEXT: unreachable
-; CHECK: do.body:
-; CHECK-NEXT: unreachable
-; CHECK: if.then33:
-; CHECK-NEXT: unreachable
-; CHECK: cond.false.i28:
-; CHECK-NEXT: unreachable
-; CHECK: _ZN5boost4math4signIgEEiRKT_.exit30:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test
+; IS__TUNIT____-SAME: (i32 signext [[N:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: if.then2:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: if.end4:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: if.then9:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: if.then12:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: if.else14:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: do.body:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: if.then33:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: cond.false.i28:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: _ZN5boost4math4signIgEEiRKT_.exit30:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test
+; IS__CGSCC____-SAME: (i32 signext [[N:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: if.then2:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: if.end4:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: if.then9:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: if.then12:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: if.else14:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: do.body:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: if.then33:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: cond.false.i28:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: _ZN5boost4math4signIgEEiRKT_.exit30:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/global.ll b/llvm/test/Transforms/Attributor/IPConstantProp/global.ll
index fbd0d9f74d57..d30c764e5258 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/global.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/global.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,16 +7,29 @@
@_ZL6test1g = internal global i32 42, align 4
define void @_Z7test1f1v() nounwind {
-; CHECK-LABEL: define {{[^@]+}}@_Z7test1f1v()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* @_ZL6test1g, align 4
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP]], 0
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: store i32 0, i32* @_ZL6test1g, align 4
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@_Z7test1f1v()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = load i32, i32* @_ZL6test1g, align 4
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP]], 0
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: store i32 0, i32* @_ZL6test1g, align 4
+; IS__TUNIT____-NEXT: br label [[IF_END]]
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@_Z7test1f1v()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = load i32, i32* @_ZL6test1g, align 4
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[TMP]], 0
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: store i32 0, i32* @_ZL6test1g, align 4
+; IS__CGSCC____-NEXT: br label [[IF_END]]
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: ret void
;
entry:
%tmp = load i32, i32* @_ZL6test1g, align 4
@@ -32,10 +45,17 @@ if.end: ; preds = %if.then, %entry
}
define i32 @_Z7test1f2v() nounwind {
-; CHECK-LABEL: define {{[^@]+}}@_Z7test1f2v()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* @_ZL6test1g, align 4
-; CHECK-NEXT: ret i32 [[TMP]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@_Z7test1f2v()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = load i32, i32* @_ZL6test1g, align 4
+; IS__TUNIT____-NEXT: ret i32 [[TMP]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@_Z7test1f2v()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = load i32, i32* @_ZL6test1g, align 4
+; IS__CGSCC____-NEXT: ret i32 [[TMP]]
;
entry:
%tmp = load i32, i32* @_ZL6test1g, align 4
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll
index 7232d969667d..c1a50c55e847 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -40,30 +40,51 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define internal i32 @cb0(i32 %zero) {
-; CHECK-LABEL: define {{[^@]+}}@cb0
-; CHECK-SAME: (i32 returned [[ZERO:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cb0
+; IS__TUNIT____-SAME: (i32 returned [[ZERO:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cb0
+; IS__CGSCC____-SAME: (i32 returned [[ZERO:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 0
;
entry:
ret i32 %zero
}
define internal i32 @cb1(i32 %unknown) {
-; CHECK-LABEL: define {{[^@]+}}@cb1
-; CHECK-SAME: (i32 returned [[UNKNOWN:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[UNKNOWN]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cb1
+; IS__TUNIT____-SAME: (i32 returned [[UNKNOWN:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 [[UNKNOWN]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cb1
+; IS__CGSCC____-SAME: (i32 returned [[UNKNOWN:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 [[UNKNOWN]]
;
entry:
ret i32 %unknown
}
define internal i32 @cb2(i32 %unknown) {
-; CHECK-LABEL: define {{[^@]+}}@cb2
-; CHECK-SAME: (i32 returned [[UNKNOWN:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[UNKNOWN]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cb2
+; IS__TUNIT____-SAME: (i32 returned [[UNKNOWN:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 [[UNKNOWN]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cb2
+; IS__CGSCC____-SAME: (i32 returned [[UNKNOWN:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 [[UNKNOWN]]
;
entry:
%call = call i32 @cb0(i32 0)
@@ -71,20 +92,34 @@ entry:
}
define internal i32 @cb3(i32 %unknown) {
-; CHECK-LABEL: define {{[^@]+}}@cb3
-; CHECK-SAME: (i32 returned [[UNKNOWN:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[UNKNOWN]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cb3
+; IS__TUNIT____-SAME: (i32 returned [[UNKNOWN:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 [[UNKNOWN]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cb3
+; IS__CGSCC____-SAME: (i32 returned [[UNKNOWN:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 [[UNKNOWN]]
;
entry:
ret i32 %unknown
}
define internal i32 @cb4(i32 %unknown) {
-; CHECK-LABEL: define {{[^@]+}}@cb4
-; CHECK-SAME: (i32 returned [[UNKNOWN:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[UNKNOWN]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cb4
+; IS__TUNIT____-SAME: (i32 returned [[UNKNOWN:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 [[UNKNOWN]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cb4
+; IS__CGSCC____-SAME: (i32 returned [[UNKNOWN:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 [[UNKNOWN]]
;
entry:
ret i32 %unknown
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
index 8fcbbba977ed..467d641bac07 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -86,6 +86,7 @@ define internal i8* @side_effects(i8 %v) {
}
define internal i8* @no_side_effects(i8 %v) readonly nounwind {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@no_side_effects
; IS__CGSCC____-SAME: (i8 [[V:%.*]])
; IS__CGSCC____-NEXT: ret i8* null
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll b/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll
index e31670ab773b..e954d3465242 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -8,6 +8,7 @@ target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc19.0.24215"
define i32 @dipsy(i32, i32) local_unnamed_addr #0 {
+; CHECK: Function Attrs: naked
; CHECK-LABEL: define {{[^@]+}}@dipsy
; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr
; CHECK-NEXT: BasicBlock0:
@@ -20,6 +21,7 @@ BasicBlock0:
}
define void @tinkywinky(i32, i32, i32) local_unnamed_addr #0 {
+; CHECK: Function Attrs: naked
; CHECK-LABEL: define {{[^@]+}}@tinkywinky
; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]]) local_unnamed_addr
; CHECK-NEXT: BasicBlock1:
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
index 4b19fbebbcb1..00ca0cc92e8b 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
index b28b38f89687..90021fdd5756 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -67,21 +67,30 @@ entry:
declare !callback !0 dso_local i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*)
define internal i8* @foo(i8* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i8* noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[ARG:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i8* null
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
+; IS__TUNIT____-SAME: (i8* noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[ARG:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i8* null
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
+; IS__CGSCC____-SAME: (i8* noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[ARG:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i8* null
;
entry:
ret i8* %arg
}
define internal i8* @bar(i8* %arg) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[ARG:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -92,11 +101,13 @@ entry:
}
define internal i8* @baz(i8* %arg) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@baz
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i8* [[ARG]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@baz
; IS__CGSCC____-SAME: (i8* nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -107,11 +118,13 @@ entry:
}
define internal i8* @buz(i8* %arg) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@buz
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: ret i8* [[ARG]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@buz
; IS__CGSCC____-SAME: (i8* nofree nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]])
; IS__CGSCC____-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll b/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll
index 717552aee1c3..4d9a6ce4600f 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,6 +7,7 @@
; CHECK-NOT: %X
define internal i32 @foo(i32 %X) {
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo()
; IS__CGSCC____-NEXT: unreachable
;
@@ -16,8 +17,13 @@ define internal i32 @foo(i32 %X) {
}
define void @bar() {
-; CHECK-LABEL: define {{[^@]+}}@bar()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bar()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bar()
+; IS__CGSCC____-NEXT: unreachable
;
call i32 @foo( i32 17 ) ; <i32>:1 [#uses=0]
ret void
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll
index a0d71566c3ba..63115d831883 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -11,9 +11,15 @@
; FIXME: Remove obsolete calls/instructions
define i32 @main() noreturn nounwind {
-; CHECK-LABEL: define {{[^@]+}}@main()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 123
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@main()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 123
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@main()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 123
;
entry:
%call2 = tail call i32 @wwrite(i64 0) nounwind
@@ -21,6 +27,7 @@ entry:
}
define internal i32 @wwrite(i64 %i) nounwind readnone {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@wwrite()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
index 040be04ec3ee..933887fb3cc0 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -6,6 +6,7 @@
;; This function returns its second argument on all return statements
define internal i32* @incdec(i1 %C, i32* %V) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@incdec
; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* noalias nofree nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]])
; IS__TUNIT____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4
@@ -19,6 +20,7 @@ define internal i32* @incdec(i1 %C, i32* %V) {
; IS__TUNIT____-NEXT: store i32 [[X2]], i32* [[V]], align 4
; IS__TUNIT____-NEXT: ret i32* [[V]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@incdec
; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nofree nonnull returned align 4 dereferenceable(4) "no-capture-maybe-returned" [[V:%.*]])
; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4
@@ -49,12 +51,21 @@ F: ; preds = %0
;; This function returns its first argument as a part of a multiple return
;; value
define internal { i32, i32 } @foo(i32 %A, i32 %B) {
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]])
-; CHECK-NEXT: [[X:%.*]] = add i32 [[A]], [[B]]
-; CHECK-NEXT: [[Y:%.*]] = insertvalue { i32, i32 } undef, i32 [[A]], 0
-; CHECK-NEXT: [[Z:%.*]] = insertvalue { i32, i32 } [[Y]], i32 [[X]], 1
-; CHECK-NEXT: ret { i32, i32 } [[Z]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
+; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]])
+; IS__TUNIT____-NEXT: [[X:%.*]] = add i32 [[A]], [[B]]
+; IS__TUNIT____-NEXT: [[Y:%.*]] = insertvalue { i32, i32 } undef, i32 [[A]], 0
+; IS__TUNIT____-NEXT: [[Z:%.*]] = insertvalue { i32, i32 } [[Y]], i32 [[X]], 1
+; IS__TUNIT____-NEXT: ret { i32, i32 } [[Z]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
+; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]])
+; IS__CGSCC____-NEXT: [[X:%.*]] = add i32 [[A]], [[B]]
+; IS__CGSCC____-NEXT: [[Y:%.*]] = insertvalue { i32, i32 } undef, i32 [[A]], 0
+; IS__CGSCC____-NEXT: [[Z:%.*]] = insertvalue { i32, i32 } [[Y]], i32 [[X]], 1
+; IS__CGSCC____-NEXT: ret { i32, i32 } [[Z]]
;
%X = add i32 %A, %B
%Y = insertvalue { i32, i32 } undef, i32 %A, 0
@@ -63,6 +74,7 @@ define internal { i32, i32 } @foo(i32 %A, i32 %B) {
}
define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #2 personality i32 (...)* @__gxx_personality_v0
; IS__TUNIT____-NEXT: [[Q:%.*]] = alloca i32, align 4
@@ -81,6 +93,7 @@ define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
; IS__TUNIT____: RET:
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #1 personality i32 (...)* @__gxx_personality_v0
; IS__CGSCC____-NEXT: [[Q:%.*]] = alloca i32, align 4
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll
index c82766937471..e598d759dc4e 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,14 +7,25 @@
; FIXME: icmp folding is missing
define i1 @invokecaller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
-; CHECK-LABEL: define {{[^@]+}}@invokecaller
-; CHECK-SAME: (i1 [[C:%.*]]) #0 personality i32 (...)* @__gxx_personality_v0
-; CHECK-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]])
-; CHECK-NEXT: br label [[OK:%.*]]
-; CHECK: OK:
-; CHECK-NEXT: ret i1 true
-; CHECK: FAIL:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@invokecaller
+; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #0 personality i32 (...)* @__gxx_personality_v0
+; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]])
+; IS__TUNIT____-NEXT: br label [[OK:%.*]]
+; IS__TUNIT____: OK:
+; IS__TUNIT____-NEXT: ret i1 true
+; IS__TUNIT____: FAIL:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@invokecaller
+; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #0 personality i32 (...)* @__gxx_personality_v0
+; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @foo(i1 [[C]])
+; IS__CGSCC____-NEXT: br label [[OK:%.*]]
+; IS__CGSCC____: OK:
+; IS__CGSCC____-NEXT: ret i1 true
+; IS__CGSCC____: FAIL:
+; IS__CGSCC____-NEXT: unreachable
;
%X = invoke i32 @foo( i1 %C ) to label %OK unwind label %FAIL ; <i32> [#uses=1]
OK:
@@ -27,6 +38,7 @@ FAIL:
}
define internal i32 @foo(i1 %C) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
; IS__TUNIT____-SAME: (i1 [[C:%.*]])
; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
@@ -35,6 +47,7 @@ define internal i32 @foo(i1 %C) {
; IS__TUNIT____: F:
; IS__TUNIT____-NEXT: ret i32 undef
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
; IS__CGSCC____-SAME: (i1 [[C:%.*]])
; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
@@ -53,9 +66,15 @@ F: ; preds = %0
}
define i1 @caller(i1 %C) {
-; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (i1 [[C:%.*]])
-; CHECK-NEXT: ret i1 true
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
+; IS__TUNIT____-SAME: (i1 [[C:%.*]])
+; IS__TUNIT____-NEXT: ret i1 true
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
+; IS__CGSCC____-SAME: (i1 [[C:%.*]])
+; IS__CGSCC____-NEXT: ret i1 true
;
%X = call i32 @foo( i1 %C ) ; <i32> [#uses=1]
%Y = icmp ne i32 %X, 0 ; <i1> [#uses=1]
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
index 26d4206dcdf0..0934412e9112 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,17 +9,31 @@
%0 = type { i32, i32 }
define internal %0 @foo(i1 %Q) {
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i1 [[Q:%.*]])
-; CHECK-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
-; CHECK: T:
-; CHECK-NEXT: [[MRV:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
-; CHECK-NEXT: [[MRV1:%.*]] = insertvalue [[TMP0]] %mrv, i32 22, 1
-; CHECK-NEXT: ret [[TMP0]] %mrv1
-; CHECK: F:
-; CHECK-NEXT: [[MRV2:%.*]] = insertvalue [[TMP0]] undef, i32 21, 0
-; CHECK-NEXT: [[MRV3:%.*]] = insertvalue [[TMP0]] %mrv2, i32 23, 1
-; CHECK-NEXT: ret [[TMP0]] %mrv3
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
+; IS__TUNIT____-SAME: (i1 [[Q:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
+; IS__TUNIT____: T:
+; IS__TUNIT____-NEXT: [[MRV:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
+; IS__TUNIT____-NEXT: [[MRV1:%.*]] = insertvalue [[TMP0]] %mrv, i32 22, 1
+; IS__TUNIT____-NEXT: ret [[TMP0]] %mrv1
+; IS__TUNIT____: F:
+; IS__TUNIT____-NEXT: [[MRV2:%.*]] = insertvalue [[TMP0]] undef, i32 21, 0
+; IS__TUNIT____-NEXT: [[MRV3:%.*]] = insertvalue [[TMP0]] %mrv2, i32 23, 1
+; IS__TUNIT____-NEXT: ret [[TMP0]] %mrv3
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
+; IS__CGSCC____-SAME: (i1 [[Q:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
+; IS__CGSCC____: T:
+; IS__CGSCC____-NEXT: [[MRV:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
+; IS__CGSCC____-NEXT: [[MRV1:%.*]] = insertvalue [[TMP0]] %mrv, i32 22, 1
+; IS__CGSCC____-NEXT: ret [[TMP0]] %mrv1
+; IS__CGSCC____: F:
+; IS__CGSCC____-NEXT: [[MRV2:%.*]] = insertvalue [[TMP0]] undef, i32 21, 0
+; IS__CGSCC____-NEXT: [[MRV3:%.*]] = insertvalue [[TMP0]] %mrv2, i32 23, 1
+; IS__CGSCC____-NEXT: ret [[TMP0]] %mrv3
;
br i1 %Q, label %T, label %F
@@ -35,16 +49,29 @@ F: ; preds = %0
}
define internal %0 @bar(i1 %Q) {
-; CHECK-LABEL: define {{[^@]+}}@bar
-; CHECK-SAME: (i1 [[Q:%.*]])
-; CHECK-NEXT: [[A:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
-; CHECK-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
-; CHECK: T:
-; CHECK-NEXT: [[B:%.*]] = insertvalue [[TMP0]] %A, i32 22, 1
-; CHECK-NEXT: ret [[TMP0]] %B
-; CHECK: F:
-; CHECK-NEXT: [[C:%.*]] = insertvalue [[TMP0]] %A, i32 23, 1
-; CHECK-NEXT: ret [[TMP0]] %C
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
+; IS__TUNIT____-SAME: (i1 [[Q:%.*]])
+; IS__TUNIT____-NEXT: [[A:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
+; IS__TUNIT____-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
+; IS__TUNIT____: T:
+; IS__TUNIT____-NEXT: [[B:%.*]] = insertvalue [[TMP0]] %A, i32 22, 1
+; IS__TUNIT____-NEXT: ret [[TMP0]] %B
+; IS__TUNIT____: F:
+; IS__TUNIT____-NEXT: [[C:%.*]] = insertvalue [[TMP0]] %A, i32 23, 1
+; IS__TUNIT____-NEXT: ret [[TMP0]] %C
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
+; IS__CGSCC____-SAME: (i1 [[Q:%.*]])
+; IS__CGSCC____-NEXT: [[A:%.*]] = insertvalue [[TMP0:%.*]] undef, i32 21, 0
+; IS__CGSCC____-NEXT: br i1 [[Q]], label [[T:%.*]], label [[F:%.*]]
+; IS__CGSCC____: T:
+; IS__CGSCC____-NEXT: [[B:%.*]] = insertvalue [[TMP0]] %A, i32 22, 1
+; IS__CGSCC____-NEXT: ret [[TMP0]] %B
+; IS__CGSCC____: F:
+; IS__CGSCC____-NEXT: [[C:%.*]] = insertvalue [[TMP0]] %A, i32 23, 1
+; IS__CGSCC____-NEXT: ret [[TMP0]] %C
;
%A = insertvalue %0 undef, i32 21, 0
br i1 %Q, label %T, label %F
@@ -59,10 +86,17 @@ F: ; preds = %0
}
define %0 @caller(i1 %Q) {
-; CHECK-LABEL: define {{[^@]+}}@caller
-; CHECK-SAME: (i1 [[Q:%.*]])
-; CHECK-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
-; CHECK-NEXT: ret [[TMP0]] %X
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
+; IS__TUNIT____-SAME: (i1 [[Q:%.*]])
+; IS__TUNIT____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
+; IS__TUNIT____-NEXT: ret [[TMP0]] %X
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
+; IS__CGSCC____-SAME: (i1 [[Q:%.*]])
+; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
+; IS__CGSCC____-NEXT: ret [[TMP0]] %X
;
%X = call %0 @foo(i1 %Q)
%A = extractvalue %0 %X, 0
@@ -77,18 +111,33 @@ define %0 @caller(i1 %Q) {
; Similar to @caller but the result of both calls are actually used.
define i32 @caller2(i1 %Q) {
-; CHECK-LABEL: define {{[^@]+}}@caller2
-; CHECK-SAME: (i1 [[Q:%.*]])
-; CHECK-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
-; CHECK-NEXT: [[A:%.*]] = extractvalue [[TMP0]] %X, 0
-; CHECK-NEXT: [[B:%.*]] = extractvalue [[TMP0]] %X, 1
-; CHECK-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]])
-; CHECK-NEXT: [[C:%.*]] = extractvalue [[TMP0]] %Y, 0
-; CHECK-NEXT: [[D:%.*]] = extractvalue [[TMP0]] %Y, 1
-; CHECK-NEXT: [[M:%.*]] = add i32 [[A]], [[C]]
-; CHECK-NEXT: [[N:%.*]] = add i32 [[B]], [[D]]
-; CHECK-NEXT: [[R:%.*]] = add i32 [[N]], [[M]]
-; CHECK-NEXT: ret i32 [[R]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2
+; IS__TUNIT____-SAME: (i1 [[Q:%.*]])
+; IS__TUNIT____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
+; IS__TUNIT____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] %X, 0
+; IS__TUNIT____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] %X, 1
+; IS__TUNIT____-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]])
+; IS__TUNIT____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] %Y, 0
+; IS__TUNIT____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] %Y, 1
+; IS__TUNIT____-NEXT: [[M:%.*]] = add i32 [[A]], [[C]]
+; IS__TUNIT____-NEXT: [[N:%.*]] = add i32 [[B]], [[D]]
+; IS__TUNIT____-NEXT: [[R:%.*]] = add i32 [[N]], [[M]]
+; IS__TUNIT____-NEXT: ret i32 [[R]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2
+; IS__CGSCC____-SAME: (i1 [[Q:%.*]])
+; IS__CGSCC____-NEXT: [[X:%.*]] = call [[TMP0:%.*]] @foo(i1 [[Q]])
+; IS__CGSCC____-NEXT: [[A:%.*]] = extractvalue [[TMP0]] %X, 0
+; IS__CGSCC____-NEXT: [[B:%.*]] = extractvalue [[TMP0]] %X, 1
+; IS__CGSCC____-NEXT: [[Y:%.*]] = call [[TMP0]] @bar(i1 [[Q]])
+; IS__CGSCC____-NEXT: [[C:%.*]] = extractvalue [[TMP0]] %Y, 0
+; IS__CGSCC____-NEXT: [[D:%.*]] = extractvalue [[TMP0]] %Y, 1
+; IS__CGSCC____-NEXT: [[M:%.*]] = add i32 [[A]], [[C]]
+; IS__CGSCC____-NEXT: [[N:%.*]] = add i32 [[B]], [[D]]
+; IS__CGSCC____-NEXT: [[R:%.*]] = add i32 [[N]], [[M]]
+; IS__CGSCC____-NEXT: ret i32 [[R]]
;
%X = call %0 @foo(i1 %Q)
%A = extractvalue %0 %X, 0
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll b/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll
index f958e068da17..11b65dfe51dc 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/solve-after-each-resolving-undefs-for-function.ll
@@ -1,10 +1,11 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
define internal i32 @testf(i1 %c) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@testf
; IS__CGSCC____-SAME: (i1 [[C:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -30,6 +31,7 @@ if.end: ; preds = %if.then1, %entry
}
define internal i32 @test1(i1 %c) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
; IS__CGSCC____-SAME: (i1 [[C:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -57,9 +59,15 @@ ret2: ; preds = %if.then, %entry
}
define i32 @main(i1 %c) {
-; CHECK-LABEL: define {{[^@]+}}@main
-; CHECK-SAME: (i1 [[C:%.*]])
-; CHECK-NEXT: ret i32 99
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@main
+; IS__TUNIT____-SAME: (i1 [[C:%.*]])
+; IS__TUNIT____-NEXT: ret i32 99
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@main
+; IS__CGSCC____-SAME: (i1 [[C:%.*]])
+; IS__CGSCC____-NEXT: ret i32 99
;
%res = call i32 @test1(i1 %c)
ret i32 %res
diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll
index 12dd77a61b98..58dfbaefaa98 100644
--- a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll
+++ b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -24,13 +24,23 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@gsh = dso_local global i32 0, align 4
define internal i32 @callee(i32* %thread_local_ptr, i32* %shared_ptr) {
-; CHECK-LABEL: define {{[^@]+}}@callee
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[THREAD_LOCAL_PTR:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[SHARED_PTR:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[THREAD_LOCAL_PTR]], align 4
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @gsh, align 4
-; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP]], [[TMP1]]
-; CHECK-NEXT: ret i32 [[ADD]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@callee
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[THREAD_LOCAL_PTR:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[SHARED_PTR:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = load i32, i32* [[THREAD_LOCAL_PTR]], align 4
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* @gsh, align 4
+; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP]], [[TMP1]]
+; IS__TUNIT____-NEXT: ret i32 [[ADD]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@callee
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[THREAD_LOCAL_PTR:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[SHARED_PTR:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = load i32, i32* [[THREAD_LOCAL_PTR]], align 4
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* @gsh, align 4
+; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP]], [[TMP1]]
+; IS__CGSCC____-NEXT: ret i32 [[ADD]]
;
entry:
%tmp = load i32, i32* %thread_local_ptr, align 4
diff --git a/llvm/test/Transforms/Attributor/align.ll b/llvm/test/Transforms/Attributor/align.ll
index 858c8eba16c9..0ee08d76f541 100644
--- a/llvm/test/Transforms/Attributor/align.ll
+++ b/llvm/test/Transforms/Attributor/align.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -12,28 +12,47 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; TEST 1
define i32* @test1(i32* align 8 %0) #0 {
-; CHECK-LABEL: define {{[^@]+}}@test1
-; CHECK-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]])
-; CHECK-NEXT: ret i32* [[TMP0]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test1
+; IS__TUNIT____-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]])
+; IS__TUNIT____-NEXT: ret i32* [[TMP0]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
+; IS__CGSCC____-SAME: (i32* nofree readnone returned align 8 "no-capture-maybe-returned" [[TMP0:%.*]])
+; IS__CGSCC____-NEXT: ret i32* [[TMP0]]
;
ret i32* %0
}
; TEST 2
define i32* @test2(i32* %0) #0 {
-; CHECK-LABEL: define {{[^@]+}}@test2
-; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]])
-; CHECK-NEXT: ret i32* [[TMP0]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
+; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]])
+; IS__TUNIT____-NEXT: ret i32* [[TMP0]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
+; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[TMP0:%.*]])
+; IS__CGSCC____-NEXT: ret i32* [[TMP0]]
;
ret i32* %0
}
; TEST 3
define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 {
-; CHECK-LABEL: define {{[^@]+}}@test3
-; CHECK-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]])
-; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
-; CHECK-NEXT: ret i32* [[RET]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test3
+; IS__TUNIT____-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]])
+; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
+; IS__TUNIT____-NEXT: ret i32* [[RET]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test3
+; IS__CGSCC____-SAME: (i32* nofree readnone align 8 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 4 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]])
+; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
+; IS__CGSCC____-NEXT: ret i32* [[RET]]
;
%ret = select i1 %2, i32* %0, i32* %1
ret i32* %ret
@@ -41,10 +60,17 @@ define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 {
; TEST 4
define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 {
-; CHECK-LABEL: define {{[^@]+}}@test4
-; CHECK-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]])
-; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
-; CHECK-NEXT: ret i32* [[RET]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test4
+; IS__TUNIT____-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]])
+; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
+; IS__TUNIT____-NEXT: ret i32* [[RET]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test4
+; IS__CGSCC____-SAME: (i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree readnone align 32 "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]])
+; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP1]]
+; IS__CGSCC____-NEXT: ret i32* [[RET]]
;
%ret = select i1 %2, i32* %0, i32* %1
ret i32* %ret
@@ -76,16 +102,26 @@ define i32* @test5_2() {
; TEST 6
; SCC
define i32* @test6_1() #0 {
-; CHECK-LABEL: define {{[^@]+}}@test6_1()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1()
+; IS__CGSCC_NPM-NEXT: unreachable
;
%ret = tail call i32* @test6_2()
ret i32* %ret
}
define i32* @test6_2() #0 {
-; CHECK-LABEL: define {{[^@]+}}@test6_2()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2()
+; IS__CGSCC_NPM-NEXT: unreachable
;
%ret = tail call i32* @test6_1()
ret i32* %ret
@@ -111,6 +147,7 @@ define i32* @test6_2() #0 {
; Function Attrs: nounwind readnone ssp uwtable
define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@f1
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
@@ -122,6 +159,7 @@ define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
; IS__TUNIT____-NEXT: ret i8* [[TMP6]]
;
+; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@f1
; IS__CGSCC____-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
@@ -148,6 +186,7 @@ define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
; Function Attrs: nounwind readnone ssp uwtable
define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@f2() local_unnamed_addr
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null
; CHECK-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]
@@ -180,6 +219,7 @@ define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
; Function Attrs: nounwind readnone ssp uwtable
define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@f3() local_unnamed_addr
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null
; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]]
@@ -205,10 +245,12 @@ define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
; TEST 7
; Better than IR information
define align 4 i8* @test7() #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@test7()
; IS__TUNIT____-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
; IS__TUNIT____-NEXT: ret i8* [[C]]
;
+; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@test7()
; IS__CGSCC____-NEXT: [[C:%.*]] = tail call nonnull align 8 dereferenceable(1) i8* @f1(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1)
; IS__CGSCC____-NEXT: ret i8* [[C]]
@@ -220,6 +262,7 @@ define align 4 i8* @test7() #0 {
; TEST 7b
; Function Attrs: nounwind readnone ssp uwtable
define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@f1b
; IS__TUNIT____-SAME: (i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
@@ -233,6 +276,7 @@ define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
; IS__TUNIT____-NEXT: ret i8* [[TMP6]]
;
+; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@f1b
; IS__CGSCC____-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
@@ -263,6 +307,7 @@ define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
; Function Attrs: nounwind readnone ssp uwtable
define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
;
+; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@f2b() local_unnamed_addr
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null
; CHECK-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]
@@ -296,6 +341,7 @@ define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
; Function Attrs: nounwind readnone ssp uwtable
define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
;
+; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@f3b() local_unnamed_addr
; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null
; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]]
@@ -319,11 +365,13 @@ define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
}
define align 4 i32* @test7b(i32* align 32 %p) #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@test7b
; IS__TUNIT____-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]])
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
; IS__TUNIT____-NEXT: ret i32* [[P]]
;
+; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@test7b
; IS__CGSCC____-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]])
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree nonnull readnone align 8 dereferenceable(1) @a1)
@@ -356,6 +404,7 @@ define void @test8_helper() {
declare void @user_i32_ptr(i32* nocapture readnone) nounwind
define internal void @test8(i32* %a, i32* %b, i32* %c) {
+; IS__TUNIT____: Function Attrs: nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@test8
; IS__TUNIT____-SAME: (i32* noalias nocapture readnone align 4 [[A:%.*]], i32* noalias nocapture readnone align 4 [[B:%.*]], i32* noalias nocapture readnone [[C:%.*]])
; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]])
@@ -363,6 +412,7 @@ define internal void @test8(i32* %a, i32* %b, i32* %c) {
; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone [[C]])
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@test8
; IS__CGSCC____-SAME: (i32* nocapture readnone align 4 [[A:%.*]], i32* nocapture readnone align 4 [[B:%.*]], i32* nocapture readnone [[C:%.*]])
; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture readnone align 4 [[A]])
@@ -396,6 +446,7 @@ define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) {
; FIXME: This will work with an upcoming patch (D66618 or similar)
; store i32 -1, i32* %g1, align 32
define i32* @test10a(i32* align 32 %p) {
+; CHECK: Function Attrs: nofree nosync nounwind
; CHECK-LABEL: define {{[^@]+}}@test10a
; CHECK-SAME: (i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]])
; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32
@@ -438,6 +489,7 @@ e:
; FIXME: This will work with an upcoming patch (D66618 or similar)
; store i32 -1, i32* %g1, align 32
define i32* @test10b(i32* align 32 %p) {
+; CHECK: Function Attrs: nofree nosync nounwind
; CHECK-LABEL: define {{[^@]+}}@test10b
; CHECK-SAME: (i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]])
; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[P]], align 32
@@ -475,11 +527,19 @@ e:
define i64 @test11(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test11
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]])
-; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
-; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8
-; CHECK-NEXT: ret i64 [[RET]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test11
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]])
+; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__TUNIT____-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8
+; IS__TUNIT____-NEXT: ret i64 [[RET]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test11
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[P:%.*]])
+; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__CGSCC____-NEXT: [[RET:%.*]] = load i64, i64* [[P_CAST]], align 8
+; IS__CGSCC____-NEXT: ret i64 [[RET]]
;
%p-cast = bitcast i32* %p to i64*
%ret = load i64, i64* %p-cast, align 8
@@ -491,13 +551,23 @@ define i64 @test11(i32* %p) {
; FXIME: %p should have nonnull
define i64 @test12-1(i32* align 4 %p) {
-; CHECK-LABEL: define {{[^@]+}}@test12-1
-; CHECK-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]])
-; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
-; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
-; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16
-; CHECK-NEXT: ret i64 [[RET]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-1
+; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]])
+; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
+; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
+; IS__TUNIT____-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16
+; IS__TUNIT____-NEXT: ret i64 [[RET]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-1
+; IS__CGSCC____-SAME: (i32* nocapture nofree readonly align 16 [[P:%.*]])
+; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
+; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
+; IS__CGSCC____-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX1]], align 16
+; IS__CGSCC____-NEXT: ret i64 [[RET]]
;
%p-cast = bitcast i32* %p to i64*
%arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
@@ -507,12 +577,21 @@ define i64 @test12-1(i32* align 4 %p) {
}
define i64 @test12-2(i32* align 4 %p) {
-; CHECK-LABEL: define {{[^@]+}}@test12-2
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]])
-; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
-; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
-; CHECK-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16
-; CHECK-NEXT: ret i64 [[RET]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-2
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]])
+; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
+; IS__TUNIT____-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16
+; IS__TUNIT____-NEXT: ret i64 [[RET]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-2
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) [[P:%.*]])
+; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
+; IS__CGSCC____-NEXT: [[RET:%.*]] = load i64, i64* [[ARRAYIDX0]], align 16
+; IS__CGSCC____-NEXT: ret i64 [[RET]]
;
%p-cast = bitcast i32* %p to i64*
%arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
@@ -522,13 +601,23 @@ define i64 @test12-2(i32* align 4 %p) {
; FXIME: %p should have nonnull
define void @test12-3(i32* align 4 %p) {
-; CHECK-LABEL: define {{[^@]+}}@test12-3
-; CHECK-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]])
-; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
-; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
-; CHECK-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-3
+; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]])
+; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
+; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
+; IS__TUNIT____-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-3
+; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly align 16 [[P:%.*]])
+; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 1
+; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr i64, i64* [[ARRAYIDX0]], i64 3
+; IS__CGSCC____-NEXT: store i64 0, i64* [[ARRAYIDX1]], align 16
+; IS__CGSCC____-NEXT: ret void
;
%p-cast = bitcast i32* %p to i64*
%arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
@@ -538,12 +627,21 @@ define void @test12-3(i32* align 4 %p) {
}
define void @test12-4(i32* align 4 %p) {
-; CHECK-LABEL: define {{[^@]+}}@test12-4
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]])
-; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
-; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
-; CHECK-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test12-4
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]])
+; IS__TUNIT____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
+; IS__TUNIT____-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test12-4
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) [[P:%.*]])
+; IS__CGSCC____-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
+; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]], i64 0
+; IS__CGSCC____-NEXT: store i64 0, i64* [[ARRAYIDX0]], align 16
+; IS__CGSCC____-NEXT: ret void
;
%p-cast = bitcast i32* %p to i64*
%arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
@@ -554,6 +652,7 @@ define void @test12-4(i32* align 4 %p) {
declare void @use(i64*) willreturn nounwind
define void @test12-5(i32* align 4 %p) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@test12-5
; CHECK-SAME: (i32* align 16 [[P:%.*]])
; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
@@ -570,6 +669,7 @@ define void @test12-5(i32* align 4 %p) {
}
define void @test12-6(i32* align 4 %p) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@test12-6
; CHECK-SAME: (i32* align 16 [[P:%.*]])
; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
@@ -584,17 +684,31 @@ define void @test12-6(i32* align 4 %p) {
}
define void @test13(i1 %c, i32* align 32 %dst) #0 {
-; CHECK-LABEL: define {{[^@]+}}@test13
-; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
-; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
-; CHECK: truebb:
-; CHECK-NEXT: br label [[END:%.*]]
-; CHECK: falsebb:
-; CHECK-NEXT: br label [[END]]
-; CHECK: end:
-; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
-; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test13
+; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; IS__TUNIT____: truebb:
+; IS__TUNIT____-NEXT: br label [[END:%.*]]
+; IS__TUNIT____: falsebb:
+; IS__TUNIT____-NEXT: br label [[END]]
+; IS__TUNIT____: end:
+; IS__TUNIT____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
+; IS__TUNIT____-NEXT: store i32 0, i32* [[PTR]], align 32
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test13
+; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; IS__CGSCC____: truebb:
+; IS__CGSCC____-NEXT: br label [[END:%.*]]
+; IS__CGSCC____: falsebb:
+; IS__CGSCC____-NEXT: br label [[END]]
+; IS__CGSCC____: end:
+; IS__CGSCC____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ null, [[FALSEBB]] ]
+; IS__CGSCC____-NEXT: store i32 0, i32* [[PTR]], align 32
+; IS__CGSCC____-NEXT: ret void
;
br i1 %c, label %truebb, label %falsebb
truebb:
@@ -608,17 +722,31 @@ end:
}
define void @test13-1(i1 %c, i32* align 32 %dst) {
-; CHECK-LABEL: define {{[^@]+}}@test13-1
-; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
-; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
-; CHECK: truebb:
-; CHECK-NEXT: br label [[END:%.*]]
-; CHECK: falsebb:
-; CHECK-NEXT: br label [[END]]
-; CHECK: end:
-; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
-; CHECK-NEXT: store i32 0, i32* [[PTR]], align 16
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-1
+; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; IS__TUNIT____: truebb:
+; IS__TUNIT____-NEXT: br label [[END:%.*]]
+; IS__TUNIT____: falsebb:
+; IS__TUNIT____-NEXT: br label [[END]]
+; IS__TUNIT____: end:
+; IS__TUNIT____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
+; IS__TUNIT____-NEXT: store i32 0, i32* [[PTR]], align 16
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-1
+; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; IS__CGSCC____: truebb:
+; IS__CGSCC____-NEXT: br label [[END:%.*]]
+; IS__CGSCC____: falsebb:
+; IS__CGSCC____-NEXT: br label [[END]]
+; IS__CGSCC____: end:
+; IS__CGSCC____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
+; IS__CGSCC____-NEXT: store i32 0, i32* [[PTR]], align 16
+; IS__CGSCC____-NEXT: ret void
;
br i1 %c, label %truebb, label %falsebb
truebb:
@@ -632,17 +760,31 @@ end:
}
define void @test13-2(i1 %c, i32* align 32 %dst) {
-; CHECK-LABEL: define {{[^@]+}}@test13-2
-; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
-; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
-; CHECK: truebb:
-; CHECK-NEXT: br label [[END:%.*]]
-; CHECK: falsebb:
-; CHECK-NEXT: br label [[END]]
-; CHECK: end:
-; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
-; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-2
+; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; IS__TUNIT____: truebb:
+; IS__TUNIT____-NEXT: br label [[END:%.*]]
+; IS__TUNIT____: falsebb:
+; IS__TUNIT____-NEXT: br label [[END]]
+; IS__TUNIT____: end:
+; IS__TUNIT____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
+; IS__TUNIT____-NEXT: store i32 0, i32* [[PTR]], align 32
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-2
+; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; IS__CGSCC____: truebb:
+; IS__CGSCC____-NEXT: br label [[END:%.*]]
+; IS__CGSCC____: falsebb:
+; IS__CGSCC____-NEXT: br label [[END]]
+; IS__CGSCC____: end:
+; IS__CGSCC____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
+; IS__CGSCC____-NEXT: store i32 0, i32* [[PTR]], align 32
+; IS__CGSCC____-NEXT: ret void
;
br i1 %c, label %truebb, label %falsebb
truebb:
@@ -656,17 +798,31 @@ end:
}
define void @test13-3(i1 %c, i32* align 32 %dst) {
-; CHECK-LABEL: define {{[^@]+}}@test13-3
-; CHECK-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
-; CHECK-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
-; CHECK: truebb:
-; CHECK-NEXT: br label [[END:%.*]]
-; CHECK: falsebb:
-; CHECK-NEXT: br label [[END]]
-; CHECK: end:
-; CHECK-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
-; CHECK-NEXT: store i32 0, i32* [[PTR]], align 32
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test13-3
+; IS__TUNIT____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; IS__TUNIT____: truebb:
+; IS__TUNIT____-NEXT: br label [[END:%.*]]
+; IS__TUNIT____: falsebb:
+; IS__TUNIT____-NEXT: br label [[END]]
+; IS__TUNIT____: end:
+; IS__TUNIT____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
+; IS__TUNIT____-NEXT: store i32 0, i32* [[PTR]], align 32
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test13-3
+; IS__CGSCC____-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align 32 [[DST:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label [[FALSEBB:%.*]]
+; IS__CGSCC____: truebb:
+; IS__CGSCC____-NEXT: br label [[END:%.*]]
+; IS__CGSCC____: falsebb:
+; IS__CGSCC____-NEXT: br label [[END]]
+; IS__CGSCC____: end:
+; IS__CGSCC____-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
+; IS__CGSCC____-NEXT: store i32 0, i32* [[PTR]], align 32
+; IS__CGSCC____-NEXT: ret void
;
br i1 %c, label %truebb, label %falsebb
truebb:
@@ -681,19 +837,33 @@ end:
; Don't crash on ptr2int/int2ptr uses.
define i64 @ptr2int(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@ptr2int
-; CHECK-SAME: (i32* nofree readnone [[P:%.*]])
-; CHECK-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
-; CHECK-NEXT: ret i64 [[P2I]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr2int
+; IS__TUNIT____-SAME: (i32* nofree readnone [[P:%.*]])
+; IS__TUNIT____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
+; IS__TUNIT____-NEXT: ret i64 [[P2I]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr2int
+; IS__CGSCC____-SAME: (i32* nofree readnone [[P:%.*]])
+; IS__CGSCC____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[P]] to i64
+; IS__CGSCC____-NEXT: ret i64 [[P2I]]
;
%p2i = ptrtoint i32* %p to i64
ret i64 %p2i
}
define i64* @int2ptr(i64 %i) {
-; CHECK-LABEL: define {{[^@]+}}@int2ptr
-; CHECK-SAME: (i64 [[I:%.*]])
-; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64*
-; CHECK-NEXT: ret i64* [[I2P]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@int2ptr
+; IS__TUNIT____-SAME: (i64 [[I:%.*]])
+; IS__TUNIT____-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64*
+; IS__TUNIT____-NEXT: ret i64* [[I2P]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@int2ptr
+; IS__CGSCC____-SAME: (i64 [[I:%.*]])
+; IS__CGSCC____-NEXT: [[I2P:%.*]] = inttoptr i64 [[I]] to i64*
+; IS__CGSCC____-NEXT: ret i64* [[I2P]]
;
%i2p = inttoptr i64 %i to i64*
ret i64* %i2p
@@ -701,10 +871,17 @@ define i64* @int2ptr(i64 %i) {
; Use the store alignment only for the pointer operand.
define void @aligned_store(i8* %Value, i8** %Ptr) {
-; CHECK-LABEL: define {{[^@]+}}@aligned_store
-; CHECK-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]])
-; CHECK-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@aligned_store
+; IS__TUNIT____-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@aligned_store
+; IS__CGSCC____-SAME: (i8* nofree writeonly [[VALUE:%.*]], i8** nocapture nofree nonnull writeonly align 32 dereferenceable(8) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: store i8* [[VALUE]], i8** [[PTR]], align 32
+; IS__CGSCC____-NEXT: ret void
;
store i8* %Value, i8** %Ptr, align 32
ret void
@@ -724,11 +901,19 @@ define void @align_call_op_not_store(i8* align 2048 %arg) {
}
define void @align_store_after_bc(i32* align 2048 %arg) {
;
-; CHECK-LABEL: define {{[^@]+}}@align_store_after_bc
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]])
-; CHECK-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
-; CHECK-NEXT: store i8 0, i8* [[BC]], align 2048
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@align_store_after_bc
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]])
+; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
+; IS__TUNIT____-NEXT: store i8 0, i8* [[BC]], align 2048
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@align_store_after_bc
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 2048 dereferenceable(1) [[ARG:%.*]])
+; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
+; IS__CGSCC____-NEXT: store i8 0, i8* [[BC]], align 2048
+; IS__CGSCC____-NEXT: ret void
;
%bc = bitcast i32* %arg to i8*
store i8 0, i8* %bc
@@ -739,15 +924,23 @@ define void @align_store_after_bc(i32* align 2048 %arg) {
; we cannot also put on the caller.
@cnd = external global i1
define i32 @musttail_callee_1(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@musttail_callee_1
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]])
-; CHECK-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32
-; CHECK-NEXT: ret i32 [[V]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_callee_1
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]])
+; IS__TUNIT____-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32
+; IS__TUNIT____-NEXT: ret i32 [[V]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_callee_1
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[P:%.*]])
+; IS__CGSCC____-NEXT: [[V:%.*]] = load i32, i32* [[P]], align 32
+; IS__CGSCC____-NEXT: ret i32 [[V]]
;
%v = load i32, i32* %p, align 32
ret i32 %v
}
define i32 @musttail_caller_1(i32* %p) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@musttail_caller_1
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[P:%.*]])
; IS__TUNIT____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
@@ -758,6 +951,7 @@ define i32 @musttail_caller_1(i32* %p) {
; IS__TUNIT____: exit:
; IS__TUNIT____-NEXT: ret i32 0
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@musttail_caller_1
; IS__CGSCC____-SAME: (i32* nocapture nofree readonly [[P:%.*]])
; IS__CGSCC____-NEXT: [[C:%.*]] = load i1, i1* @cnd, align 1
diff --git a/llvm/test/Transforms/Attributor/allow_list.ll b/llvm/test/Transforms/Attributor/allow_list.ll
index 7670090cb03b..3e483dd1d4d7 100644
--- a/llvm/test/Transforms/Attributor/allow_list.ll
+++ b/llvm/test/Transforms/Attributor/allow_list.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -S -passes=attributor --attributor-seed-allow-list asd < %s | FileCheck %s --check-prefixes=CHECK_DISABLED
; RUN: opt -S -passes=attributor --attributor-seed-allow-list AAValueSimplify < %s | FileCheck %s --check-prefixes=CHECK_ENABLED
@@ -6,6 +6,7 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; Function Attrs: nounwind uwtable
define internal i32 @range_test(i32 %a) #0 {
+; CHECK_DISABLED: Function Attrs: noinline nounwind uwtable
; CHECK_DISABLED-LABEL: define {{[^@]+}}@range_test
; CHECK_DISABLED-SAME: (i32 [[A:%.*]])
; CHECK_DISABLED-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[A]], 100
@@ -19,10 +20,12 @@ define internal i32 @range_test(i32 %a) #0 {
; Function Attrs: nounwind uwtable
define i32 @range_use() #0 {
+; CHECK_DISABLED: Function Attrs: noinline nounwind uwtable
; CHECK_DISABLED-LABEL: define {{[^@]+}}@range_use()
; CHECK_DISABLED-NEXT: [[TMP1:%.*]] = call i32 @range_test(i32 123)
; CHECK_DISABLED-NEXT: ret i32 [[TMP1]]
;
+; CHECK_ENABLED: Function Attrs: noinline nounwind uwtable
; CHECK_ENABLED-LABEL: define {{[^@]+}}@range_use()
; CHECK_ENABLED-NEXT: ret i32 1
;
@@ -30,4 +33,4 @@ define i32 @range_use() #0 {
ret i32 %1
}
-attributes #0 = { nounwind uwtable noinline }
\ No newline at end of file
+attributes #0 = { nounwind uwtable noinline }
diff --git a/llvm/test/Transforms/Attributor/alwaysinline.ll b/llvm/test/Transforms/Attributor/alwaysinline.ll
index 49fc2983fde6..a3aaa3782645 100644
--- a/llvm/test/Transforms/Attributor/alwaysinline.ll
+++ b/llvm/test/Transforms/Attributor/alwaysinline.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,23 +9,31 @@
; the function is not exactly defined, and marked alwaysinline and can be inlined,
; so the function can be analyzed
-; CHECK: Function Attrs: alwaysinline
-; CHECK-SAME: willreturn
define linkonce void @inner1() alwaysinline {
-; CHECK-LABEL: define {{[^@]+}}@inner1()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: alwaysinline nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@inner1()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: alwaysinline nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@inner1()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret void
;
entry:
ret void
}
-; CHECK: Function Attrs:
-; CHECK-SAME: willreturn
define void @outer1() {
-; CHECK-LABEL: define {{[^@]+}}@outer1()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@outer1()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@outer1()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret void
;
entry:
call void @inner1()
@@ -34,7 +42,6 @@ entry:
; The function is not alwaysinline and is not exactly defined
; so it will not be analyzed
-; CHECK-NOT: Function Attrs:
define linkonce i32 @inner2() {
; CHECK-LABEL: define {{[^@]+}}@inner2()
; CHECK-NEXT: entry:
@@ -59,12 +66,8 @@ entry:
; This function cannot be inlined although it is marked alwaysinline
; it is `unexactly defined` and alwaysinline but cannot be inlined.
; so it will not be analyzed
-; CHECK: Function Attrs:
-; CHECK-NOT: nofree
-; CHECK-NOT: nosync
-; CHECK-NOT: nounwind
-; CHECK-NOT: readnone
define linkonce i32 @inner3(i8* %addr) alwaysinline {
+; CHECK: Function Attrs: alwaysinline
; CHECK-LABEL: define {{[^@]+}}@inner3
; CHECK-SAME: (i8* [[ADDR:%.*]])
; CHECK-NEXT: entry:
@@ -84,7 +87,6 @@ two:
ret i32 44
}
-; CHECK-NOT: Function Attrs:
define i32 @outer3(i32 %x) {
; CHECK-LABEL: define {{[^@]+}}@outer3
; CHECK-SAME: (i32 [[X:%.*]])
diff --git a/llvm/test/Transforms/Attributor/callbacks.ll b/llvm/test/Transforms/Attributor/callbacks.ll
index 249b9fd0276e..d7fe9dd84261 100644
--- a/llvm/test/Transforms/Attributor/callbacks.ll
+++ b/llvm/test/Transforms/Attributor/callbacks.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -178,6 +178,7 @@ entry:
; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
define internal void @t1_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
;
+; NOT_TUNIT_NPM: Function Attrs: nosync
; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@t1_callback_callee
; NOT_TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
; NOT_TUNIT_NPM-NEXT: entry:
@@ -187,6 +188,7 @@ define internal void @t1_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a,
; NOT_TUNIT_NPM-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* nocapture [[TMP0]])
; NOT_TUNIT_NPM-NEXT: ret void
;
+; IS__TUNIT_NPM: Function Attrs: nosync
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_callback_callee
; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* noalias nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
index dea81f9c3d14..402ed41f91fa 100644
--- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll
+++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -11,11 +11,19 @@ declare void @deref_phi_user(i32* %a);
; take mininimum of return values
;
define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@test1
-; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
-; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
-; CHECK-NEXT: ret i32* [[TMP5]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test1
+; IS__TUNIT____-SAME: (i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
+; IS__TUNIT____-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
+; IS__TUNIT____-NEXT: ret i32* [[TMP5]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
+; IS__CGSCC____-SAME: (i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
+; IS__CGSCC____-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
+; IS__CGSCC____-NEXT: ret i32* [[TMP5]]
;
%4 = bitcast double* %1 to i32*
%5 = select i1 %2, i32* %0, i32* %4
@@ -24,11 +32,19 @@ define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1
; TEST 2
define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@test2
-; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
-; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
-; CHECK-NEXT: ret i32* [[TMP5]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
+; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
+; IS__TUNIT____-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
+; IS__TUNIT____-NEXT: ret i32* [[TMP5]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
+; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" [[TMP0:%.*]], double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP1:%.*]], i1 zeroext [[TMP2:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: [[TMP4:%.*]] = bitcast double* [[TMP1]] to i32*
+; IS__CGSCC____-NEXT: [[TMP5:%.*]] = select i1 [[TMP2]], i32* [[TMP0]], i32* [[TMP4]]
+; IS__CGSCC____-NEXT: ret i32* [[TMP5]]
;
%4 = bitcast double* %1 to i32*
%5 = select i1 %2, i32* %0, i32* %4
@@ -38,32 +54,55 @@ define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8
; TEST 3
; GEP inbounds
define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@test3_1
-; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
-; CHECK-NEXT: ret i32* [[RET]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_1
+; IS__TUNIT____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
+; IS__TUNIT____-NEXT: ret i32* [[RET]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_1
+; IS__CGSCC____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
+; IS__CGSCC____-NEXT: ret i32* [[RET]]
;
%ret = getelementptr inbounds i32, i32* %0, i64 1
ret i32* %ret
}
define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@test3_2
-; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4
-; CHECK-NEXT: ret i32* [[RET]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_2
+; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4
+; IS__TUNIT____-NEXT: ret i32* [[RET]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_2
+; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: [[RET:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 4
+; IS__CGSCC____-NEXT: ret i32* [[RET]]
;
%ret = getelementptr inbounds i32, i32* %0, i64 4
ret i32* %ret
}
define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@test3_3
-; CHECK-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[RET1:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
-; CHECK-NEXT: [[RET2:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 2
-; CHECK-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[RET1]], i32* [[RET2]]
-; CHECK-NEXT: ret i32* [[RET]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test3_3
+; IS__TUNIT____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: [[RET1:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
+; IS__TUNIT____-NEXT: [[RET2:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 2
+; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[RET1]], i32* [[RET2]]
+; IS__TUNIT____-NEXT: ret i32* [[RET]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test3_3
+; IS__CGSCC____-SAME: (i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]], i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" [[TMP1:%.*]], i1 [[TMP2:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: [[RET1:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 1
+; IS__CGSCC____-NEXT: [[RET2:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 2
+; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[TMP2]], i32* [[RET1]], i32* [[RET2]]
+; IS__CGSCC____-NEXT: ret i32* [[RET]]
;
%ret1 = getelementptr inbounds i32, i32* %0, i64 1
%ret2 = getelementptr inbounds i32, i32* %1, i64 2
@@ -75,9 +114,15 @@ define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1
; Better than known in IR.
define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@test4
-; CHECK-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
-; CHECK-NEXT: ret i32* [[TMP0]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test4
+; IS__TUNIT____-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: ret i32* [[TMP0]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test4
+; IS__CGSCC____-SAME: (i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: ret i32* [[TMP0]]
;
ret i32* %0
}
@@ -189,6 +234,7 @@ for.end: ; preds = %for.cond.cleanup
declare i32* @unkown_ptr() willreturn nounwind
declare i32 @unkown_f(i32*) willreturn nounwind
define i32* @f7_0(i32* %ptr) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@f7_0
; CHECK-SAME: (i32* nonnull returned dereferenceable(8) [[PTR:%.*]])
; CHECK-NEXT: [[T:%.*]] = tail call i32 @unkown_f(i32* nonnull dereferenceable(8) [[PTR]])
@@ -199,6 +245,7 @@ define i32* @f7_0(i32* %ptr) {
}
define void @f7_1(i32* %ptr, i1 %c) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@f7_1
; CHECK-SAME: (i32* nonnull align 4 dereferenceable(4) [[PTR:%.*]], i1 [[C:%.*]])
; CHECK-NEXT: [[A:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4 dereferenceable(4) [[PTR]])
@@ -228,6 +275,7 @@ if.false:
}
define void @f7_2(i1 %c) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@f7_2
; CHECK-SAME: (i1 [[C:%.*]])
; CHECK-NEXT: [[PTR:%.*]] = tail call nonnull align 4 dereferenceable(4) i32* @unkown_ptr()
@@ -258,6 +306,7 @@ if.false:
}
define i32* @f7_3() {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@f7_3()
; CHECK-NEXT: [[PTR:%.*]] = tail call nonnull align 16 dereferenceable(4) i32* @unkown_ptr()
; CHECK-NEXT: store i32 10, i32* [[PTR]], align 16
@@ -270,11 +319,19 @@ define i32* @f7_3() {
; FIXME: This should have a return dereferenceable(8) but we need to make sure it will work in loops as well.
define i32* @test_for_minus_index(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test_for_minus_index
-; CHECK-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]])
-; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 -2
-; CHECK-NEXT: store i32 1, i32* [[Q]], align 4
-; CHECK-NEXT: ret i32* [[Q]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_for_minus_index
+; IS__TUNIT____-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]])
+; IS__TUNIT____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 -2
+; IS__TUNIT____-NEXT: store i32 1, i32* [[Q]], align 4
+; IS__TUNIT____-NEXT: ret i32* [[Q]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_for_minus_index
+; IS__CGSCC____-SAME: (i32* nofree nonnull writeonly align 4 "no-capture-maybe-returned" [[P:%.*]])
+; IS__CGSCC____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 -2
+; IS__CGSCC____-NEXT: store i32 1, i32* [[Q]], align 4
+; IS__CGSCC____-NEXT: ret i32* [[Q]]
;
%q = getelementptr inbounds i32, i32* %p, i32 -2
store i32 1, i32* %q
@@ -282,10 +339,17 @@ define i32* @test_for_minus_index(i32* %p) {
}
define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100) %0) {
-; CHECK-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]])
-; CHECK-NEXT: store i32 1, i32* [[TMP0]], align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]])
+; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP0]], align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@deref_or_null_and_nonnull
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(100) [[TMP0:%.*]])
+; IS__CGSCC____-NEXT: store i32 1, i32* [[TMP0]], align 4
+; IS__CGSCC____-NEXT: ret void
;
store i32 1, i32* %0
ret void
@@ -300,37 +364,73 @@ define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100) %0) {
; FIXME: %ptr should be dereferenceable(31)
define void @test8(i8* %ptr) #0 {
-; IS________OPM-LABEL: define {{[^@]+}}@test8
-; IS________OPM-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]])
-; IS________OPM-NEXT: br label [[TMP1:%.*]]
-; IS________OPM: 1:
-; IS________OPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
-; IS________OPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
-; IS________OPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
-; IS________OPM-NEXT: store i8 32, i8* [[TMP3]], align 1
-; IS________OPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
-; IS________OPM-NEXT: br label [[TMP5]]
-; IS________OPM: 5:
-; IS________OPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
-; IS________OPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
-; IS________OPM: 7:
-; IS________OPM-NEXT: ret void
-;
-; IS________NPM-LABEL: define {{[^@]+}}@test8
-; IS________NPM-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(21) [[PTR:%.*]])
-; IS________NPM-NEXT: br label [[TMP1:%.*]]
-; IS________NPM: 1:
-; IS________NPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
-; IS________NPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
-; IS________NPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
-; IS________NPM-NEXT: store i8 32, i8* [[TMP3]], align 1
-; IS________NPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
-; IS________NPM-NEXT: br label [[TMP5]]
-; IS________NPM: 5:
-; IS________NPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
-; IS________NPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
-; IS________NPM: 7:
-; IS________NPM-NEXT: ret void
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test8
+; IS__TUNIT_OPM-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]])
+; IS__TUNIT_OPM-NEXT: br label [[TMP1:%.*]]
+; IS__TUNIT_OPM: 1:
+; IS__TUNIT_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
+; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
+; IS__TUNIT_OPM-NEXT: store i8 32, i8* [[TMP3]], align 1
+; IS__TUNIT_OPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
+; IS__TUNIT_OPM-NEXT: br label [[TMP5]]
+; IS__TUNIT_OPM: 5:
+; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
+; IS__TUNIT_OPM: 7:
+; IS__TUNIT_OPM-NEXT: ret void
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test8
+; IS__TUNIT_NPM-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(21) [[PTR:%.*]])
+; IS__TUNIT_NPM-NEXT: br label [[TMP1:%.*]]
+; IS__TUNIT_NPM: 1:
+; IS__TUNIT_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
+; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
+; IS__TUNIT_NPM-NEXT: store i8 32, i8* [[TMP3]], align 1
+; IS__TUNIT_NPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
+; IS__TUNIT_NPM-NEXT: br label [[TMP5]]
+; IS__TUNIT_NPM: 5:
+; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
+; IS__TUNIT_NPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
+; IS__TUNIT_NPM: 7:
+; IS__TUNIT_NPM-NEXT: ret void
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test8
+; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]])
+; IS__CGSCC_OPM-NEXT: br label [[TMP1:%.*]]
+; IS__CGSCC_OPM: 1:
+; IS__CGSCC_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
+; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
+; IS__CGSCC_OPM-NEXT: store i8 32, i8* [[TMP3]], align 1
+; IS__CGSCC_OPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
+; IS__CGSCC_OPM-NEXT: br label [[TMP5]]
+; IS__CGSCC_OPM: 5:
+; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
+; IS__CGSCC_OPM: 7:
+; IS__CGSCC_OPM-NEXT: ret void
+;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test8
+; IS__CGSCC_NPM-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(21) [[PTR:%.*]])
+; IS__CGSCC_NPM-NEXT: br label [[TMP1:%.*]]
+; IS__CGSCC_NPM: 1:
+; IS__CGSCC_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 20, [[TMP0:%.*]] ], [ [[TMP4:%.*]], [[TMP5:%.*]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = sext i32 [[I_0]] to i64
+; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP2]]
+; IS__CGSCC_NPM-NEXT: store i8 32, i8* [[TMP3]], align 1
+; IS__CGSCC_NPM-NEXT: [[TMP4]] = add nsw i32 [[I_0]], 1
+; IS__CGSCC_NPM-NEXT: br label [[TMP5]]
+; IS__CGSCC_NPM: 5:
+; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP4]], 30
+; IS__CGSCC_NPM-NEXT: br i1 [[TMP6]], label [[TMP1]], label [[TMP7:%.*]]
+; IS__CGSCC_NPM: 7:
+; IS__CGSCC_NPM-NEXT: ret void
;
br label %1
1: ; preds = %5, %0
@@ -350,12 +450,21 @@ define void @test8(i8* %ptr) #0 {
; 8.2 (negative case)
define void @test8_neg(i32 %i, i8* %ptr) #0 {
-; CHECK-LABEL: define {{[^@]+}}@test8_neg
-; CHECK-SAME: (i32 [[I:%.*]], i8* nocapture nofree nonnull writeonly [[PTR:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[I]] to i64
-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP1]]
-; CHECK-NEXT: store i8 65, i8* [[TMP2]], align 1
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_neg
+; IS__TUNIT____-SAME: (i32 [[I:%.*]], i8* nocapture nofree nonnull writeonly [[PTR:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = sext i32 [[I]] to i64
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP1]]
+; IS__TUNIT____-NEXT: store i8 65, i8* [[TMP2]], align 1
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_neg
+; IS__CGSCC____-SAME: (i32 [[I:%.*]], i8* nocapture nofree nonnull writeonly [[PTR:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = sext i32 [[I]] to i64
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[PTR]], i64 [[TMP1]]
+; IS__CGSCC____-NEXT: store i8 65, i8* [[TMP2]], align 1
+; IS__CGSCC____-NEXT: ret void
;
%1 = sext i32 %i to i64
%2 = getelementptr inbounds i8, i8* %ptr, i64 %1
@@ -372,21 +481,73 @@ define void @test8_neg(i32 %i, i8* %ptr) #0 {
; NOTE: %p should not be dereferenceable
define internal void @fill_range_not_inbounds(i32* %p, i64 %start){
-; CHECK-LABEL: define {{[^@]+}}@fill_range_not_inbounds
-; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
-; CHECK-NEXT: br label [[FOR_BODY:%.*]]
-; CHECK: for.cond.cleanup:
-; CHECK-NEXT: ret void
-; CHECK: for.body:
-; CHECK-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
-; CHECK-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
-; CHECK-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
-; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
+; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
+; IS__TUNIT_OPM-NEXT: br label [[FOR_BODY:%.*]]
+; IS__TUNIT_OPM: for.cond.cleanup:
+; IS__TUNIT_OPM-NEXT: ret void
+; IS__TUNIT_OPM: for.body:
+; IS__TUNIT_OPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
+; IS__TUNIT_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
+; IS__TUNIT_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
+; IS__TUNIT_OPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
+; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
+; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
+; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
+; IS__TUNIT_NPM-NEXT: br label [[FOR_BODY:%.*]]
+; IS__TUNIT_NPM: for.cond.cleanup:
+; IS__TUNIT_NPM-NEXT: ret void
+; IS__TUNIT_NPM: for.body:
+; IS__TUNIT_NPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
+; IS__TUNIT_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
+; IS__TUNIT_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
+; IS__TUNIT_NPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
+; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
+; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
+; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
+; IS__CGSCC_OPM-NEXT: br label [[FOR_BODY:%.*]]
+; IS__CGSCC_OPM: for.cond.cleanup:
+; IS__CGSCC_OPM-NEXT: ret void
+; IS__CGSCC_OPM: for.body:
+; IS__CGSCC_OPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
+; IS__CGSCC_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
+; IS__CGSCC_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
+; IS__CGSCC_OPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
+; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
+; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fill_range_not_inbounds
+; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
+; IS__CGSCC_NPM-NEXT: br label [[FOR_BODY:%.*]]
+; IS__CGSCC_NPM: for.cond.cleanup:
+; IS__CGSCC_NPM-NEXT: ret void
+; IS__CGSCC_NPM: for.body:
+; IS__CGSCC_NPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
+; IS__CGSCC_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]], i64 [[I_06]]
+; IS__CGSCC_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
+; IS__CGSCC_NPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
+; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
+; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
;
entry:
%0 = add nsw i64 %start, 9
@@ -407,21 +568,73 @@ for.body: ; preds = %entry, %for.body
; FIXME: %p should be dereferenceable(40)
define internal void @fill_range_inbounds(i32* %p, i64 %start){
-; CHECK-LABEL: define {{[^@]+}}@fill_range_inbounds
-; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
-; CHECK-NEXT: br label [[FOR_BODY:%.*]]
-; CHECK: for.cond.cleanup:
-; CHECK-NEXT: ret void
-; CHECK: for.body:
-; CHECK-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
-; CHECK-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
-; CHECK-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
-; CHECK-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
-; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fill_range_inbounds
+; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
+; IS__TUNIT_OPM-NEXT: br label [[FOR_BODY:%.*]]
+; IS__TUNIT_OPM: for.cond.cleanup:
+; IS__TUNIT_OPM-NEXT: ret void
+; IS__TUNIT_OPM: for.body:
+; IS__TUNIT_OPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; IS__TUNIT_OPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
+; IS__TUNIT_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
+; IS__TUNIT_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
+; IS__TUNIT_OPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
+; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
+; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fill_range_inbounds
+; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
+; IS__TUNIT_NPM-NEXT: br label [[FOR_BODY:%.*]]
+; IS__TUNIT_NPM: for.cond.cleanup:
+; IS__TUNIT_NPM-NEXT: ret void
+; IS__TUNIT_NPM: for.body:
+; IS__TUNIT_NPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
+; IS__TUNIT_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
+; IS__TUNIT_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
+; IS__TUNIT_NPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
+; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
+; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fill_range_inbounds
+; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
+; IS__CGSCC_OPM-NEXT: br label [[FOR_BODY:%.*]]
+; IS__CGSCC_OPM: for.cond.cleanup:
+; IS__CGSCC_OPM-NEXT: ret void
+; IS__CGSCC_OPM: for.body:
+; IS__CGSCC_OPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; IS__CGSCC_OPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
+; IS__CGSCC_OPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
+; IS__CGSCC_OPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
+; IS__CGSCC_OPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
+; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
+; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
+;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fill_range_inbounds
+; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64 [[START:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
+; IS__CGSCC_NPM-NEXT: br label [[FOR_BODY:%.*]]
+; IS__CGSCC_NPM: for.cond.cleanup:
+; IS__CGSCC_NPM-NEXT: ret void
+; IS__CGSCC_NPM: for.body:
+; IS__CGSCC_NPM-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ]
+; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
+; IS__CGSCC_NPM-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32* [[P]], i64 [[I_06]]
+; IS__CGSCC_NPM-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
+; IS__CGSCC_NPM-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
+; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
+; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP:%.*]]
;
entry:
%0 = add nsw i64 %start, 9
@@ -441,13 +654,41 @@ for.body: ; preds = %entry, %for.body
}
define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly %range) {
-; CHECK-LABEL: define {{[^@]+}}@call_fill_range
-; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
-; CHECK-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
-; CHECK-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
-; CHECK-NEXT: ret void
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@call_fill_range
+; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
+; IS__TUNIT_OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
+; IS__TUNIT_OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
+; IS__TUNIT_OPM-NEXT: ret void
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@call_fill_range
+; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
+; IS__TUNIT_NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
+; IS__TUNIT_NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
+; IS__TUNIT_NPM-NEXT: ret void
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@call_fill_range
+; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
+; IS__CGSCC_OPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
+; IS__CGSCC_OPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
+; IS__CGSCC_OPM-NEXT: ret void
+;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@call_fill_range
+; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8, !range !0
+; IS__CGSCC_NPM-NEXT: tail call void @fill_range_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
+; IS__CGSCC_NPM-NEXT: tail call void @fill_range_not_inbounds(i32* nocapture nofree writeonly [[P]], i64 [[TMP0]])
+; IS__CGSCC_NPM-NEXT: ret void
;
entry:
%0 = load i64, i64* %range, align 8, !range !0
@@ -468,6 +709,7 @@ declare void @use3(i8*, i8*, i8*) willreturn nounwind
; fun2(dereferenceable(4) %a, %b)
; We can say that %a is dereferenceable(4) but %b is not.
define void @simple-path(i8* %a, i8 * %b, i8 %c) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@simple-path
; CHECK-SAME: (i8* nonnull dereferenceable(4) [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
@@ -502,6 +744,7 @@ if.else:
; }
; %a is dereferenceable(12)
define void @complex-path(i8* %a, i8* %b, i8 %c) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@complex-path
; CHECK-SAME: (i8* nonnull dereferenceable(12) [[A:%.*]], i8* nocapture nofree readnone [[B:%.*]], i8 [[C:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
@@ -547,31 +790,59 @@ cont2:
;
; FIXME: %ptr should be dereferenceable(4)
define dso_local void @rec-branch-1(i32 %a, i32 %b, i32 %c, i32* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@rec-branch-1
-; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
-; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0
-; CHECK-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
-; CHECK: if.then2:
-; CHECK-NEXT: store i32 1, i32* [[PTR]], align 4
-; CHECK-NEXT: br label [[IF_END8:%.*]]
-; CHECK: if.else:
-; CHECK-NEXT: store i32 2, i32* [[PTR]], align 4
-; CHECK-NEXT: br label [[IF_END8]]
-; CHECK: if.else3:
-; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0
-; CHECK-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
-; CHECK: if.then5:
-; CHECK-NEXT: store i32 3, i32* [[PTR]], align 4
-; CHECK-NEXT: br label [[IF_END8]]
-; CHECK: if.else6:
-; CHECK-NEXT: store i32 4, i32* [[PTR]], align 4
-; CHECK-NEXT: br label [[IF_END8]]
-; CHECK: if.end8:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@rec-branch-1
+; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
+; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0
+; IS__TUNIT____-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
+; IS__TUNIT____: if.then2:
+; IS__TUNIT____-NEXT: store i32 1, i32* [[PTR]], align 4
+; IS__TUNIT____-NEXT: br label [[IF_END8:%.*]]
+; IS__TUNIT____: if.else:
+; IS__TUNIT____-NEXT: store i32 2, i32* [[PTR]], align 4
+; IS__TUNIT____-NEXT: br label [[IF_END8]]
+; IS__TUNIT____: if.else3:
+; IS__TUNIT____-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0
+; IS__TUNIT____-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
+; IS__TUNIT____: if.then5:
+; IS__TUNIT____-NEXT: store i32 3, i32* [[PTR]], align 4
+; IS__TUNIT____-NEXT: br label [[IF_END8]]
+; IS__TUNIT____: if.else6:
+; IS__TUNIT____-NEXT: store i32 4, i32* [[PTR]], align 4
+; IS__TUNIT____-NEXT: br label [[IF_END8]]
+; IS__TUNIT____: if.end8:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@rec-branch-1
+; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A]], 0
+; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE3:%.*]], label [[IF_THEN:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[B]], 0
+; IS__CGSCC____-NEXT: br i1 [[TOBOOL1]], label [[IF_ELSE:%.*]], label [[IF_THEN2:%.*]]
+; IS__CGSCC____: if.then2:
+; IS__CGSCC____-NEXT: store i32 1, i32* [[PTR]], align 4
+; IS__CGSCC____-NEXT: br label [[IF_END8:%.*]]
+; IS__CGSCC____: if.else:
+; IS__CGSCC____-NEXT: store i32 2, i32* [[PTR]], align 4
+; IS__CGSCC____-NEXT: br label [[IF_END8]]
+; IS__CGSCC____: if.else3:
+; IS__CGSCC____-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 0
+; IS__CGSCC____-NEXT: br i1 [[TOBOOL4]], label [[IF_ELSE6:%.*]], label [[IF_THEN5:%.*]]
+; IS__CGSCC____: if.then5:
+; IS__CGSCC____-NEXT: store i32 3, i32* [[PTR]], align 4
+; IS__CGSCC____-NEXT: br label [[IF_END8]]
+; IS__CGSCC____: if.else6:
+; IS__CGSCC____-NEXT: store i32 4, i32* [[PTR]], align 4
+; IS__CGSCC____-NEXT: br label [[IF_END8]]
+; IS__CGSCC____: if.end8:
+; IS__CGSCC____-NEXT: ret void
;
entry:
%tobool = icmp eq i32 %a, 0
@@ -620,6 +891,7 @@ if.end8: ; preds = %if.then5, %if.else6
; }
; FIXME: %ptr should be dereferenceable(4)
define dso_local void @rec-branch-2(i32 %a, i32 %b, i32 %c, i32* %ptr) {
+; CHECK: Function Attrs: argmemonly nofree nosync nounwind writeonly
; CHECK-LABEL: define {{[^@]+}}@rec-branch-2
; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]], i32* nocapture nofree writeonly [[PTR:%.*]])
; CHECK-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/dereferenceable-2.ll b/llvm/test/Transforms/Attributor/dereferenceable-2.ll
index b4abb2bb0c33..af38f5dfd9bc 100644
--- a/llvm/test/Transforms/Attributor/dereferenceable-2.ll
+++ b/llvm/test/Transforms/Attributor/dereferenceable-2.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -8,21 +8,39 @@
; https://bugs.llvm.org/show_bug.cgi?id=21780
define <4 x double> @PR21780(double* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@PR21780
-; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 1
-; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 2
-; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3
-; CHECK-NEXT: [[T0:%.*]] = load double, double* [[PTR]], align 8
-; CHECK-NEXT: [[T1:%.*]] = load double, double* [[ARRAYIDX1]], align 8
-; CHECK-NEXT: [[T2:%.*]] = load double, double* [[ARRAYIDX2]], align 8
-; CHECK-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
-; CHECK-NEXT: [[VECINIT0:%.*]] = insertelement <4 x double> undef, double [[T0]], i32 0
-; CHECK-NEXT: [[VECINIT1:%.*]] = insertelement <4 x double> [[VECINIT0]], double [[T1]], i32 1
-; CHECK-NEXT: [[VECINIT2:%.*]] = insertelement <4 x double> [[VECINIT1]], double [[T2]], i32 2
-; CHECK-NEXT: [[VECINIT3:%.*]] = insertelement <4 x double> [[VECINIT2]], double [[T3]], i32 3
-; CHECK-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x double> [[VECINIT3]], <4 x double> [[VECINIT3]], <4 x i32> <i32 0, i32 0, i32 2, i32 2>
-; CHECK-NEXT: ret <4 x double> [[SHUFFLE]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@PR21780
+; IS__TUNIT____-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 1
+; IS__TUNIT____-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 2
+; IS__TUNIT____-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3
+; IS__TUNIT____-NEXT: [[T0:%.*]] = load double, double* [[PTR]], align 8
+; IS__TUNIT____-NEXT: [[T1:%.*]] = load double, double* [[ARRAYIDX1]], align 8
+; IS__TUNIT____-NEXT: [[T2:%.*]] = load double, double* [[ARRAYIDX2]], align 8
+; IS__TUNIT____-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
+; IS__TUNIT____-NEXT: [[VECINIT0:%.*]] = insertelement <4 x double> undef, double [[T0]], i32 0
+; IS__TUNIT____-NEXT: [[VECINIT1:%.*]] = insertelement <4 x double> [[VECINIT0]], double [[T1]], i32 1
+; IS__TUNIT____-NEXT: [[VECINIT2:%.*]] = insertelement <4 x double> [[VECINIT1]], double [[T2]], i32 2
+; IS__TUNIT____-NEXT: [[VECINIT3:%.*]] = insertelement <4 x double> [[VECINIT2]], double [[T3]], i32 3
+; IS__TUNIT____-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x double> [[VECINIT3]], <4 x double> [[VECINIT3]], <4 x i32> <i32 0, i32 0, i32 2, i32 2>
+; IS__TUNIT____-NEXT: ret <4 x double> [[SHUFFLE]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@PR21780
+; IS__CGSCC____-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 1
+; IS__CGSCC____-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 2
+; IS__CGSCC____-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3
+; IS__CGSCC____-NEXT: [[T0:%.*]] = load double, double* [[PTR]], align 8
+; IS__CGSCC____-NEXT: [[T1:%.*]] = load double, double* [[ARRAYIDX1]], align 8
+; IS__CGSCC____-NEXT: [[T2:%.*]] = load double, double* [[ARRAYIDX2]], align 8
+; IS__CGSCC____-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
+; IS__CGSCC____-NEXT: [[VECINIT0:%.*]] = insertelement <4 x double> undef, double [[T0]], i32 0
+; IS__CGSCC____-NEXT: [[VECINIT1:%.*]] = insertelement <4 x double> [[VECINIT0]], double [[T1]], i32 1
+; IS__CGSCC____-NEXT: [[VECINIT2:%.*]] = insertelement <4 x double> [[VECINIT1]], double [[T2]], i32 2
+; IS__CGSCC____-NEXT: [[VECINIT3:%.*]] = insertelement <4 x double> [[VECINIT2]], double [[T3]], i32 3
+; IS__CGSCC____-NEXT: [[SHUFFLE:%.*]] = shufflevector <4 x double> [[VECINIT3]], <4 x double> [[VECINIT3]], <4 x i32> <i32 0, i32 0, i32 2, i32 2>
+; IS__CGSCC____-NEXT: ret <4 x double> [[SHUFFLE]]
;
; GEP of index 0 is simplified away.
@@ -45,11 +63,19 @@ define <4 x double> @PR21780(double* %ptr) {
define double @PR21780_only_access3_with_inbounds(double* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@PR21780_only_access3_with_inbounds
-; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
-; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3
-; CHECK-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
-; CHECK-NEXT: ret double [[T3]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@PR21780_only_access3_with_inbounds
+; IS__TUNIT____-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3
+; IS__TUNIT____-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
+; IS__TUNIT____-NEXT: ret double [[T3]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@PR21780_only_access3_with_inbounds
+; IS__CGSCC____-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds double, double* [[PTR]], i64 3
+; IS__CGSCC____-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
+; IS__CGSCC____-NEXT: ret double [[T3]]
;
%arrayidx3 = getelementptr inbounds double, double* %ptr, i64 3
@@ -58,11 +84,19 @@ define double @PR21780_only_access3_with_inbounds(double* %ptr) {
}
define double @PR21780_only_access3_without_inbounds(double* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@PR21780_only_access3_without_inbounds
-; CHECK-SAME: (double* nocapture nofree readonly align 8 [[PTR:%.*]])
-; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3
-; CHECK-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
-; CHECK-NEXT: ret double [[T3]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@PR21780_only_access3_without_inbounds
+; IS__TUNIT____-SAME: (double* nocapture nofree readonly align 8 [[PTR:%.*]])
+; IS__TUNIT____-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3
+; IS__TUNIT____-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
+; IS__TUNIT____-NEXT: ret double [[T3]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@PR21780_only_access3_without_inbounds
+; IS__CGSCC____-SAME: (double* nocapture nofree readonly align 8 [[PTR:%.*]])
+; IS__CGSCC____-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3
+; IS__CGSCC____-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
+; IS__CGSCC____-NEXT: ret double [[T3]]
;
%arrayidx3 = getelementptr double, double* %ptr, i64 3
%t3 = load double, double* %arrayidx3, align 8
@@ -70,11 +104,19 @@ define double @PR21780_only_access3_without_inbounds(double* %ptr) {
}
define double @PR21780_without_inbounds(double* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@PR21780_without_inbounds
-; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
-; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3
-; CHECK-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
-; CHECK-NEXT: ret double [[T3]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@PR21780_without_inbounds
+; IS__TUNIT____-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3
+; IS__TUNIT____-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
+; IS__TUNIT____-NEXT: ret double [[T3]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@PR21780_without_inbounds
+; IS__CGSCC____-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(32) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: [[ARRAYIDX3:%.*]] = getelementptr double, double* [[PTR]], i64 3
+; IS__CGSCC____-NEXT: [[T3:%.*]] = load double, double* [[ARRAYIDX3]], align 8
+; IS__CGSCC____-NEXT: ret double [[T3]]
;
%arrayidx1 = getelementptr double, double* %ptr, i64 1
@@ -92,12 +134,21 @@ define double @PR21780_without_inbounds(double* %ptr) {
; Unsimplified, but still valid. Also, throw in some bogus arguments.
define void @gep0(i8* %unused, i8* %other, i8* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@gep0
-; CHECK-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull writeonly dereferenceable(1) [[OTHER:%.*]], i8* nocapture nofree nonnull readonly dereferenceable(3) [[PTR:%.*]])
-; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, i8* [[PTR]], i64 2
-; CHECK-NEXT: [[T2:%.*]] = load i8, i8* [[ARRAYIDX2]], align 1
-; CHECK-NEXT: store i8 [[T2]], i8* [[OTHER]], align 1
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@gep0
+; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull writeonly dereferenceable(1) [[OTHER:%.*]], i8* nocapture nofree nonnull readonly dereferenceable(3) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, i8* [[PTR]], i64 2
+; IS__TUNIT____-NEXT: [[T2:%.*]] = load i8, i8* [[ARRAYIDX2]], align 1
+; IS__TUNIT____-NEXT: store i8 [[T2]], i8* [[OTHER]], align 1
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@gep0
+; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull writeonly dereferenceable(1) [[OTHER:%.*]], i8* nocapture nofree nonnull readonly dereferenceable(3) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: [[ARRAYIDX2:%.*]] = getelementptr i8, i8* [[PTR]], i64 2
+; IS__CGSCC____-NEXT: [[T2:%.*]] = load i8, i8* [[ARRAYIDX2]], align 1
+; IS__CGSCC____-NEXT: store i8 [[T2]], i8* [[OTHER]], align 1
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx0 = getelementptr i8, i8* %ptr, i64 0
%arrayidx1 = getelementptr i8, i8* %ptr, i64 1
@@ -113,9 +164,15 @@ define void @gep0(i8* %unused, i8* %other, i8* %ptr) {
; Multiple arguments may be dereferenceable.
define void @ordering(i8* %ptr1, i32* %ptr2) {
-; CHECK-LABEL: define {{[^@]+}}@ordering
-; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR1:%.*]], i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR2:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ordering
+; IS__TUNIT____-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR1:%.*]], i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR2:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ordering
+; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR1:%.*]], i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR2:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%a20 = getelementptr i32, i32* %ptr2, i64 0
%a12 = getelementptr i8, i8* %ptr1, i64 2
@@ -133,12 +190,21 @@ define void @ordering(i8* %ptr1, i32* %ptr2) {
; Not in entry block.
define void @not_entry_but_guaranteed_to_execute(i8* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@not_entry_but_guaranteed_to_execute
-; CHECK-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[EXIT:%.*]]
-; CHECK: exit:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@not_entry_but_guaranteed_to_execute
+; IS__TUNIT____-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[EXIT:%.*]]
+; IS__TUNIT____: exit:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@not_entry_but_guaranteed_to_execute
+; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull readnone dereferenceable(3) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[EXIT:%.*]]
+; IS__CGSCC____: exit:
+; IS__CGSCC____-NEXT: ret void
;
entry:
br label %exit
@@ -155,14 +221,25 @@ exit:
; Not in entry block and not guaranteed to execute.
define void @not_entry_not_guaranteed_to_execute(i8* %ptr, i1 %cond) {
-; CHECK-LABEL: define {{[^@]+}}@not_entry_not_guaranteed_to_execute
-; CHECK-SAME: (i8* nocapture nofree readnone [[PTR:%.*]], i1 [[COND:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 [[COND]], label [[LOADS:%.*]], label [[EXIT:%.*]]
-; CHECK: loads:
-; CHECK-NEXT: ret void
-; CHECK: exit:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@not_entry_not_guaranteed_to_execute
+; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[PTR:%.*]], i1 [[COND:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br i1 [[COND]], label [[LOADS:%.*]], label [[EXIT:%.*]]
+; IS__TUNIT____: loads:
+; IS__TUNIT____-NEXT: ret void
+; IS__TUNIT____: exit:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@not_entry_not_guaranteed_to_execute
+; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[PTR:%.*]], i1 [[COND:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br i1 [[COND]], label [[LOADS:%.*]], label [[EXIT:%.*]]
+; IS__CGSCC____: loads:
+; IS__CGSCC____-NEXT: ret void
+; IS__CGSCC____: exit:
+; IS__CGSCC____-NEXT: ret void
;
entry:
br i1 %cond, label %loads, label %exit
@@ -181,14 +258,25 @@ exit:
; The last load may not execute, so derefenceable bytes only covers the 1st two loads.
define void @partial_in_entry(i16* %ptr, i1 %cond) {
-; CHECK-LABEL: define {{[^@]+}}@partial_in_entry
-; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(4) [[PTR:%.*]], i1 [[COND:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 [[COND]], label [[LOADS:%.*]], label [[EXIT:%.*]]
-; CHECK: loads:
-; CHECK-NEXT: ret void
-; CHECK: exit:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@partial_in_entry
+; IS__TUNIT____-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(4) [[PTR:%.*]], i1 [[COND:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br i1 [[COND]], label [[LOADS:%.*]], label [[EXIT:%.*]]
+; IS__TUNIT____: loads:
+; IS__TUNIT____-NEXT: ret void
+; IS__TUNIT____: exit:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@partial_in_entry
+; IS__CGSCC____-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(4) [[PTR:%.*]], i1 [[COND:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br i1 [[COND]], label [[LOADS:%.*]], label [[EXIT:%.*]]
+; IS__CGSCC____: loads:
+; IS__CGSCC____-NEXT: ret void
+; IS__CGSCC____: exit:
+; IS__CGSCC____-NEXT: ret void
;
entry:
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0
@@ -208,11 +296,19 @@ exit:
; The 2nd and 3rd loads may never execute.
define void @volatile_is_not_dereferenceable(i16* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
-; CHECK-SAME: (i16* nofree align 2 [[PTR:%.*]])
-; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
-; CHECK-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
+; IS__TUNIT____-SAME: (i16* nofree align 2 [[PTR:%.*]])
+; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
+; IS__TUNIT____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_is_not_dereferenceable
+; IS__CGSCC____-SAME: (i16* nofree align 2 [[PTR:%.*]])
+; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i16, i16* [[PTR]], i64 0
+; IS__CGSCC____-NEXT: [[T0:%.*]] = load volatile i16, i16* [[ARRAYIDX0]], align 2
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0
%arrayidx1 = getelementptr i16, i16* %ptr, i64 1
@@ -226,9 +322,15 @@ define void @volatile_is_not_dereferenceable(i16* %ptr) {
; TODO: We should allow inference for atomic (but not volatile) ops.
define void @atomic_is_alright(i16* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@atomic_is_alright
-; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(6) [[PTR:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomic_is_alright
+; IS__TUNIT____-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(6) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomic_is_alright
+; IS__CGSCC____-SAME: (i16* nocapture nofree nonnull readnone align 2 dereferenceable(6) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx0 = getelementptr i16, i16* %ptr, i64 0
%arrayidx1 = getelementptr i16, i16* %ptr, i64 1
@@ -260,9 +362,15 @@ define void @not_guaranteed_to_transfer_execution(i16* %ptr) {
; We must have consecutive accesses.
define void @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) {
-; CHECK-LABEL: define {{[^@]+}}@variable_gep_index
-; CHECK-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]], i64 [[VARIABLE_INDEX:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@variable_gep_index
+; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]], i64 [[VARIABLE_INDEX:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@variable_gep_index
+; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[UNUSED:%.*]], i8* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]], i64 [[VARIABLE_INDEX:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx1 = getelementptr i8, i8* %ptr, i64 %variable_index
%arrayidx2 = getelementptr i8, i8* %ptr, i64 2
@@ -276,9 +384,15 @@ define void @variable_gep_index(i8* %unused, i8* %ptr, i64 %variable_index) {
define void @multi_index_gep(<4 x i8>* %ptr) {
; FIXME: %ptr should be dereferenceable(4)
-; CHECK-LABEL: define {{[^@]+}}@multi_index_gep
-; CHECK-SAME: (<4 x i8>* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@multi_index_gep
+; IS__TUNIT____-SAME: (<4 x i8>* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@multi_index_gep
+; IS__CGSCC____-SAME: (<4 x i8>* nocapture nofree nonnull readnone dereferenceable(1) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx00 = getelementptr <4 x i8>, <4 x i8>* %ptr, i64 0, i64 0
%t0 = load i8, i8* %arrayidx00
@@ -288,9 +402,15 @@ define void @multi_index_gep(<4 x i8>* %ptr) {
; Could round weird bitwidths down?
define void @not_byte_multiple(i9* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@not_byte_multiple
-; CHECK-SAME: (i9* nocapture nofree nonnull readnone align 2 dereferenceable(2) [[PTR:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@not_byte_multiple
+; IS__TUNIT____-SAME: (i9* nocapture nofree nonnull readnone align 2 dereferenceable(2) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@not_byte_multiple
+; IS__CGSCC____-SAME: (i9* nocapture nofree nonnull readnone align 2 dereferenceable(2) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx0 = getelementptr i9, i9* %ptr, i64 0
%t0 = load i9, i9* %arrayidx0
@@ -300,9 +420,15 @@ define void @not_byte_multiple(i9* %ptr) {
; Missing direct access from the pointer.
define void @no_pointer_deref(i16* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@no_pointer_deref
-; CHECK-SAME: (i16* nocapture nofree readnone align 2 [[PTR:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@no_pointer_deref
+; IS__TUNIT____-SAME: (i16* nocapture nofree readnone align 2 [[PTR:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@no_pointer_deref
+; IS__CGSCC____-SAME: (i16* nocapture nofree readnone align 2 [[PTR:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx1 = getelementptr i16, i16* %ptr, i64 1
%arrayidx2 = getelementptr i16, i16* %ptr, i64 2
@@ -314,9 +440,15 @@ define void @no_pointer_deref(i16* %ptr) {
; Out-of-order is ok, but missing access concludes dereferenceable range.
define void @non_consecutive(i32* %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@non_consecutive
-; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@non_consecutive
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@non_consecutive
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx1 = getelementptr i32, i32* %ptr, i64 1
%arrayidx0 = getelementptr i32, i32* %ptr, i64 0
@@ -330,9 +462,15 @@ define void @non_consecutive(i32* %ptr) {
; Improve on existing dereferenceable attribute.
define void @more_bytes(i32* dereferenceable(8) %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@more_bytes
-; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@more_bytes
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@more_bytes
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx3 = getelementptr i32, i32* %ptr, i64 3
%arrayidx1 = getelementptr i32, i32* %ptr, i64 1
@@ -348,9 +486,15 @@ define void @more_bytes(i32* dereferenceable(8) %ptr) {
; Improve on existing dereferenceable_or_null attribute.
define void @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@more_bytes_and_not_null
-; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@more_bytes_and_not_null
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@more_bytes_and_not_null
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx3 = getelementptr i32, i32* %ptr, i64 3
%arrayidx1 = getelementptr i32, i32* %ptr, i64 1
@@ -366,9 +510,15 @@ define void @more_bytes_and_not_null(i32* dereferenceable_or_null(8) %ptr) {
; But don't pessimize existing dereferenceable attribute.
define void @better_bytes(i32* dereferenceable(100) %ptr) {
-; CHECK-LABEL: define {{[^@]+}}@better_bytes
-; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(100) [[PTR:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@better_bytes
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(100) [[PTR:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@better_bytes
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(100) [[PTR:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%arrayidx3 = getelementptr i32, i32* %ptr, i64 3
%arrayidx1 = getelementptr i32, i32* %ptr, i64 1
@@ -382,9 +532,15 @@ define void @better_bytes(i32* dereferenceable(100) %ptr) {
}
define void @bitcast(i32* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@bitcast
-; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[ARG:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bitcast
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[ARG:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bitcast
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(8) [[ARG:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%ptr = bitcast i32* %arg to float*
%arrayidx0 = getelementptr float, float* %ptr, i64 0
@@ -395,9 +551,15 @@ define void @bitcast(i32* %arg) {
}
define void @bitcast_
diff erent_sizes(double* %arg1, i8* %arg2) {
-; CHECK-LABEL: define {{[^@]+}}@bitcast_
diff erent_sizes
-; CHECK-SAME: (double* nocapture nofree nonnull readnone align 4 dereferenceable(12) [[ARG1:%.*]], i8* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[ARG2:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bitcast_
diff erent_sizes
+; IS__TUNIT____-SAME: (double* nocapture nofree nonnull readnone align 4 dereferenceable(12) [[ARG1:%.*]], i8* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[ARG2:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bitcast_
diff erent_sizes
+; IS__CGSCC____-SAME: (double* nocapture nofree nonnull readnone align 4 dereferenceable(12) [[ARG1:%.*]], i8* nocapture nofree nonnull readnone align 4 dereferenceable(16) [[ARG2:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%ptr1 = bitcast double* %arg1 to float*
%a10 = getelementptr float, float* %ptr1, i64 0
@@ -416,9 +578,15 @@ define void @bitcast_
diff erent_sizes(double* %arg1, i8* %arg2) {
}
define void @negative_offset(i32* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@negative_offset
-; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ARG:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_offset
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ARG:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_offset
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[ARG:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
%ptr = bitcast i32* %arg to float*
%arrayidx0 = getelementptr float, float* %ptr, i64 0
@@ -429,14 +597,25 @@ define void @negative_offset(i32* %arg) {
}
define void @stores(i32* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@stores
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]])
-; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float*
-; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr float, float* [[PTR]], i64 0
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1
-; CHECK-NEXT: store float 1.000000e+00, float* [[ARRAYIDX0]], align 4
-; CHECK-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@stores
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]])
+; IS__TUNIT____-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float*
+; IS__TUNIT____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr float, float* [[PTR]], i64 0
+; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1
+; IS__TUNIT____-NEXT: store float 1.000000e+00, float* [[ARRAYIDX0]], align 4
+; IS__TUNIT____-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@stores
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]])
+; IS__CGSCC____-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float*
+; IS__CGSCC____-NEXT: [[ARRAYIDX0:%.*]] = getelementptr float, float* [[PTR]], i64 0
+; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1
+; IS__CGSCC____-NEXT: store float 1.000000e+00, float* [[ARRAYIDX0]], align 4
+; IS__CGSCC____-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4
+; IS__CGSCC____-NEXT: ret void
;
%ptr = bitcast i32* %arg to float*
%arrayidx0 = getelementptr float, float* %ptr, i64 0
@@ -447,12 +626,21 @@ define void @stores(i32* %arg) {
}
define void @load_store(i32* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@load_store
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]])
-; CHECK-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float*
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1
-; CHECK-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@load_store
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]])
+; IS__TUNIT____-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float*
+; IS__TUNIT____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1
+; IS__TUNIT____-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@load_store
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(8) [[ARG:%.*]])
+; IS__CGSCC____-NEXT: [[PTR:%.*]] = bitcast i32* [[ARG]] to float*
+; IS__CGSCC____-NEXT: [[ARRAYIDX1:%.*]] = getelementptr float, float* [[PTR]], i64 1
+; IS__CGSCC____-NEXT: store float 2.000000e+00, float* [[ARRAYIDX1]], align 4
+; IS__CGSCC____-NEXT: ret void
;
%ptr = bitcast i32* %arg to float*
%arrayidx0 = getelementptr float, float* %ptr, i64 0
@@ -463,12 +651,21 @@ define void @load_store(i32* %arg) {
}
define void @
diff erent_size1(i32* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@
diff erent_size1
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]])
-; CHECK-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double*
-; CHECK-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8
-; CHECK-NEXT: store i32 0, i32* [[ARG]], align 8
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@
diff erent_size1
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]])
+; IS__TUNIT____-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double*
+; IS__TUNIT____-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8
+; IS__TUNIT____-NEXT: store i32 0, i32* [[ARG]], align 8
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@
diff erent_size1
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]])
+; IS__CGSCC____-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double*
+; IS__CGSCC____-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8
+; IS__CGSCC____-NEXT: store i32 0, i32* [[ARG]], align 8
+; IS__CGSCC____-NEXT: ret void
;
%arg-cast = bitcast i32* %arg to double*
store double 0.000000e+00, double* %arg-cast
@@ -477,12 +674,21 @@ define void @
diff erent_size1(i32* %arg) {
}
define void @
diff erent_size2(i32* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@
diff erent_size2
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]])
-; CHECK-NEXT: store i32 0, i32* [[ARG]], align 8
-; CHECK-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double*
-; CHECK-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@
diff erent_size2
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]])
+; IS__TUNIT____-NEXT: store i32 0, i32* [[ARG]], align 8
+; IS__TUNIT____-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double*
+; IS__TUNIT____-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@
diff erent_size2
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[ARG:%.*]])
+; IS__CGSCC____-NEXT: store i32 0, i32* [[ARG]], align 8
+; IS__CGSCC____-NEXT: [[ARG_CAST:%.*]] = bitcast i32* [[ARG]] to double*
+; IS__CGSCC____-NEXT: store double 0.000000e+00, double* [[ARG_CAST]], align 8
+; IS__CGSCC____-NEXT: ret void
;
store i32 0, i32* %arg
%arg-cast = bitcast i32* %arg to double*
@@ -509,56 +715,111 @@ define void @
diff erent_size2(i32* %arg) {
;
; ATTRIBUTOR_CGSCC_NPM-LABEL: define i32 @require_cfg_analysis(i32 %c, i32* {{.*}} dereferenceable(4) %p)
define i32 @require_cfg_analysis(i32 %c, i32* %p) {
-; IS________OPM-LABEL: define {{[^@]+}}@require_cfg_analysis
-; IS________OPM-SAME: (i32 [[C:%.*]], i32* nocapture nofree writeonly [[P:%.*]])
-; IS________OPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0
-; IS________OPM-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]]
-; IS________OPM: l1:
-; IS________OPM-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[C]], 1
-; IS________OPM-NEXT: br i1 [[TOBOOL2]], label [[L3:%.*]], label [[L4:%.*]]
-; IS________OPM: l2:
-; IS________OPM-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2
-; IS________OPM-NEXT: br i1 [[TOBOOL3]], label [[L3]], label [[L4]]
-; IS________OPM: l3:
-; IS________OPM-NEXT: br label [[L5:%.*]]
-; IS________OPM: l4:
-; IS________OPM-NEXT: br label [[L5]]
-; IS________OPM: l5:
-; IS________OPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 4
-; IS________OPM-NEXT: br i1 [[TOBOOL4]], label [[L6:%.*]], label [[L7:%.*]]
-; IS________OPM: l6:
-; IS________OPM-NEXT: store i32 0, i32* [[P]], align 4
-; IS________OPM-NEXT: br label [[END:%.*]]
-; IS________OPM: l7:
-; IS________OPM-NEXT: store i32 1, i32* [[P]], align 4
-; IS________OPM-NEXT: br label [[END]]
-; IS________OPM: end:
-; IS________OPM-NEXT: ret i32 1
-;
-; IS________NPM-LABEL: define {{[^@]+}}@require_cfg_analysis
-; IS________NPM-SAME: (i32 [[C:%.*]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]])
-; IS________NPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0
-; IS________NPM-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]]
-; IS________NPM: l1:
-; IS________NPM-NEXT: br label [[L4:%.*]]
-; IS________NPM: l2:
-; IS________NPM-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2
-; IS________NPM-NEXT: br i1 [[TOBOOL3]], label [[L3:%.*]], label [[L4]]
-; IS________NPM: l3:
-; IS________NPM-NEXT: br label [[L5:%.*]]
-; IS________NPM: l4:
-; IS________NPM-NEXT: br label [[L5]]
-; IS________NPM: l5:
-; IS________NPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 4
-; IS________NPM-NEXT: br i1 [[TOBOOL4]], label [[L6:%.*]], label [[L7:%.*]]
-; IS________NPM: l6:
-; IS________NPM-NEXT: store i32 0, i32* [[P]], align 4
-; IS________NPM-NEXT: br label [[END:%.*]]
-; IS________NPM: l7:
-; IS________NPM-NEXT: store i32 1, i32* [[P]], align 4
-; IS________NPM-NEXT: br label [[END]]
-; IS________NPM: end:
-; IS________NPM-NEXT: ret i32 1
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@require_cfg_analysis
+; IS__TUNIT_OPM-SAME: (i32 [[C:%.*]], i32* nocapture nofree writeonly [[P:%.*]])
+; IS__TUNIT_OPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0
+; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]]
+; IS__TUNIT_OPM: l1:
+; IS__TUNIT_OPM-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[C]], 1
+; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL2]], label [[L3:%.*]], label [[L4:%.*]]
+; IS__TUNIT_OPM: l2:
+; IS__TUNIT_OPM-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2
+; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL3]], label [[L3]], label [[L4]]
+; IS__TUNIT_OPM: l3:
+; IS__TUNIT_OPM-NEXT: br label [[L5:%.*]]
+; IS__TUNIT_OPM: l4:
+; IS__TUNIT_OPM-NEXT: br label [[L5]]
+; IS__TUNIT_OPM: l5:
+; IS__TUNIT_OPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 4
+; IS__TUNIT_OPM-NEXT: br i1 [[TOBOOL4]], label [[L6:%.*]], label [[L7:%.*]]
+; IS__TUNIT_OPM: l6:
+; IS__TUNIT_OPM-NEXT: store i32 0, i32* [[P]], align 4
+; IS__TUNIT_OPM-NEXT: br label [[END:%.*]]
+; IS__TUNIT_OPM: l7:
+; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[P]], align 4
+; IS__TUNIT_OPM-NEXT: br label [[END]]
+; IS__TUNIT_OPM: end:
+; IS__TUNIT_OPM-NEXT: ret i32 1
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@require_cfg_analysis
+; IS__TUNIT_NPM-SAME: (i32 [[C:%.*]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__TUNIT_NPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0
+; IS__TUNIT_NPM-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]]
+; IS__TUNIT_NPM: l1:
+; IS__TUNIT_NPM-NEXT: br label [[L4:%.*]]
+; IS__TUNIT_NPM: l2:
+; IS__TUNIT_NPM-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2
+; IS__TUNIT_NPM-NEXT: br i1 [[TOBOOL3]], label [[L3:%.*]], label [[L4]]
+; IS__TUNIT_NPM: l3:
+; IS__TUNIT_NPM-NEXT: br label [[L5:%.*]]
+; IS__TUNIT_NPM: l4:
+; IS__TUNIT_NPM-NEXT: br label [[L5]]
+; IS__TUNIT_NPM: l5:
+; IS__TUNIT_NPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 4
+; IS__TUNIT_NPM-NEXT: br i1 [[TOBOOL4]], label [[L6:%.*]], label [[L7:%.*]]
+; IS__TUNIT_NPM: l6:
+; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[P]], align 4
+; IS__TUNIT_NPM-NEXT: br label [[END:%.*]]
+; IS__TUNIT_NPM: l7:
+; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[P]], align 4
+; IS__TUNIT_NPM-NEXT: br label [[END]]
+; IS__TUNIT_NPM: end:
+; IS__TUNIT_NPM-NEXT: ret i32 1
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@require_cfg_analysis
+; IS__CGSCC_OPM-SAME: (i32 [[C:%.*]], i32* nocapture nofree writeonly [[P:%.*]])
+; IS__CGSCC_OPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0
+; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]]
+; IS__CGSCC_OPM: l1:
+; IS__CGSCC_OPM-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[C]], 1
+; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL2]], label [[L3:%.*]], label [[L4:%.*]]
+; IS__CGSCC_OPM: l2:
+; IS__CGSCC_OPM-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2
+; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL3]], label [[L3]], label [[L4]]
+; IS__CGSCC_OPM: l3:
+; IS__CGSCC_OPM-NEXT: br label [[L5:%.*]]
+; IS__CGSCC_OPM: l4:
+; IS__CGSCC_OPM-NEXT: br label [[L5]]
+; IS__CGSCC_OPM: l5:
+; IS__CGSCC_OPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 4
+; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL4]], label [[L6:%.*]], label [[L7:%.*]]
+; IS__CGSCC_OPM: l6:
+; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[P]], align 4
+; IS__CGSCC_OPM-NEXT: br label [[END:%.*]]
+; IS__CGSCC_OPM: l7:
+; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[P]], align 4
+; IS__CGSCC_OPM-NEXT: br label [[END]]
+; IS__CGSCC_OPM: end:
+; IS__CGSCC_OPM-NEXT: ret i32 1
+;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@require_cfg_analysis
+; IS__CGSCC_NPM-SAME: (i32 [[C:%.*]], i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__CGSCC_NPM-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C]], 0
+; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL1]], label [[L1:%.*]], label [[L2:%.*]]
+; IS__CGSCC_NPM: l1:
+; IS__CGSCC_NPM-NEXT: br label [[L4:%.*]]
+; IS__CGSCC_NPM: l2:
+; IS__CGSCC_NPM-NEXT: [[TOBOOL3:%.*]] = icmp eq i32 [[C]], 2
+; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL3]], label [[L3:%.*]], label [[L4]]
+; IS__CGSCC_NPM: l3:
+; IS__CGSCC_NPM-NEXT: br label [[L5:%.*]]
+; IS__CGSCC_NPM: l4:
+; IS__CGSCC_NPM-NEXT: br label [[L5]]
+; IS__CGSCC_NPM: l5:
+; IS__CGSCC_NPM-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[C]], 4
+; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL4]], label [[L6:%.*]], label [[L7:%.*]]
+; IS__CGSCC_NPM: l6:
+; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[P]], align 4
+; IS__CGSCC_NPM-NEXT: br label [[END:%.*]]
+; IS__CGSCC_NPM: l7:
+; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[P]], align 4
+; IS__CGSCC_NPM-NEXT: br label [[END]]
+; IS__CGSCC_NPM: end:
+; IS__CGSCC_NPM-NEXT: ret i32 1
;
%tobool1 = icmp eq i32 %c, 0
br i1 %tobool1, label %l1, label %l2
diff --git a/llvm/test/Transforms/Attributor/heap_to_stack.ll b/llvm/test/Transforms/Attributor/heap_to_stack.ll
index 909cda54fc86..f46da51e2dfd 100644
--- a/llvm/test/Transforms/Attributor/heap_to_stack.ll
+++ b/llvm/test/Transforms/Attributor/heap_to_stack.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -287,11 +287,13 @@ define void @test6(i32) {
; TEST 7 - free is dead.
define void @test7() {
+; IS________OPM: Function Attrs: noreturn
; IS________OPM-LABEL: define {{[^@]+}}@test7()
; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call()
; IS________OPM-NEXT: unreachable
;
+; IS________NPM: Function Attrs: noreturn
; IS________NPM-LABEL: define {{[^@]+}}@test7()
; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4, align 1
; IS________NPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call()
diff --git a/llvm/test/Transforms/Attributor/internal-noalias.ll b/llvm/test/Transforms/Attributor/internal-noalias.ll
index 182cadf48a0b..67aa1ec985e9 100644
--- a/llvm/test/Transforms/Attributor/internal-noalias.ll
+++ b/llvm/test/Transforms/Attributor/internal-noalias.ll
@@ -1,10 +1,11 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@visible
; IS__TUNIT____-SAME: (i32* noalias nocapture nofree readonly [[A:%.*]], i32* noalias nocapture nofree readonly [[B:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -13,6 +14,7 @@ define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 {
; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]]
; IS__TUNIT____-NEXT: ret i32 [[ADD]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@visible
; IS__CGSCC____-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -29,6 +31,7 @@ entry:
}
define private i32 @noalias_args(i32* %A, i32* %B) #0 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@noalias_args
; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -39,6 +42,7 @@ define private i32 @noalias_args(i32* %A, i32* %B) #0 {
; IS__TUNIT____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]]
; IS__TUNIT____-NEXT: ret i32 [[ADD2]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -60,6 +64,7 @@ entry:
define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@noalias_args_argmem
; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -68,6 +73,7 @@ define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 {
; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
; IS__TUNIT____-NEXT: ret i32 [[ADD]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -84,6 +90,7 @@ entry:
}
define dso_local i32 @visible_local(i32* %A) #0 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@visible_local
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[A:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -94,6 +101,7 @@ define dso_local i32 @visible_local(i32* %A) #0 {
; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]]
; IS__TUNIT____-NEXT: ret i32 [[ADD]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -114,6 +122,7 @@ entry:
}
define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@noalias_args_argmem_ro
; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__TUNIT_OPM-NEXT: [[T0:%.*]] = load i32, i32* [[A]], align 4
@@ -121,6 +130,7 @@ define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 {
; IS__TUNIT_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]]
; IS__TUNIT_OPM-NEXT: ret i32 [[ADD]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@noalias_args_argmem_ro
; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca i32, align 4
@@ -132,6 +142,7 @@ define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 {
; IS__TUNIT_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]]
; IS__TUNIT_NPM-NEXT: ret i32 [[ADD]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem_ro
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A:%.*]], i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B:%.*]])
; IS__CGSCC____-NEXT: [[T0:%.*]] = load i32, i32* [[A]], align 4
@@ -146,12 +157,14 @@ define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 {
}
define i32 @visible_local_2() {
-; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@visible_local_2()
-; NOT_TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 4
-; NOT_TUNIT_NPM-NEXT: store i32 5, i32* [[B]], align 4
-; NOT_TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
-; NOT_TUNIT_NPM-NEXT: ret i32 [[CALL]]
-;
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@visible_local_2()
+; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__TUNIT_OPM-NEXT: store i32 5, i32* [[B]], align 4
+; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
+; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@visible_local_2()
; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 4
; IS__TUNIT_NPM-NEXT: store i32 5, i32* [[B]], align 4
@@ -159,6 +172,13 @@ define i32 @visible_local_2() {
; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[B]], align 4
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32 [[TMP1]], i32 [[TMP2]])
; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local_2()
+; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4
+; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_ro(i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]], i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
+; IS__CGSCC____-NEXT: ret i32 [[CALL]]
;
%B = alloca i32, align 4
store i32 5, i32* %B, align 4
@@ -167,12 +187,14 @@ define i32 @visible_local_2() {
}
define internal i32 @noalias_args_argmem_rn(i32* %A, i32* %B) #1 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@noalias_args_argmem_rn
; IS__TUNIT____-SAME: (i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[B:%.*]])
; IS__TUNIT____-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4
; IS__TUNIT____-NEXT: store i32 0, i32* [[B]], align 4
; IS__TUNIT____-NEXT: ret i32 [[T0]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@noalias_args_argmem_rn
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull align 4 dereferenceable(4) [[B:%.*]])
; IS__CGSCC____-NEXT: [[T0:%.*]] = load i32, i32* [[B]], align 4
@@ -185,11 +207,19 @@ define internal i32 @noalias_args_argmem_rn(i32* %A, i32* %B) #1 {
}
define i32 @visible_local_3() {
-; CHECK-LABEL: define {{[^@]+}}@visible_local_3()
-; CHECK-NEXT: [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT: store i32 5, i32* [[B]], align 4
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[B]])
-; CHECK-NEXT: ret i32 [[CALL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@visible_local_3()
+; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__TUNIT____-NEXT: store i32 5, i32* [[B]], align 4
+; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[B]])
+; IS__TUNIT____-NEXT: ret i32 [[CALL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local_3()
+; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4
+; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4
+; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @noalias_args_argmem_rn(i32* noalias nocapture nofree nonnull align 4 dereferenceable(4) [[B]])
+; IS__CGSCC____-NEXT: ret i32 [[CALL]]
;
%B = alloca i32, align 4
store i32 5, i32* %B, align 4
diff --git a/llvm/test/Transforms/Attributor/liveness.ll b/llvm/test/Transforms/Attributor/liveness.ll
index 1ce3ff007092..04899eb1f712 100644
--- a/llvm/test/Transforms/Attributor/liveness.ll
+++ b/llvm/test/Transforms/Attributor/liveness.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; TODO: The old pass manager cgscc run is disabled as it causes a crash on windows which is under investigation: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/23151
@@ -27,6 +27,7 @@ declare i32 @bar() nosync readnone
; and nothing should be deduced for it.
define internal i32 @dead_internal_func(i32 %0) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@dead_internal_func()
; IS__CGSCC____-NEXT: br label [[TMP2:%.*]]
; IS__CGSCC____: 1:
@@ -55,8 +56,8 @@ define internal i32 @dead_internal_func(i32 %0) {
br i1 %10, label %3, label %5
}
-; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
define i32 @volatile_load(i32*) norecurse nounwind uwtable {
+; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@volatile_load
; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]])
; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4
@@ -67,6 +68,7 @@ define i32 @volatile_load(i32*) norecurse nounwind uwtable {
}
define internal i32 @internal_load(i32*) norecurse nounwind uwtable {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_load()
; IS__CGSCC____-NEXT: ret i32 undef
;
@@ -75,8 +77,8 @@ define internal i32 @internal_load(i32*) norecurse nounwind uwtable {
}
; TEST 1: Only first block is live.
-; CHECK: Function Attrs: nofree noreturn nosync nounwind
define i32 @first_block_no_return(i32 %a, i32* nonnull %ptr1, i32* %ptr2) #0 {
+; CHECK: Function Attrs: nofree noreturn nosync nounwind
; CHECK-LABEL: define {{[^@]+}}@first_block_no_return
; CHECK-SAME: (i32 [[A:%.*]], i32* nocapture nofree nonnull readnone [[PTR1:%.*]], i32* nocapture nofree readnone [[PTR2:%.*]])
; CHECK-NEXT: entry:
@@ -118,8 +120,8 @@ cond.end: ; preds = %cond.false, %cond.t
; This is just an example. For example we can put a sync call in a
; dead block and check if it is deduced.
-; CHECK: Function Attrs: nosync
define i32 @dead_block_present(i32 %a, i32* %ptr1) #0 {
+; CHECK: Function Attrs: nosync
; CHECK-LABEL: define {{[^@]+}}@dead_block_present
; CHECK-SAME: (i32 [[A:%.*]], i32* nocapture nofree readnone [[PTR1:%.*]])
; CHECK-NEXT: entry:
@@ -157,6 +159,7 @@ cond.end: ; preds = %cond.false, %cond.t
; TEST 3: both cond.true and cond.false are dead, therfore cond.end is dead as well.
define i32 @all_dead(i32 %a) #0 {
+; CHECK: Function Attrs: nofree noreturn nosync nounwind
; CHECK-LABEL: define {{[^@]+}}@all_dead
; CHECK-SAME: (i32 [[A:%.*]])
; CHECK-NEXT: entry:
@@ -478,13 +481,23 @@ cleanup:
; FIXME: Should be able to detect undefined behavior.
define void @ub(i32* %0) {
-; CHECK-LABEL: define {{[^@]+}}@ub
-; CHECK-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]])
-; CHECK-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1
-; CHECK-NEXT: [[STILL_POISON:%.*]] = and i32 [[POISON]], 0
-; CHECK-NEXT: [[POISON_YET_AGAIN:%.*]] = getelementptr i32, i32* [[TMP0]], i32 [[STILL_POISON]]
-; CHECK-NEXT: store i32 0, i32* [[POISON_YET_AGAIN]], align 4
-; CHECK-NEXT: ret void
+; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@ub
+; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]])
+; NOT_CGSCC_NPM-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1
+; NOT_CGSCC_NPM-NEXT: [[STILL_POISON:%.*]] = and i32 [[POISON]], 0
+; NOT_CGSCC_NPM-NEXT: [[POISON_YET_AGAIN:%.*]] = getelementptr i32, i32* [[TMP0]], i32 [[STILL_POISON]]
+; NOT_CGSCC_NPM-NEXT: store i32 0, i32* [[POISON_YET_AGAIN]], align 4
+; NOT_CGSCC_NPM-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ub
+; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[TMP0:%.*]])
+; IS__CGSCC____-NEXT: [[POISON:%.*]] = sub nuw i32 0, 1
+; IS__CGSCC____-NEXT: [[STILL_POISON:%.*]] = and i32 [[POISON]], 0
+; IS__CGSCC____-NEXT: [[POISON_YET_AGAIN:%.*]] = getelementptr i32, i32* [[TMP0]], i32 [[STILL_POISON]]
+; IS__CGSCC____-NEXT: store i32 0, i32* [[POISON_YET_AGAIN]], align 4
+; IS__CGSCC____-NEXT: ret void
;
%poison = sub nuw i32 0, 1 ; Results in a poison value.
%still_poison = and i32 %poison, 0 ; 0, but also poison.
@@ -494,11 +507,19 @@ define void @ub(i32* %0) {
}
define void @inf_loop() #0 {
-; CHECK-LABEL: define {{[^@]+}}@inf_loop()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
-; CHECK: while.body:
-; CHECK-NEXT: br label [[WHILE_BODY]]
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@inf_loop()
+; NOT_CGSCC_NPM-NEXT: entry:
+; NOT_CGSCC_NPM-NEXT: br label [[WHILE_BODY:%.*]]
+; NOT_CGSCC_NPM: while.body:
+; NOT_CGSCC_NPM-NEXT: br label [[WHILE_BODY]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone
+; IS__CGSCC____-LABEL: define {{[^@]+}}@inf_loop()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__CGSCC____: while.body:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY]]
;
entry:
br label %while.body
@@ -511,6 +532,7 @@ while.body: ; preds = %entry, %while.body
; FIXME: Detect infloops, and mark affected blocks dead.
define i32 @test5(i32, i32) #0 {
+; CHECK: Function Attrs: nosync readnone
; CHECK-LABEL: define {{[^@]+}}@test5
; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]]
@@ -547,9 +569,15 @@ cond.end: ; preds = %cond.if, %con
}
define void @rec() #0 {
-; CHECK-LABEL: define {{[^@]+}}@rec()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@rec()
+; NOT_CGSCC_NPM-NEXT: entry:
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@rec()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
call void @rec()
@@ -561,17 +589,31 @@ entry:
; and unreachable should be put after call to @rec().
define i32 @test6(i32, i32) #0 {
-; CHECK-LABEL: define {{[^@]+}}@test6
-; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
-; CHECK-NEXT: unreachable
-; CHECK: cond.if:
-; CHECK-NEXT: unreachable
-; CHECK: cond.elseif:
-; CHECK-NEXT: unreachable
-; CHECK: cond.else:
-; CHECK-NEXT: unreachable
-; CHECK: cond.end:
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6
+; NOT_CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
+; NOT_CGSCC_NPM-NEXT: unreachable
+; NOT_CGSCC_NPM: cond.if:
+; NOT_CGSCC_NPM-NEXT: unreachable
+; NOT_CGSCC_NPM: cond.elseif:
+; NOT_CGSCC_NPM-NEXT: unreachable
+; NOT_CGSCC_NPM: cond.else:
+; NOT_CGSCC_NPM-NEXT: unreachable
+; NOT_CGSCC_NPM: cond.end:
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test6
+; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: cond.if:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: cond.elseif:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: cond.else:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: cond.end:
+; IS__CGSCC____-NEXT: unreachable
;
call void @rec()
%3 = icmp sgt i32 %0, %1
@@ -738,6 +780,7 @@ define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
declare void @sink() nofree nosync nounwind willreturn
define void @test_unreachable() {
+; CHECK: Function Attrs: nofree noreturn nosync nounwind
; CHECK-LABEL: define {{[^@]+}}@test_unreachable()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: call void @test_unreachable()
@@ -929,6 +972,7 @@ define linkonce_odr void @non_exact3() {
}
define internal void @non_dead_a0() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a0()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -937,6 +981,7 @@ define internal void @non_dead_a0() {
ret void
}
define internal void @non_dead_a1() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a1()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -945,6 +990,7 @@ define internal void @non_dead_a1() {
ret void
}
define internal void @non_dead_a2() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a2()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -953,6 +999,7 @@ define internal void @non_dead_a2() {
ret void
}
define internal void @non_dead_a3() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a3()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -961,6 +1008,7 @@ define internal void @non_dead_a3() {
ret void
}
define internal void @non_dead_a4() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a4()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -969,6 +1017,7 @@ define internal void @non_dead_a4() {
ret void
}
define internal void @non_dead_a5() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a5()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -977,6 +1026,7 @@ define internal void @non_dead_a5() {
ret void
}
define internal void @non_dead_a6() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a6()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -985,6 +1035,7 @@ define internal void @non_dead_a6() {
ret void
}
define internal void @non_dead_a7() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a7()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -993,6 +1044,7 @@ define internal void @non_dead_a7() {
ret void
}
define internal void @non_dead_a8() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a8()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1001,6 +1053,7 @@ define internal void @non_dead_a8() {
ret void
}
define internal void @non_dead_a9() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a9()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1009,6 +1062,7 @@ define internal void @non_dead_a9() {
ret void
}
define internal void @non_dead_a10() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a10()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1017,6 +1071,7 @@ define internal void @non_dead_a10() {
ret void
}
define internal void @non_dead_a11() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a11()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1025,6 +1080,7 @@ define internal void @non_dead_a11() {
ret void
}
define internal void @non_dead_a12() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a12()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1033,6 +1089,7 @@ define internal void @non_dead_a12() {
ret void
}
define internal void @non_dead_a13() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a13()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1041,6 +1098,7 @@ define internal void @non_dead_a13() {
ret void
}
define internal void @non_dead_a14() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a14()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1049,6 +1107,7 @@ define internal void @non_dead_a14() {
ret void
}
define internal void @non_dead_a15() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_a15()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1057,6 +1116,7 @@ define internal void @non_dead_a15() {
ret void
}
define internal void @non_dead_b0() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b0()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1065,6 +1125,7 @@ define internal void @non_dead_b0() {
ret void
}
define internal void @non_dead_b1() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b1()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1073,6 +1134,7 @@ define internal void @non_dead_b1() {
ret void
}
define internal void @non_dead_b2() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b2()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1081,6 +1143,7 @@ define internal void @non_dead_b2() {
ret void
}
define internal void @non_dead_b3() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b3()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1089,6 +1152,7 @@ define internal void @non_dead_b3() {
ret void
}
define internal void @non_dead_b4() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b4()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1097,6 +1161,7 @@ define internal void @non_dead_b4() {
ret void
}
define internal void @non_dead_b5() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b5()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1105,6 +1170,7 @@ define internal void @non_dead_b5() {
ret void
}
define internal void @non_dead_b6() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b6()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1113,6 +1179,7 @@ define internal void @non_dead_b6() {
ret void
}
define internal void @non_dead_b7() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b7()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1121,6 +1188,7 @@ define internal void @non_dead_b7() {
ret void
}
define internal void @non_dead_b8() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b8()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1129,6 +1197,7 @@ define internal void @non_dead_b8() {
ret void
}
define internal void @non_dead_b9() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b9()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1137,6 +1206,7 @@ define internal void @non_dead_b9() {
ret void
}
define internal void @non_dead_b10() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b10()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1145,6 +1215,7 @@ define internal void @non_dead_b10() {
ret void
}
define internal void @non_dead_b11() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b11()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1153,6 +1224,7 @@ define internal void @non_dead_b11() {
ret void
}
define internal void @non_dead_b12() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b12()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1161,6 +1233,7 @@ define internal void @non_dead_b12() {
ret void
}
define internal void @non_dead_b13() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b13()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1169,6 +1242,7 @@ define internal void @non_dead_b13() {
ret void
}
define internal void @non_dead_b14() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b14()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1177,6 +1251,7 @@ define internal void @non_dead_b14() {
ret void
}
define internal void @non_dead_b15() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_b15()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1185,6 +1260,7 @@ define internal void @non_dead_b15() {
ret void
}
define internal void @non_dead_c0() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c0()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1193,6 +1269,7 @@ define internal void @non_dead_c0() {
ret void
}
define internal void @non_dead_c1() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c1()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1201,6 +1278,7 @@ define internal void @non_dead_c1() {
ret void
}
define internal void @non_dead_c2() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c2()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1209,6 +1287,7 @@ define internal void @non_dead_c2() {
ret void
}
define internal void @non_dead_c3() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c3()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1217,6 +1296,7 @@ define internal void @non_dead_c3() {
ret void
}
define internal void @non_dead_c4() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c4()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1225,6 +1305,7 @@ define internal void @non_dead_c4() {
ret void
}
define internal void @non_dead_c5() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c5()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1233,6 +1314,7 @@ define internal void @non_dead_c5() {
ret void
}
define internal void @non_dead_c6() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c6()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1241,6 +1323,7 @@ define internal void @non_dead_c6() {
ret void
}
define internal void @non_dead_c7() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c7()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1249,6 +1332,7 @@ define internal void @non_dead_c7() {
ret void
}
define internal void @non_dead_c8() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c8()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1257,6 +1341,7 @@ define internal void @non_dead_c8() {
ret void
}
define internal void @non_dead_c9() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c9()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1265,6 +1350,7 @@ define internal void @non_dead_c9() {
ret void
}
define internal void @non_dead_c10() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c10()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1273,6 +1359,7 @@ define internal void @non_dead_c10() {
ret void
}
define internal void @non_dead_c11() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c11()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1281,6 +1368,7 @@ define internal void @non_dead_c11() {
ret void
}
define internal void @non_dead_c12() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c12()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1289,6 +1377,7 @@ define internal void @non_dead_c12() {
ret void
}
define internal void @non_dead_c13() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c13()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1297,6 +1386,7 @@ define internal void @non_dead_c13() {
ret void
}
define internal void @non_dead_c14() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c14()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1305,6 +1395,7 @@ define internal void @non_dead_c14() {
ret void
}
define internal void @non_dead_c15() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_c15()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1313,6 +1404,7 @@ define internal void @non_dead_c15() {
ret void
}
define internal void @non_dead_d0() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d0()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1321,6 +1413,7 @@ define internal void @non_dead_d0() {
ret void
}
define internal void @non_dead_d1() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d1()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1329,6 +1422,7 @@ define internal void @non_dead_d1() {
ret void
}
define internal void @non_dead_d2() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d2()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1337,6 +1431,7 @@ define internal void @non_dead_d2() {
ret void
}
define internal void @non_dead_d3() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d3()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1345,6 +1440,7 @@ define internal void @non_dead_d3() {
ret void
}
define internal void @non_dead_d4() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d4()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1353,6 +1449,7 @@ define internal void @non_dead_d4() {
ret void
}
define internal void @non_dead_d5() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d5()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1361,6 +1458,7 @@ define internal void @non_dead_d5() {
ret void
}
define internal void @non_dead_d6() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d6()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1369,6 +1467,7 @@ define internal void @non_dead_d6() {
ret void
}
define internal void @non_dead_d7() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d7()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1377,6 +1476,7 @@ define internal void @non_dead_d7() {
ret void
}
define internal void @non_dead_d8() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d8()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1385,6 +1485,7 @@ define internal void @non_dead_d8() {
ret void
}
define internal void @non_dead_d9() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d9()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1393,6 +1494,7 @@ define internal void @non_dead_d9() {
ret void
}
define internal void @non_dead_d10() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d10()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1401,6 +1503,7 @@ define internal void @non_dead_d10() {
ret void
}
define internal void @non_dead_d11() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d11()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1409,6 +1512,7 @@ define internal void @non_dead_d11() {
ret void
}
define internal void @non_dead_d12() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d12()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1417,6 +1521,7 @@ define internal void @non_dead_d12() {
ret void
}
define internal void @non_dead_d13() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d13()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1425,6 +1530,7 @@ define internal void @non_dead_d13() {
ret void
}
define internal void @non_dead_d14() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d14()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1433,6 +1539,7 @@ define internal void @non_dead_d14() {
ret void
}
define internal void @non_dead_d15() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@non_dead_d15()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1462,6 +1569,7 @@ live_with_dead_entry:
}
define void @live_with_dead_entry_lp() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@live_with_dead_entry_lp() #2 personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
; CHECK-NEXT: entry:
; CHECK-NEXT: invoke void @blowup()
@@ -1495,6 +1603,7 @@ live_with_dead_entry:
}
define internal void @useless_arg_sink(i32* %a) {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@useless_arg_sink()
; CHECK-NEXT: call void @sink()
; CHECK-NEXT: ret void
@@ -1504,6 +1613,7 @@ define internal void @useless_arg_sink(i32* %a) {
}
define internal void @useless_arg_almost_sink(i32* %a) {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@useless_arg_almost_sink()
; CHECK-NEXT: call void @useless_arg_sink()
; CHECK-NEXT: ret void
@@ -1546,6 +1656,7 @@ define void @useless_arg_ext_int_ext(i32* %a) {
; FIXME: We should fold terminators.
define internal i32 @switch_default(i64 %i) nounwind {
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@switch_default()
; NOT_CGSCC_NPM-NEXT: entry:
; NOT_CGSCC_NPM-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
@@ -1558,6 +1669,7 @@ define internal i32 @switch_default(i64 %i) nounwind {
; NOT_CGSCC_NPM: return:
; NOT_CGSCC_NPM-NEXT: unreachable
;
+; IS__CGSCC____: Function Attrs: nofree nosync nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@switch_default()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
@@ -1585,6 +1697,7 @@ return:
}
define i32 @switch_default_caller() {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@switch_default_caller()
; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @switch_default()
; CHECK-NEXT: ret i32 123
@@ -1594,6 +1707,7 @@ define i32 @switch_default_caller() {
}
define internal i32 @switch_default_dead(i64 %i) nounwind {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@switch_default_dead()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
@@ -1619,8 +1733,13 @@ return:
}
define i32 @switch_default_dead_caller() {
-; CHECK-LABEL: define {{[^@]+}}@switch_default_dead_caller()
-; CHECK-NEXT: ret i32 123
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@switch_default_dead_caller()
+; NOT_CGSCC_NPM-NEXT: ret i32 123
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@switch_default_dead_caller()
+; IS__CGSCC____-NEXT: ret i32 123
;
%call2 = tail call i32 @switch_default_dead(i64 0)
ret i32 %call2
@@ -1841,9 +1960,15 @@ for.end.1:
declare noalias i8* @malloc(i64)
define i32 @h(i32 %i) {
-; CHECK-LABEL: define {{[^@]+}}@h
-; CHECK-SAME: (i32 [[I:%.*]])
-; CHECK-NEXT: ret i32 0
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@h
+; NOT_CGSCC_NPM-SAME: (i32 [[I:%.*]])
+; NOT_CGSCC_NPM-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@h
+; IS__CGSCC____-SAME: (i32 [[I:%.*]])
+; IS__CGSCC____-NEXT: ret i32 0
;
ret i32 0
}
@@ -1854,6 +1979,7 @@ define i32 @h(i32 %i) {
@p = global i8 0
define void @bad_gep() {
+; CHECK: Function Attrs: nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@bad_gep()
; CHECK-NEXT: entry:
; CHECK-NEXT: [[N:%.*]] = alloca i8, align 1
diff --git a/llvm/test/Transforms/Attributor/liveness_chains.ll b/llvm/test/Transforms/Attributor/liveness_chains.ll
index 53c05bf2d7a7..5339ea839e33 100644
--- a/llvm/test/Transforms/Attributor/liveness_chains.ll
+++ b/llvm/test/Transforms/Attributor/liveness_chains.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -9,9 +9,15 @@
declare i32 @source() nounwind readonly
define i32 @chain_dead(i32 %arg) {
-; CHECK-LABEL: define {{[^@]+}}@chain_dead
-; CHECK-SAME: (i32 [[ARG:%.*]])
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@chain_dead
+; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@chain_dead
+; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
+; IS__CGSCC____-NEXT: ret i32 0
;
%init = call i32 @source()
%v0 = add i32 %arg, %init
@@ -28,6 +34,7 @@ define i32 @chain_dead(i32 %arg) {
}
define i32 @chain_alive(i32 %arg) {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@chain_alive
; CHECK-SAME: (i32 [[ARG:%.*]])
; CHECK-NEXT: [[INIT:%.*]] = call i32 @source()
diff --git a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
index 846a3615d0b4..6e74cb2bed61 100644
--- a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
+++ b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
@@ -1,38 +1,71 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
define i8 @test1(i32 %a, i32 %length) {
-; IS________OPM-LABEL: define {{[^@]+}}@test1
-; IS________OPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]])
-; IS________OPM-NEXT: entry:
-; IS________OPM-NEXT: br label [[LOOP:%.*]]
-; IS________OPM: loop:
-; IS________OPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
-; IS________OPM-NEXT: [[CND:%.*]] = icmp sge i32 [[IV]], 0
-; IS________OPM-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
-; IS________OPM: backedge:
-; IS________OPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
-; IS________OPM-NEXT: [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
-; IS________OPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
-; IS________OPM: exit:
-; IS________OPM-NEXT: ret i8 0
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test1
+; IS__TUNIT_OPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: br label [[LOOP:%.*]]
+; IS__TUNIT_OPM: loop:
+; IS__TUNIT_OPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; IS__TUNIT_OPM-NEXT: [[CND:%.*]] = icmp sge i32 [[IV]], 0
+; IS__TUNIT_OPM-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
+; IS__TUNIT_OPM: backedge:
+; IS__TUNIT_OPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; IS__TUNIT_OPM-NEXT: [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
+; IS__TUNIT_OPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
+; IS__TUNIT_OPM: exit:
+; IS__TUNIT_OPM-NEXT: ret i8 0
;
-; IS________NPM-LABEL: define {{[^@]+}}@test1
-; IS________NPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]])
-; IS________NPM-NEXT: entry:
-; IS________NPM-NEXT: br label [[LOOP:%.*]]
-; IS________NPM: loop:
-; IS________NPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
-; IS________NPM-NEXT: br label [[BACKEDGE]]
-; IS________NPM: backedge:
-; IS________NPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
-; IS________NPM-NEXT: [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
-; IS________NPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]]
-; IS________NPM: exit:
-; IS________NPM-NEXT: ret i8 0
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test1
+; IS__TUNIT_NPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: br label [[LOOP:%.*]]
+; IS__TUNIT_NPM: loop:
+; IS__TUNIT_NPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; IS__TUNIT_NPM-NEXT: br label [[BACKEDGE]]
+; IS__TUNIT_NPM: backedge:
+; IS__TUNIT_NPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; IS__TUNIT_NPM-NEXT: [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
+; IS__TUNIT_NPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]]
+; IS__TUNIT_NPM: exit:
+; IS__TUNIT_NPM-NEXT: ret i8 0
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test1
+; IS__CGSCC_OPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]]
+; IS__CGSCC_OPM: loop:
+; IS__CGSCC_OPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; IS__CGSCC_OPM-NEXT: [[CND:%.*]] = icmp sge i32 [[IV]], 0
+; IS__CGSCC_OPM-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
+; IS__CGSCC_OPM: backedge:
+; IS__CGSCC_OPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; IS__CGSCC_OPM-NEXT: [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
+; IS__CGSCC_OPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
+; IS__CGSCC_OPM: exit:
+; IS__CGSCC_OPM-NEXT: ret i8 0
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test1
+; IS__CGSCC_NPM-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: br label [[LOOP:%.*]]
+; IS__CGSCC_NPM: loop:
+; IS__CGSCC_NPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; IS__CGSCC_NPM-NEXT: br label [[BACKEDGE]]
+; IS__CGSCC_NPM: backedge:
+; IS__CGSCC_NPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; IS__CGSCC_NPM-NEXT: [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
+; IS__CGSCC_NPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]]
+; IS__CGSCC_NPM: exit:
+; IS__CGSCC_NPM-NEXT: ret i8 0
;
entry:
br label %loop
@@ -52,26 +85,93 @@ exit:
}
define i8 @test2(i32 %n) {
-; CHECK-LABEL: define {{[^@]+}}@test2
-; CHECK-SAME: (i32 [[N:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[LOOP:%.*]]
-; CHECK: loop:
-; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
-; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
-; CHECK-NEXT: [[CND1:%.*]] = icmp sge i32 [[IV]], 0
-; CHECK-NEXT: [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
-; CHECK-NEXT: [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
-; CHECK-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
-; CHECK: backedge:
-; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
-; CHECK-NEXT: [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
-; CHECK-NEXT: [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
-; CHECK-NEXT: [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
-; CHECK-NEXT: [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
-; CHECK-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
-; CHECK: exit:
-; CHECK-NEXT: ret i8 0
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test2
+; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: br label [[LOOP:%.*]]
+; IS__TUNIT_OPM: loop:
+; IS__TUNIT_OPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; IS__TUNIT_OPM-NEXT: [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
+; IS__TUNIT_OPM-NEXT: [[CND1:%.*]] = icmp sge i32 [[IV]], 0
+; IS__TUNIT_OPM-NEXT: [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
+; IS__TUNIT_OPM-NEXT: [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
+; IS__TUNIT_OPM-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
+; IS__TUNIT_OPM: backedge:
+; IS__TUNIT_OPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; IS__TUNIT_OPM-NEXT: [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
+; IS__TUNIT_OPM-NEXT: [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
+; IS__TUNIT_OPM-NEXT: [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
+; IS__TUNIT_OPM-NEXT: [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
+; IS__TUNIT_OPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
+; IS__TUNIT_OPM: exit:
+; IS__TUNIT_OPM-NEXT: ret i8 0
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test2
+; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: br label [[LOOP:%.*]]
+; IS__TUNIT_NPM: loop:
+; IS__TUNIT_NPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; IS__TUNIT_NPM-NEXT: [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
+; IS__TUNIT_NPM-NEXT: [[CND1:%.*]] = icmp sge i32 [[IV]], 0
+; IS__TUNIT_NPM-NEXT: [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
+; IS__TUNIT_NPM-NEXT: [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
+; IS__TUNIT_NPM-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
+; IS__TUNIT_NPM: backedge:
+; IS__TUNIT_NPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; IS__TUNIT_NPM-NEXT: [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
+; IS__TUNIT_NPM-NEXT: [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
+; IS__TUNIT_NPM-NEXT: [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
+; IS__TUNIT_NPM-NEXT: [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
+; IS__TUNIT_NPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
+; IS__TUNIT_NPM: exit:
+; IS__TUNIT_NPM-NEXT: ret i8 0
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2
+; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]]
+; IS__CGSCC_OPM: loop:
+; IS__CGSCC_OPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; IS__CGSCC_OPM-NEXT: [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
+; IS__CGSCC_OPM-NEXT: [[CND1:%.*]] = icmp sge i32 [[IV]], 0
+; IS__CGSCC_OPM-NEXT: [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
+; IS__CGSCC_OPM-NEXT: [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
+; IS__CGSCC_OPM-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
+; IS__CGSCC_OPM: backedge:
+; IS__CGSCC_OPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; IS__CGSCC_OPM-NEXT: [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
+; IS__CGSCC_OPM-NEXT: [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
+; IS__CGSCC_OPM-NEXT: [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
+; IS__CGSCC_OPM-NEXT: [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
+; IS__CGSCC_OPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
+; IS__CGSCC_OPM: exit:
+; IS__CGSCC_OPM-NEXT: ret i8 0
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test2
+; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: br label [[LOOP:%.*]]
+; IS__CGSCC_NPM: loop:
+; IS__CGSCC_NPM-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; IS__CGSCC_NPM-NEXT: [[IV2:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[IV2_NEXT:%.*]], [[BACKEDGE]] ]
+; IS__CGSCC_NPM-NEXT: [[CND1:%.*]] = icmp sge i32 [[IV]], 0
+; IS__CGSCC_NPM-NEXT: [[CND2:%.*]] = icmp sgt i32 [[IV2]], 0
+; IS__CGSCC_NPM-NEXT: [[CND:%.*]] = and i1 [[CND1]], [[CND2]]
+; IS__CGSCC_NPM-NEXT: br i1 [[CND]], label [[BACKEDGE]], label [[EXIT:%.*]]
+; IS__CGSCC_NPM: backedge:
+; IS__CGSCC_NPM-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
+; IS__CGSCC_NPM-NEXT: [[IV2_NEXT]] = sub nsw i32 [[IV2]], 1
+; IS__CGSCC_NPM-NEXT: [[CONT1:%.*]] = icmp slt i32 [[IV_NEXT]], 400
+; IS__CGSCC_NPM-NEXT: [[CONT2:%.*]] = icmp sgt i32 [[IV2_NEXT]], 0
+; IS__CGSCC_NPM-NEXT: [[CONT:%.*]] = and i1 [[CONT1]], [[CONT2]]
+; IS__CGSCC_NPM-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT]]
+; IS__CGSCC_NPM: exit:
+; IS__CGSCC_NPM-NEXT: ret i8 0
;
entry:
br label %loop
diff --git a/llvm/test/Transforms/Attributor/lvi-for-ashr.ll b/llvm/test/Transforms/Attributor/lvi-for-ashr.ll
index a9d46b97b228..a6be5bcc9740 100644
--- a/llvm/test/Transforms/Attributor/lvi-for-ashr.ll
+++ b/llvm/test/Transforms/Attributor/lvi-for-ashr.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,25 +7,47 @@
; FIXME: DOT should be replaced with 3
define i32 @test-ashr(i32 %c) {
-; CHECK-LABEL: define {{[^@]+}}@test-ashr
-; CHECK-SAME: (i32 [[C:%.*]])
-; CHECK-NEXT: chk65:
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
-; CHECK-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
-; CHECK: chk0:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
-; CHECK-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
-; CHECK: bb_if:
-; CHECK-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
-; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
-; CHECK-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
-; CHECK: bb_then:
-; CHECK-NEXT: [[CMP3:%.*]] = icmp eq i32 [[ASHR_VAL]], 16
-; CHECK-NEXT: [[DOT:%.*]] = select i1 [[CMP3]], i32 3, i32 2
-; CHECK-NEXT: br label [[RETURN]]
-; CHECK: return:
-; CHECK-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
-; CHECK-NEXT: ret i32 [[RETVAL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test-ashr
+; IS__TUNIT____-SAME: (i32 [[C:%.*]])
+; IS__TUNIT____-NEXT: chk65:
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
+; IS__TUNIT____: chk0:
+; IS__TUNIT____-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
+; IS__TUNIT____: bb_if:
+; IS__TUNIT____-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
+; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
+; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
+; IS__TUNIT____: bb_then:
+; IS__TUNIT____-NEXT: [[CMP3:%.*]] = icmp eq i32 [[ASHR_VAL]], 16
+; IS__TUNIT____-NEXT: [[DOT:%.*]] = select i1 [[CMP3]], i32 3, i32 2
+; IS__TUNIT____-NEXT: br label [[RETURN]]
+; IS__TUNIT____: return:
+; IS__TUNIT____-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
+; IS__TUNIT____-NEXT: ret i32 [[RETVAL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test-ashr
+; IS__CGSCC____-SAME: (i32 [[C:%.*]])
+; IS__CGSCC____-NEXT: chk65:
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[C]], 65
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RETURN:%.*]], label [[CHK0:%.*]]
+; IS__CGSCC____: chk0:
+; IS__CGSCC____-NEXT: [[CMP1:%.*]] = icmp slt i32 [[C]], 0
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RETURN]], label [[BB_IF:%.*]]
+; IS__CGSCC____: bb_if:
+; IS__CGSCC____-NEXT: [[ASHR_VAL:%.*]] = ashr exact i32 [[C]], 2
+; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[ASHR_VAL]], 15
+; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[BB_THEN:%.*]], label [[RETURN]]
+; IS__CGSCC____: bb_then:
+; IS__CGSCC____-NEXT: [[CMP3:%.*]] = icmp eq i32 [[ASHR_VAL]], 16
+; IS__CGSCC____-NEXT: [[DOT:%.*]] = select i1 [[CMP3]], i32 3, i32 2
+; IS__CGSCC____-NEXT: br label [[RETURN]]
+; IS__CGSCC____: return:
+; IS__CGSCC____-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1, [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
+; IS__CGSCC____-NEXT: ret i32 [[RETVAL]]
;
chk65:
%cmp = icmp sgt i32 %c, 65
diff --git a/llvm/test/Transforms/Attributor/memory_locations.ll b/llvm/test/Transforms/Attributor/memory_locations.ll
index 42dc2e51be3a..be3f9a0f829b 100644
--- a/llvm/test/Transforms/Attributor/memory_locations.ll
+++ b/llvm/test/Transforms/Attributor/memory_locations.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -10,8 +10,8 @@ target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
; CHECK: Function Attrs: inaccessiblememonly
declare noalias i8* @malloc(i64) inaccessiblememonly
-; CHECK: Function Attrs: inaccessiblememonly
define dso_local i8* @internal_only(i32 %arg) {
+; CHECK: Function Attrs: inaccessiblememonly
; CHECK-LABEL: define {{[^@]+}}@internal_only
; CHECK-SAME: (i32 [[ARG:%.*]])
; CHECK-NEXT: entry:
@@ -25,8 +25,8 @@ entry:
ret i8* %call
}
-; CHECK: Function Attrs: inaccessiblememonly
define dso_local i8* @internal_only_rec(i32 %arg) {
+; CHECK: Function Attrs: inaccessiblememonly
; CHECK-LABEL: define {{[^@]+}}@internal_only_rec
; CHECK-SAME: (i32 [[ARG:%.*]])
; CHECK-NEXT: entry:
@@ -65,8 +65,8 @@ return: ; preds = %if.end, %if.then
ret i8* %retval.0
}
-; CHECK: Function Attrs: inaccessiblememonly
define dso_local i8* @internal_only_rec_static_helper(i32 %arg) {
+; CHECK: Function Attrs: inaccessiblememonly
; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_helper
; CHECK-SAME: (i32 [[ARG:%.*]])
; CHECK-NEXT: entry:
@@ -78,8 +78,8 @@ entry:
ret i8* %call
}
-; CHECK: Function Attrs: inaccessiblememonly
define internal i8* @internal_only_rec_static(i32 %arg) {
+; CHECK: Function Attrs: inaccessiblememonly
; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static
; CHECK-SAME: (i32 [[ARG:%.*]])
; CHECK-NEXT: entry:
@@ -173,8 +173,8 @@ return: ; preds = %if.end, %if.then
ret i8* %retval.0
}
-; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
define dso_local i8* @internal_argmem_only_read(i32* %arg) {
+; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_read
; CHECK-SAME: (i32* nocapture nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]])
; CHECK-NEXT: entry:
@@ -190,8 +190,8 @@ entry:
ret i8* %call
}
-; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
define dso_local i8* @internal_argmem_only_write(i32* %arg) {
+; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_write
; CHECK-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[ARG:%.*]])
; CHECK-NEXT: entry:
@@ -205,14 +205,15 @@ entry:
ret i8* %call
}
-; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
define dso_local i8* @internal_argmem_only_rec(i32* %arg) {
+; IS__TUNIT____: Function Attrs: inaccessiblemem_or_argmemonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_argmem_only_rec
; IS__TUNIT____-SAME: (i32* nocapture [[ARG:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call noalias i8* @internal_argmem_only_rec_1(i32* nocapture align 4 [[ARG]])
; IS__TUNIT____-NEXT: ret i8* [[CALL]]
;
+; IS__CGSCC____: Function Attrs: inaccessiblemem_or_argmemonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_argmem_only_rec
; IS__CGSCC____-SAME: (i32* nocapture nonnull align 4 dereferenceable(4) [[ARG:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -224,8 +225,8 @@ entry:
ret i8* %call
}
-; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
define internal i8* @internal_argmem_only_rec_1(i32* %arg) {
+; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_1
; CHECK-SAME: (i32* nocapture nonnull align 4 dereferenceable(4) [[ARG:%.*]])
; CHECK-NEXT: entry:
@@ -280,8 +281,8 @@ return: ; preds = %if.end3, %if.then2,
ret i8* %retval.0
}
-; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
define internal i8* @internal_argmem_only_rec_2(i32* %arg) {
+; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_2
; CHECK-SAME: (i32* nocapture nonnull align 4 dereferenceable(4) [[ARG:%.*]])
; CHECK-NEXT: entry:
@@ -302,8 +303,8 @@ declare i8* @argmem_only(i8* %arg) argmemonly
declare i8* @inaccesible_argmem_only_decl(i8* %arg) inaccessiblemem_or_argmemonly
declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) nounwind argmemonly willreturn
-; CHECK: Function Attrs: argmemonly
define void @callerA1(i8* %arg) {
+; CHECK: Function Attrs: argmemonly
; CHECK-LABEL: define {{[^@]+}}@callerA1
; CHECK-SAME: (i8* [[ARG:%.*]])
; CHECK-NEXT: [[TMP1:%.*]] = call i8* @argmem_only(i8* [[ARG]])
@@ -312,8 +313,8 @@ define void @callerA1(i8* %arg) {
call i8* @argmem_only(i8* %arg)
ret void
}
-; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
define void @callerA2(i8* %arg) {
+; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
; CHECK-LABEL: define {{[^@]+}}@callerA2
; CHECK-SAME: (i8* [[ARG:%.*]])
; CHECK-NEXT: [[TMP1:%.*]] = call i8* @inaccesible_argmem_only_decl(i8* [[ARG]])
@@ -322,8 +323,8 @@ define void @callerA2(i8* %arg) {
call i8* @inaccesible_argmem_only_decl(i8* %arg)
ret void
}
-; CHECK: Function Attrs: readnone
define void @callerB1() {
+; CHECK: Function Attrs: readnone
; CHECK-LABEL: define {{[^@]+}}@callerB1()
; CHECK-NEXT: [[STACK:%.*]] = alloca i8, align 1
; CHECK-NEXT: [[TMP1:%.*]] = call i8* @argmem_only(i8* nonnull dereferenceable(1) [[STACK]])
@@ -333,8 +334,8 @@ define void @callerB1() {
call i8* @argmem_only(i8* %stack)
ret void
}
-; CHECK: Function Attrs: inaccessiblememonly
define void @callerB2() {
+; CHECK: Function Attrs: inaccessiblememonly
; CHECK-LABEL: define {{[^@]+}}@callerB2()
; CHECK-NEXT: [[STACK:%.*]] = alloca i8, align 1
; CHECK-NEXT: [[TMP1:%.*]] = call i8* @inaccesible_argmem_only_decl(i8* nonnull dereferenceable(1) [[STACK]])
@@ -344,7 +345,6 @@ define void @callerB2() {
call i8* @inaccesible_argmem_only_decl(i8* %stack)
ret void
}
-; CHECK-NOT: Function Attrs
define void @callerC1() {
; CHECK-LABEL: define {{[^@]+}}@callerC1()
; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @unknown_ptr()
@@ -355,7 +355,6 @@ define void @callerC1() {
call i8* @argmem_only(i8* %unknown)
ret void
}
-; CHECK-NOT: Function Attrs
define void @callerC2() {
; CHECK-LABEL: define {{[^@]+}}@callerC2()
; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @unknown_ptr()
@@ -366,7 +365,6 @@ define void @callerC2() {
call i8* @inaccesible_argmem_only_decl(i8* %unknown)
ret void
}
-; CHECK-NOT: Function Attrs
define void @callerD1() {
; CHECK-LABEL: define {{[^@]+}}@callerD1()
; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @argmem_only(i8* noalias nocapture align 536870912 null)
@@ -377,7 +375,6 @@ define void @callerD1() {
store i8 0, i8* %unknown
ret void
}
-; CHECK-NOT: Function Attrs
define void @callerD2() {
; CHECK-LABEL: define {{[^@]+}}@callerD2()
; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @inaccesible_argmem_only_decl(i8* noalias nocapture align 536870912 null)
@@ -389,91 +386,114 @@ define void @callerD2() {
ret void
}
-; CHECK: Function Attrs: nofree {{(norecurse )?}}nosync nounwind readnone willreturn
define void @callerE(i8* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@callerE
-; CHECK-SAME: (i8* nocapture nofree readnone [[ARG:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@callerE
+; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[ARG:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@callerE
+; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[ARG:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
call void @llvm.lifetime.start.p0i8(i64 4, i8* %arg)
ret void
}
-; CHECK: Function Attrs:
-; CHECK-SAME: writeonly
define void @write_global() {
-; CHECK-LABEL: define {{[^@]+}}@write_global()
-; CHECK-NEXT: store i32 0, i32* @G, align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@write_global()
+; IS__TUNIT____-NEXT: store i32 0, i32* @G, align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@write_global()
+; IS__CGSCC____-NEXT: store i32 0, i32* @G, align 4
+; IS__CGSCC____-NEXT: ret void
;
store i32 0, i32* @G, align 4
ret void
}
-; CHECK: Function Attrs: argmemonly
-; CHECK-SAME: writeonly
define void @write_global_via_arg(i32* %GPtr) {
-; CHECK-LABEL: define {{[^@]+}}@write_global_via_arg
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[GPTR:%.*]])
-; CHECK-NEXT: store i32 0, i32* [[GPTR]], align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@write_global_via_arg
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[GPTR:%.*]])
+; IS__TUNIT____-NEXT: store i32 0, i32* [[GPTR]], align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@write_global_via_arg
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[GPTR:%.*]])
+; IS__CGSCC____-NEXT: store i32 0, i32* [[GPTR]], align 4
+; IS__CGSCC____-NEXT: ret void
;
store i32 0, i32* %GPtr, align 4
ret void
}
-; CHECK: Function Attrs:
-; CHECK-NOT: argmemonly
-; CHECK-SAME: writeonly
-; CHECK-NOT: argmemonly
define internal void @write_global_via_arg_internal(i32* %GPtr) {
-; CHECK-LABEL: define {{[^@]+}}@write_global_via_arg_internal()
-; CHECK-NEXT: store i32 0, i32* @G, align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@write_global_via_arg_internal()
+; IS__TUNIT____-NEXT: store i32 0, i32* @G, align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@write_global_via_arg_internal()
+; IS__CGSCC____-NEXT: store i32 0, i32* @G, align 4
+; IS__CGSCC____-NEXT: ret void
;
store i32 0, i32* %GPtr, align 4
ret void
}
-
-; CHECK: Function Attrs:
-; CHECK-SAME: writeonly
define void @writeonly_global() {
-; CHECK-LABEL: define {{[^@]+}}@writeonly_global()
-; CHECK-NEXT: call void @write_global()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global()
+; IS__TUNIT____-NEXT: call void @write_global()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global()
+; IS__CGSCC____-NEXT: call void @write_global()
+; IS__CGSCC____-NEXT: ret void
;
call void @write_global()
ret void
}
-; CHECK: Function Attrs:
-; CHECK-SAME: writeonly
define void @writeonly_global_via_arg() {
-; CHECK-LABEL: define {{[^@]+}}@writeonly_global_via_arg()
-; CHECK-NEXT: call void @write_global_via_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) @G)
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global_via_arg()
+; IS__TUNIT____-NEXT: call void @write_global_via_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) @G)
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global_via_arg()
+; IS__CGSCC____-NEXT: call void @write_global_via_arg(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) @G)
+; IS__CGSCC____-NEXT: ret void
;
call void @write_global_via_arg(i32* @G)
ret void
}
-; CHECK: Function Attrs:
-; CHECK-SAME: writeonly
define void @writeonly_global_via_arg_internal() {
;
-; CHECK-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal()
-; CHECK-NEXT: call void @write_global_via_arg_internal()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal()
+; IS__TUNIT____-NEXT: call void @write_global_via_arg_internal()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@writeonly_global_via_arg_internal()
+; IS__CGSCC____-NEXT: call void @write_global_via_arg_internal()
+; IS__CGSCC____-NEXT: ret void
;
call void @write_global_via_arg_internal(i32* @G)
ret void
}
-
-; CHECK: Function Attrs:
-; CHECK-NOT: readnone
-; CHECK-SAME: argmemonly
-; CHECK-NOT: readnone
define i8 @recursive_not_readnone(i8* %ptr, i1 %c) {
+; CHECK: Function Attrs: argmemonly nofree nosync nounwind
; CHECK-LABEL: define {{[^@]+}}@recursive_not_readnone
; CHECK-SAME: (i8* nocapture nofree writeonly [[PTR:%.*]], i1 [[C:%.*]])
; CHECK-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
@@ -497,11 +517,8 @@ f:
ret i8 0
}
-; CHECK: Function Attrs:
-; CHECK-NOT: readnone
-; CHECK-SAME: argmemonly
-; CHECK-NOT: readnone
define internal i8 @recursive_not_readnone_internal(i8* %ptr, i1 %c) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]])
; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
@@ -514,6 +531,7 @@ define internal i8 @recursive_not_readnone_internal(i8* %ptr, i1 %c) {
; IS__TUNIT____-NEXT: store i8 1, i8* [[PTR]], align 1
; IS__TUNIT____-NEXT: ret i8 0
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal
; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly dereferenceable(1) [[PTR:%.*]], i1 [[C:%.*]])
; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
@@ -537,9 +555,8 @@ f:
ret i8 0
}
-; CHECK: Function Attrs:
-; CHECK-SAME: readnone
define i8 @readnone_caller(i1 %c) {
+; CHECK: Function Attrs: nofree nosync nounwind readnone
; CHECK-LABEL: define {{[^@]+}}@readnone_caller
; CHECK-SAME: (i1 [[C:%.*]])
; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
@@ -551,11 +568,8 @@ define i8 @readnone_caller(i1 %c) {
ret i8 %r
}
-; CHECK: Function Attrs:
-; CHECK-NOT: readnone
-; CHECK-SAME: argmemonly
-; CHECK-NOT: readnone
define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]])
; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
@@ -568,6 +582,7 @@ define internal i8 @recursive_not_readnone_internal2(i8* %ptr, i1 %c) {
; IS__TUNIT____-NEXT: store i8 1, i8* [[PTR]], align 1
; IS__TUNIT____-NEXT: ret i8 0
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@recursive_not_readnone_internal2
; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull writeonly [[PTR:%.*]], i1 [[C:%.*]])
; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i8, align 1
@@ -591,9 +606,8 @@ f:
ret i8 0
}
-; CHECK: Function Attrs:
-; CHECK-SAME: readnone
define i8 @readnone_caller2(i1 %c) {
+; CHECK: Function Attrs: nofree nosync nounwind readnone
; CHECK-LABEL: define {{[^@]+}}@readnone_caller2
; CHECK-SAME: (i1 [[C:%.*]])
; CHECK-NEXT: [[R:%.*]] = call i8 @recursive_not_readnone_internal2(i8* undef, i1 [[C]])
@@ -603,23 +617,31 @@ define i8 @readnone_caller2(i1 %c) {
ret i8 %r
}
-; CHECK: Function Attrs:
-; CHECK-NOT: argmemonly
define internal void @argmemonly_before_ipconstprop(i32* %p) argmemonly {
-; CHECK-LABEL: define {{[^@]+}}@argmemonly_before_ipconstprop()
-; CHECK-NEXT: store i32 0, i32* @G, align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@argmemonly_before_ipconstprop()
+; IS__TUNIT____-NEXT: store i32 0, i32* @G, align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@argmemonly_before_ipconstprop()
+; IS__CGSCC____-NEXT: store i32 0, i32* @G, align 4
+; IS__CGSCC____-NEXT: ret void
;
store i32 0, i32* %p
ret void
}
-; CHECK: Function Attrs:
-; CHECK-NOT: argmemonly
define void @argmemonky_caller() {
-; CHECK-LABEL: define {{[^@]+}}@argmemonky_caller()
-; CHECK-NEXT: call void @argmemonly_before_ipconstprop()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@argmemonky_caller()
+; IS__TUNIT____-NEXT: call void @argmemonly_before_ipconstprop()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@argmemonky_caller()
+; IS__CGSCC____-NEXT: call void @argmemonly_before_ipconstprop()
+; IS__CGSCC____-NEXT: ret void
;
call void @argmemonly_before_ipconstprop(i32* @G)
ret void
diff --git a/llvm/test/Transforms/Attributor/misc.ll b/llvm/test/Transforms/Attributor/misc.ll
index 5c8ddc16a9a0..6101380c4bae 100644
--- a/llvm/test/Transforms/Attributor/misc.ll
+++ b/llvm/test/Transforms/Attributor/misc.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -95,11 +95,19 @@ entry:
define internal void @foo(i32* %a) {
;
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: store i32 0, i32* [[A]], align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: store i32 0, i32* [[A]], align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: store i32 0, i32* [[A]], align 4
+; IS__CGSCC____-NEXT: ret void
;
entry:
store i32 0, i32* %a
diff --git a/llvm/test/Transforms/Attributor/misc_crash.ll b/llvm/test/Transforms/Attributor/misc_crash.ll
index f8e10fa44545..afb3093aeeb7 100644
--- a/llvm/test/Transforms/Attributor/misc_crash.ll
+++ b/llvm/test/Transforms/Attributor/misc_crash.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -S %s | FileCheck %s
; RUN: opt -passes=attributor -S %s | FileCheck %s
@@ -6,8 +6,9 @@
@var2 = internal global i32 0
define i32 addrspace(1)* @foo(i32 addrspace(4)* %arg) {
+; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i32 addrspace(4)* nofree readnone [[ARG:%.*]]) #0
+; CHECK-SAME: (i32 addrspace(4)* nofree readnone [[ARG:%.*]])
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = addrspacecast i32 addrspace(4)* [[ARG]] to i32 addrspace(1)*
; CHECK-NEXT: ret i32 addrspace(1)* [[TMP0]]
@@ -18,8 +19,9 @@ entry:
}
define i32* @func1() {
-; CHECK-LABEL: define {{[^@]+}}@func1() #0
-; CHECK-NEXT: [[PTR:%.*]] = call i32* @func1a() #0
+; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn
+; CHECK-LABEL: define {{[^@]+}}@func1()
+; CHECK-NEXT: [[PTR:%.*]] = call i32* @func1a()
; CHECK-NEXT: ret i32* [[PTR]]
;
%ptr = call i32* @func1a([1 x i32]* @var1)
@@ -36,8 +38,9 @@ define internal i32* @func1a([1 x i32]* %arg) {
; UTC_ARGS: --enable
define internal void @func2a(i32* %0) {
+; CHECK: Function Attrs: nofree nosync nounwind willreturn writeonly
; CHECK-LABEL: define {{[^@]+}}@func2a
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]]) #1
+; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]])
; CHECK-NEXT: store i32 0, i32* @var2, align 4
; CHECK-NEXT: ret void
;
diff --git a/llvm/test/Transforms/Attributor/new_attributes.ll b/llvm/test/Transforms/Attributor/new_attributes.ll
index 5b6934b0c899..f944db358f61 100644
--- a/llvm/test/Transforms/Attributor/new_attributes.ll
+++ b/llvm/test/Transforms/Attributor/new_attributes.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-max-iterations=2 -S | FileCheck %s
; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-max-iterations=3 -S | FileCheck %s
; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-max-iterations=4 -S | FileCheck %s
@@ -13,26 +14,24 @@ declare i32 @foo1()
declare i32 @foo2()
declare i32 @foo3()
-; CHECK-NOT: Function
-; CHECK: define internal i32 @bar() {
-; CHECK-NEXT: %1 = call i32 @foo1()
-; CHECK-NEXT: %2 = call i32 @foo2()
-; CHECK-NEXT: %3 = call i32 @foo3()
-; CHECK-NEXT: ret i32 undef
-; CHECK-NEXT: }
define internal i32 @bar() {
+; CHECK-LABEL: define {{[^@]+}}@bar()
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @foo1()
+; CHECK-NEXT: [[TMP2:%.*]] = call i32 @foo2()
+; CHECK-NEXT: [[TMP3:%.*]] = call i32 @foo3()
+; CHECK-NEXT: ret i32 undef
+;
%1 = call i32 @foo1()
%2 = call i32 @foo2()
%3 = call i32 @foo3()
ret i32 1
}
-; CHECK-NOT: Function
-; CHECK: define i32 @baz() {
-; CHECK-NEXT: %1 = call i32 @bar()
-; CHECK-NEXT: ret i32 0
-; CHECK-NEXT: }
define i32 @baz() {
+; CHECK-LABEL: define {{[^@]+}}@baz()
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 @bar()
+; CHECK-NEXT: ret i32 0
+;
%1 = call i32 @bar()
ret i32 0
}
diff --git a/llvm/test/Transforms/Attributor/noalias.ll b/llvm/test/Transforms/Attributor/noalias.ll
index 9831d52ca848..71cf2263867c 100644
--- a/llvm/test/Transforms/Attributor/noalias.ll
+++ b/llvm/test/Transforms/Attributor/noalias.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; TODO: The old pass manager cgscc run is disabled as it causes a crash on windows which is under investigation: http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/23151
@@ -42,9 +42,15 @@ define i8* @return_noalias(){
}
define void @nocapture(i8* %a){
-; CHECK-LABEL: define {{[^@]+}}@nocapture
-; CHECK-SAME: (i8* nocapture nofree readnone [[A:%.*]])
-; CHECK-NEXT: ret void
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@nocapture
+; NOT_CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[A:%.*]])
+; NOT_CGSCC_NPM-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nocapture
+; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[A:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
ret void
}
@@ -98,6 +104,7 @@ define i8* @call_alias(){
; }
define i8* @bar() nounwind uwtable {
+; CHECK: Function Attrs: nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@bar()
; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz()
; CHECK-NEXT: ret i8* [[TMP1]]
@@ -107,6 +114,7 @@ define i8* @bar() nounwind uwtable {
}
define i8* @foo1(i32 %0) nounwind uwtable {
+; CHECK: Function Attrs: nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@foo1
; CHECK-SAME: (i32 [[TMP0:%.*]])
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
@@ -136,16 +144,26 @@ declare i8* @baz(...) nounwind uwtable
; Returning global pointer. Should not be noalias.
define i8** @getter() {
-; CHECK-LABEL: define {{[^@]+}}@getter()
-; CHECK-NEXT: ret i8** @G
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@getter()
+; NOT_CGSCC_NPM-NEXT: ret i8** @G
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@getter()
+; IS__CGSCC____-NEXT: ret i8** @G
;
ret i8** @G
}
; Returning global pointer. Should not be noalias.
define i8** @calle1(){
-; CHECK-LABEL: define {{[^@]+}}@calle1()
-; CHECK-NEXT: ret i8** @G
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@calle1()
+; NOT_CGSCC_NPM-NEXT: ret i8** @G
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@calle1()
+; IS__CGSCC____-NEXT: ret i8** @G
;
%1 = call i8** @getter()
ret i8** %1
@@ -155,6 +173,7 @@ define i8** @calle1(){
declare noalias i8* @strdup(i8* nocapture) nounwind
define i8* @test6() nounwind uwtable ssp {
+; CHECK: Function Attrs: nounwind ssp uwtable
; CHECK-LABEL: define {{[^@]+}}@test6()
; CHECK-NEXT: [[X:%.*]] = alloca [2 x i8], align 1
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i8], [2 x i8]* [[X]], i64 0, i64 0
@@ -176,6 +195,7 @@ define i8* @test6() nounwind uwtable ssp {
; TEST 7
define i8* @test7() nounwind {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@test7()
; CHECK-NEXT: entry:
; CHECK-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 4)
@@ -205,6 +225,7 @@ return:
; TEST 8
define i8* @test8(i32* %0) nounwind uwtable {
+; CHECK: Function Attrs: nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@test8
; CHECK-SAME: (i32* [[TMP0:%.*]])
; CHECK-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 4)
@@ -476,11 +497,13 @@ define void @test13_use_alias(){
; TEST 14 i2p casts
define internal i32 @p2i(i32* %arg) {
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@p2i
; NOT_CGSCC_NPM-SAME: (i32* noalias nofree readnone [[ARG:%.*]])
; NOT_CGSCC_NPM-NEXT: [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32
; NOT_CGSCC_NPM-NEXT: ret i32 [[P2I]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@p2i
; IS__CGSCC____-SAME: (i32* nofree readnone [[ARG:%.*]])
; IS__CGSCC____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32
@@ -491,6 +514,7 @@ define internal i32 @p2i(i32* %arg) {
}
define i32 @i2p(i32* %arg) {
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readonly willreturn
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@i2p
; NOT_CGSCC_NPM-SAME: (i32* nofree readonly [[ARG:%.*]])
; NOT_CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]])
@@ -499,6 +523,7 @@ define i32 @i2p(i32* %arg) {
; NOT_CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nocapture nofree readonly align 4 [[BC]])
; NOT_CGSCC_NPM-NEXT: ret i32 [[CALL]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@i2p
; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]])
; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree readnone [[ARG]])
@@ -514,10 +539,17 @@ define i32 @i2p(i32* %arg) {
ret i32 %call
}
define internal i32 @ret(i32* %arg) {
-; CHECK-LABEL: define {{[^@]+}}@ret
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]])
-; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4
-; CHECK-NEXT: ret i32 [[L]]
+; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@ret
+; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]])
+; NOT_CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4
+; NOT_CGSCC_NPM-NEXT: ret i32 [[L]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]])
+; IS__CGSCC____-NEXT: [[L:%.*]] = load i32, i32* [[ARG]], align 4
+; IS__CGSCC____-NEXT: ret i32 [[L]]
;
%l = load i32, i32* %arg
ret i32 %l
@@ -591,26 +623,41 @@ declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
@alias_of_p = external global i32*
define void @make_alias(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@make_alias
-; CHECK-SAME: (i32* nofree writeonly [[P:%.*]])
-; CHECK-NEXT: store i32* [[P]], i32** @alias_of_p, align 8
-; CHECK-NEXT: ret void
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@make_alias
+; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]])
+; NOT_CGSCC_NPM-NEXT: store i32* [[P]], i32** @alias_of_p, align 8
+; NOT_CGSCC_NPM-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@make_alias
+; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]])
+; IS__CGSCC____-NEXT: store i32* [[P]], i32** @alias_of_p, align 8
+; IS__CGSCC____-NEXT: ret void
;
store i32* %p, i32** @alias_of_p
ret void
}
define void @only_store(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@only_store
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]])
-; CHECK-NEXT: store i32 0, i32* [[P]], align 4
-; CHECK-NEXT: ret void
+; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@only_store
+; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]])
+; NOT_CGSCC_NPM-NEXT: store i32 0, i32* [[P]], align 4
+; NOT_CGSCC_NPM-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@only_store
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__CGSCC____-NEXT: store i32 0, i32* [[P]], align 4
+; IS__CGSCC____-NEXT: ret void
;
store i32 0, i32* %p
ret void
}
define void @test15_caller(i32* noalias %p, i32 %c) {
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test15_caller
; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]])
; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
@@ -622,6 +669,7 @@ define void @test15_caller(i32* noalias %p, i32 %c) {
; NOT_CGSCC_NPM-NEXT: tail call void @make_alias(i32* nofree writeonly [[P]])
; NOT_CGSCC_NPM-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@test15_caller
; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C:%.*]])
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
@@ -666,6 +714,7 @@ if.end:
; Therefore, only one of the two conditions of if statementes will be fulfilled.
define internal void @test16_sub(i32* noalias %p, i32 %c1, i32 %c2) {
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test16_sub
; NOT_CGSCC_NPM-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]])
; NOT_CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
@@ -683,6 +732,7 @@ define internal void @test16_sub(i32* noalias %p, i32 %c1, i32 %c2) {
; NOT_CGSCC_NPM: if.end3:
; NOT_CGSCC_NPM-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_sub
; IS__CGSCC____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32 [[C1:%.*]], i32 [[C2:%.*]])
; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
@@ -721,10 +771,17 @@ if.end3:
}
define void @test16_caller(i32* %p, i32 %c) {
-; CHECK-LABEL: define {{[^@]+}}@test16_caller
-; CHECK-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]])
-; CHECK-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]])
-; CHECK-NEXT: ret void
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind willreturn writeonly
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test16_caller
+; NOT_CGSCC_NPM-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]])
+; NOT_CGSCC_NPM-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]])
+; NOT_CGSCC_NPM-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test16_caller
+; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]], i32 [[C:%.*]])
+; IS__CGSCC____-NEXT: tail call void @test16_sub(i32* noalias nofree writeonly [[P]], i32 [[C]], i32 [[C]])
+; IS__CGSCC____-NEXT: ret void
;
tail call void @test16_sub(i32* %p, i32 %c, i32 %c)
ret void
diff --git a/llvm/test/Transforms/Attributor/nocapture-1.ll b/llvm/test/Transforms/Attributor/nocapture-1.ll
index 559c626b5741..45606b09bec8 100644
--- a/llvm/test/Transforms/Attributor/nocapture-1.ll
+++ b/llvm/test/Transforms/Attributor/nocapture-1.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,45 +7,78 @@
@g = global i32* null ; <i32**> [#uses=1]
define i32* @c1(i32* %q) {
-; CHECK-LABEL: define {{[^@]+}}@c1
-; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[Q:%.*]])
-; CHECK-NEXT: ret i32* [[Q]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@c1
+; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[Q:%.*]])
+; IS__TUNIT____-NEXT: ret i32* [[Q]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@c1
+; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[Q:%.*]])
+; IS__CGSCC____-NEXT: ret i32* [[Q]]
;
ret i32* %q
}
; It would also be acceptable to mark %q as readnone. Update @c3 too.
define void @c2(i32* %q) {
-; CHECK-LABEL: define {{[^@]+}}@c2
-; CHECK-SAME: (i32* nofree writeonly [[Q:%.*]])
-; CHECK-NEXT: store i32* [[Q]], i32** @g, align 8
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@c2
+; IS__TUNIT____-SAME: (i32* nofree writeonly [[Q:%.*]])
+; IS__TUNIT____-NEXT: store i32* [[Q]], i32** @g, align 8
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@c2
+; IS__CGSCC____-SAME: (i32* nofree writeonly [[Q:%.*]])
+; IS__CGSCC____-NEXT: store i32* [[Q]], i32** @g, align 8
+; IS__CGSCC____-NEXT: ret void
;
store i32* %q, i32** @g
ret void
}
define void @c3(i32* %q) {
-; CHECK-LABEL: define {{[^@]+}}@c3
-; CHECK-SAME: (i32* nofree writeonly [[Q:%.*]])
-; CHECK-NEXT: call void @c2(i32* nofree writeonly [[Q]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@c3
+; IS__TUNIT____-SAME: (i32* nofree writeonly [[Q:%.*]])
+; IS__TUNIT____-NEXT: call void @c2(i32* nofree writeonly [[Q]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@c3
+; IS__CGSCC____-SAME: (i32* nofree writeonly [[Q:%.*]])
+; IS__CGSCC____-NEXT: call void @c2(i32* nofree writeonly [[Q]])
+; IS__CGSCC____-NEXT: ret void
;
call void @c2(i32* %q)
ret void
}
define i1 @c4(i32* %q, i32 %bitno) {
-; CHECK-LABEL: define {{[^@]+}}@c4
-; CHECK-SAME: (i32* nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
-; CHECK-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
-; CHECK-NEXT: [[BIT:%.*]] = trunc i32 [[TMP2]] to i1
-; CHECK-NEXT: br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]
-; CHECK: l0:
-; CHECK-NEXT: ret i1 false
-; CHECK: l1:
-; CHECK-NEXT: ret i1 true
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@c4
+; IS__TUNIT____-SAME: (i32* nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
+; IS__TUNIT____-NEXT: [[BIT:%.*]] = trunc i32 [[TMP2]] to i1
+; IS__TUNIT____-NEXT: br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]
+; IS__TUNIT____: l0:
+; IS__TUNIT____-NEXT: ret i1 false
+; IS__TUNIT____: l1:
+; IS__TUNIT____-NEXT: ret i1 true
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@c4
+; IS__CGSCC____-SAME: (i32* nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
+; IS__CGSCC____-NEXT: [[BIT:%.*]] = trunc i32 [[TMP2]] to i1
+; IS__CGSCC____-NEXT: br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]
+; IS__CGSCC____: l0:
+; IS__CGSCC____-NEXT: ret i1 false
+; IS__CGSCC____: l1:
+; IS__CGSCC____-NEXT: ret i1 true
;
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -59,16 +92,29 @@ l1:
; c4b is c4 but without the escaping part
define i1 @c4b(i32* %q, i32 %bitno) {
-; CHECK-LABEL: define {{[^@]+}}@c4b
-; CHECK-SAME: (i32* nocapture nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
-; CHECK-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
-; CHECK-NEXT: [[BIT:%.*]] = trunc i32 [[TMP2]] to i1
-; CHECK-NEXT: br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]
-; CHECK: l0:
-; CHECK-NEXT: ret i1 false
-; CHECK: l1:
-; CHECK-NEXT: ret i1 false
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@c4b
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
+; IS__TUNIT____-NEXT: [[BIT:%.*]] = trunc i32 [[TMP2]] to i1
+; IS__TUNIT____-NEXT: br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]
+; IS__TUNIT____: l0:
+; IS__TUNIT____-NEXT: ret i1 false
+; IS__TUNIT____: l1:
+; IS__TUNIT____-NEXT: ret i1 false
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@c4b
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
+; IS__CGSCC____-NEXT: [[BIT:%.*]] = trunc i32 [[TMP2]] to i1
+; IS__CGSCC____-NEXT: br i1 [[BIT]], label [[L1:%.*]], label [[L0:%.*]]
+; IS__CGSCC____: l0:
+; IS__CGSCC____-NEXT: ret i1 false
+; IS__CGSCC____: l1:
+; IS__CGSCC____-NEXT: ret i1 false
;
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -83,14 +129,25 @@ l1:
@lookup_table = global [2 x i1] [ i1 0, i1 1 ]
define i1 @c5(i32* %q, i32 %bitno) {
-; CHECK-LABEL: define {{[^@]+}}@c5
-; CHECK-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]])
-; CHECK-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
-; CHECK-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1
-; CHECK-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]]
-; CHECK-NEXT: [[VAL:%.*]] = load i1, i1* [[LOOKUP]], align 1
-; CHECK-NEXT: ret i1 [[VAL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@c5
+; IS__TUNIT____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
+; IS__TUNIT____-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1
+; IS__TUNIT____-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]]
+; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i1, i1* [[LOOKUP]], align 1
+; IS__TUNIT____-NEXT: ret i1 [[VAL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@c5
+; IS__CGSCC____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
+; IS__CGSCC____-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1
+; IS__CGSCC____-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]]
+; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i1, i1* [[LOOKUP]], align 1
+; IS__CGSCC____-NEXT: ret i1 [[VAL]]
;
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -104,6 +161,7 @@ define i1 @c5(i32* %q, i32 %bitno) {
declare void @throw_if_bit_set(i8*, i8) readonly
define i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@c6
; CHECK-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #4 personality i32 (...)* @__gxx_personality_v0
; CHECK-NEXT: invoke void @throw_if_bit_set(i8* readonly [[Q]], i8 [[BIT]])
@@ -128,13 +186,23 @@ ret1:
declare i32 @__gxx_personality_v0(...)
define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind {
-; CHECK-LABEL: define {{[^@]+}}@lookup_bit
-; CHECK-SAME: (i32* nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
-; CHECK-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
-; CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
-; CHECK-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1
-; CHECK-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]]
-; CHECK-NEXT: ret i1* [[LOOKUP]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@lookup_bit
+; IS__TUNIT____-SAME: (i32* nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
+; IS__TUNIT____-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1
+; IS__TUNIT____-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]]
+; IS__TUNIT____-NEXT: ret i1* [[LOOKUP]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@lookup_bit
+; IS__CGSCC____-SAME: (i32* nofree readnone [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = ptrtoint i32* [[Q]] to i32
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP]], [[BITNO]]
+; IS__CGSCC____-NEXT: [[BIT:%.*]] = and i32 [[TMP2]], 1
+; IS__CGSCC____-NEXT: [[LOOKUP:%.*]] = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 [[BIT]]
+; IS__CGSCC____-NEXT: ret i1* [[LOOKUP]]
;
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -144,11 +212,19 @@ define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind {
}
define i1 @c7(i32* %q, i32 %bitno) {
-; CHECK-LABEL: define {{[^@]+}}@c7
-; CHECK-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]])
-; CHECK-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]])
-; CHECK-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1
-; CHECK-NEXT: ret i1 [[VAL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@c7
+; IS__TUNIT____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__TUNIT____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]])
+; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1
+; IS__TUNIT____-NEXT: ret i1 [[VAL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@c7
+; IS__CGSCC____-SAME: (i32* nofree readonly [[Q:%.*]], i32 [[BITNO:%.*]])
+; IS__CGSCC____-NEXT: [[PTR:%.*]] = call i1* @lookup_bit(i32* noalias nofree readnone [[Q]], i32 [[BITNO]])
+; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i1, i1* [[PTR]], align 1
+; IS__CGSCC____-NEXT: ret i1 [[VAL]]
;
%ptr = call i1* @lookup_bit(i32* %q, i32 %bitno)
%val = load i1, i1* %ptr
@@ -157,19 +233,35 @@ define i1 @c7(i32* %q, i32 %bitno) {
define i32 @nc1(i32* %q, i32* %p, i1 %b) {
-; CHECK-LABEL: define {{[^@]+}}@nc1
-; CHECK-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]])
-; CHECK-NEXT: e:
-; CHECK-NEXT: br label [[L:%.*]]
-; CHECK: l:
-; CHECK-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
-; CHECK-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
-; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[X]] to i32*
-; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
-; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
-; CHECK-NEXT: store i32 0, i32* [[TMP]], align 4
-; CHECK-NEXT: store i32* [[Y]], i32** @g, align 8
-; CHECK-NEXT: ret i32 [[VAL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nc1
+; IS__TUNIT____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]])
+; IS__TUNIT____-NEXT: e:
+; IS__TUNIT____-NEXT: br label [[L:%.*]]
+; IS__TUNIT____: l:
+; IS__TUNIT____-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
+; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = bitcast i32* [[X]] to i32*
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
+; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
+; IS__TUNIT____-NEXT: store i32 0, i32* [[TMP]], align 4
+; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8
+; IS__TUNIT____-NEXT: ret i32 [[VAL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1
+; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32* nocapture nofree [[P:%.*]], i1 [[B:%.*]])
+; IS__CGSCC____-NEXT: e:
+; IS__CGSCC____-NEXT: br label [[L:%.*]]
+; IS__CGSCC____: l:
+; IS__CGSCC____-NEXT: [[X:%.*]] = phi i32* [ [[P]], [[E:%.*]] ]
+; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = bitcast i32* [[X]] to i32*
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
+; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
+; IS__CGSCC____-NEXT: store i32 0, i32* [[TMP]], align 4
+; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8
+; IS__CGSCC____-NEXT: ret i32 [[VAL]]
;
e:
br label %l
@@ -185,19 +277,35 @@ l:
}
define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) {
-; CHECK-LABEL: define {{[^@]+}}@nc1_addrspace
-; CHECK-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]])
-; CHECK-NEXT: e:
-; CHECK-NEXT: br label [[L:%.*]]
-; CHECK: l:
-; CHECK-NEXT: [[X:%.*]] = phi i32 addrspace(1)* [ [[P]], [[E:%.*]] ]
-; CHECK-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
-; CHECK-NEXT: [[TMP:%.*]] = addrspacecast i32 addrspace(1)* [[X]] to i32*
-; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
-; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
-; CHECK-NEXT: store i32 0, i32* [[TMP]], align 4
-; CHECK-NEXT: store i32* [[Y]], i32** @g, align 8
-; CHECK-NEXT: ret i32 [[VAL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nc1_addrspace
+; IS__TUNIT____-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]])
+; IS__TUNIT____-NEXT: e:
+; IS__TUNIT____-NEXT: br label [[L:%.*]]
+; IS__TUNIT____: l:
+; IS__TUNIT____-NEXT: [[X:%.*]] = phi i32 addrspace(1)* [ [[P]], [[E:%.*]] ]
+; IS__TUNIT____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = addrspacecast i32 addrspace(1)* [[X]] to i32*
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
+; IS__TUNIT____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
+; IS__TUNIT____-NEXT: store i32 0, i32* [[TMP]], align 4
+; IS__TUNIT____-NEXT: store i32* [[Y]], i32** @g, align 8
+; IS__TUNIT____-NEXT: ret i32 [[VAL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nc1_addrspace
+; IS__CGSCC____-SAME: (i32* nofree [[Q:%.*]], i32 addrspace(1)* nocapture nofree [[P:%.*]], i1 [[B:%.*]])
+; IS__CGSCC____-NEXT: e:
+; IS__CGSCC____-NEXT: br label [[L:%.*]]
+; IS__CGSCC____: l:
+; IS__CGSCC____-NEXT: [[X:%.*]] = phi i32 addrspace(1)* [ [[P]], [[E:%.*]] ]
+; IS__CGSCC____-NEXT: [[Y:%.*]] = phi i32* [ [[Q]], [[E]] ]
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = addrspacecast i32 addrspace(1)* [[X]] to i32*
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = select i1 [[B]], i32* [[TMP]], i32* [[Y]]
+; IS__CGSCC____-NEXT: [[VAL:%.*]] = load i32, i32* [[TMP2]], align 4
+; IS__CGSCC____-NEXT: store i32 0, i32* [[TMP]], align 4
+; IS__CGSCC____-NEXT: store i32* [[Y]], i32** @g, align 8
+; IS__CGSCC____-NEXT: ret i32 [[VAL]]
;
e:
br label %l
@@ -213,10 +321,17 @@ l:
}
define void @nc2(i32* %p, i32* %q) {
-; CHECK-LABEL: define {{[^@]+}}@nc2
-; CHECK-SAME: (i32* nocapture nofree [[P:%.*]], i32* nofree [[Q:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 false)
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nc2
+; IS__TUNIT____-SAME: (i32* nocapture nofree [[P:%.*]], i32* nofree [[Q:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 false)
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nc2
+; IS__CGSCC____-SAME: (i32* nocapture nofree [[P:%.*]], i32* nofree [[Q:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @nc1(i32* nofree [[Q]], i32* nocapture nofree [[P]], i1 false)
+; IS__CGSCC____-NEXT: ret void
;
%1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32> [#uses=0]
ret void
@@ -237,6 +352,7 @@ define void @nc3(void ()* %p) {
; FIXME: readonly and nocapture missing on the pointer.
declare void @external(i8* readonly) nounwind argmemonly
define void @nc4(i8* %p) {
+; CHECK: Function Attrs: argmemonly nounwind
; CHECK-LABEL: define {{[^@]+}}@nc4
; CHECK-SAME: (i8* [[P:%.*]])
; CHECK-NEXT: call void @external(i8* readonly [[P]])
@@ -259,6 +375,7 @@ define void @nc5(void (i8*)* %f, i8* %p) {
; It would be acceptable to add readnone to %y1_1 and %y1_2.
define void @test1_1(i8* %x1_1, i8* %y1_1, i1 %c) {
+; CHECK: Function Attrs: nofree nosync nounwind writeonly
; CHECK-LABEL: define {{[^@]+}}@test1_1
; CHECK-SAME: (i8* nocapture nofree readnone [[X1_1:%.*]], i8* nocapture nofree readnone [[Y1_1:%.*]], i1 [[C:%.*]])
; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test1_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[Y1_1]], i1 [[C]])
@@ -271,6 +388,7 @@ define void @test1_1(i8* %x1_1, i8* %y1_1, i1 %c) {
}
define i8* @test1_2(i8* %x1_2, i8* %y1_2, i1 %c) {
+; CHECK: Function Attrs: nofree nosync nounwind writeonly
; CHECK-LABEL: define {{[^@]+}}@test1_2
; CHECK-SAME: (i8* nocapture nofree readnone [[X1_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y1_2:%.*]], i1 [[C:%.*]])
; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
@@ -291,9 +409,15 @@ f:
}
define void @test2(i8* %x2) {
-; CHECK-LABEL: define {{[^@]+}}@test2
-; CHECK-SAME: (i8* nocapture nofree readnone [[X2:%.*]])
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
+; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X2:%.*]])
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
+; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X2:%.*]])
+; IS__CGSCC____-NEXT: unreachable
;
call void @test2(i8* %x2)
store i32* null, i32** @g
@@ -301,9 +425,15 @@ define void @test2(i8* %x2) {
}
define void @test3(i8* %x3, i8* %y3, i8* %z3) {
-; CHECK-LABEL: define {{[^@]+}}@test3
-; CHECK-SAME: (i8* nocapture nofree readnone [[X3:%.*]], i8* nocapture nofree readnone [[Y3:%.*]], i8* nocapture nofree readnone [[Z3:%.*]])
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test3
+; IS__TUNIT____-SAME: (i8* nocapture nofree readnone [[X3:%.*]], i8* nocapture nofree readnone [[Y3:%.*]], i8* nocapture nofree readnone [[Z3:%.*]])
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test3
+; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[X3:%.*]], i8* nocapture nofree readnone [[Y3:%.*]], i8* nocapture nofree readnone [[Z3:%.*]])
+; IS__CGSCC____-NEXT: unreachable
;
call void @test3(i8* %z3, i8* %y3, i8* %x3)
store i32* null, i32** @g
@@ -311,6 +441,7 @@ define void @test3(i8* %x3, i8* %y3, i8* %z3) {
}
define void @test4_1(i8* %x4_1, i1 %c) {
+; CHECK: Function Attrs: nofree nosync nounwind writeonly
; CHECK-LABEL: define {{[^@]+}}@test4_1
; CHECK-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]])
; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nocapture nofree readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned" [[X4_1]], i8* noalias nocapture nofree readnone undef, i1 [[C]])
@@ -323,6 +454,7 @@ define void @test4_1(i8* %x4_1, i1 %c) {
}
define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2, i1 %c) {
+; CHECK: Function Attrs: nofree nosync nounwind writeonly
; CHECK-LABEL: define {{[^@]+}}@test4_2
; CHECK-SAME: (i8* nocapture nofree readnone [[X4_2:%.*]], i8* nofree readnone returned "no-capture-maybe-returned" [[Y4_2:%.*]], i8* nocapture nofree readnone [[Z4_2:%.*]], i1 [[C:%.*]])
; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
@@ -371,42 +503,72 @@ define void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) {
}
define void @test_cmpxchg(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test_cmpxchg
-; CHECK-SAME: (i32* nocapture nofree nonnull dereferenceable(4) [[P:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[P]], i32 0, i32 1 acquire monotonic
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_cmpxchg
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull dereferenceable(4) [[P:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[P]], i32 0, i32 1 acquire monotonic
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_cmpxchg
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull dereferenceable(4) [[P:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = cmpxchg i32* [[P]], i32 0, i32 1 acquire monotonic
+; IS__CGSCC____-NEXT: ret void
;
cmpxchg i32* %p, i32 0, i32 1 acquire monotonic
ret void
}
define void @test_cmpxchg_ptr(i32** %p, i32* %q) {
-; CHECK-LABEL: define {{[^@]+}}@test_cmpxchg_ptr
-; CHECK-SAME: (i32** nocapture nofree nonnull dereferenceable(8) [[P:%.*]], i32* nofree [[Q:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = cmpxchg i32** [[P]], i32* null, i32* [[Q]] acquire monotonic
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_cmpxchg_ptr
+; IS__TUNIT____-SAME: (i32** nocapture nofree nonnull dereferenceable(8) [[P:%.*]], i32* nofree [[Q:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = cmpxchg i32** [[P]], i32* null, i32* [[Q]] acquire monotonic
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_cmpxchg_ptr
+; IS__CGSCC____-SAME: (i32** nocapture nofree nonnull dereferenceable(8) [[P:%.*]], i32* nofree [[Q:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = cmpxchg i32** [[P]], i32* null, i32* [[Q]] acquire monotonic
+; IS__CGSCC____-NEXT: ret void
;
cmpxchg i32** %p, i32* null, i32* %q acquire monotonic
ret void
}
define void @test_atomicrmw(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test_atomicrmw
-; CHECK-SAME: (i32* nocapture nofree nonnull dereferenceable(4) [[P:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_atomicrmw
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull dereferenceable(4) [[P:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_atomicrmw
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull dereferenceable(4) [[P:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = atomicrmw add i32* [[P]], i32 1 seq_cst
+; IS__CGSCC____-NEXT: ret void
;
atomicrmw add i32* %p, i32 1 seq_cst
ret void
}
define void @test_volatile(i32* %x) {
-; CHECK-LABEL: define {{[^@]+}}@test_volatile
-; CHECK-SAME: (i32* nofree align 4 [[X:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[X]], i64 1
-; CHECK-NEXT: store volatile i32 0, i32* [[GEP]], align 4
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_volatile
+; IS__TUNIT____-SAME: (i32* nofree align 4 [[X:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[X]], i64 1
+; IS__TUNIT____-NEXT: store volatile i32 0, i32* [[GEP]], align 4
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_volatile
+; IS__CGSCC____-SAME: (i32* nofree align 4 [[X:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[GEP:%.*]] = getelementptr i32, i32* [[X]], i64 1
+; IS__CGSCC____-NEXT: store volatile i32 0, i32* [[GEP]], align 4
+; IS__CGSCC____-NEXT: ret void
;
entry:
%gep = getelementptr i32, i32* %x, i64 1
@@ -415,6 +577,7 @@ entry:
}
define void @nocaptureLaunder(i8* %p) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@nocaptureLaunder
; CHECK-SAME: (i8* nocapture [[P:%.*]])
; CHECK-NEXT: entry:
@@ -430,6 +593,7 @@ entry:
@g2 = global i8* null
define void @captureLaunder(i8* %p) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@captureLaunder
; CHECK-SAME: (i8* [[P:%.*]])
; CHECK-NEXT: [[B:%.*]] = call i8* @llvm.launder.invariant.group.p0i8(i8* [[P]])
@@ -442,6 +606,7 @@ define void @captureLaunder(i8* %p) {
}
define void @nocaptureStrip(i8* %p) {
+; CHECK: Function Attrs: nosync nounwind willreturn writeonly
; CHECK-LABEL: define {{[^@]+}}@nocaptureStrip
; CHECK-SAME: (i8* nocapture writeonly [[P:%.*]])
; CHECK-NEXT: entry:
@@ -457,6 +622,7 @@ entry:
@g3 = global i8* null
define void @captureStrip(i8* %p) {
+; CHECK: Function Attrs: nosync nounwind willreturn writeonly
; CHECK-LABEL: define {{[^@]+}}@captureStrip
; CHECK-SAME: (i8* writeonly [[P:%.*]])
; CHECK-NEXT: [[B:%.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8* noalias readnone [[P]])
@@ -469,32 +635,55 @@ define void @captureStrip(i8* %p) {
}
define i1 @captureICmp(i32* %x) {
-; CHECK-LABEL: define {{[^@]+}}@captureICmp
-; CHECK-SAME: (i32* nofree readnone [[X:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32* [[X]], null
-; CHECK-NEXT: ret i1 [[TMP1]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@captureICmp
+; IS__TUNIT____-SAME: (i32* nofree readnone [[X:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = icmp eq i32* [[X]], null
+; IS__TUNIT____-NEXT: ret i1 [[TMP1]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@captureICmp
+; IS__CGSCC____-SAME: (i32* nofree readnone [[X:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = icmp eq i32* [[X]], null
+; IS__CGSCC____-NEXT: ret i1 [[TMP1]]
;
%1 = icmp eq i32* %x, null
ret i1 %1
}
define i1 @captureICmpRev(i32* %x) {
-; CHECK-LABEL: define {{[^@]+}}@captureICmpRev
-; CHECK-SAME: (i32* nofree readnone [[X:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32* null, [[X]]
-; CHECK-NEXT: ret i1 [[TMP1]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@captureICmpRev
+; IS__TUNIT____-SAME: (i32* nofree readnone [[X:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = icmp eq i32* null, [[X]]
+; IS__TUNIT____-NEXT: ret i1 [[TMP1]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@captureICmpRev
+; IS__CGSCC____-SAME: (i32* nofree readnone [[X:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = icmp eq i32* null, [[X]]
+; IS__CGSCC____-NEXT: ret i1 [[TMP1]]
;
%1 = icmp eq i32* null, %x
ret i1 %1
}
define i1 @nocaptureInboundsGEPICmp(i32* %x) {
-; CHECK-LABEL: define {{[^@]+}}@nocaptureInboundsGEPICmp
-; CHECK-SAME: (i32* nocapture nofree readnone [[X:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[X]], i32 5
-; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8*
-; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8* [[TMP2]], null
-; CHECK-NEXT: ret i1 [[TMP3]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureInboundsGEPICmp
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[X:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[X]], i32 5
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8*
+; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp eq i8* [[TMP2]], null
+; IS__TUNIT____-NEXT: ret i1 [[TMP3]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureInboundsGEPICmp
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[X:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[X]], i32 5
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8*
+; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp eq i8* [[TMP2]], null
+; IS__CGSCC____-NEXT: ret i1 [[TMP3]]
;
%1 = getelementptr inbounds i32, i32* %x, i32 5
%2 = bitcast i32* %1 to i8*
@@ -503,12 +692,21 @@ define i1 @nocaptureInboundsGEPICmp(i32* %x) {
}
define i1 @nocaptureInboundsGEPICmpRev(i32* %x) {
-; CHECK-LABEL: define {{[^@]+}}@nocaptureInboundsGEPICmpRev
-; CHECK-SAME: (i32* nocapture nofree readnone [[X:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[X]], i32 5
-; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8*
-; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i8* null, [[TMP2]]
-; CHECK-NEXT: ret i1 [[TMP3]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureInboundsGEPICmpRev
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[X:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[X]], i32 5
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8*
+; IS__TUNIT____-NEXT: [[TMP3:%.*]] = icmp eq i8* null, [[TMP2]]
+; IS__TUNIT____-NEXT: ret i1 [[TMP3]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureInboundsGEPICmpRev
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[X:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = getelementptr inbounds i32, i32* [[X]], i32 5
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8*
+; IS__CGSCC____-NEXT: [[TMP3:%.*]] = icmp eq i8* null, [[TMP2]]
+; IS__CGSCC____-NEXT: ret i1 [[TMP3]]
;
%1 = getelementptr inbounds i32, i32* %x, i32 5
%2 = bitcast i32* %1 to i8*
@@ -517,11 +715,19 @@ define i1 @nocaptureInboundsGEPICmpRev(i32* %x) {
}
define i1 @nocaptureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) {
-; CHECK-LABEL: define {{[^@]+}}@nocaptureDereferenceableOrNullICmp
-; CHECK-SAME: (i32* nocapture nofree readnone dereferenceable_or_null(4) [[X:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
-; CHECK-NEXT: ret i1 [[TMP2]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nocaptureDereferenceableOrNullICmp
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone dereferenceable_or_null(4) [[X:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
+; IS__TUNIT____-NEXT: ret i1 [[TMP2]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nocaptureDereferenceableOrNullICmp
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone dereferenceable_or_null(4) [[X:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
+; IS__CGSCC____-NEXT: ret i1 [[TMP2]]
;
%1 = bitcast i32* %x to i8*
%2 = icmp eq i8* %1, null
@@ -529,11 +735,19 @@ define i1 @nocaptureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x
}
define i1 @captureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) null_pointer_is_valid {
-; CHECK-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp
-; CHECK-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]])
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
-; CHECK-NEXT: ret i1 [[TMP2]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp
+; IS__TUNIT____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]])
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
+; IS__TUNIT____-NEXT: ret i1 [[TMP2]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@captureDereferenceableOrNullICmp
+; IS__CGSCC____-SAME: (i32* nofree readnone dereferenceable_or_null(4) [[X:%.*]])
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[X]] to i8*
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP1]], null
+; IS__CGSCC____-NEXT: ret i1 [[TMP2]]
;
%1 = bitcast i32* %x to i8*
%2 = icmp eq i8* %1, null
@@ -555,6 +769,7 @@ entry:
declare i8* @unknownpi8pi8(i8*,i8* returned)
define i8* @test_returned1(i8* %A, i8* returned %B) nounwind readonly {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@test_returned1
; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]])
; CHECK-NEXT: entry:
@@ -567,6 +782,7 @@ entry:
}
define i8* @test_returned2(i8* %A, i8* %B) {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@test_returned2
; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned [[B:%.*]])
; CHECK-NEXT: entry:
@@ -584,6 +800,7 @@ declare void @val_use(i8 %ptr) readonly nounwind
; FIXME: Both pointers should be nocapture
define void @ptr_uses(i8* %ptr, i8* %wptr) {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@ptr_uses
; CHECK-SAME: (i8* [[PTR:%.*]], i8* nocapture nonnull writeonly dereferenceable(1) [[WPTR:%.*]])
; CHECK-NEXT: store i8 0, i8* [[WPTR]], align 1
diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll b/llvm/test/Transforms/Attributor/nocapture-2.ll
index 5e97dd0a461a..c16047de065d 100644
--- a/llvm/test/Transforms/Attributor/nocapture-2.ll
+++ b/llvm/test/Transforms/Attributor/nocapture-2.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=10 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -18,12 +18,21 @@ declare i32* @unknown()
;
; no-capture is missing on %p because it is not dereferenceable
define i32 @is_null_return(i32* %p) #0 {
-; CHECK-LABEL: define {{[^@]+}}@is_null_return
-; CHECK-SAME: (i32* nofree readnone [[P:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[P]], null
-; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
-; CHECK-NEXT: ret i32 [[CONV]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@is_null_return
+; IS__TUNIT____-SAME: (i32* nofree readnone [[P:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[P]], null
+; IS__TUNIT____-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+; IS__TUNIT____-NEXT: ret i32 [[CONV]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@is_null_return
+; IS__CGSCC____-SAME: (i32* nofree readnone [[P:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[P]], null
+; IS__CGSCC____-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32
+; IS__CGSCC____-NEXT: ret i32 [[CONV]]
;
entry:
%cmp = icmp eq i32* %p, null
@@ -43,27 +52,51 @@ entry:
;
; no-capture is missing on %p because it is not dereferenceable
define i32 @is_null_control(i32* %p) #0 {
-; CHECK-LABEL: define {{[^@]+}}@is_null_control
-; CHECK-SAME: (i32* nofree [[P:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[P]], null
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: store i32 1, i32* [[RETVAL]], align 4
-; CHECK-NEXT: br label [[RETURN:%.*]]
-; CHECK: if.end:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32* null, [[P]]
-; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
-; CHECK: if.then2:
-; CHECK-NEXT: store i32 1, i32* [[RETVAL]], align 4
-; CHECK-NEXT: br label [[RETURN]]
-; CHECK: if.end3:
-; CHECK-NEXT: store i32 0, i32* [[RETVAL]], align 4
-; CHECK-NEXT: br label [[RETURN]]
-; CHECK: return:
-; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[RETVAL]], align 4
-; CHECK-NEXT: ret i32 [[TMP0]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@is_null_control
+; IS__TUNIT____-SAME: (i32* nofree [[P:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32* [[P]], null
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: store i32 1, i32* [[RETVAL]], align 4
+; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: [[CMP1:%.*]] = icmp eq i32* null, [[P]]
+; IS__TUNIT____-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
+; IS__TUNIT____: if.then2:
+; IS__TUNIT____-NEXT: store i32 1, i32* [[RETVAL]], align 4
+; IS__TUNIT____-NEXT: br label [[RETURN]]
+; IS__TUNIT____: if.end3:
+; IS__TUNIT____-NEXT: store i32 0, i32* [[RETVAL]], align 4
+; IS__TUNIT____-NEXT: br label [[RETURN]]
+; IS__TUNIT____: return:
+; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[RETVAL]], align 4
+; IS__TUNIT____-NEXT: ret i32 [[TMP0]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@is_null_control
+; IS__CGSCC____-SAME: (i32* nofree [[P:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32* [[P]], null
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: store i32 1, i32* [[RETVAL]], align 4
+; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: [[CMP1:%.*]] = icmp eq i32* null, [[P]]
+; IS__CGSCC____-NEXT: br i1 [[CMP1]], label [[IF_THEN2:%.*]], label [[IF_END3:%.*]]
+; IS__CGSCC____: if.then2:
+; IS__CGSCC____-NEXT: store i32 1, i32* [[RETVAL]], align 4
+; IS__CGSCC____-NEXT: br label [[RETURN]]
+; IS__CGSCC____: if.end3:
+; IS__CGSCC____-NEXT: store i32 0, i32* [[RETVAL]], align 4
+; IS__CGSCC____-NEXT: br label [[RETURN]]
+; IS__CGSCC____: return:
+; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[RETVAL]], align 4
+; IS__CGSCC____-NEXT: ret i32 [[TMP0]]
;
entry:
%retval = alloca i32, align 4
@@ -99,10 +132,17 @@ return: ; preds = %if.end3, %if.then2,
; }
;
define double* @srec0(double* %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@srec0
-; CHECK-SAME: (double* nocapture nofree readnone [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@srec0
+; IS__TUNIT____-SAME: (double* nocapture nofree readnone [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@srec0
+; IS__CGSCC____-SAME: (double* nocapture nofree readnone [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
%call = call double* @srec0(double* %a)
@@ -123,10 +163,17 @@ entry:
; Other arguments are possible here due to the no-return behavior.
;
define i32* @srec16(i32* %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@srec16
-; CHECK-SAME: (i32* nocapture nofree readnone [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@srec16
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@srec16
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
%call = call i32* @srec16(i32* %a)
@@ -162,6 +209,7 @@ entry:
; return scc_A((int*)(scc_A(a) ? scc_B((double*)a) : scc_C(a)));
; }
define float* @scc_A(i32* dereferenceable_or_null(4) %a) {
+; CHECK: Function Attrs: nofree nosync nounwind readnone
; CHECK-LABEL: define {{[^@]+}}@scc_A
; CHECK-SAME: (i32* nofree readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]])
; CHECK-NEXT: entry:
@@ -207,6 +255,7 @@ cond.end: ; preds = %cond.false, %cond.t
}
define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
+; CHECK: Function Attrs: nofree nosync nounwind readnone
; CHECK-LABEL: define {{[^@]+}}@scc_B
; CHECK-SAME: (double* nofree readnone returned dereferenceable_or_null(8) "no-capture-maybe-returned" [[A:%.*]])
; CHECK-NEXT: entry:
@@ -252,6 +301,7 @@ cond.end: ; preds = %cond.false, %cond.t
}
define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
+; CHECK: Function Attrs: nofree nosync nounwind readnone
; CHECK-LABEL: define {{[^@]+}}@scc_C
; CHECK-SAME: (i16* nofree readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" [[A:%.*]])
; CHECK-NEXT: entry:
@@ -311,6 +361,7 @@ cond.end: ; preds = %cond.false, %cond.t
declare void @external_no_capture(i32* nocapture)
define void @test_external_no_capture(i32* %p) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@test_external_no_capture
; CHECK-SAME: (i32* nocapture [[P:%.*]])
; CHECK-NEXT: entry:
@@ -329,6 +380,7 @@ entry:
; }
;
define void @test_var_arg_call(i8* %p, i32 %a) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@test_var_arg_call
; CHECK-SAME: (i8* nocapture [[P:%.*]], i32 [[A:%.*]])
; CHECK-NEXT: entry:
@@ -352,11 +404,19 @@ declare i32 @printf(i8* nocapture, ...)
;
; There should *not* be a no-capture attribute on %a
define i64* @not_captured_but_returned_0(i64* %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@not_captured_but_returned_0
-; CHECK-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: store i64 0, i64* [[A]], align 8
-; CHECK-NEXT: ret i64* [[A]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@not_captured_but_returned_0
+; IS__TUNIT____-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: store i64 0, i64* [[A]], align 8
+; IS__TUNIT____-NEXT: ret i64* [[A]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@not_captured_but_returned_0
+; IS__CGSCC____-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: store i64 0, i64* [[A]], align 8
+; IS__CGSCC____-NEXT: ret i64* [[A]]
;
entry:
store i64 0, i64* %a, align 8
@@ -372,12 +432,21 @@ entry:
;
; There should *not* be a no-capture attribute on %a
define i64* @not_captured_but_returned_1(i64* %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@not_captured_but_returned_1
-; CHECK-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i64, i64* [[A]], i64 1
-; CHECK-NEXT: store i64 1, i64* [[ADD_PTR]], align 8
-; CHECK-NEXT: ret i64* [[ADD_PTR]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@not_captured_but_returned_1
+; IS__TUNIT____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i64, i64* [[A]], i64 1
+; IS__TUNIT____-NEXT: store i64 1, i64* [[ADD_PTR]], align 8
+; IS__TUNIT____-NEXT: ret i64* [[ADD_PTR]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@not_captured_but_returned_1
+; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i64, i64* [[A]], i64 1
+; IS__CGSCC____-NEXT: store i64 1, i64* [[ADD_PTR]], align 8
+; IS__CGSCC____-NEXT: ret i64* [[ADD_PTR]]
;
entry:
%add.ptr = getelementptr inbounds i64, i64* %a, i64 1
@@ -393,6 +462,7 @@ entry:
; }
;
define void @test_not_captured_but_returned_calls(i64* %a) #0 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@test_not_captured_but_returned_calls
; IS__TUNIT____-SAME: (i64* nocapture nofree writeonly align 8 [[A:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -400,6 +470,7 @@ define void @test_not_captured_but_returned_calls(i64* %a) #0 {
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@test_not_captured_but_returned_calls
; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -421,12 +492,14 @@ entry:
;
; There should *not* be a no-capture attribute on %a
define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a
; IS__TUNIT____-SAME: (i64* nofree returned writeonly align 8 "no-capture-maybe-returned" [[A:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64* @not_captured_but_returned_0(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
; IS__TUNIT____-NEXT: ret i64* [[CALL]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0a
; IS__CGSCC____-SAME: (i64* nofree nonnull returned writeonly align 8 dereferenceable(8) [[A:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -446,6 +519,7 @@ entry:
;
; There should *not* be a no-capture attribute on %a
define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0b
; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 [[A:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -454,6 +528,7 @@ define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_0b
; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(8) [[A:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -477,12 +552,14 @@ entry:
;
; There should *not* be a no-capture attribute on %a
define i64* @negative_test_not_captured_but_returned_call_1a(i64* %a) #0 {
+; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind uwtable willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1a
; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A:%.*]])
; IS__TUNIT____-NEXT: entry:
; IS__TUNIT____-NEXT: [[CALL:%.*]] = call nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree writeonly align 8 "no-capture-maybe-returned" [[A]])
; IS__TUNIT____-NEXT: ret i64* [[CALL]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1a
; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -502,6 +579,7 @@ entry:
;
; There should *not* be a no-capture attribute on %a
define void @negative_test_not_captured_but_returned_call_1b(i64* %a) #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind uwtable willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b
; IS__TUNIT____-SAME: (i64* nofree writeonly align 8 [[A:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -510,6 +588,7 @@ define void @negative_test_not_captured_but_returned_call_1b(i64* %a) #0 {
; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind uwtable willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@negative_test_not_captured_but_returned_call_1b
; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8 dereferenceable(16) [[A:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -537,6 +616,7 @@ entry:
;
define i32* @ret_arg_or_unknown(i32* %b) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown
; CHECK-SAME: (i32* [[B:%.*]])
; CHECK-NEXT: entry:
@@ -561,6 +641,7 @@ ret_unknown:
}
define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
; CHECK-SAME: (i32* [[B:%.*]])
; CHECK-NEXT: entry:
@@ -597,6 +678,7 @@ r:
declare i32* @readonly_unknown(i32*, i32*) readonly
define void @not_captured_by_readonly_call(i32* %b) #0 {
+; CHECK: Function Attrs: noinline nounwind readonly uwtable
; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]])
; CHECK-NEXT: entry:
@@ -614,6 +696,7 @@ entry:
; Make sure the returned flag on %r is strong enough to justify nocapture on %b but **not** on %r.
;
define i32* @not_captured_by_readonly_call_not_returned_either1(i32* %b, i32* returned %r) {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either1
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]])
; CHECK-NEXT: entry:
@@ -627,6 +710,7 @@ entry:
declare i32* @readonly_unknown_r1a(i32*, i32* returned) readonly
define i32* @not_captured_by_readonly_call_not_returned_either2(i32* %b, i32* %r) {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either2
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]])
; CHECK-NEXT: entry:
@@ -640,6 +724,7 @@ entry:
declare i32* @readonly_unknown_r1b(i32*, i32* returned) readonly nounwind
define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r) {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]])
; CHECK-NEXT: entry:
@@ -652,6 +737,7 @@ entry:
}
define i32* @not_captured_by_readonly_call_not_returned_either4(i32* %b, i32* %r) nounwind {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call_not_returned_either4
; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned [[R:%.*]])
; CHECK-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/nofree.ll b/llvm/test/Transforms/Attributor/nofree.ll
index fd7324dc9b3d..d19e17479765 100644
--- a/llvm/test/Transforms/Attributor/nofree.ll
+++ b/llvm/test/Transforms/Attributor/nofree.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=11 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -16,11 +16,14 @@ declare void @_ZdaPv(i8*) local_unnamed_addr #2
; TEST 1 (positive case)
-; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
define void @only_return() #0 {
-; CHECK-LABEL: define {{[^@]+}}@only_return()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@only_return()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@only_return()
+; IS__CGSCC____-NEXT: ret void
;
ret void
}
@@ -32,9 +35,8 @@ define void @only_return() #0 {
; free(p);
; }
-; CHECK: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: nofree
define void @only_free(i8* nocapture %0) local_unnamed_addr #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@only_free
; CHECK-SAME: (i8* nocapture [[TMP0:%.*]]) local_unnamed_addr
; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP0]])
@@ -57,6 +59,7 @@ define void @only_free(i8* nocapture %0) local_unnamed_addr #0 {
define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@free_in_scc1
; CHECK-SAME: (i8* nocapture [[TMP0:%.*]]) local_unnamed_addr
; CHECK-NEXT: tail call void @free_in_scc2(i8* nocapture [[TMP0]])
@@ -67,9 +70,8 @@ define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr #0 {
}
-; CHECK: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: nofree
define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@free_in_scc2
; CHECK-SAME: (i8* nocapture [[TMP0:%.*]]) local_unnamed_addr
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[TMP0]], null
@@ -106,21 +108,27 @@ end:
; }
-; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
define void @mutual_recursion1() #0 {
-; CHECK-LABEL: define {{[^@]+}}@mutual_recursion1()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@mutual_recursion1()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@mutual_recursion1()
+; IS__CGSCC_NPM-NEXT: unreachable
;
call void @mutual_recursion2()
ret void
}
-; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
define void @mutual_recursion2() #0 {
-; CHECK-LABEL: define {{[^@]+}}@mutual_recursion2()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@mutual_recursion2()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@mutual_recursion2()
+; IS__CGSCC_NPM-NEXT: unreachable
;
call void @mutual_recursion1()
ret void
@@ -133,9 +141,8 @@ define void @mutual_recursion2() #0 {
; delete [] p;
; }
-; CHECK: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: nofree
define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@_Z9delete_opPc
; CHECK-SAME: (i8* [[TMP0:%.*]]) local_unnamed_addr
; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
@@ -160,9 +167,8 @@ define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #0 {
; TEST 6 (negative case)
; Call realloc
-; CHECK: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: nofree
define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@call_realloc
; CHECK-SAME: (i8* nocapture [[TMP0:%.*]], i64 [[TMP1:%.*]]) local_unnamed_addr
; CHECK-NEXT: [[RET:%.*]] = tail call i8* @realloc(i8* nocapture [[TMP0]], i64 [[TMP1]])
@@ -181,11 +187,14 @@ define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr #0
; CHECK-NEXT: declare void @nofree_function()
declare void @nofree_function() nofree readnone #0
-; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
define void @call_nofree_function() #0 {
-; CHECK-LABEL: define {{[^@]+}}@call_nofree_function()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@call_nofree_function()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@call_nofree_function()
+; IS__CGSCC____-NEXT: ret void
;
tail call void @nofree_function()
ret void
@@ -200,9 +209,8 @@ define void @call_nofree_function() #0 {
declare void @maybe_free() #0
-; CHECK: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: nofree
define void @call_maybe_free() #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@call_maybe_free()
; CHECK-NEXT: tail call void @maybe_free()
; CHECK-NEXT: ret void
@@ -215,9 +223,8 @@ define void @call_maybe_free() #0 {
; TEST 9 (negative case)
; Call both of above functions
-; CHECK: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: nofree
define void @call_both() #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@call_both()
; CHECK-NEXT: tail call void @maybe_free()
; CHECK-NEXT: ret void
@@ -234,20 +241,24 @@ define void @call_both() #0 {
; CHECK-NEXT: declare float @llvm.floor.f32(float)
declare float @llvm.floor.f32(float)
-; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
define void @call_floor(float %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@call_floor
-; CHECK-SAME: (float [[A:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@call_floor
+; IS__TUNIT____-SAME: (float [[A:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@call_floor
+; IS__CGSCC____-SAME: (float [[A:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
tail call float @llvm.floor.f32(float %a)
ret void
}
; FIXME: missing nofree
-; CHECK: Function Attrs: noinline nosync nounwind readnone uwtable
define float @call_floor2(float %a) #0 {
+; CHECK: Function Attrs: noinline nosync nounwind readnone uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@call_floor2
; CHECK-SAME: (float [[A:%.*]])
; CHECK-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]])
@@ -260,21 +271,27 @@ define float @call_floor2(float %a) #0 {
; TEST 11 (positive case)
; Check propagation.
-; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
define void @f1() #0 {
-; CHECK-LABEL: define {{[^@]+}}@f1()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@f1()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@f1()
+; IS__CGSCC____-NEXT: ret void
;
tail call void @nofree_function()
ret void
}
-; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
define void @f2() #0 {
-; CHECK-LABEL: define {{[^@]+}}@f2()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@f2()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@f2()
+; IS__CGSCC____-NEXT: ret void
;
tail call void @f1()
ret void
@@ -282,6 +299,7 @@ define void @f2() #0 {
; TEST 12 NoFree argument - positive.
define double @test12(double* nocapture readonly %a) {
+; CHECK: Function Attrs: nofree nounwind
; CHECK-LABEL: define {{[^@]+}}@test12
; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8 dereferenceable(8) [[A:%.*]])
; CHECK-NEXT: entry:
@@ -300,6 +318,7 @@ declare double @cos(double) nobuiltin nounwind nofree
; FIXME: %a should be nofree.
; TEST 13 NoFree argument - positive.
define noalias i32* @test13(i64* nocapture readonly %a) {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@test13
; CHECK-SAME: (i64* nocapture nonnull readonly align 8 dereferenceable(8) [[A:%.*]])
; CHECK-NEXT: entry:
@@ -316,6 +335,7 @@ entry:
}
define void @test14(i8* nocapture %0, i8* nocapture %1) {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@test14
; CHECK-SAME: (i8* nocapture [[TMP0:%.*]], i8* nocapture nofree readnone [[TMP1:%.*]])
; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP0]])
diff --git a/llvm/test/Transforms/Attributor/nonnull.ll b/llvm/test/Transforms/Attributor/nonnull.ll
index 9e4a4ac4bb18..c67bc3e4f17b 100644
--- a/llvm/test/Transforms/Attributor/nonnull.ll
+++ b/llvm/test/Transforms/Attributor/nonnull.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -22,15 +22,22 @@ define i8* @test1() {
; Return a pointer trivially nonnull (argument attribute)
define i8* @test2(i8* nonnull %p) {
-; CHECK-LABEL: define {{[^@]+}}@test2
-; CHECK-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]])
-; CHECK-NEXT: ret i8* [[P]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
+; IS__TUNIT____-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]])
+; IS__TUNIT____-NEXT: ret i8* [[P]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
+; IS__CGSCC____-SAME: (i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[P:%.*]])
+; IS__CGSCC____-NEXT: ret i8* [[P]]
;
ret i8* %p
}
define i8* @test2A(i1 %c, i8* %ret) {
; ATTRIBUTOR: define nonnull i8* @test2A(i1 %c, i8* nofree nonnull readnone returned %ret)
+; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2A
; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]])
; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
@@ -41,6 +48,7 @@ define i8* @test2A(i1 %c, i8* %ret) {
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "nonnull"(i8* [[RET]]) ]
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
;
+; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2A
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned "no-capture-maybe-returned" [[RET:%.*]])
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
@@ -62,6 +70,7 @@ B:
define i8* @test2B(i1 %c, i8* %ret) {
; ATTRIBUTOR: define nonnull dereferenceable(4) i8* @test2B(i1 %c, i8* nofree nonnull readnone returned dereferenceable(4) %ret)
+; NOT_CGSCC_OPM: Function Attrs: nounwind willreturn
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test2B
; NOT_CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]])
; NOT_CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
@@ -72,6 +81,7 @@ define i8* @test2B(i1 %c, i8* %ret) {
; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [ "dereferenceable"(i8* [[RET]], i32 4) ]
; NOT_CGSCC_OPM-NEXT: ret i8* [[RET]]
;
+; IS__CGSCC_OPM: Function Attrs: nounwind willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test2B
; IS__CGSCC_OPM-SAME: (i1 [[C:%.*]], i8* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[RET:%.*]])
; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[A:%.*]], label [[B:%.*]]
@@ -127,16 +137,26 @@ define i8* @test3(i1 %c) {
; nonnull if neither can ever return null. (In this case, they
; just never return period.)
define i8* @test4_helper() {
-; CHECK-LABEL: define {{[^@]+}}@test4_helper()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper()
+; IS__CGSCC_NPM-NEXT: unreachable
;
%ret = call i8* @test4()
ret i8* %ret
}
define i8* @test4() {
-; CHECK-LABEL: define {{[^@]+}}@test4()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4()
+; IS__CGSCC_NPM-NEXT: unreachable
;
%ret = call i8* @test4_helper()
ret i8* %ret
@@ -145,13 +165,23 @@ define i8* @test4() {
; Given a mutual recursive set of functions which *can* return null
; make sure we haven't marked them as nonnull.
define i8* @test5_helper(i1 %c) {
-; CHECK-LABEL: define {{[^@]+}}@test5_helper
-; CHECK-SAME: (i1 [[C:%.*]])
-; CHECK-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
-; CHECK: rec:
-; CHECK-NEXT: br label [[END]]
-; CHECK: end:
-; CHECK-NEXT: ret i8* null
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test5_helper
+; NOT_CGSCC_NPM-SAME: (i1 [[C:%.*]])
+; NOT_CGSCC_NPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
+; NOT_CGSCC_NPM: rec:
+; NOT_CGSCC_NPM-NEXT: br label [[END]]
+; NOT_CGSCC_NPM: end:
+; NOT_CGSCC_NPM-NEXT: ret i8* null
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5_helper
+; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]])
+; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
+; IS__CGSCC_NPM: rec:
+; IS__CGSCC_NPM-NEXT: br label [[END]]
+; IS__CGSCC_NPM: end:
+; IS__CGSCC_NPM-NEXT: ret i8* null
;
br i1 %c, label %rec, label %end
rec:
@@ -162,17 +192,23 @@ end:
}
define i8* @test5(i1 %c) {
-; CHECK-LABEL: define {{[^@]+}}@test5
-; CHECK-SAME: (i1 [[C:%.*]])
-; CHECK-NEXT: ret i8* null
+; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test5
+; NOT_CGSCC_NPM-SAME: (i1 [[C:%.*]])
+; NOT_CGSCC_NPM-NEXT: ret i8* null
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test5
+; IS__CGSCC_NPM-SAME: (i1 [[C:%.*]])
+; IS__CGSCC_NPM-NEXT: ret i8* null
;
%ret = call i8* @test5_helper(i1 %c)
ret i8* %ret
}
; Local analysis, but going through a self recursive phi
-; CHECK: Function Attrs: noreturn
define i8* @test6a() {
+; CHECK: Function Attrs: noreturn
; CHECK-LABEL: define {{[^@]+}}@test6a()
; CHECK-NEXT: entry:
; CHECK-NEXT: [[RET:%.*]] = call i8* @ret_nonnull()
@@ -215,30 +251,51 @@ exit:
}
define i8* @test7(i8* %a) {
-; CHECK-LABEL: define {{[^@]+}}@test7
-; CHECK-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]])
-; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0
-; CHECK-NEXT: ret i8* [[B]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test7
+; IS__TUNIT____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]])
+; IS__TUNIT____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0
+; IS__TUNIT____-NEXT: ret i8* [[B]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test7
+; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[A:%.*]])
+; IS__CGSCC____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 0
+; IS__CGSCC____-NEXT: ret i8* [[B]]
;
%b = getelementptr inbounds i8, i8* %a, i64 0
ret i8* %b
}
define i8* @test8(i8* %a) {
-; CHECK-LABEL: define {{[^@]+}}@test8
-; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]])
-; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1
-; CHECK-NEXT: ret i8* [[B]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test8
+; IS__TUNIT____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]])
+; IS__TUNIT____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1
+; IS__TUNIT____-NEXT: ret i8* [[B]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test8
+; IS__CGSCC____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]])
+; IS__CGSCC____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 1
+; IS__CGSCC____-NEXT: ret i8* [[B]]
;
%b = getelementptr inbounds i8, i8* %a, i64 1
ret i8* %b
}
define i8* @test9(i8* %a, i64 %n) {
-; CHECK-LABEL: define {{[^@]+}}@test9
-; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]])
-; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
-; CHECK-NEXT: ret i8* [[B]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test9
+; IS__TUNIT____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]])
+; IS__TUNIT____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
+; IS__TUNIT____-NEXT: ret i8* [[B]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test9
+; IS__CGSCC____-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]])
+; IS__CGSCC____-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64 [[N]]
+; IS__CGSCC____-NEXT: ret i8* [[B]]
;
%b = getelementptr inbounds i8, i8* %a, i64 %n
ret i8* %b
@@ -247,6 +304,7 @@ define i8* @test9(i8* %a, i64 %n) {
; ATTRIBUTOR_OPM: define i8* @test10
; ATTRIBUTOR_NPM: define nonnull i8* @test10
define i8* @test10(i8* %a, i64 %n) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@test10
; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]], i64 [[N:%.*]])
; CHECK-NEXT: call void @llvm.assume(i1 true)
@@ -319,6 +377,7 @@ define void @test13_helper() {
ret void
}
define internal void @test13(i8* %a, i8* %b, i8* %c) {
+; IS__TUNIT____: Function Attrs: nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@test13
; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull readnone [[A:%.*]], i8* noalias nocapture nofree readnone [[B:%.*]], i8* noalias nocapture nofree readnone [[C:%.*]])
; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree nonnull readnone [[A]])
@@ -326,6 +385,7 @@ define internal void @test13(i8* %a, i8* %b, i8* %c) {
; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[C]])
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@test13
; IS__CGSCC____-SAME: (i8* nocapture nofree readnone [[A:%.*]], i8* nocapture nofree readnone [[B:%.*]], i8* nocapture nofree readnone [[C:%.*]])
; IS__CGSCC____-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree readnone [[A]])
@@ -355,6 +415,7 @@ declare nonnull i8* @nonnull()
define internal i32* @f1(i32* %arg) {
; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull readonly %arg)
+; CHECK: Function Attrs: argmemonly nofree nosync nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@f1
; CHECK-SAME: (i32* nofree readonly [[ARG:%.*]])
; CHECK-NEXT: bb:
@@ -402,6 +463,7 @@ bb9: ; preds = %bb4, %bb
}
define internal i32* @f2(i32* %arg) {
+; CHECK: Function Attrs: argmemonly nofree nosync nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@f2
; CHECK-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4) [[ARG:%.*]])
; CHECK-NEXT: bb:
@@ -415,6 +477,7 @@ bb:
define dso_local noalias i32* @f3(i32* %arg) {
; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly %arg)
+; CHECK: Function Attrs: argmemonly nofree nosync nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@f3
; CHECK-SAME: (i32* nofree readonly [[ARG:%.*]])
; CHECK-NEXT: bb:
@@ -450,6 +513,7 @@ declare void @fun3(i8*, i8*, i8*) #1
; fun2(nonnull %a, %b)
; We can say that %a is nonnull but %b is not.
define void @f16(i8* %a, i8 * %b, i8 %c) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@f16
; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
@@ -478,6 +542,7 @@ if.else:
; fun1(nonnull %a)
; We can say that %a is nonnull
define void @f17(i8* %a, i8 %c) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@f17
; CHECK-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]])
; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
@@ -516,6 +581,7 @@ cont:
; fun1(nonnull %a)
define void @f18(i8* %a, i8* %b, i8 %c) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@f18
; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]])
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[C]], 0
@@ -564,6 +630,7 @@ cont2:
; TEST 19: Loop
define void @f19(i8* %a, i8* %b, i8 %c) {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@f19
; CHECK-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]])
; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
@@ -727,6 +794,7 @@ define i8 @parent7(i8* %a) {
declare i32 @esfp(...)
define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
+; NOT_CGSCC_OPM: Function Attrs: nounwind
; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@parent8
; NOT_CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #4 personality i8* bitcast (i32 (...)* @esfp to i8*)
; NOT_CGSCC_OPM-NEXT: entry:
@@ -740,6 +808,7 @@ define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (..
; NOT_CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer
; NOT_CGSCC_OPM-NEXT: unreachable
;
+; IS__CGSCC_OPM: Function Attrs: nounwind
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@parent8
; IS__CGSCC_OPM-SAME: (i8* nonnull [[A:%.*]], i8* nocapture nofree readnone [[BOGUS1:%.*]], i8* nonnull [[B:%.*]]) #5 personality i8* bitcast (i32 (...)* @esfp to i8*)
; IS__CGSCC_OPM-NEXT: entry:
@@ -769,10 +838,17 @@ exc:
}
define i32* @gep1(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@gep1
-; CHECK-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
-; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
-; CHECK-NEXT: ret i32* [[Q]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@gep1
+; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
+; IS__TUNIT____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
+; IS__TUNIT____-NEXT: ret i32* [[Q]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@gep1
+; IS__CGSCC____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
+; IS__CGSCC____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
+; IS__CGSCC____-NEXT: ret i32* [[Q]]
;
%q = getelementptr inbounds i32, i32* %p, i32 1
ret i32* %q
@@ -780,20 +856,34 @@ define i32* @gep1(i32* %p) {
define i32* @gep1_no_null_opt(i32* %p) #0 {
; Should't be able to derive nonnull based on gep.
-; CHECK-LABEL: define {{[^@]+}}@gep1_no_null_opt
-; CHECK-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
-; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
-; CHECK-NEXT: ret i32* [[Q]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@gep1_no_null_opt
+; IS__TUNIT____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
+; IS__TUNIT____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
+; IS__TUNIT____-NEXT: ret i32* [[Q]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@gep1_no_null_opt
+; IS__CGSCC____-SAME: (i32* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
+; IS__CGSCC____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32* [[P]], i32 1
+; IS__CGSCC____-NEXT: ret i32* [[Q]]
;
%q = getelementptr inbounds i32, i32* %p, i32 1
ret i32* %q
}
define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
-; CHECK-LABEL: define {{[^@]+}}@gep2
-; CHECK-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
-; CHECK-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1
-; CHECK-NEXT: ret i32 addrspace(3)* [[Q]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@gep2
+; IS__TUNIT____-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
+; IS__TUNIT____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1
+; IS__TUNIT____-NEXT: ret i32 addrspace(3)* [[Q]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@gep2
+; IS__CGSCC____-SAME: (i32 addrspace(3)* nofree readnone "no-capture-maybe-returned" [[P:%.*]])
+; IS__CGSCC____-NEXT: [[Q:%.*]] = getelementptr inbounds i32, i32 addrspace(3)* [[P]], i32 1
+; IS__CGSCC____-NEXT: ret i32 addrspace(3)* [[Q]]
;
%q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1
ret i32 addrspace(3)* %q
@@ -801,15 +891,22 @@ define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
; FIXME: We should propagate dereferenceable here but *not* nonnull
define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) {
-; CHECK-LABEL: define {{[^@]+}}@as
-; CHECK-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]])
-; CHECK-NEXT: ret i32 addrspace(3)* [[P]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@as
+; IS__TUNIT____-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]])
+; IS__TUNIT____-NEXT: ret i32 addrspace(3)* [[P]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@as
+; IS__CGSCC____-SAME: (i32 addrspace(3)* nofree nonnull readnone returned dereferenceable(4) "no-capture-maybe-returned" [[P:%.*]])
+; IS__CGSCC____-NEXT: ret i32 addrspace(3)* [[P]]
;
ret i32 addrspace(3)* %p
}
; CHECK-NOT: @g2()
define internal i32* @g2() {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@g2()
; IS__CGSCC____-NEXT: ret i32* inttoptr (i64 4 to i32*)
;
@@ -817,8 +914,13 @@ define internal i32* @g2() {
}
define i32* @g1() {
-; CHECK-LABEL: define {{[^@]+}}@g1()
-; CHECK-NEXT: ret i32* inttoptr (i64 4 to i32*)
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@g1()
+; IS__TUNIT____-NEXT: ret i32* inttoptr (i64 4 to i32*)
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@g1()
+; IS__CGSCC____-NEXT: ret i32* inttoptr (i64 4 to i32*)
;
%c = call i32* @g2()
ret i32* %c
@@ -826,11 +928,13 @@ define i32* @g1() {
declare void @use_i32_ptr(i32* readnone nocapture) nounwind
define internal void @called_by_weak(i32* %a) {
+; IS__TUNIT____: Function Attrs: nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@called_by_weak
; IS__TUNIT____-SAME: (i32* noalias nocapture nonnull readnone [[A:%.*]])
; IS__TUNIT____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]])
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_weak
; IS__CGSCC____-SAME: (i32* nocapture nonnull readnone [[A:%.*]])
; IS__CGSCC____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone [[A]])
@@ -853,11 +957,13 @@ define weak_odr void @weak_caller(i32* nonnull %a) {
; Expect nonnull
define internal void @control(i32* dereferenceable(4) %a) {
+; IS__TUNIT____: Function Attrs: nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@control
; IS__TUNIT____-SAME: (i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]])
; IS__TUNIT____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]])
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@control
; IS__CGSCC____-SAME: (i32* nocapture nonnull readnone align 16 dereferenceable(8) [[A:%.*]])
; IS__CGSCC____-NEXT: call void @use_i32_ptr(i32* noalias nocapture nonnull readnone align 16 dereferenceable(8) [[A]])
@@ -868,6 +974,7 @@ define internal void @control(i32* dereferenceable(4) %a) {
}
; Avoid nonnull as we do not touch naked functions
define internal void @naked(i32* dereferenceable(4) %a) naked {
+; CHECK: Function Attrs: naked
; CHECK-LABEL: define {{[^@]+}}@naked
; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]])
; CHECK-NEXT: call void @use_i32_ptr(i32* [[A]])
@@ -878,6 +985,7 @@ define internal void @naked(i32* dereferenceable(4) %a) naked {
}
; Avoid nonnull as we do not touch optnone
define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline {
+; CHECK: Function Attrs: noinline optnone
; CHECK-LABEL: define {{[^@]+}}@optnone
; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]])
; CHECK-NEXT: call void @use_i32_ptr(i32* [[A]])
@@ -911,20 +1019,37 @@ declare void @h(i32*) willreturn nounwind
declare i32 @g(i32*) willreturn nounwind
define i32 @nonnull_exec_ctx_1(i32* %a, i32 %b) {
;
-; CHECK-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
-; CHECK-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
-; CHECK-NEXT: en:
-; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
-; CHECK-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
-; CHECK: ex:
-; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
-; CHECK-NEXT: ret i32 [[TMP5]]
-; CHECK: hd:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
-; CHECK-NEXT: tail call void @h(i32* [[A]])
-; CHECK-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
-; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
-; CHECK-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
+; IS________OPM: Function Attrs: nounwind
+; IS________OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
+; IS________OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
+; IS________OPM-NEXT: en:
+; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; IS________OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; IS________OPM: ex:
+; IS________OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
+; IS________OPM-NEXT: ret i32 [[TMP5]]
+; IS________OPM: hd:
+; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
+; IS________OPM-NEXT: tail call void @h(i32* [[A]])
+; IS________OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; IS________OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; IS________OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
+;
+; IS________NPM: Function Attrs: nounwind willreturn
+; IS________NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
+; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
+; IS________NPM-NEXT: en:
+; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; IS________NPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; IS________NPM: ex:
+; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
+; IS________NPM-NEXT: ret i32 [[TMP5]]
+; IS________NPM: hd:
+; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
+; IS________NPM-NEXT: tail call void @h(i32* [[A]])
+; IS________NPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; IS________NPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; IS________NPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
en:
%tmp3 = icmp eq i32 %b, 0
@@ -944,22 +1069,41 @@ hd:
define i32 @nonnull_exec_ctx_1b(i32* %a, i32 %b) {
;
-; CHECK-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
-; CHECK-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
-; CHECK-NEXT: en:
-; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
-; CHECK-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
-; CHECK: ex:
-; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
-; CHECK-NEXT: ret i32 [[TMP5]]
-; CHECK: hd:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
-; CHECK-NEXT: tail call void @h(i32* [[A]])
-; CHECK-NEXT: br label [[HD2]]
-; CHECK: hd2:
-; CHECK-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
-; CHECK-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
-; CHECK-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
+; IS________OPM: Function Attrs: nounwind
+; IS________OPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
+; IS________OPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
+; IS________OPM-NEXT: en:
+; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; IS________OPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; IS________OPM: ex:
+; IS________OPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
+; IS________OPM-NEXT: ret i32 [[TMP5]]
+; IS________OPM: hd:
+; IS________OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
+; IS________OPM-NEXT: tail call void @h(i32* [[A]])
+; IS________OPM-NEXT: br label [[HD2]]
+; IS________OPM: hd2:
+; IS________OPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; IS________OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; IS________OPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
+;
+; IS________NPM: Function Attrs: nounwind willreturn
+; IS________NPM-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
+; IS________NPM-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
+; IS________NPM-NEXT: en:
+; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
+; IS________NPM-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
+; IS________NPM: ex:
+; IS________NPM-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
+; IS________NPM-NEXT: ret i32 [[TMP5]]
+; IS________NPM: hd:
+; IS________NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
+; IS________NPM-NEXT: tail call void @h(i32* [[A]])
+; IS________NPM-NEXT: br label [[HD2]]
+; IS________NPM: hd2:
+; IS________NPM-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
+; IS________NPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
+; IS________NPM-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
en:
%tmp3 = icmp eq i32 %b, 0
@@ -982,6 +1126,7 @@ hd2:
define i32 @nonnull_exec_ctx_2(i32* %a, i32 %b) willreturn nounwind {
;
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
; CHECK-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]])
; CHECK-NEXT: en:
@@ -1015,6 +1160,7 @@ hd:
define i32 @nonnull_exec_ctx_2b(i32* %a, i32 %b) willreturn nounwind {
;
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
; CHECK-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]])
; CHECK-NEXT: en:
@@ -1151,6 +1297,7 @@ declare i8* @strrchr(i8* %0, i32 %1) nofree nounwind readonly
; We should not mark the return of @strrchr as `nonnull`, it may well be NULL!
define i8* @mybasename(i8* nofree readonly %str) {
+; CHECK: Function Attrs: nofree nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@mybasename
; CHECK-SAME: (i8* nofree readonly [[STR:%.*]])
; CHECK-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly [[STR]], i32 47)
diff --git a/llvm/test/Transforms/Attributor/norecurse.ll b/llvm/test/Transforms/Attributor/norecurse.ll
index 41e8d7c0bb11..da40ea6c2321 100644
--- a/llvm/test/Transforms/Attributor/norecurse.ll
+++ b/llvm/test/Transforms/Attributor/norecurse.ll
@@ -1,54 +1,61 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=9 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
-; IS__CGSSA____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
define i32 @leaf() {
-; CHECK-LABEL: define {{[^@]+}}@leaf()
-; CHECK-NEXT: ret i32 1
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@leaf()
+; IS__TUNIT____-NEXT: ret i32 1
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@leaf()
+; IS__CGSCC____-NEXT: ret i32 1
;
ret i32 1
}
-; CHECK: Function Attrs
-; CHECK-SAME: readnone
-; CHECK-NOT: norecurse
define i32 @self_rec() {
-; CHECK-LABEL: define {{[^@]+}}@self_rec()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@self_rec()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@self_rec()
+; IS__CGSCC____-NEXT: unreachable
;
%a = call i32 @self_rec()
ret i32 4
}
-; CHECK: Function Attrs
-; CHECK-SAME: readnone
-; CHECK-NOT: norecurse
define i32 @indirect_rec() {
-; CHECK-LABEL: define {{[^@]+}}@indirect_rec()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec()
+; IS__CGSCC_NPM-NEXT: unreachable
;
%a = call i32 @indirect_rec2()
ret i32 %a
}
-; CHECK: Function Attrs
-; CHECK-SAME: readnone
-; CHECK-NOT: norecurse
define i32 @indirect_rec2() {
-; CHECK-LABEL: define {{[^@]+}}@indirect_rec2()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2()
+; IS__CGSCC_NPM-NEXT: unreachable
;
%a = call i32 @indirect_rec()
ret i32 %a
}
-; CHECK: Function Attrs
-; CHECK-SAME: readnone
-; CHECK-NOT: norecurse
define i32 @extern() {
+; CHECK: Function Attrs: nosync readnone
; CHECK-LABEL: define {{[^@]+}}@extern()
; CHECK-NEXT: [[A:%.*]] = call i32 @k()
; CHECK-NEXT: ret i32 [[A]]
@@ -61,9 +68,8 @@ define i32 @extern() {
; CHECK-NEXT: declare i32 @k()
declare i32 @k() readnone
-; CHECK: Function Attrs
-; CHECK-NOT: norecurse
define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
+; CHECK: Function Attrs: argmemonly nosync nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@intrinsic
; CHECK-SAME: (i8* nocapture writeonly [[DEST:%.*]], i8* nocapture readonly [[SRC:%.*]], i32 [[LEN:%.*]])
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly [[DEST]], i8* noalias nocapture readonly [[SRC]], i32 [[LEN]], i1 false)
@@ -77,20 +83,22 @@ define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
; CHECK-NEXT: declare void @llvm.memcpy.p0i8.p0i8.i32
declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
-; IS__TUNIT____: Function Attrs
-; IS__TUNIT____-SAME: nosync readnone
-; IS__CGSSA____: Function Attrs
-; IS__CGSSA____-SAME: norecurse nosync readnone
define internal i32 @called_by_norecurse() {
-; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse()
-; CHECK-NEXT: [[A:%.*]] = call i32 @k()
-; CHECK-NEXT: ret i32 undef
+; IS__TUNIT____: Function Attrs: nosync readnone
+; IS__TUNIT____-LABEL: define {{[^@]+}}@called_by_norecurse()
+; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @k()
+; IS__TUNIT____-NEXT: ret i32 undef
+;
+; IS__CGSCC____: Function Attrs: norecurse nosync readnone
+; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_norecurse()
+; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @k()
+; IS__CGSCC____-NEXT: ret i32 undef
;
%a = call i32 @k()
ret i32 %a
}
-; CHECK: Function Attrs
define void @m() norecurse {
+; CHECK: Function Attrs: norecurse nosync readnone
; CHECK-LABEL: define {{[^@]+}}@m()
; CHECK-NEXT: [[A:%.*]] = call i32 @called_by_norecurse()
; CHECK-NEXT: ret void
@@ -99,10 +107,8 @@ define void @m() norecurse {
ret void
}
-; CHECK: Function Attrs
-; FIXME: norecurse missing
-; CHECK-SAME: nosync readnone
define internal i32 @called_by_norecurse_indirectly() {
+; CHECK: Function Attrs: nosync readnone
; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly()
; CHECK-NEXT: [[A:%.*]] = call i32 @k()
; CHECK-NEXT: ret i32 [[A]]
@@ -110,19 +116,22 @@ define internal i32 @called_by_norecurse_indirectly() {
%a = call i32 @k()
ret i32 %a
}
-; IS__TUNIT____: Function Attrs
-; IS__TUNIT____-SAME: nosync readnone
-; IS__CGSSA____: Function Attrs
-; IS__CGSSA____-SAME: norecurse nosync readnone
define internal i32 @o() {
-; CHECK-LABEL: define {{[^@]+}}@o()
-; CHECK-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()
-; CHECK-NEXT: ret i32 [[A]]
+; IS__TUNIT____: Function Attrs: nosync readnone
+; IS__TUNIT____-LABEL: define {{[^@]+}}@o()
+; IS__TUNIT____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()
+; IS__TUNIT____-NEXT: ret i32 [[A]]
+;
+; IS__CGSCC____: Function Attrs: norecurse nosync readnone
+; IS__CGSCC____-LABEL: define {{[^@]+}}@o()
+; IS__CGSCC____-NEXT: [[A:%.*]] = call i32 @called_by_norecurse_indirectly()
+; IS__CGSCC____-NEXT: ret i32 [[A]]
;
%a = call i32 @called_by_norecurse_indirectly()
ret i32 %a
}
define i32 @p() norecurse {
+; CHECK: Function Attrs: norecurse nosync readnone
; CHECK-LABEL: define {{[^@]+}}@p()
; CHECK-NEXT: [[A:%.*]] = call i32 @o()
; CHECK-NEXT: ret i32 [[A]]
@@ -131,9 +140,8 @@ define i32 @p() norecurse {
ret i32 %a
}
-; NOT_CGSCC_NPM: Function Attrs: nofree nosync nounwind
-; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
define void @f(i32 %x) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
; IS__TUNIT____-LABEL: define {{[^@]+}}@f
; IS__TUNIT____-SAME: (i32 [[X:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -148,18 +156,33 @@ define void @f(i32 %x) {
; IS__TUNIT____: if.end:
; IS__TUNIT____-NEXT: ret void
;
-; IS__CGSCC____-LABEL: define {{[^@]+}}@f
-; IS__CGSCC____-SAME: (i32 [[X:%.*]])
-; IS__CGSCC____-NEXT: entry:
-; IS__CGSCC____-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
-; IS__CGSCC____-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
-; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
-; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
-; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; IS__CGSCC____: if.then:
-; IS__CGSCC____-NEXT: br label [[IF_END]]
-; IS__CGSCC____: if.end:
-; IS__CGSCC____-NEXT: ret void
+; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
+; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
+; IS__CGSCC_OPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
+; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
+; IS__CGSCC_OPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
+; IS__CGSCC_OPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC_OPM: if.then:
+; IS__CGSCC_OPM-NEXT: br label [[IF_END]]
+; IS__CGSCC_OPM: if.end:
+; IS__CGSCC_OPM-NEXT: ret void
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
+; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
+; IS__CGSCC_NPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
+; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
+; IS__CGSCC_NPM-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
+; IS__CGSCC_NPM-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC_NPM: if.then:
+; IS__CGSCC_NPM-NEXT: br label [[IF_END]]
+; IS__CGSCC_NPM: if.end:
+; IS__CGSCC_NPM-NEXT: ret void
;
entry:
%x.addr = alloca i32, align 4
@@ -177,21 +200,27 @@ if.end:
}
define void @g() norecurse {
-; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@g()
-; NOT_CGSCC_OPM-NEXT: entry:
-; NOT_CGSCC_OPM-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone
+; IS__TUNIT____-LABEL: define {{[^@]+}}@g()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g()
; IS__CGSCC_OPM-NEXT: entry:
; IS__CGSCC_OPM-NEXT: call void @f(i32 0)
; IS__CGSCC_OPM-NEXT: ret void
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g()
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: ret void
+;
entry:
call void @f(i32 0)
ret void
}
-; CHECK-NOT: Function Attrs
define linkonce_odr i32 @leaf_redefinable() {
; CHECK-LABEL: define {{[^@]+}}@leaf_redefinable()
; CHECK-NEXT: ret i32 1
@@ -200,7 +229,6 @@ define linkonce_odr i32 @leaf_redefinable() {
}
; Call through a function pointer
-; CHECK-NOT: Function Attrs
define i32 @eval_func1(i32 (i32)* , i32) local_unnamed_addr {
; CHECK-LABEL: define {{[^@]+}}@eval_func1
; CHECK-SAME: (i32 (i32)* nocapture nofree nonnull [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr
@@ -211,8 +239,8 @@ define i32 @eval_func1(i32 (i32)* , i32) local_unnamed_addr {
ret i32 %3
}
-; CHECK: Function Attrs: null_pointer_is_valid
define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr null_pointer_is_valid{
+; CHECK: Function Attrs: null_pointer_is_valid
; CHECK-LABEL: define {{[^@]+}}@eval_func2
; CHECK-SAME: (i32 (i32)* nocapture nofree [[TMP0:%.*]], i32 [[TMP1:%.*]]) local_unnamed_addr
; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]])
@@ -223,13 +251,19 @@ define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr null_pointer_is_vali
}
; Call an unknown function in a dead block.
-; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
declare void @unknown()
define i32 @call_unknown_in_dead_block() local_unnamed_addr {
-; CHECK-LABEL: define {{[^@]+}}@call_unknown_in_dead_block() local_unnamed_addr
-; CHECK-NEXT: ret i32 0
-; CHECK: Dead:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@call_unknown_in_dead_block() local_unnamed_addr
+; IS__TUNIT____-NEXT: ret i32 0
+; IS__TUNIT____: Dead:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@call_unknown_in_dead_block() local_unnamed_addr
+; IS__CGSCC____-NEXT: ret i32 0
+; IS__CGSCC____: Dead:
+; IS__CGSCC____-NEXT: unreachable
;
ret i32 0
Dead:
diff --git a/llvm/test/Transforms/Attributor/noreturn.ll b/llvm/test/Transforms/Attributor/noreturn.ll
index 0520a52a47b9..ea0e2bd6103f 100644
--- a/llvm/test/Transforms/Attributor/noreturn.ll
+++ b/llvm/test/Transforms/Attributor/noreturn.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -16,12 +16,16 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; return srec0();
; }
;
-; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
define void @srec0() #0 {
-; CHECK-LABEL: define {{[^@]+}}@srec0()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@srec0()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@srec0()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
call void @srec0()
@@ -35,15 +39,22 @@ entry:
; return srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(a))))))))))))))));
; }
;
-; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
define i32 @srec16(i32 %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@srec16
-; CHECK-SAME: (i32 [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
-; CHECK: exit:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@srec16
+; IS__TUNIT____-SAME: (i32 [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: exit:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@srec16
+; IS__CGSCC____-SAME: (i32 [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: exit:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
%call = call i32 @srec16(i32 %a)
@@ -75,15 +86,22 @@ exit:
; while (1);
; }
;
+define i32 @endless_loop(i32 %a) #0 {
; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
+; IS__TUNIT____-LABEL: define {{[^@]+}}@endless_loop
+; IS__TUNIT____-SAME: (i32 [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__TUNIT____: while.body:
+; IS__TUNIT____-NEXT: br label [[WHILE_BODY]]
+;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
-define i32 @endless_loop(i32 %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@endless_loop
-; CHECK-SAME: (i32 [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
-; CHECK: while.body:
-; CHECK-NEXT: br label [[WHILE_BODY]]
+; IS__CGSCC____-LABEL: define {{[^@]+}}@endless_loop
+; IS__CGSCC____-SAME: (i32 [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__CGSCC____: while.body:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY]]
;
entry:
br label %while.body
@@ -101,17 +119,26 @@ while.body: ; preds = %entry, %while.body
; }
;
; FIXME: no-return missing (D65243 should fix this)
+define i32 @dead_return(i32 %a) #0 {
; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
+; IS__TUNIT____-LABEL: define {{[^@]+}}@dead_return
+; IS__TUNIT____-SAME: (i32 [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__TUNIT____: while.body:
+; IS__TUNIT____-NEXT: br label [[WHILE_BODY]]
+; IS__TUNIT____: return:
+; IS__TUNIT____-NEXT: unreachable
+;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
-define i32 @dead_return(i32 %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@dead_return
-; CHECK-SAME: (i32 [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
-; CHECK: while.body:
-; CHECK-NEXT: br label [[WHILE_BODY]]
-; CHECK: return:
-; CHECK-NEXT: unreachable
+; IS__CGSCC____-LABEL: define {{[^@]+}}@dead_return
+; IS__CGSCC____-SAME: (i32 [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__CGSCC____: while.body:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY]]
+; IS__CGSCC____: return:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
br label %while.body
@@ -130,20 +157,32 @@ return: ; No predecessors!
; return a == 0 ? endless_loop(a) : srec16(a);
; }
;
-; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
define i32 @multiple_noreturn_calls(i32 %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@multiple_noreturn_calls
-; CHECK-SAME: (i32 [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
-; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
-; CHECK: cond.true:
-; CHECK-NEXT: unreachable
-; CHECK: cond.false:
-; CHECK-NEXT: unreachable
-; CHECK: cond.end:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@multiple_noreturn_calls
+; IS__TUNIT____-SAME: (i32 [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; IS__TUNIT____: cond.true:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: cond.false:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: cond.end:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@multiple_noreturn_calls
+; IS__CGSCC____-SAME: (i32 [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[A]], 0
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]]
+; IS__CGSCC____: cond.true:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: cond.false:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: cond.end:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
%cmp = icmp eq i32 %a, 0
@@ -166,14 +205,20 @@ cond.end: ; preds = %cond.false, %cond.t
; 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.
+define i32 @endless_loop_but_willreturn() willreturn {
; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@endless_loop_but_willreturn()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__TUNIT____: while.body:
+; IS__TUNIT____-NEXT: br label [[WHILE_BODY]]
+;
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
-define i32 @endless_loop_but_willreturn() willreturn {
-; CHECK-LABEL: define {{[^@]+}}@endless_loop_but_willreturn()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
-; CHECK: while.body:
-; CHECK-NEXT: br label [[WHILE_BODY]]
+; IS__CGSCC____-LABEL: define {{[^@]+}}@endless_loop_but_willreturn()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__CGSCC____: while.body:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY]]
;
entry:
br label %while.body
@@ -183,12 +228,16 @@ while.body: ; preds = %entry, %while.body
}
; TEST 6b: willreturn means *not* no-return or UB
+define i32 @UB_and_willreturn() willreturn {
; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@UB_and_willreturn()
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+;
; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
-define i32 @UB_and_willreturn() willreturn {
-; CHECK-LABEL: define {{[^@]+}}@UB_and_willreturn()
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; IS__CGSCC____-LABEL: define {{[^@]+}}@UB_and_willreturn()
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
unreachable
diff --git a/llvm/test/Transforms/Attributor/noreturn_async.ll b/llvm/test/Transforms/Attributor/noreturn_async.ll
index c632a4e6d118..4c0fc203eb09 100644
--- a/llvm/test/Transforms/Attributor/noreturn_async.ll
+++ b/llvm/test/Transforms/Attributor/noreturn_async.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s
;
; This file is the same as noreturn_sync.ll but with a personality which
diff --git a/llvm/test/Transforms/Attributor/noreturn_sync.ll b/llvm/test/Transforms/Attributor/noreturn_sync.ll
index 055a324e02ba..22b675427cf0 100644
--- a/llvm/test/Transforms/Attributor/noreturn_sync.ll
+++ b/llvm/test/Transforms/Attributor/noreturn_sync.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s
;
; This file is the same as noreturn_async.ll but with a personality which
@@ -41,7 +42,7 @@ define dso_local i32 @"?catchoverflow@@YAHXZ"() personality i8* bitcast (i32 (.
entry:
%retval = alloca i32, align 4
%__exception_code = alloca i32, align 4
- invoke void @"?overflow@@YAXXZ"()
+ invoke void @"?overflow@@YAXXZ"()
to label %invoke.cont unwind label %catch.dispatch
; CHECK: call void @"?overflow@@YAXXZ"()
; CHECK-NEXT: unreachable
@@ -98,9 +99,9 @@ define dso_local i32 @"?catchoverflow@@YAHXZ_may_throw"() personality i8* bitca
entry:
%retval = alloca i32, align 4
%__exception_code = alloca i32, align 4
-; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"()
+; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"()
; CHECK: to label %invoke.cont unwind label %catch.dispatch
- invoke void @"?overflow@@YAXXZ_may_throw"()
+ invoke void @"?overflow@@YAXXZ_may_throw"()
to label %invoke.cont unwind label %catch.dispatch
invoke.cont: ; preds = %entry
diff --git a/llvm/test/Transforms/Attributor/nosync.ll b/llvm/test/Transforms/Attributor/nosync.ll
index fc01770ee47e..33614b636f53 100644
--- a/llvm/test/Transforms/Attributor/nosync.ll
+++ b/llvm/test/Transforms/Attributor/nosync.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -28,14 +28,20 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
%struct.RT = type { i8, [10 x [20 x i32]], i8 }
%struct.ST = type { i32, double, %struct.RT }
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind optsize readnone ssp uwtable
define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (%struct.ST* nofree readnone "no-capture-maybe-returned" [[S:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
-; CHECK-NEXT: ret i32* [[ARRAYIDX]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
+; IS__TUNIT____-SAME: (%struct.ST* nofree readnone "no-capture-maybe-returned" [[S:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
+; IS__TUNIT____-NEXT: ret i32* [[ARRAYIDX]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind optsize readnone ssp uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
+; IS__CGSCC____-SAME: (%struct.ST* nofree readnone "no-capture-maybe-returned" [[S:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S]], i64 1, i32 2, i32 1, i64 5, i64 13
+; IS__CGSCC____-NEXT: ret i32* [[ARRAYIDX]]
;
entry:
%arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13
@@ -49,9 +55,8 @@ entry:
; return n;
; }
-; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind uwtable
define i32 @load_monotonic(i32* nocapture readonly %0) norecurse nounwind uwtable {
+; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@load_monotonic
; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[TMP0:%.*]])
; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, i32* [[TMP0]] monotonic, align 4
@@ -68,9 +73,8 @@ define i32 @load_monotonic(i32* nocapture readonly %0) norecurse nounwind uwtabl
; atomic_load_explicit(num, memory_order_relaxed);
; }
-; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nosync nounwind uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind uwtable
define void @store_monotonic(i32* nocapture %0) norecurse nounwind uwtable {
+; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@store_monotonic
; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]])
; CHECK-NEXT: store atomic i32 10, i32* [[TMP0]] monotonic, align 4
@@ -87,10 +91,8 @@ define void @store_monotonic(i32* nocapture %0) norecurse nounwind uwtable {
; return n;
; }
-; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; CHECK-NOT: nosync
define i32 @load_acquire(i32* nocapture readonly %0) norecurse nounwind uwtable {
+; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@load_acquire
; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[TMP0:%.*]])
; CHECK-NEXT: [[TMP2:%.*]] = load atomic i32, i32* [[TMP0]] acquire, align 4
@@ -106,10 +108,8 @@ define i32 @load_acquire(i32* nocapture readonly %0) norecurse nounwind uwtable
; atomic_store_explicit(num, 10, memory_order_release);
; }
-; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; CHECK-NOT: nosync
define void @load_release(i32* nocapture %0) norecurse nounwind uwtable {
+; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@load_release
; CHECK-SAME: (i32* nocapture nofree writeonly align 4 [[TMP0:%.*]])
; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0]] release, align 4
@@ -121,10 +121,8 @@ define void @load_release(i32* nocapture %0) norecurse nounwind uwtable {
; TEST 6 - negative volatile, relaxed atomic
-; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; CHECK-NOT: nosync
define void @load_volatile_release(i32* nocapture %0) norecurse nounwind uwtable {
+; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@load_volatile_release
; CHECK-SAME: (i32* nocapture nofree writeonly align 4 [[TMP0:%.*]])
; CHECK-NEXT: store atomic volatile i32 10, i32* [[TMP0]] release, align 4
@@ -140,10 +138,8 @@ define void @load_volatile_release(i32* nocapture %0) norecurse nounwind uwtable
; *num = 14;
; }
-; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; CHECK-NOT: nosync
define void @volatile_store(i32* %0) norecurse nounwind uwtable {
+; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@volatile_store
; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]])
; CHECK-NEXT: store volatile i32 14, i32* [[TMP0]], align 4
@@ -160,10 +156,8 @@ define void @volatile_store(i32* %0) norecurse nounwind uwtable {
; return n;
; }
-; IS__TUNIT____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind uwtable
-; CHECK-NOT: nosync
define i32 @volatile_load(i32* %0) norecurse nounwind uwtable {
+; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@volatile_load
; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]])
; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4
@@ -179,9 +173,8 @@ define i32 @volatile_load(i32* %0) norecurse nounwind uwtable {
; CHECK-NEXT: declare void @nosync_function()
declare void @nosync_function() noinline nounwind uwtable nosync
-; IS__TUNIT____: Function Attrs: noinline nosync nounwind uwtable
-; IS__CGSCC____: Function Attrs: noinline nosync nounwind uwtable
define void @call_nosync_function() nounwind uwtable noinline {
+; CHECK: Function Attrs: noinline nosync nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@call_nosync_function()
; CHECK-NEXT: tail call void @nosync_function()
; CHECK-NEXT: ret void
@@ -196,10 +189,8 @@ define void @call_nosync_function() nounwind uwtable noinline {
; CHECK-NEXT: declare void @might_sync()
declare void @might_sync() noinline nounwind uwtable
-; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
-; IS__CGSCC____: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: nosync
define void @call_might_sync() nounwind uwtable noinline {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@call_might_sync()
; CHECK-NEXT: tail call void @might_sync()
; CHECK-NEXT: ret void
@@ -211,26 +202,32 @@ define void @call_might_sync() nounwind uwtable noinline {
; TEST 11 - positive, should deduce nosync
; volatile operation in same scc but dead. Call volatile_load defined in TEST 8.
-; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
define i32 @scc1(i32* %0) noinline nounwind uwtable {
-; CHECK-LABEL: define {{[^@]+}}@scc1
-; CHECK-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]])
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@scc1
+; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]])
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc1
+; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]])
+; IS__CGSCC_NPM-NEXT: unreachable
;
tail call void @scc2(i32* %0);
%val = tail call i32 @volatile_load(i32* %0);
ret i32 %val;
}
-; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
define void @scc2(i32* %0) noinline nounwind uwtable {
-; CHECK-LABEL: define {{[^@]+}}@scc2
-; CHECK-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]])
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@scc2
+; NOT_CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]])
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc2
+; IS__CGSCC_NPM-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]])
+; IS__CGSCC_NPM-NEXT: unreachable
;
tail call i32 @scc1(i32* %0);
ret void;
@@ -255,15 +252,24 @@ define void @scc2(i32* %0) noinline nounwind uwtable {
%"struct.std::atomic" = type { %"struct.std::__atomic_base" }
%"struct.std::__atomic_base" = type { i8 }
-; CHECK-NOT: nosync
define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
-; CHECK-LABEL: define {{[^@]+}}@foo1
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]])
-; CHECK-NEXT: store i32 100, i32* [[TMP0]], align 4
-; CHECK-NEXT: fence release
-; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
-; CHECK-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo1
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]])
+; IS__TUNIT____-NEXT: store i32 100, i32* [[TMP0]], align 4
+; IS__TUNIT____-NEXT: fence release
+; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
+; IS__TUNIT____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]])
+; IS__CGSCC____-NEXT: store i32 100, i32* [[TMP0]], align 4
+; IS__CGSCC____-NEXT: fence release
+; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
+; IS__CGSCC____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
+; IS__CGSCC____-NEXT: ret void
;
store i32 100, i32* %0, align 4
fence release
@@ -272,20 +278,34 @@ define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
ret void
}
-; CHECK-NOT: nosync
define void @bar(i32* %0, %"struct.std::atomic"* %1) {
-; CHECK-LABEL: define {{[^@]+}}@bar
-; CHECK-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]])
-; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
-; CHECK-NEXT: br label [[TMP4:%.*]]
-; CHECK: 4:
-; CHECK-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
-; CHECK-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
-; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
-; CHECK-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
-; CHECK: 8:
-; CHECK-NEXT: fence acquire
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nounwind
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bar
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]])
+; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
+; IS__TUNIT____-NEXT: br label [[TMP4:%.*]]
+; IS__TUNIT____: 4:
+; IS__TUNIT____-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
+; IS__TUNIT____-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+; IS__TUNIT____-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
+; IS__TUNIT____-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
+; IS__TUNIT____: 8:
+; IS__TUNIT____-NEXT: fence acquire
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bar
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]])
+; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
+; IS__CGSCC____-NEXT: br label [[TMP4:%.*]]
+; IS__CGSCC____: 4:
+; IS__CGSCC____-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
+; IS__CGSCC____-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+; IS__CGSCC____-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
+; IS__CGSCC____-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
+; IS__CGSCC____: 8:
+; IS__CGSCC____-NEXT: fence acquire
+; IS__CGSCC____-NEXT: ret void
;
%3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
br label %4
@@ -302,16 +322,24 @@ define void @bar(i32* %0, %"struct.std::atomic"* %1) {
}
; TEST 13 - Fence syncscope("singlethread") seq_cst
+define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo1_singlethread
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]])
+; IS__TUNIT____-NEXT: store i32 100, i32* [[TMP0]], align 4
+; IS__TUNIT____-NEXT: fence syncscope("singlethread") release
+; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
+; IS__TUNIT____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
+; IS__TUNIT____-NEXT: ret void
+;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn
-define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
-; CHECK-LABEL: define {{[^@]+}}@foo1_singlethread
-; CHECK-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]])
-; CHECK-NEXT: store i32 100, i32* [[TMP0]], align 4
-; CHECK-NEXT: fence syncscope("singlethread") release
-; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
-; CHECK-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
-; CHECK-NEXT: ret void
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1_singlethread
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) [[TMP1:%.*]])
+; IS__CGSCC____-NEXT: store i32 100, i32* [[TMP0]], align 4
+; IS__CGSCC____-NEXT: fence syncscope("singlethread") release
+; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
+; IS__CGSCC____-NEXT: store atomic i8 1, i8* [[TMP3]] monotonic, align 1
+; IS__CGSCC____-NEXT: ret void
;
store i32 100, i32* %0, align 4
fence syncscope("singlethread") release
@@ -320,21 +348,34 @@ define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
ret void
}
+define void @bar_singlethread(i32* %0, %"struct.std::atomic"* %1) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bar_singlethread
+; IS__TUNIT____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]])
+; IS__TUNIT____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
+; IS__TUNIT____-NEXT: br label [[TMP4:%.*]]
+; IS__TUNIT____: 4:
+; IS__TUNIT____-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
+; IS__TUNIT____-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+; IS__TUNIT____-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
+; IS__TUNIT____-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
+; IS__TUNIT____: 8:
+; IS__TUNIT____-NEXT: fence syncscope("singlethread") acquire
+; IS__TUNIT____-NEXT: ret void
+;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind
-define void @bar_singlethread(i32* %0, %"struct.std::atomic"* %1) {
-; CHECK-LABEL: define {{[^@]+}}@bar_singlethread
-; CHECK-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]])
-; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
-; CHECK-NEXT: br label [[TMP4:%.*]]
-; CHECK: 4:
-; CHECK-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
-; CHECK-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
-; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
-; CHECK-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
-; CHECK: 8:
-; CHECK-NEXT: fence syncscope("singlethread") acquire
-; CHECK-NEXT: ret void
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bar_singlethread
+; IS__CGSCC____-SAME: (i32* nocapture nofree readnone [[TMP0:%.*]], %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) [[TMP1:%.*]])
+; IS__CGSCC____-NEXT: [[TMP3:%.*]] = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* [[TMP1]], i64 0, i32 0, i32 0
+; IS__CGSCC____-NEXT: br label [[TMP4:%.*]]
+; IS__CGSCC____: 4:
+; IS__CGSCC____-NEXT: [[TMP5:%.*]] = load atomic i8, i8* [[TMP3]] monotonic, align 1
+; IS__CGSCC____-NEXT: [[TMP6:%.*]] = and i8 [[TMP5]], 1
+; IS__CGSCC____-NEXT: [[TMP7:%.*]] = icmp eq i8 [[TMP6]], 0
+; IS__CGSCC____-NEXT: br i1 [[TMP7]], label [[TMP4]], label [[TMP8:%.*]]
+; IS__CGSCC____: 8:
+; IS__CGSCC____-NEXT: fence syncscope("singlethread") acquire
+; IS__CGSCC____-NEXT: ret void
;
%3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
br label %4
@@ -357,10 +398,8 @@ declare void @llvm.memset(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
; It is odd to add nocapture but a result of the llvm.memcpy nocapture.
;
-; IS__TUNIT____: Function Attrs: argmemonly nounwind
-; IS__CGSCC____: Function Attrs: argmemonly nounwind
-; CHECK-NOT: nosync
define i32 @memcpy_volatile(i8* %ptr1, i8* %ptr2) {
+; CHECK: Function Attrs: argmemonly nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@memcpy_volatile
; CHECK-SAME: (i8* nocapture writeonly [[PTR1:%.*]], i8* nocapture readonly [[PTR2:%.*]])
; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias nocapture writeonly [[PTR1]], i8* noalias nocapture readonly [[PTR2]], i32 8, i1 true)
@@ -374,9 +413,8 @@ define i32 @memcpy_volatile(i8* %ptr1, i8* %ptr2) {
; It is odd to add nocapture but a result of the llvm.memset nocapture.
;
-; IS__TUNIT____: Function Attrs: argmemonly nosync
-; IS__CGSCC____: Function Attrs: argmemonly nosync
define i32 @memset_non_volatile(i8* %ptr1, i8 %val) {
+; CHECK: Function Attrs: argmemonly nosync nounwind willreturn writeonly
; CHECK-LABEL: define {{[^@]+}}@memset_non_volatile
; CHECK-SAME: (i8* nocapture writeonly [[PTR1:%.*]], i8 [[VAL:%.*]])
; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nocapture writeonly [[PTR1]], i8 [[VAL]], i32 8, i1 false)
@@ -402,6 +440,7 @@ declare void @readnone_test() convergent readnone
; TEST 17 - negative. Convergent
define void @convergent_readnone(){
+; CHECK: Function Attrs: readnone
; CHECK-LABEL: define {{[^@]+}}@convergent_readnone()
; CHECK-NEXT: call void @readnone_test()
; CHECK-NEXT: ret void
@@ -417,10 +456,8 @@ declare void @llvm.x86.sse2.clflush(i8*)
; TEST 18 - negative. Synchronizing intrinsic
-; IS__TUNIT____: Function Attrs: nounwind
-; IS__CGSCC____: Function Attrs: nounwind
-; CHECK-NOT: nosync
define void @i_totally_sync() {
+; CHECK: Function Attrs: nounwind
; CHECK-LABEL: define {{[^@]+}}@i_totally_sync()
; CHECK-NEXT: tail call void @llvm.x86.sse2.clflush(i8* nonnull align 4 dereferenceable(4) bitcast (i32* @a to i8*))
; CHECK-NEXT: ret void
@@ -433,20 +470,23 @@ declare float @llvm.cos(float %val) readnone
; TEST 19 - positive, readnone & non-convergent intrinsic.
+define i32 @cos_test(float %x) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cos_test
+; IS__TUNIT____-SAME: (float [[X:%.*]])
+; IS__TUNIT____-NEXT: ret i32 4
+;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
-define i32 @cos_test(float %x) {
-; CHECK-LABEL: define {{[^@]+}}@cos_test
-; CHECK-SAME: (float [[X:%.*]])
-; CHECK-NEXT: ret i32 4
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cos_test
+; IS__CGSCC____-SAME: (float [[X:%.*]])
+; IS__CGSCC____-NEXT: ret i32 4
;
call float @llvm.cos(float %x)
ret i32 4
}
-; IS__TUNIT____: Function Attrs: nosync nounwind
-; IS__CGSCC____: Function Attrs: nosync nounwind
define float @cos_test2(float %x) {
+; CHECK: Function Attrs: nosync nounwind readnone willreturn
; CHECK-LABEL: define {{[^@]+}}@cos_test2
; CHECK-SAME: (float [[X:%.*]])
; CHECK-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]])
diff --git a/llvm/test/Transforms/Attributor/nounwind.ll b/llvm/test/Transforms/Attributor/nounwind.ll
index 7f5287a74d74..3eb525a015e7 100644
--- a/llvm/test/Transforms/Attributor/nounwind.ll
+++ b/llvm/test/Transforms/Attributor/nounwind.ll
@@ -1,26 +1,31 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
; TEST 1
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind
-; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind
define i32 @foo1() {
-; CHECK-LABEL: define {{[^@]+}}@foo1()
-; CHECK-NEXT: ret i32 1
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo1()
+; IS__TUNIT____-NEXT: ret i32 1
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo1()
+; IS__CGSCC____-NEXT: ret i32 1
;
ret i32 1
}
; TEST 2
-; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind
-; IS__CGSCC_OPM: Function Attrs: nofree noreturn nosync nounwind
-; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind
define i32 @scc1_foo() {
-; CHECK-LABEL: define {{[^@]+}}@scc1_foo()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@scc1_foo()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc1_foo()
+; IS__CGSCC_NPM-NEXT: unreachable
;
%1 = call i32 @scc1_bar()
ret i32 1
@@ -28,12 +33,14 @@ define i32 @scc1_foo() {
; TEST 3
-; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind
-; IS__CGSCC_OPM: Function Attrs: nofree noreturn nosync nounwind
-; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind
define i32 @scc1_bar() {
-; CHECK-LABEL: define {{[^@]+}}@scc1_bar()
-; CHECK-NEXT: unreachable
+; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@scc1_bar()
+; NOT_CGSCC_NPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@scc1_bar()
+; IS__CGSCC_NPM-NEXT: unreachable
;
%1 = call i32 @scc1_foo()
ret i32 1
diff --git a/llvm/test/Transforms/Attributor/range.ll b/llvm/test/Transforms/Attributor/range.ll
index f105bb3fad0e..8f6ccf4c1e5d 100644
--- a/llvm/test/Transforms/Attributor/range.ll
+++ b/llvm/test/Transforms/Attributor/range.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=17 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -7,26 +7,36 @@
; FIXME: CGSCC is not looking at callees and calleers even though it could be allowed.
define i32 @test0(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test0
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
-; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, !range !0
-; CHECK-NEXT: ret i32 [[A]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test0
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__TUNIT____-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, !range !0
+; IS__TUNIT____-NEXT: ret i32 [[A]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test0
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__CGSCC____-NEXT: [[A:%.*]] = load i32, i32* [[P]], align 4, !range !0
+; IS__CGSCC____-NEXT: ret i32 [[A]]
;
%a = load i32, i32* %p, !range !0
ret i32 %a
}
define i32 @test0-range-check(i32* %p) {
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test0-range-check
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_OPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !0
; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test0-range-check
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_NPM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !0
; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-range-check
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
@@ -296,12 +306,21 @@ define void @test0-icmp-check(i32* %p){
ret void
}
define i32 @test1(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test1
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
-; CHECK-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, !range !1
-; CHECK-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
-; CHECK-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
-; CHECK-NEXT: ret i32 [[MUL_10_THEN_200_1091]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test1
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__TUNIT____-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, !range !1
+; IS__TUNIT____-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
+; IS__TUNIT____-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
+; IS__TUNIT____-NEXT: ret i32 [[MUL_10_THEN_200_1091]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__CGSCC____-NEXT: [[LOAD_10_100:%.*]] = load i32, i32* [[P]], align 4, !range !1
+; IS__CGSCC____-NEXT: [[ADD_10_THEN_20_110:%.*]] = add i32 [[LOAD_10_100]], 10
+; IS__CGSCC____-NEXT: [[MUL_10_THEN_200_1091:%.*]] = mul i32 [[ADD_10_THEN_20_110]], 10
+; IS__CGSCC____-NEXT: ret i32 [[MUL_10_THEN_200_1091]]
;
%load-10-100 = load i32, i32* %p, !range !1
%add-10-then-20-110 = add i32 %load-10-100, 10
@@ -311,18 +330,21 @@ define i32 @test1(i32* %p) {
define i1 @test1-check(i32* %p) {
;
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test1-check
; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_OPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #3, !range !2
; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
; IS__TUNIT_OPM-NEXT: ret i1 [[CMP]]
;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test1-check
; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT_NPM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree readonly align 4 [[P]]) #2, !range !2
; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
; IS__TUNIT_NPM-NEXT: ret i1 [[CMP]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test1-check
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
@@ -347,13 +369,23 @@ define i1 @test1-check(i32* %p) {
; }
define i32 @test2(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test2
-; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 4
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
-; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3
-; CHECK-NEXT: ret i32 [[COND]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 4
+; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
+; IS__TUNIT____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3
+; IS__TUNIT____-NEXT: ret i32 [[COND]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[P]], align 4
+; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0
+; IS__CGSCC____-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 4, i32 3
+; IS__CGSCC____-NEXT: ret i32 [[COND]]
;
entry:
%0 = load i32, i32* %p, align 4
@@ -363,6 +395,7 @@ entry:
}
define i32 @test2_check(i32* %p) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind readonly willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_check
; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -374,6 +407,7 @@ define i32 @test2_check(i32* %p) {
; IS__TUNIT____: return:
; IS__TUNIT____-NEXT: ret i32 2
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind readonly willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_check
; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -432,23 +466,43 @@ return: ; preds = %if.end, %if.then
declare dso_local void @unkown()
define internal i32 @r1(i32) local_unnamed_addr {
-; IS________OPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
-; IS________OPM-NEXT: br label [[TMP4:%.*]]
-; IS________OPM: 1:
-; IS________OPM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
-; IS________OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
-; IS________OPM: 3:
-; IS________OPM-NEXT: ret i32 20
-; IS________OPM: f:
-; IS________OPM-NEXT: ret i32 10
-; IS________OPM: 4:
-; IS________OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
-; IS________OPM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
-; IS________OPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
-; IS________OPM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
-; IS________OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
-; IS________OPM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
-;
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
+; IS__TUNIT_OPM-NEXT: br label [[TMP4:%.*]]
+; IS__TUNIT_OPM: 1:
+; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
+; IS__TUNIT_OPM: 3:
+; IS__TUNIT_OPM-NEXT: ret i32 20
+; IS__TUNIT_OPM: f:
+; IS__TUNIT_OPM-NEXT: ret i32 10
+; IS__TUNIT_OPM: 4:
+; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
+; IS__TUNIT_OPM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
+; IS__TUNIT_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
+; IS__CGSCC_OPM-NEXT: br label [[TMP4:%.*]]
+; IS__CGSCC_OPM: 1:
+; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
+; IS__CGSCC_OPM: 3:
+; IS__CGSCC_OPM-NEXT: ret i32 20
+; IS__CGSCC_OPM: f:
+; IS__CGSCC_OPM-NEXT: ret i32 10
+; IS__CGSCC_OPM: 4:
+; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [ [[TMP8:%.*]], [[TMP4]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]], [[TMP4]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
+; IS__CGSCC_OPM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
+; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
; IS__CGSCC_NPM-NEXT: br label [[TMP3:%.*]]
; IS__CGSCC_NPM: 1:
@@ -495,13 +549,23 @@ define void @f1(i32){
; IS________OPM: 5:
; IS________OPM-NEXT: ret void
;
-; IS________NPM-LABEL: define {{[^@]+}}@f1
-; IS________NPM-SAME: (i32 [[TMP0:%.*]])
-; IS________NPM-NEXT: br label [[TMP3:%.*]]
-; IS________NPM: 2:
-; IS________NPM-NEXT: unreachable
-; IS________NPM: 3:
-; IS________NPM-NEXT: ret void
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f1
+; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
+; IS__TUNIT_NPM-NEXT: br label [[TMP3:%.*]]
+; IS__TUNIT_NPM: 2:
+; IS__TUNIT_NPM-NEXT: unreachable
+; IS__TUNIT_NPM: 3:
+; IS__TUNIT_NPM-NEXT: ret void
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f1
+; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]])
+; IS__CGSCC_NPM-NEXT: br label [[TMP3:%.*]]
+; IS__CGSCC_NPM: 2:
+; IS__CGSCC_NPM-NEXT: unreachable
+; IS__CGSCC_NPM: 3:
+; IS__CGSCC_NPM-NEXT: ret void
;
%2 = tail call i32 @r1(i32 %0)
%3 = icmp sgt i32 %2, 15
@@ -526,16 +590,29 @@ define void @f1(i32){
; }
; }
define dso_local i32 @test4-f1(i32 %u) {
-; CHECK-LABEL: define {{[^@]+}}@test4-f1
-; CHECK-SAME: (i32 [[U:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: br label [[RETURN]]
-; CHECK: return:
-; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT: ret i32 [[RETVAL_0]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test4-f1
+; IS__TUNIT____-SAME: (i32 [[U:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: br label [[RETURN]]
+; IS__TUNIT____: return:
+; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
+; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-f1
+; IS__CGSCC____-SAME: (i32 [[U:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[RETURN:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: br label [[RETURN]]
+; IS__CGSCC____: return:
+; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[U]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]
+; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
;
; FIXME: RETVAL_0 >= 0
entry:
@@ -552,11 +629,19 @@ return: ; preds = %entry, %if.then
define dso_local i32 @test4-g1(i32 %u) {
-; CHECK-LABEL: define {{[^@]+}}@test4-g1
-; CHECK-SAME: (i32 [[U:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]])
-; CHECK-NEXT: ret i32 [[CALL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test4-g1
+; IS__TUNIT____-SAME: (i32 [[U:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]])
+; IS__TUNIT____-NEXT: ret i32 [[CALL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-g1
+; IS__CGSCC____-SAME: (i32 [[U:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test4-f1(i32 [[U]])
+; IS__CGSCC____-NEXT: ret i32 [[CALL]]
;
; FIXME: %call should have range [0, inf]
@@ -574,19 +659,35 @@ entry:
; }
; }
define dso_local i32 @test4-f2(i32 %u) {
-; CHECK-LABEL: define {{[^@]+}}@test4-f2
-; CHECK-SAME: (i32 [[U:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
-; CHECK-NEXT: br label [[RETURN:%.*]]
-; CHECK: if.else:
-; CHECK-NEXT: br label [[RETURN]]
-; CHECK: return:
-; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
-; CHECK-NEXT: ret i32 [[RETVAL_0]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test4-f2
+; IS__TUNIT____-SAME: (i32 [[U:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
+; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
+; IS__TUNIT____: if.else:
+; IS__TUNIT____-NEXT: br label [[RETURN]]
+; IS__TUNIT____: return:
+; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
+; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-f2
+; IS__CGSCC____-SAME: (i32 [[U:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[U]], -1
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[U]], 1
+; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
+; IS__CGSCC____: if.else:
+; IS__CGSCC____-NEXT: br label [[RETURN]]
+; IS__CGSCC____: return:
+; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[ADD]], [[IF_THEN]] ], [ 1, [[IF_ELSE]] ]
+; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
;
entry:
%cmp = icmp sgt i32 %u, -1
@@ -606,18 +707,27 @@ return: ; preds = %if.else, %if.then
define dso_local i32 @test4-g2(i32 %u) {
-; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@test4-g2
-; NOT_TUNIT_NPM-SAME: (i32 [[U:%.*]])
-; NOT_TUNIT_NPM-NEXT: entry:
-; NOT_TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
-; NOT_TUNIT_NPM-NEXT: ret i32 [[CALL]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test4-g2
+; IS__TUNIT_OPM-SAME: (i32 [[U:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
+; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test4-g2
; IS__TUNIT_NPM-SAME: (i32 [[U:%.*]])
; IS__TUNIT_NPM-NEXT: entry:
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #1, !range !3
; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test4-g2
+; IS__CGSCC____-SAME: (i32 [[U:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
+; IS__CGSCC____-NEXT: ret i32 [[CALL]]
+;
entry:
%call = tail call i32 @test4-f2(i32 %u)
ret i32 %call
@@ -700,30 +810,57 @@ declare dso_local i32 @foo(i32)
; FIXME: All but the return is not needed anymore
define dso_local zeroext i1 @phi(i32 %arg) {
-; CHECK-LABEL: define {{[^@]+}}@phi
-; CHECK-SAME: (i32 [[ARG:%.*]])
-; CHECK-NEXT: bb:
-; CHECK-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
-; CHECK-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
-; CHECK: bb1:
-; CHECK-NEXT: br label [[BB3:%.*]]
-; CHECK: bb2:
-; CHECK-NEXT: br label [[BB3]]
-; CHECK: bb3:
-; CHECK-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
-; CHECK-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
-; CHECK: bb5:
-; CHECK-NEXT: br label [[BB9:%.*]]
-; CHECK: bb7:
-; CHECK-NEXT: br label [[BB9]]
-; CHECK: bb9:
-; CHECK-NEXT: br label [[BB12:%.*]]
-; CHECK: bb11:
-; CHECK-NEXT: unreachable
-; CHECK: bb12:
-; CHECK-NEXT: br label [[BB13:%.*]]
-; CHECK: bb13:
-; CHECK-NEXT: ret i1 false
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@phi
+; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
+; IS__TUNIT____-NEXT: bb:
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
+; IS__TUNIT____-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
+; IS__TUNIT____: bb1:
+; IS__TUNIT____-NEXT: br label [[BB3:%.*]]
+; IS__TUNIT____: bb2:
+; IS__TUNIT____-NEXT: br label [[BB3]]
+; IS__TUNIT____: bb3:
+; IS__TUNIT____-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
+; IS__TUNIT____-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
+; IS__TUNIT____: bb5:
+; IS__TUNIT____-NEXT: br label [[BB9:%.*]]
+; IS__TUNIT____: bb7:
+; IS__TUNIT____-NEXT: br label [[BB9]]
+; IS__TUNIT____: bb9:
+; IS__TUNIT____-NEXT: br label [[BB12:%.*]]
+; IS__TUNIT____: bb11:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: bb12:
+; IS__TUNIT____-NEXT: br label [[BB13:%.*]]
+; IS__TUNIT____: bb13:
+; IS__TUNIT____-NEXT: ret i1 false
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@phi
+; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
+; IS__CGSCC____-NEXT: bb:
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = icmp sgt i32 [[ARG]], 5
+; IS__CGSCC____-NEXT: br i1 [[TMP]], label [[BB1:%.*]], label [[BB2:%.*]]
+; IS__CGSCC____: bb1:
+; IS__CGSCC____-NEXT: br label [[BB3:%.*]]
+; IS__CGSCC____: bb2:
+; IS__CGSCC____-NEXT: br label [[BB3]]
+; IS__CGSCC____: bb3:
+; IS__CGSCC____-NEXT: [[TMP4:%.*]] = icmp sgt i32 [[ARG]], 10
+; IS__CGSCC____-NEXT: br i1 [[TMP4]], label [[BB5:%.*]], label [[BB7:%.*]]
+; IS__CGSCC____: bb5:
+; IS__CGSCC____-NEXT: br label [[BB9:%.*]]
+; IS__CGSCC____: bb7:
+; IS__CGSCC____-NEXT: br label [[BB9]]
+; IS__CGSCC____: bb9:
+; IS__CGSCC____-NEXT: br label [[BB12:%.*]]
+; IS__CGSCC____: bb11:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: bb12:
+; IS__CGSCC____-NEXT: br label [[BB13:%.*]]
+; IS__CGSCC____: bb13:
+; IS__CGSCC____-NEXT: ret i1 false
;
bb:
%tmp = icmp sgt i32 %arg, 5
@@ -765,10 +902,17 @@ bb13: ; preds = %bb12, %bb11
}
define dso_local i1 @select(i32 %a) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@select
-; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i1 false
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@select
+; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i1 false
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@select
+; IS__CGSCC____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i1 false
;
entry:
%cmp = icmp sgt i32 %a, 5
@@ -781,10 +925,17 @@ entry:
}
define dso_local i32 @select_zext(i32 %a) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@select_zext
-; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@select_zext
+; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@select_zext
+; IS__CGSCC____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 0
;
entry:
%cmp = icmp sgt i32 %a, 5
@@ -799,13 +950,23 @@ entry:
; FIXME: We do not look through the ptr casts here.
define dso_local i64 @select_int2ptr_bitcast_ptr2int(i32 %a) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
-; CHECK-SAME: (i32 [[A:%.*]]) local_unnamed_addr
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[I2P:%.*]] = inttoptr i1 false to i1*
-; CHECK-NEXT: [[BC:%.*]] = bitcast i1* [[I2P]] to i32*
-; CHECK-NEXT: [[P2I:%.*]] = ptrtoint i32* [[BC]] to i64
-; CHECK-NEXT: ret i64 [[P2I]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
+; IS__TUNIT____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[I2P:%.*]] = inttoptr i1 false to i1*
+; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i1* [[I2P]] to i32*
+; IS__TUNIT____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[BC]] to i64
+; IS__TUNIT____-NEXT: ret i64 [[P2I]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@select_int2ptr_bitcast_ptr2int
+; IS__CGSCC____-SAME: (i32 [[A:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[I2P:%.*]] = inttoptr i1 false to i1*
+; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i1* [[I2P]] to i32*
+; IS__CGSCC____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[BC]] to i64
+; IS__CGSCC____-NEXT: ret i64 [[P2I]]
;
entry:
%cmp = icmp sgt i32 %a, 5
@@ -823,60 +984,105 @@ entry:
; }
define i1 @f_fcmp(float %a, float %b) {
-; CHECK-LABEL: define {{[^@]+}}@f_fcmp
-; CHECK-SAME: (float [[A:%.*]], float [[B:%.*]])
-; CHECK-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]]
-; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
-; CHECK-NEXT: ret i1 [[S]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@f_fcmp
+; IS__TUNIT____-SAME: (float [[A:%.*]], float [[B:%.*]])
+; IS__TUNIT____-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]]
+; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
+; IS__TUNIT____-NEXT: ret i1 [[S]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@f_fcmp
+; IS__CGSCC____-SAME: (float [[A:%.*]], float [[B:%.*]])
+; IS__CGSCC____-NEXT: [[R:%.*]] = fcmp uge float [[A]], [[B]]
+; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
+; IS__CGSCC____-NEXT: ret i1 [[S]]
;
%r = fcmp uge float %a, %b
%s = select i1 %r, i1 %r, i1 0
ret i1 %s
}
define i1 @d_fcmp(double %a, double %b) {
-; CHECK-LABEL: define {{[^@]+}}@d_fcmp
-; CHECK-SAME: (double [[A:%.*]], double [[B:%.*]])
-; CHECK-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]]
-; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
-; CHECK-NEXT: ret i1 [[S]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@d_fcmp
+; IS__TUNIT____-SAME: (double [[A:%.*]], double [[B:%.*]])
+; IS__TUNIT____-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]]
+; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
+; IS__TUNIT____-NEXT: ret i1 [[S]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@d_fcmp
+; IS__CGSCC____-SAME: (double [[A:%.*]], double [[B:%.*]])
+; IS__CGSCC____-NEXT: [[R:%.*]] = fcmp oeq double [[A]], [[B]]
+; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
+; IS__CGSCC____-NEXT: ret i1 [[S]]
;
%r = fcmp oeq double %a, %b
%s = select i1 %r, i1 %r, i1 0
ret i1 %s
}
define i1 @dp_icmp(double* %a, double* %b) {
-; CHECK-LABEL: define {{[^@]+}}@dp_icmp
-; CHECK-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]])
-; CHECK-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]]
-; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
-; CHECK-NEXT: ret i1 [[S]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@dp_icmp
+; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]])
+; IS__TUNIT____-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]]
+; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
+; IS__TUNIT____-NEXT: ret i1 [[S]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@dp_icmp
+; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]])
+; IS__CGSCC____-NEXT: [[R:%.*]] = icmp sge double* [[A]], [[B]]
+; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
+; IS__CGSCC____-NEXT: ret i1 [[S]]
;
%r = icmp sge double* %a, %b
%s = select i1 %r, i1 %r, i1 0
ret i1 %s
}
define i1 @ip_icmp(i8* %a, i8* %b) {
-; CHECK-LABEL: define {{[^@]+}}@ip_icmp
-; CHECK-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]])
-; CHECK-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]]
-; CHECK-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
-; CHECK-NEXT: ret i1 [[S]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ip_icmp
+; IS__TUNIT____-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]])
+; IS__TUNIT____-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]]
+; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
+; IS__TUNIT____-NEXT: ret i1 [[S]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ip_icmp
+; IS__CGSCC____-SAME: (i8* nofree readnone [[A:%.*]], i8* nofree readnone [[B:%.*]])
+; IS__CGSCC____-NEXT: [[R:%.*]] = icmp ult i8* [[A]], [[B]]
+; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[R]], i1 [[R]], i1 false
+; IS__CGSCC____-NEXT: ret i1 [[S]]
;
%r = icmp ult i8* %a, %b
%s = select i1 %r, i1 %r, i1 0
ret i1 %s
}
define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dpa, double* %dpb, i8* %ipa, i8* %ipb) {
-; CHECK-LABEL: define {{[^@]+}}@fcmp_caller
-; CHECK-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]])
-; CHECK-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]])
-; CHECK-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]])
-; CHECK-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]])
-; CHECK-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]])
-; CHECK-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
-; CHECK-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
-; CHECK-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
-; CHECK-NEXT: ret i1 [[O3]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@fcmp_caller
+; IS__TUNIT____-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]])
+; IS__TUNIT____-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]])
+; IS__TUNIT____-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]])
+; IS__TUNIT____-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]])
+; IS__TUNIT____-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]])
+; IS__TUNIT____-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
+; IS__TUNIT____-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
+; IS__TUNIT____-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
+; IS__TUNIT____-NEXT: ret i1 [[O3]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@fcmp_caller
+; IS__CGSCC____-SAME: (float [[FA:%.*]], float [[FB:%.*]], double [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double* nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree readnone [[IPB:%.*]])
+; IS__CGSCC____-NEXT: [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float [[FB]])
+; IS__CGSCC____-NEXT: [[R2:%.*]] = call i1 @d_fcmp(double [[DA]], double [[DB]])
+; IS__CGSCC____-NEXT: [[R3:%.*]] = call i1 @dp_icmp(double* noalias nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]])
+; IS__CGSCC____-NEXT: [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree readnone [[IPA]], i8* noalias nofree readnone [[IPB]])
+; IS__CGSCC____-NEXT: [[O1:%.*]] = or i1 [[R1]], [[R2]]
+; IS__CGSCC____-NEXT: [[O2:%.*]] = or i1 [[R3]], [[R4]]
+; IS__CGSCC____-NEXT: [[O3:%.*]] = or i1 [[O1]], [[O2]]
+; IS__CGSCC____-NEXT: ret i1 [[O3]]
;
%r1 = call i1 @f_fcmp(float %fa, float %fb)
%r2 = call i1 @d_fcmp(double %da, double %db)
@@ -889,22 +1095,37 @@ define i1 @fcmp_caller(float %fa, float %fb, double %da, double %db, double* %dp
}
define i8 @ret_two() {
-; CHECK-LABEL: define {{[^@]+}}@ret_two()
-; CHECK-NEXT: ret i8 2
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_two()
+; IS__TUNIT____-NEXT: ret i8 2
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_two()
+; IS__CGSCC____-NEXT: ret i8 2
;
ret i8 2
}
define i8 @ret_undef() {
-; CHECK-LABEL: define {{[^@]+}}@ret_undef()
-; CHECK-NEXT: ret i8 undef
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef()
+; IS__TUNIT____-NEXT: ret i8 undef
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_undef()
+; IS__CGSCC____-NEXT: ret i8 undef
;
ret i8 undef
}
; Verify we collapse undef to a value and return something non-undef here.
define i8 @undef_collapse_1() {
-; CHECK-LABEL: define {{[^@]+}}@undef_collapse_1()
-; CHECK-NEXT: ret i8 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_1()
+; IS__TUNIT____-NEXT: ret i8 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_collapse_1()
+; IS__CGSCC____-NEXT: ret i8 0
;
%c = call i8 @ret_undef()
%s = shl i8 %c, 2
@@ -913,8 +1134,13 @@ define i8 @undef_collapse_1() {
; Verify we collapse undef to a value and return something non-undef here.
define i8 @undef_collapse_2() {
-; CHECK-LABEL: define {{[^@]+}}@undef_collapse_2()
-; CHECK-NEXT: ret i8 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_2()
+; IS__TUNIT____-NEXT: ret i8 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_collapse_2()
+; IS__CGSCC____-NEXT: ret i8 0
;
%c = call i8 @ret_two()
%s = shl i8 undef, %c
@@ -923,9 +1149,11 @@ define i8 @undef_collapse_2() {
define i8 @undef_collapse_caller() {
;
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_caller()
; IS__TUNIT____-NEXT: ret i8 0
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@undef_collapse_caller()
; IS__CGSCC____-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1()
; IS__CGSCC____-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2()
@@ -939,20 +1167,29 @@ define i8 @undef_collapse_caller() {
}
define i32 @ret1or2(i1 %c) {
-; CHECK-LABEL: define {{[^@]+}}@ret1or2
-; CHECK-SAME: (i1 [[C:%.*]])
-; CHECK-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2
-; CHECK-NEXT: ret i32 [[S]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret1or2
+; IS__TUNIT____-SAME: (i1 [[C:%.*]])
+; IS__TUNIT____-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2
+; IS__TUNIT____-NEXT: ret i32 [[S]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret1or2
+; IS__CGSCC____-SAME: (i1 [[C:%.*]])
+; IS__CGSCC____-NEXT: [[S:%.*]] = select i1 [[C]], i32 1, i32 2
+; IS__CGSCC____-NEXT: ret i32 [[S]]
;
%s = select i1 %c, i32 1, i32 2
ret i32 %s
}
define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
;
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_range_1
; IS__TUNIT____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
; IS__TUNIT____-NEXT: ret i1 true
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_range_1
; IS__CGSCC____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
; IS__CGSCC____-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
@@ -976,6 +1213,7 @@ define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
define i1 @callee_range_2(i1 %c1, i1 %c2) {
;
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callee_range_2
; IS__TUNIT_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
; IS__TUNIT_OPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #2, !range !4
@@ -986,6 +1224,7 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; IS__TUNIT_OPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
; IS__TUNIT_OPM-NEXT: ret i1 [[F]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee_range_2
; IS__TUNIT_NPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
; IS__TUNIT_NPM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #1, !range !5
@@ -996,6 +1235,7 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
; IS__TUNIT_NPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
; IS__TUNIT_NPM-NEXT: ret i1 [[F]]
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_range_2
; IS__CGSCC____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
; IS__CGSCC____-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
@@ -1017,37 +1257,70 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
define i32 @ret100() {
-; CHECK-LABEL: define {{[^@]+}}@ret100()
-; CHECK-NEXT: ret i32 100
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret100()
+; IS__TUNIT____-NEXT: ret i32 100
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret100()
+; IS__CGSCC____-NEXT: ret i32 100
;
ret i32 100
}
define i1 @ctx_adjustment(i32 %V) {
;
-; IS________OPM-LABEL: define {{[^@]+}}@ctx_adjustment
-; IS________OPM-SAME: (i32 [[V:%.*]])
-; IS________OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
-; IS________OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
-; IS________OPM: if.true:
-; IS________OPM-NEXT: br label [[END:%.*]]
-; IS________OPM: if.false:
-; IS________OPM-NEXT: br label [[END]]
-; IS________OPM: end:
-; IS________OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]
-; IS________OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100
-; IS________OPM-NEXT: ret i1 [[C2]]
-;
-; IS________NPM-LABEL: define {{[^@]+}}@ctx_adjustment
-; IS________NPM-SAME: (i32 [[V:%.*]])
-; IS________NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
-; IS________NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
-; IS________NPM: if.true:
-; IS________NPM-NEXT: br label [[END:%.*]]
-; IS________NPM: if.false:
-; IS________NPM-NEXT: br label [[END]]
-; IS________NPM: end:
-; IS________NPM-NEXT: ret i1 true
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@ctx_adjustment
+; IS__TUNIT_OPM-SAME: (i32 [[V:%.*]])
+; IS__TUNIT_OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
+; IS__TUNIT_OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
+; IS__TUNIT_OPM: if.true:
+; IS__TUNIT_OPM-NEXT: br label [[END:%.*]]
+; IS__TUNIT_OPM: if.false:
+; IS__TUNIT_OPM-NEXT: br label [[END]]
+; IS__TUNIT_OPM: end:
+; IS__TUNIT_OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]
+; IS__TUNIT_OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100
+; IS__TUNIT_OPM-NEXT: ret i1 [[C2]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@ctx_adjustment
+; IS__TUNIT_NPM-SAME: (i32 [[V:%.*]])
+; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
+; IS__TUNIT_NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
+; IS__TUNIT_NPM: if.true:
+; IS__TUNIT_NPM-NEXT: br label [[END:%.*]]
+; IS__TUNIT_NPM: if.false:
+; IS__TUNIT_NPM-NEXT: br label [[END]]
+; IS__TUNIT_NPM: end:
+; IS__TUNIT_NPM-NEXT: ret i1 true
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@ctx_adjustment
+; IS__CGSCC_OPM-SAME: (i32 [[V:%.*]])
+; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
+; IS__CGSCC_OPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
+; IS__CGSCC_OPM: if.true:
+; IS__CGSCC_OPM-NEXT: br label [[END:%.*]]
+; IS__CGSCC_OPM: if.false:
+; IS__CGSCC_OPM-NEXT: br label [[END]]
+; IS__CGSCC_OPM: end:
+; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100, [[IF_FALSE]] ]
+; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100
+; IS__CGSCC_OPM-NEXT: ret i1 [[C2]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@ctx_adjustment
+; IS__CGSCC_NPM-SAME: (i32 [[V:%.*]])
+; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
+; IS__CGSCC_NPM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
+; IS__CGSCC_NPM: if.true:
+; IS__CGSCC_NPM-NEXT: br label [[END:%.*]]
+; IS__CGSCC_NPM: if.false:
+; IS__CGSCC_NPM-NEXT: br label [[END]]
+; IS__CGSCC_NPM: end:
+; IS__CGSCC_NPM-NEXT: ret i1 true
;
%c1 = icmp sge i32 %V, 100
br i1 %c1, label %if.true, label %if.false
@@ -1064,16 +1337,24 @@ end:
define i32 @func(i1 %c) {
-; CHECK-LABEL: define {{[^@]+}}@func
-; CHECK-SAME: (i1 [[C:%.*]])
-; CHECK-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
-; CHECK-NEXT: ret i32 [[RET]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@func
+; IS__TUNIT____-SAME: (i1 [[C:%.*]])
+; IS__TUNIT____-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
+; IS__TUNIT____-NEXT: ret i32 [[RET]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@func
+; IS__CGSCC____-SAME: (i1 [[C:%.*]])
+; IS__CGSCC____-NEXT: [[RET:%.*]] = select i1 [[C]], i32 0, i32 1
+; IS__CGSCC____-NEXT: ret i32 [[RET]]
;
%ret = select i1 %c, i32 0, i32 1
ret i32 %ret
}
define i32 @simplify_callsite_argument(i1 %d) {
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@simplify_callsite_argument
; IS__TUNIT_OPM-SAME: (i1 [[D:%.*]])
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
@@ -1085,6 +1366,7 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__TUNIT_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) #2, !range !3
; IS__TUNIT_OPM-NEXT: ret i32 [[RET2]]
;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@simplify_callsite_argument
; IS__TUNIT_NPM-SAME: (i1 [[D:%.*]])
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
@@ -1096,6 +1378,7 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__TUNIT_NPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false) #1, !range !4
; IS__TUNIT_NPM-NEXT: ret i32 [[RET2]]
;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@simplify_callsite_argument
; IS__CGSCC_OPM-SAME: (i1 [[D:%.*]])
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
@@ -1107,6 +1390,7 @@ define i32 @simplify_callsite_argument(i1 %d) {
; IS__CGSCC_OPM-NEXT: [[RET2:%.*]] = call i32 @func(i1 false)
; IS__CGSCC_OPM-NEXT: ret i32 [[RET2]]
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@simplify_callsite_argument
; IS__CGSCC_NPM-SAME: (i1 [[D:%.*]])
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = select i1 [[D]], i1 true, i1 false
diff --git a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll
index d42997f05b41..3c7e8c5ff4d7 100644
--- a/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll
+++ b/llvm/test/Transforms/Attributor/read_write_returned_arguments_scc.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=16 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -34,8 +34,8 @@
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-; CHECK: Function Attrs: argmemonly nofree nosync nounwind
define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@external_ret2_nrw
; IS__TUNIT____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree returned [[W0:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -45,6 +45,7 @@ define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree align 4 [[R0]], i32* nofree [[W0]])
; IS__TUNIT____-NEXT: ret i32* [[CALL3]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@external_ret2_nrw
; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree align 4 [[R0:%.*]], i32* nofree returned [[W0:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -62,8 +63,8 @@ entry:
ret i32* %call3
}
-; CHECK: Function Attrs: argmemonly nofree nosync nounwind
define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_ret0_nw
; IS__TUNIT____-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree [[W0:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -88,6 +89,7 @@ define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]], [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret0_nw
; IS__CGSCC____-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree [[W0:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -138,8 +140,8 @@ return: ; preds = %if.end, %if.then
ret i32* %retval.0
}
-; CHECK: Function Attrs: argmemonly nofree nosync nounwind
define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_ret1_rrw
; IS__TUNIT____-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[R1:%.*]], i32* nofree [[W0:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -167,6 +169,7 @@ define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL8]], [[IF_END]] ], [ [[R1]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* undef
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rrw
; IS__CGSCC____-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[R1:%.*]], i32* nofree [[W0:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -223,22 +226,36 @@ return: ; preds = %if.end, %if.then
ret i32* %retval.0
}
+define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@external_sink_ret2_nrw
+; IS__TUNIT____-SAME: (i32* nofree [[N0:%.*]], i32* nocapture nofree readonly [[R0:%.*]], i32* nofree returned writeonly "no-capture-maybe-returned" [[W0:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[N0]], null
+; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
+; IS__TUNIT____-NEXT: store i32 [[TMP0]], i32* [[W0]], align 4
+; IS__TUNIT____-NEXT: br label [[RETURN]]
+; IS__TUNIT____: return:
+; IS__TUNIT____-NEXT: ret i32* [[W0]]
+;
; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn
-define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
-; CHECK-LABEL: define {{[^@]+}}@external_sink_ret2_nrw
-; CHECK-SAME: (i32* nofree [[N0:%.*]], i32* nocapture nofree readonly [[R0:%.*]], i32* nofree returned writeonly "no-capture-maybe-returned" [[W0:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[N0]], null
-; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: br label [[RETURN:%.*]]
-; CHECK: if.end:
-; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
-; CHECK-NEXT: store i32 [[TMP0]], i32* [[W0]], align 4
-; CHECK-NEXT: br label [[RETURN]]
-; CHECK: return:
-; CHECK-NEXT: ret i32* [[W0]]
+; IS__CGSCC____-LABEL: define {{[^@]+}}@external_sink_ret2_nrw
+; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nocapture nofree readonly [[R0:%.*]], i32* nofree returned writeonly "no-capture-maybe-returned" [[W0:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[N0]], null
+; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
+; IS__CGSCC____-NEXT: store i32 [[TMP0]], i32* [[W0]], align 4
+; IS__CGSCC____-NEXT: br label [[RETURN]]
+; IS__CGSCC____: return:
+; IS__CGSCC____-NEXT: ret i32* [[W0]]
;
entry:
%tobool = icmp ne i32* %n0, null
@@ -256,8 +273,8 @@ return: ; preds = %if.end, %if.then
ret i32* %w0
}
-; CHECK: Function Attrs: argmemonly nofree nosync nounwind
define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_ret1_rw
; IS__TUNIT____-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[W0:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -279,6 +296,7 @@ define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL4]], [[IF_END]] ], [ [[W0]], [[IF_THEN]] ]
; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret1_rw
; IS__CGSCC____-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]], i32* nofree returned [[W0:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -323,8 +341,8 @@ return: ; preds = %if.end, %if.then
ret i32* %retval.0
}
-; CHECK: Function Attrs: argmemonly nofree nosync nounwind
define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
; IS__TUNIT____-LABEL: define {{[^@]+}}@external_source_ret2_nrw
; IS__TUNIT____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32* nofree returned [[W0:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -332,6 +350,7 @@ define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32* @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree [[W0]])
; IS__TUNIT____-NEXT: ret i32* [[CALL1]]
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree nosync nounwind
; IS__CGSCC____-LABEL: define {{[^@]+}}@external_source_ret2_nrw
; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree align 4 [[R0:%.*]], i32* nofree returned [[W0:%.*]])
; IS__CGSCC____-NEXT: entry:
diff --git a/llvm/test/Transforms/Attributor/readattrs.ll b/llvm/test/Transforms/Attributor/readattrs.ll
index a78ffb0653b6..058fa0d83d00 100644
--- a/llvm/test/Transforms/Attributor/readattrs.ll
+++ b/llvm/test/Transforms/Attributor/readattrs.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -24,20 +24,34 @@ define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2) {
}
define i8* @test2(i8* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test2
-; CHECK-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]])
-; CHECK-NEXT: store i32 0, i32* @x, align 4
-; CHECK-NEXT: ret i8* [[P]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2
+; IS__TUNIT____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]])
+; IS__TUNIT____-NEXT: store i32 0, i32* @x, align 4
+; IS__TUNIT____-NEXT: ret i8* [[P]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2
+; IS__CGSCC____-SAME: (i8* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]])
+; IS__CGSCC____-NEXT: store i32 0, i32* @x, align 4
+; IS__CGSCC____-NEXT: ret i8* [[P]]
;
store i32 0, i32* @x
ret i8* %p
}
define i1 @test3(i8* %p, i8* %q) {
-; CHECK-LABEL: define {{[^@]+}}@test3
-; CHECK-SAME: (i8* nofree readnone [[P:%.*]], i8* nofree readnone [[Q:%.*]])
-; CHECK-NEXT: [[A:%.*]] = icmp ult i8* [[P]], [[Q]]
-; CHECK-NEXT: ret i1 [[A]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test3
+; IS__TUNIT____-SAME: (i8* nofree readnone [[P:%.*]], i8* nofree readnone [[Q:%.*]])
+; IS__TUNIT____-NEXT: [[A:%.*]] = icmp ult i8* [[P]], [[Q]]
+; IS__TUNIT____-NEXT: ret i1 [[A]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test3
+; IS__CGSCC____-SAME: (i8* nofree readnone [[P:%.*]], i8* nofree readnone [[Q:%.*]])
+; IS__CGSCC____-NEXT: [[A:%.*]] = icmp ult i8* [[P]], [[Q]]
+; IS__CGSCC____-NEXT: ret i1 [[A]]
;
%A = icmp ult i8* %p, %q
ret i1 %A
@@ -46,6 +60,7 @@ define i1 @test3(i8* %p, i8* %q) {
declare void @test4_1(i8* nocapture) readonly
define void @test4_2(i8* %p) {
+; CHECK: Function Attrs: readonly
; CHECK-LABEL: define {{[^@]+}}@test4_2
; CHECK-SAME: (i8* nocapture readonly [[P:%.*]])
; CHECK-NEXT: call void @test4_1(i8* nocapture readonly [[P]])
@@ -57,10 +72,17 @@ define void @test4_2(i8* %p) {
; Missed optz'n: we could make %q readnone, but don't break test6!
define void @test5(i8** %p, i8* %q) {
-; CHECK-LABEL: define {{[^@]+}}@test5
-; CHECK-SAME: (i8** nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[P:%.*]], i8* nofree writeonly [[Q:%.*]])
-; CHECK-NEXT: store i8* [[Q]], i8** [[P]], align 8
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test5
+; IS__TUNIT____-SAME: (i8** nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[P:%.*]], i8* nofree writeonly [[Q:%.*]])
+; IS__TUNIT____-NEXT: store i8* [[Q]], i8** [[P]], align 8
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test5
+; IS__CGSCC____-SAME: (i8** nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[P:%.*]], i8* nofree writeonly [[Q:%.*]])
+; IS__CGSCC____-NEXT: store i8* [[Q]], i8** [[P]], align 8
+; IS__CGSCC____-NEXT: ret void
;
store i8* %q, i8** %p
ret void
@@ -82,24 +104,38 @@ define void @test6_2(i8** %p, i8* %q) {
; inalloca parameters are always considered written
define void @test7_1(i32* inalloca %a) {
-; CHECK-LABEL: define {{[^@]+}}@test7_1
-; CHECK-SAME: (i32* inalloca nocapture nofree writeonly [[A:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test7_1
+; IS__TUNIT____-SAME: (i32* inalloca nocapture nofree writeonly [[A:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test7_1
+; IS__CGSCC____-SAME: (i32* inalloca nocapture nofree writeonly [[A:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
ret void
}
define i32* @test8_1(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@test8_1
-; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32* [[P]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_1
+; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32* [[P]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_1
+; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[P:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32* [[P]]
;
entry:
ret i32* %p
}
define void @test8_2(i32* %p) {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_2
; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -107,6 +143,7 @@ define void @test8_2(i32* %p) {
; IS__TUNIT____-NEXT: store i32 10, i32* [[CALL]], align 4
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_2
; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -126,6 +163,7 @@ declare void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32>%val, <4 x i32*>, i32,
; CHECK-NOT: readnone
; CHECK-NOT: readonly
define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) {
+; CHECK: Function Attrs: nounwind willreturn
; CHECK-LABEL: define {{[^@]+}}@test9
; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]], <4 x i32> [[VAL:%.*]])
; CHECK-NEXT: call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> [[VAL]], <4 x i32*> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>)
@@ -137,8 +175,8 @@ define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) {
; CHECK: declare <4 x i32> @llvm.masked.gather
declare <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*>, i32, <4 x i1>, <4 x i32>)
-; CHECK: readonly
define <4 x i32> @test10(<4 x i32*> %ptrs) {
+; CHECK: Function Attrs: nounwind readonly willreturn
; CHECK-LABEL: define {{[^@]+}}@test10
; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]])
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.masked.gather.v4i32.v4p0i32(<4 x i32*> [[PTRS]], i32 4, <4 x i1> <i1 true, i1 false, i1 true, i1 false>, <4 x i32> undef)
@@ -150,9 +188,8 @@ define <4 x i32> @test10(<4 x i32*> %ptrs) {
; CHECK: declare <4 x i32> @test11_1
declare <4 x i32> @test11_1(<4 x i32*>) argmemonly nounwind readonly
-; CHECK: readonly
-; CHECK-NOT: readnone
define <4 x i32> @test11_2(<4 x i32*> %ptrs) {
+; CHECK: Function Attrs: argmemonly nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@test11_2
; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]])
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*> [[PTRS]])
@@ -165,6 +202,7 @@ define <4 x i32> @test11_2(<4 x i32*> %ptrs) {
declare <4 x i32> @test12_1(<4 x i32*>) argmemonly nounwind
; CHECK-NOT: readnone
define <4 x i32> @test12_2(<4 x i32*> %ptrs) {
+; CHECK: Function Attrs: argmemonly nounwind
; CHECK-LABEL: define {{[^@]+}}@test12_2
; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]])
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*> [[PTRS]])
@@ -175,10 +213,17 @@ define <4 x i32> @test12_2(<4 x i32*> %ptrs) {
}
define i32 @volatile_load(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@volatile_load
-; CHECK-SAME: (i32* nofree align 4 [[P:%.*]])
-; CHECK-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4
-; CHECK-NEXT: ret i32 [[LOAD]]
+; IS__TUNIT____: Function Attrs: argmemonly nofree nounwind willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@volatile_load
+; IS__TUNIT____-SAME: (i32* nofree align 4 [[P:%.*]])
+; IS__TUNIT____-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4
+; IS__TUNIT____-NEXT: ret i32 [[LOAD]]
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nounwind willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@volatile_load
+; IS__CGSCC____-SAME: (i32* nofree align 4 [[P:%.*]])
+; IS__CGSCC____-NEXT: [[LOAD:%.*]] = load volatile i32, i32* [[P]], align 4
+; IS__CGSCC____-NEXT: ret i32 [[LOAD]]
;
%load = load volatile i32, i32* %p
ret i32 %load
@@ -230,6 +275,7 @@ define void @unsound_readonly(i8* %ignored, i8* %escaped_then_written) {
declare void @escape_i8(i8* %ptr)
define void @byval_not_readonly_1(i8* byval %written) readonly {
+; CHECK: Function Attrs: readonly
; CHECK-LABEL: define {{[^@]+}}@byval_not_readonly_1
; CHECK-SAME: (i8* noalias nonnull byval dereferenceable(1) [[WRITTEN:%.*]])
; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]])
@@ -240,16 +286,24 @@ define void @byval_not_readonly_1(i8* byval %written) readonly {
}
define void @byval_not_readonly_2(i8* byval %written) readonly {
-; CHECK-LABEL: define {{[^@]+}}@byval_not_readonly_2
-; CHECK-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
-; CHECK-NEXT: store i8 0, i8* [[WRITTEN]], align 1
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@byval_not_readonly_2
+; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
+; IS__TUNIT____-NEXT: store i8 0, i8* [[WRITTEN]], align 1
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@byval_not_readonly_2
+; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
+; IS__CGSCC____-NEXT: store i8 0, i8* [[WRITTEN]], align 1
+; IS__CGSCC____-NEXT: ret void
;
store i8 0, i8* %written
ret void
}
define void @byval_not_readnone_1(i8* byval %written) readnone {
+; CHECK: Function Attrs: readnone
; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_1
; CHECK-SAME: (i8* noalias nonnull byval dereferenceable(1) [[WRITTEN:%.*]])
; CHECK-NEXT: call void @escape_i8(i8* nonnull dereferenceable(1) [[WRITTEN]])
@@ -260,20 +314,34 @@ define void @byval_not_readnone_1(i8* byval %written) readnone {
}
define void @byval_not_readnone_2(i8* byval %written) readnone {
-; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_2
-; CHECK-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
-; CHECK-NEXT: store i8 0, i8* [[WRITTEN]], align 1
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@byval_not_readnone_2
+; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
+; IS__TUNIT____-NEXT: store i8 0, i8* [[WRITTEN]], align 1
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@byval_not_readnone_2
+; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
+; IS__CGSCC____-NEXT: store i8 0, i8* [[WRITTEN]], align 1
+; IS__CGSCC____-NEXT: ret void
;
store i8 0, i8* %written
ret void
}
define void @byval_no_fnarg(i8* byval %written) {
-; CHECK-LABEL: define {{[^@]+}}@byval_no_fnarg
-; CHECK-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
-; CHECK-NEXT: store i8 0, i8* [[WRITTEN]], align 1
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@byval_no_fnarg
+; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
+; IS__TUNIT____-NEXT: store i8 0, i8* [[WRITTEN]], align 1
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@byval_no_fnarg
+; IS__CGSCC____-SAME: (i8* noalias nocapture nofree nonnull writeonly byval dereferenceable(1) [[WRITTEN:%.*]])
+; IS__CGSCC____-NEXT: store i8 0, i8* [[WRITTEN]], align 1
+; IS__CGSCC____-NEXT: ret void
;
store i8 0, i8* %written
ret void
@@ -286,6 +354,7 @@ define void @testbyval(i8* %read_only) {
; IS__TUNIT____-NEXT: call void @byval_not_readnone_1(i8* noalias nocapture readnone [[READ_ONLY]])
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: readonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@testbyval
; IS__CGSCC____-SAME: (i8* nocapture nonnull readonly dereferenceable(1) [[READ_ONLY:%.*]])
; IS__CGSCC____-NEXT: call void @byval_not_readonly_1(i8* noalias nocapture nonnull readonly dereferenceable(1) [[READ_ONLY]])
@@ -306,6 +375,7 @@ declare i8 @maybe_returned_val(i8* %ptr) readonly nounwind
declare void @val_use(i8 %ptr) readonly nounwind
define void @ptr_uses(i8* %ptr) {
+; CHECK: Function Attrs: nounwind readonly
; CHECK-LABEL: define {{[^@]+}}@ptr_uses
; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]])
; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/Attributor/reduced/register_benchmark_test.ll b/llvm/test/Transforms/Attributor/reduced/register_benchmark_test.ll
index d983bc947cac..462d333911ba 100644
--- a/llvm/test/Transforms/Attributor/reduced/register_benchmark_test.ll
+++ b/llvm/test/Transforms/Attributor/reduced/register_benchmark_test.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s
; RUN: opt -attributor-cgscc -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s
; RUN: opt -passes=attributor -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s
diff --git a/llvm/test/Transforms/Attributor/returned.ll b/llvm/test/Transforms/Attributor/returned.ll
index 1d14685ed1fc..ab6f73acdcdb 100644
--- a/llvm/test/Transforms/Attributor/returned.ll
+++ b/llvm/test/Transforms/Attributor/returned.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=14 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -38,16 +38,24 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define i32 @sink_r0(i32 %r) #0 {
-; CHECK-LABEL: define {{[^@]+}}@sink_r0
-; CHECK-SAME: (i32 returned [[R:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[R]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@sink_r0
+; IS__TUNIT____-SAME: (i32 returned [[R:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 [[R]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@sink_r0
+; IS__CGSCC____-SAME: (i32 returned [[R:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 [[R]]
;
entry:
ret i32 %r
}
define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@scc_r1
; CHECK-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]])
; CHECK-NEXT: entry:
@@ -62,6 +70,7 @@ entry:
}
define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@scc_r2
; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]])
; CHECK-NEXT: entry:
@@ -143,6 +152,7 @@ return: ; preds = %cond.end, %if.then3
}
define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_rX
; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -179,6 +189,7 @@ define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__TUNIT____-NEXT: ret i32 [[RETVAL_0]]
;
+; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@scc_rX
; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -282,16 +293,24 @@ return: ; preds = %cond.end, %if.then3
; return a == b ? r : ptr_scc_r2(a, b, r);
; }
define double* @ptr_sink_r0(double* %r) #0 {
-; CHECK-LABEL: define {{[^@]+}}@ptr_sink_r0
-; CHECK-SAME: (double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret double* [[R]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_sink_r0
+; IS__TUNIT____-SAME: (double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret double* [[R]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_sink_r0
+; IS__CGSCC____-SAME: (double* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret double* [[R]]
;
entry:
ret double* %r
}
define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r1
; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -299,6 +318,7 @@ define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double* noalias nofree readnone [[R]], double* noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL]])
; IS__TUNIT____-NEXT: ret double* [[CALL1]]
;
+; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r1
; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone returned [[R:%.*]], double* nocapture nofree readnone [[B:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -313,6 +333,7 @@ entry:
}
define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__TUNIT____-LABEL: define {{[^@]+}}@ptr_scc_r2
; IS__TUNIT____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]])
; IS__TUNIT____-NEXT: entry:
@@ -349,6 +370,7 @@ define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[CALL1]], [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
; IS__TUNIT____-NEXT: ret double* [[RETVAL_0]]
;
+; IS__CGSCC____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; IS__CGSCC____-LABEL: define {{[^@]+}}@ptr_scc_r2
; IS__CGSCC____-SAME: (double* nofree readnone [[A:%.*]], double* nofree readnone [[B:%.*]], double* nofree readnone returned [[R:%.*]])
; IS__CGSCC____-NEXT: entry:
@@ -437,10 +459,17 @@ return: ; preds = %cond.end, %if.then3
; }
;
define i32* @rt0(i32* %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@rt0
-; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@rt0
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@rt0
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
%v = load i32, i32* %a, align 4
@@ -457,10 +486,17 @@ entry:
; }
;
define i32* @rt1(i32* %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@rt1
-; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@rt1
+; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@rt1
+; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readnone align 4 dereferenceable(4) [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
%v = load i32, i32* %a, align 4
@@ -473,6 +509,7 @@ entry:
; TEST another SCC test
;
define i32* @rt2_helper(i32* %a) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@rt2_helper
; CHECK-SAME: (i32* nofree readnone returned [[A:%.*]])
; CHECK-NEXT: entry:
@@ -485,6 +522,7 @@ entry:
}
define i32* @rt2(i32* %a, i32 *%b) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@rt2
; CHECK-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone "no-capture-maybe-returned" [[B:%.*]])
; CHECK-NEXT: entry:
@@ -513,6 +551,7 @@ if.end:
; TEST another SCC test
;
define i32* @rt3_helper(i32* %a, i32* %b) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@rt3_helper
; CHECK-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]])
; CHECK-NEXT: entry:
@@ -525,6 +564,7 @@ entry:
}
define i32* @rt3(i32* %a, i32 *%b) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@rt3
; CHECK-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]])
; CHECK-NEXT: entry:
@@ -562,6 +602,7 @@ if.end:
declare void @unknown_fn(i32* (i32*)*) #0
define i32* @calls_unknown_fn(i32* %r) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@calls_unknown_fn
; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[R:%.*]])
; CHECK-NEXT: tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn)
@@ -586,6 +627,7 @@ define i32* @calls_unknown_fn(i32* %r) #0 {
; Verify the maybe-redefined function is not annotated:
;
define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn
; CHECK-SAME: (i32* [[R:%.*]])
; CHECK-NEXT: entry:
@@ -596,6 +638,7 @@ entry:
}
define i32* @calls_maybe_redefined_fn(i32* %r) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn
; CHECK-SAME: (i32* returned [[R:%.*]])
; CHECK-NEXT: entry:
@@ -620,6 +663,7 @@ entry:
; Verify the maybe-redefined function is not annotated:
;
define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn2
; CHECK-SAME: (i32* [[R:%.*]])
; CHECK-NEXT: entry:
@@ -630,6 +674,7 @@ entry:
}
define i32* @calls_maybe_redefined_fn2(i32* %r) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2
; CHECK-SAME: (i32* [[R:%.*]])
; CHECK-NEXT: entry:
@@ -652,18 +697,33 @@ entry:
; }
;
define double @select_and_phi(double %b) #0 {
-; CHECK-LABEL: define {{[^@]+}}@select_and_phi
-; CHECK-SAME: (double returned [[B:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt double [[B]], 0.000000e+00
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
-; CHECK-NEXT: ret double [[SEL]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@select_and_phi
+; IS__TUNIT____-SAME: (double returned [[B:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = fcmp ogt double [[B]], 0.000000e+00
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: br label [[IF_END]]
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
+; IS__TUNIT____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
+; IS__TUNIT____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
+; IS__TUNIT____-NEXT: ret double [[SEL]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@select_and_phi
+; IS__CGSCC____-SAME: (double returned [[B:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = fcmp ogt double [[B]], 0.000000e+00
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: br label [[IF_END]]
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi double [ [[B]], [[IF_THEN]] ], [ [[B]], [[ENTRY:%.*]] ]
+; IS__CGSCC____-NEXT: [[CMP1:%.*]] = fcmp oeq double [[B]], 0.000000e+00
+; IS__CGSCC____-NEXT: [[SEL:%.*]] = select i1 [[CMP1]], double [[B]], double [[PHI]]
+; IS__CGSCC____-NEXT: ret double [[SEL]]
;
entry:
%cmp = fcmp ogt double %b, 0.000000e+00
@@ -690,6 +750,7 @@ if.end: ; preds = %if.then, %entry
; }
;
define double @recursion_select_and_phi(i32 %a, double %b) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@recursion_select_and_phi
; CHECK-SAME: (i32 [[A:%.*]], double returned [[B:%.*]])
; CHECK-NEXT: entry:
@@ -729,11 +790,19 @@ if.end: ; preds = %if.then, %entry
; }
;
define double* @bitcast(i32* %b) #0 {
-; CHECK-LABEL: define {{[^@]+}}@bitcast
-; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
-; CHECK-NEXT: ret double* [[BC0]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bitcast
+; IS__TUNIT____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__TUNIT____-NEXT: ret double* [[BC0]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bitcast
+; IS__CGSCC____-SAME: (i32* nofree readnone returned "no-capture-maybe-returned" [[B:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__CGSCC____-NEXT: ret double* [[BC0]]
;
entry:
%bc0 = bitcast i32* %b to double*
@@ -751,23 +820,43 @@ entry:
; }
;
define double* @bitcasts_select_and_phi(i32* %b) #0 {
-; CHECK-LABEL: define {{[^@]+}}@bitcasts_select_and_phi
-; CHECK-SAME: (i32* nofree readnone returned [[B:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: [[PHI:%.*]] = phi double* [ [[BC1]], [[IF_THEN]] ], [ [[BC0]], [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[BC2:%.*]] = bitcast double* [[PHI]] to i8*
-; CHECK-NEXT: [[BC3:%.*]] = bitcast i32* [[B]] to i8*
-; CHECK-NEXT: [[CMP2:%.*]] = icmp ne double* [[BC0]], null
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP2]], i8* [[BC2]], i8* [[BC3]]
-; CHECK-NEXT: [[BC4:%.*]] = bitcast i8* [[SEL]] to double*
-; CHECK-NEXT: ret double* [[BC4]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bitcasts_select_and_phi
+; IS__TUNIT____-SAME: (i32* nofree readnone returned [[B:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
+; IS__TUNIT____-NEXT: br label [[IF_END]]
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: [[PHI:%.*]] = phi double* [ [[BC1]], [[IF_THEN]] ], [ [[BC0]], [[ENTRY:%.*]] ]
+; IS__TUNIT____-NEXT: [[BC2:%.*]] = bitcast double* [[PHI]] to i8*
+; IS__TUNIT____-NEXT: [[BC3:%.*]] = bitcast i32* [[B]] to i8*
+; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp ne double* [[BC0]], null
+; IS__TUNIT____-NEXT: [[SEL:%.*]] = select i1 [[CMP2]], i8* [[BC2]], i8* [[BC3]]
+; IS__TUNIT____-NEXT: [[BC4:%.*]] = bitcast i8* [[SEL]] to double*
+; IS__TUNIT____-NEXT: ret double* [[BC4]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bitcasts_select_and_phi
+; IS__CGSCC____-SAME: (i32* nofree readnone returned [[B:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
+; IS__CGSCC____-NEXT: br label [[IF_END]]
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: [[PHI:%.*]] = phi double* [ [[BC1]], [[IF_THEN]] ], [ [[BC0]], [[ENTRY:%.*]] ]
+; IS__CGSCC____-NEXT: [[BC2:%.*]] = bitcast double* [[PHI]] to i8*
+; IS__CGSCC____-NEXT: [[BC3:%.*]] = bitcast i32* [[B]] to i8*
+; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp ne double* [[BC0]], null
+; IS__CGSCC____-NEXT: [[SEL:%.*]] = select i1 [[CMP2]], i8* [[BC2]], i8* [[BC3]]
+; IS__CGSCC____-NEXT: [[BC4:%.*]] = bitcast i8* [[SEL]] to double*
+; IS__CGSCC____-NEXT: ret double* [[BC4]]
;
entry:
%bc0 = bitcast i32* %b to double*
@@ -800,21 +889,39 @@ if.end: ; preds = %if.then, %entry
; }
;
define double* @ret_arg_arg_undef(i32* %b) #0 {
-; CHECK-LABEL: define {{[^@]+}}@ret_arg_arg_undef
-; CHECK-SAME: (i32* nofree readnone returned [[B:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
-; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG0:%.*]], label [[IF_END:%.*]]
-; CHECK: ret_arg0:
-; CHECK-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
-; CHECK-NEXT: ret double* [[BC1]]
-; CHECK: if.end:
-; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG1:%.*]], label [[RET_UNDEF:%.*]]
-; CHECK: ret_arg1:
-; CHECK-NEXT: ret double* [[BC0]]
-; CHECK: ret_undef:
-; CHECK-NEXT: ret double* undef
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_arg_arg_undef
+; IS__TUNIT____-SAME: (i32* nofree readnone returned [[B:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG0:%.*]], label [[IF_END:%.*]]
+; IS__TUNIT____: ret_arg0:
+; IS__TUNIT____-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
+; IS__TUNIT____-NEXT: ret double* [[BC1]]
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG1:%.*]], label [[RET_UNDEF:%.*]]
+; IS__TUNIT____: ret_arg1:
+; IS__TUNIT____-NEXT: ret double* [[BC0]]
+; IS__TUNIT____: ret_undef:
+; IS__TUNIT____-NEXT: ret double* undef
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_arg_arg_undef
+; IS__CGSCC____-SAME: (i32* nofree readnone returned [[B:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG0:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC____: ret_arg0:
+; IS__CGSCC____-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
+; IS__CGSCC____-NEXT: ret double* [[BC1]]
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG1:%.*]], label [[RET_UNDEF:%.*]]
+; IS__CGSCC____: ret_arg1:
+; IS__CGSCC____-NEXT: ret double* [[BC0]]
+; IS__CGSCC____: ret_undef:
+; IS__CGSCC____-NEXT: ret double* undef
;
entry:
%bc0 = bitcast i32* %b to double*
@@ -847,21 +954,39 @@ ret_undef:
; }
;
define double* @ret_undef_arg_arg(i32* %b) #0 {
-; CHECK-LABEL: define {{[^@]+}}@ret_undef_arg_arg
-; CHECK-SAME: (i32* nofree readnone returned [[B:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
-; CHECK-NEXT: br i1 [[CMP]], label [[RET_UNDEF:%.*]], label [[IF_END:%.*]]
-; CHECK: ret_undef:
-; CHECK-NEXT: ret double* undef
-; CHECK: if.end:
-; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG0:%.*]], label [[RET_ARG1:%.*]]
-; CHECK: ret_arg0:
-; CHECK-NEXT: ret double* [[BC0]]
-; CHECK: ret_arg1:
-; CHECK-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
-; CHECK-NEXT: ret double* [[BC1]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef_arg_arg
+; IS__TUNIT____-SAME: (i32* nofree readnone returned [[B:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_UNDEF:%.*]], label [[IF_END:%.*]]
+; IS__TUNIT____: ret_undef:
+; IS__TUNIT____-NEXT: ret double* undef
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG0:%.*]], label [[RET_ARG1:%.*]]
+; IS__TUNIT____: ret_arg0:
+; IS__TUNIT____-NEXT: ret double* [[BC0]]
+; IS__TUNIT____: ret_arg1:
+; IS__TUNIT____-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
+; IS__TUNIT____-NEXT: ret double* [[BC1]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_undef_arg_arg
+; IS__CGSCC____-SAME: (i32* nofree readnone returned [[B:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_UNDEF:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC____: ret_undef:
+; IS__CGSCC____-NEXT: ret double* undef
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG0:%.*]], label [[RET_ARG1:%.*]]
+; IS__CGSCC____: ret_arg0:
+; IS__CGSCC____-NEXT: ret double* [[BC0]]
+; IS__CGSCC____: ret_arg1:
+; IS__CGSCC____-NEXT: [[BC1:%.*]] = bitcast i32* [[B]] to double*
+; IS__CGSCC____-NEXT: ret double* [[BC1]]
;
entry:
%bc0 = bitcast i32* %b to double*
@@ -894,20 +1019,37 @@ ret_arg1:
; }
;
define double* @ret_undef_arg_undef(i32* %b) #0 {
-; CHECK-LABEL: define {{[^@]+}}@ret_undef_arg_undef
-; CHECK-SAME: (i32* nofree readnone returned [[B:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
-; CHECK-NEXT: br i1 [[CMP]], label [[RET_UNDEF0:%.*]], label [[IF_END:%.*]]
-; CHECK: ret_undef0:
-; CHECK-NEXT: ret double* undef
-; CHECK: if.end:
-; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNDEF1:%.*]]
-; CHECK: ret_arg:
-; CHECK-NEXT: ret double* [[BC0]]
-; CHECK: ret_undef1:
-; CHECK-NEXT: ret double* undef
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef_arg_undef
+; IS__TUNIT____-SAME: (i32* nofree readnone returned [[B:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_UNDEF0:%.*]], label [[IF_END:%.*]]
+; IS__TUNIT____: ret_undef0:
+; IS__TUNIT____-NEXT: ret double* undef
+; IS__TUNIT____: if.end:
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNDEF1:%.*]]
+; IS__TUNIT____: ret_arg:
+; IS__TUNIT____-NEXT: ret double* [[BC0]]
+; IS__TUNIT____: ret_undef1:
+; IS__TUNIT____-NEXT: ret double* undef
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_undef_arg_undef
+; IS__CGSCC____-SAME: (i32* nofree readnone returned [[B:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[BC0:%.*]] = bitcast i32* [[B]] to double*
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq double* [[BC0]], null
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_UNDEF0:%.*]], label [[IF_END:%.*]]
+; IS__CGSCC____: ret_undef0:
+; IS__CGSCC____-NEXT: ret double* undef
+; IS__CGSCC____: if.end:
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label [[RET_UNDEF1:%.*]]
+; IS__CGSCC____: ret_arg:
+; IS__CGSCC____-NEXT: ret double* [[BC0]]
+; IS__CGSCC____: ret_undef1:
+; IS__CGSCC____-NEXT: ret double* undef
;
entry:
%bc0 = bitcast i32* %b to double*
@@ -940,6 +1082,7 @@ ret_undef1:
declare i32* @unknown(i32*)
define i32* @ret_arg_or_unknown(i32* %b) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown
; CHECK-SAME: (i32* [[B:%.*]])
; CHECK-NEXT: entry:
@@ -964,6 +1107,7 @@ ret_unknown:
}
define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
; CHECK-SAME: (i32* [[B:%.*]])
; CHECK-NEXT: entry:
@@ -997,12 +1141,21 @@ r:
; TEST inconsistent IR in dead code.
;
define i32 @deadblockcall1(i32 %A) #0 {
-; CHECK-LABEL: define {{[^@]+}}@deadblockcall1
-; CHECK-SAME: (i32 returned [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[A]]
-; CHECK: unreachableblock:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockcall1
+; IS__TUNIT____-SAME: (i32 returned [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 [[A]]
+; IS__TUNIT____: unreachableblock:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@deadblockcall1
+; IS__CGSCC____-SAME: (i32 returned [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 [[A]]
+; IS__CGSCC____: unreachableblock:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
ret i32 %A
@@ -1014,14 +1167,25 @@ unreachableblock:
declare i32 @deadblockcall_helper(i32 returned %A);
define i32 @deadblockcall2(i32 %A) #0 {
-; CHECK-LABEL: define {{[^@]+}}@deadblockcall2
-; CHECK-SAME: (i32 returned [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret i32 [[A]]
-; CHECK: unreachableblock1:
-; CHECK-NEXT: unreachable
-; CHECK: unreachableblock2:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockcall2
+; IS__TUNIT____-SAME: (i32 returned [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: ret i32 [[A]]
+; IS__TUNIT____: unreachableblock1:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: unreachableblock2:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@deadblockcall2
+; IS__CGSCC____-SAME: (i32 returned [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: ret i32 [[A]]
+; IS__CGSCC____: unreachableblock1:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: unreachableblock2:
+; IS__CGSCC____-NEXT: unreachable
;
entry:
ret i32 %A
@@ -1034,16 +1198,29 @@ unreachableblock2:
}
define i32 @deadblockphi1(i32 %A) #0 {
-; CHECK-LABEL: define {{[^@]+}}@deadblockphi1
-; CHECK-SAME: (i32 returned [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[R:%.*]]
-; CHECK: unreachableblock1:
-; CHECK-NEXT: unreachable
-; CHECK: unreachableblock2:
-; CHECK-NEXT: unreachable
-; CHECK: r:
-; CHECK-NEXT: ret i32 [[A]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockphi1
+; IS__TUNIT____-SAME: (i32 returned [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[R:%.*]]
+; IS__TUNIT____: unreachableblock1:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: unreachableblock2:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: r:
+; IS__TUNIT____-NEXT: ret i32 [[A]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@deadblockphi1
+; IS__CGSCC____-SAME: (i32 returned [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[R:%.*]]
+; IS__CGSCC____: unreachableblock1:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: unreachableblock2:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: r:
+; IS__CGSCC____-NEXT: ret i32 [[A]]
;
entry:
br label %r
@@ -1059,18 +1236,33 @@ r:
}
define i32 @deadblockphi2(i32 %A) #0 {
-; CHECK-LABEL: define {{[^@]+}}@deadblockphi2
-; CHECK-SAME: (i32 returned [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[R:%.*]]
-; CHECK: unreachableblock1:
-; CHECK-NEXT: unreachable
-; CHECK: unreachableblock2:
-; CHECK-NEXT: unreachable
-; CHECK: unreachableblock3:
-; CHECK-NEXT: unreachable
-; CHECK: r:
-; CHECK-NEXT: ret i32 [[A]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@deadblockphi2
+; IS__TUNIT____-SAME: (i32 returned [[A:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[R:%.*]]
+; IS__TUNIT____: unreachableblock1:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: unreachableblock2:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: unreachableblock3:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: r:
+; IS__TUNIT____-NEXT: ret i32 [[A]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@deadblockphi2
+; IS__CGSCC____-SAME: (i32 returned [[A:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[R:%.*]]
+; IS__CGSCC____: unreachableblock1:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: unreachableblock2:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: unreachableblock3:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: r:
+; IS__CGSCC____-NEXT: ret i32 [[A]]
;
entry:
br label %r
@@ -1091,6 +1283,7 @@ r:
declare void @noreturn() noreturn;
define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@deadblockphi3
; CHECK-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]])
; CHECK-NEXT: entry:
@@ -1207,25 +1400,38 @@ define i32 @exact(i32* align 8 %a, i32* align 8 %b) {
@G = external global i8
define i32* @ret_const() #0 {
-; CHECK-LABEL: define {{[^@]+}}@ret_const()
-; CHECK-NEXT: [[BC:%.*]] = bitcast i8* @G to i32*
-; CHECK-NEXT: ret i32* [[BC]]
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_const()
+; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* @G to i32*
+; IS__TUNIT____-NEXT: ret i32* [[BC]]
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_const()
+; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* @G to i32*
+; IS__CGSCC____-NEXT: ret i32* [[BC]]
;
%bc = bitcast i8* @G to i32*
ret i32* %bc
}
define i32* @use_const() #0 {
-; CHECK-LABEL: define {{[^@]+}}@use_const()
-; CHECK-NEXT: ret i32* bitcast (i8* @G to i32*)
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@use_const()
+; IS__TUNIT____-NEXT: ret i32* bitcast (i8* @G to i32*)
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@use_const()
+; IS__CGSCC____-NEXT: ret i32* bitcast (i8* @G to i32*)
;
%c = call i32* @ret_const()
ret i32* %c
}
define i32* @dont_use_const() #0 {
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_use_const()
; IS__TUNIT____-NEXT: [[C:%.*]] = musttail call i32* @ret_const()
; IS__TUNIT____-NEXT: ret i32* [[C]]
;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_use_const()
; IS__CGSCC____-NEXT: [[C:%.*]] = musttail call nonnull dereferenceable(1) i32* @ret_const()
; IS__CGSCC____-NEXT: ret i32* [[C]]
diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll b/llvm/test/Transforms/Attributor/undefined_behavior.ll
index b49c26e8a2f7..689403768174 100644
--- a/llvm/test/Transforms/Attributor/undefined_behavior.ll
+++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -13,16 +13,26 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
; -- Load tests --
define void @load_wholly_unreachable() {
-; CHECK-LABEL: define {{[^@]+}}@load_wholly_unreachable()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@load_wholly_unreachable()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@load_wholly_unreachable()
+; IS__CGSCC____-NEXT: unreachable
;
%a = load i32, i32* null
ret void
}
define void @loads_wholly_unreachable() {
-; CHECK-LABEL: define {{[^@]+}}@loads_wholly_unreachable()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@loads_wholly_unreachable()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@loads_wholly_unreachable()
+; IS__CGSCC____-NEXT: unreachable
;
%a = load i32, i32* null
%b = load i32, i32* null
@@ -31,13 +41,23 @@ define void @loads_wholly_unreachable() {
define void @load_single_bb_unreachable(i1 %cond) {
-; CHECK-LABEL: define {{[^@]+}}@load_single_bb_unreachable
-; CHECK-SAME: (i1 [[COND:%.*]])
-; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
-; CHECK: t:
-; CHECK-NEXT: unreachable
-; CHECK: e:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@load_single_bb_unreachable
+; IS__TUNIT____-SAME: (i1 [[COND:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@load_single_bb_unreachable
+; IS__CGSCC____-SAME: (i1 [[COND:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: ret void
;
br i1 %cond, label %t, label %e
t:
@@ -50,14 +70,20 @@ e:
; Note that while the load is removed (because it's unused), the block
; is not changed to unreachable
define void @load_null_pointer_is_defined() null_pointer_is_valid {
-; CHECK-LABEL: define {{[^@]+}}@load_null_pointer_is_defined()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@load_null_pointer_is_defined()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@load_null_pointer_is_defined()
+; IS__CGSCC____-NEXT: ret void
;
%a = load i32, i32* null
ret void
}
define internal i32* @ret_null() {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_null()
; IS__CGSCC____-NEXT: ret i32* null
;
@@ -65,8 +91,13 @@ define internal i32* @ret_null() {
}
define void @load_null_propagated() {
-; CHECK-LABEL: define {{[^@]+}}@load_null_propagated()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@load_null_propagated()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@load_null_propagated()
+; IS__CGSCC____-NEXT: unreachable
;
%ptr = call i32* @ret_null()
%a = load i32, i32* %ptr
@@ -76,21 +107,36 @@ define void @load_null_propagated() {
; -- Store tests --
define void @store_wholly_unreachable() {
-; CHECK-LABEL: define {{[^@]+}}@store_wholly_unreachable()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@store_wholly_unreachable()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@store_wholly_unreachable()
+; IS__CGSCC____-NEXT: unreachable
;
store i32 5, i32* null
ret void
}
define void @store_single_bb_unreachable(i1 %cond) {
-; CHECK-LABEL: define {{[^@]+}}@store_single_bb_unreachable
-; CHECK-SAME: (i1 [[COND:%.*]])
-; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
-; CHECK: t:
-; CHECK-NEXT: unreachable
-; CHECK: e:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@store_single_bb_unreachable
+; IS__TUNIT____-SAME: (i1 [[COND:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@store_single_bb_unreachable
+; IS__CGSCC____-SAME: (i1 [[COND:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: ret void
;
br i1 %cond, label %t, label %e
t:
@@ -101,9 +147,15 @@ e:
}
define void @store_null_pointer_is_defined() null_pointer_is_valid {
-; CHECK-LABEL: define {{[^@]+}}@store_null_pointer_is_defined()
-; CHECK-NEXT: store i32 5, i32* null, align 536870912
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind null_pointer_is_valid willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined()
+; IS__TUNIT____-NEXT: store i32 5, i32* null, align 536870912
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind null_pointer_is_valid willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_pointer_is_defined()
+; IS__CGSCC____-NEXT: store i32 5, i32* null, align 536870912
+; IS__CGSCC____-NEXT: ret void
;
store i32 5, i32* null
ret void
@@ -113,8 +165,13 @@ define void @store_null_propagated() {
; ATTRIBUTOR-LABEL: @store_null_propagated(
; ATTRIBUTOR-NEXT: unreachable
;
-; CHECK-LABEL: define {{[^@]+}}@store_null_propagated()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@store_null_propagated()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@store_null_propagated()
+; IS__CGSCC____-NEXT: unreachable
;
%ptr = call i32* @ret_null()
store i32 5, i32* %ptr
@@ -124,21 +181,36 @@ define void @store_null_propagated() {
; -- AtomicRMW tests --
define void @atomicrmw_wholly_unreachable() {
-; CHECK-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable()
+; IS__CGSCC____-NEXT: unreachable
;
%a = atomicrmw add i32* null, i32 1 acquire
ret void
}
define void @atomicrmw_single_bb_unreachable(i1 %cond) {
-; CHECK-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable
-; CHECK-SAME: (i1 [[COND:%.*]])
-; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
-; CHECK: t:
-; CHECK-NEXT: unreachable
-; CHECK: e:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable
+; IS__TUNIT____-SAME: (i1 [[COND:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_single_bb_unreachable
+; IS__CGSCC____-SAME: (i1 [[COND:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: ret void
;
br i1 %cond, label %t, label %e
t:
@@ -149,9 +221,15 @@ e:
}
define void @atomicrmw_null_pointer_is_defined() null_pointer_is_valid {
-; CHECK-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined()
-; CHECK-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nounwind null_pointer_is_valid willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined()
+; IS__TUNIT____-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined()
+; IS__CGSCC____-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire
+; IS__CGSCC____-NEXT: ret void
;
%a = atomicrmw add i32* null, i32 1 acquire
ret void
@@ -161,8 +239,13 @@ define void @atomicrmw_null_propagated() {
; ATTRIBUTOR-LABEL: @atomicrmw_null_propagated(
; ATTRIBUTOR-NEXT: unreachable
;
-; CHECK-LABEL: define {{[^@]+}}@atomicrmw_null_propagated()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomicrmw_null_propagated()
+; IS__CGSCC____-NEXT: unreachable
;
%ptr = call i32* @ret_null()
%a = atomicrmw add i32* %ptr, i32 1 acquire
@@ -172,21 +255,36 @@ define void @atomicrmw_null_propagated() {
; -- AtomicCmpXchg tests --
define void @atomiccmpxchg_wholly_unreachable() {
-; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable()
+; IS__CGSCC____-NEXT: unreachable
;
%a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic
ret void
}
define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) {
-; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable
-; CHECK-SAME: (i1 [[COND:%.*]])
-; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
-; CHECK: t:
-; CHECK-NEXT: unreachable
-; CHECK: e:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable
+; IS__TUNIT____-SAME: (i1 [[COND:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_single_bb_unreachable
+; IS__CGSCC____-SAME: (i1 [[COND:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: ret void
;
br i1 %cond, label %t, label %e
t:
@@ -197,9 +295,15 @@ e:
}
define void @atomiccmpxchg_null_pointer_is_defined() null_pointer_is_valid {
-; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined()
-; CHECK-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nounwind null_pointer_is_valid willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined()
+; IS__TUNIT____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind null_pointer_is_valid willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_pointer_is_defined()
+; IS__CGSCC____-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic
+; IS__CGSCC____-NEXT: ret void
;
%a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic
ret void
@@ -209,8 +313,13 @@ define void @atomiccmpxchg_null_propagated() {
; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated(
; ATTRIBUTOR-NEXT: unreachable
;
-; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated()
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated()
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated()
+; IS__CGSCC____-NEXT: unreachable
;
%ptr = call i32* @ret_null()
%a = cmpxchg i32* %ptr, i32 2, i32 3 acq_rel monotonic
@@ -222,12 +331,21 @@ define void @atomiccmpxchg_null_propagated() {
; Note: The unreachable on %t and %e is _not_ from AAUndefinedBehavior
define i32 @cond_br_on_undef() {
-; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef()
-; CHECK-NEXT: unreachable
-; CHECK: t:
-; CHECK-NEXT: unreachable
-; CHECK: e:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef()
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef()
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: unreachable
;
br i1 undef, label %t, label %e
t:
@@ -240,17 +358,31 @@ e:
; Valid branch - verify that this is not converted
; to unreachable.
define void @cond_br_on_undef2(i1 %cond) {
-; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef2
-; CHECK-SAME: (i1 [[COND:%.*]])
-; CHECK-NEXT: br i1 [[COND]], label [[T1:%.*]], label [[E1:%.*]]
-; CHECK: t1:
-; CHECK-NEXT: unreachable
-; CHECK: t2:
-; CHECK-NEXT: unreachable
-; CHECK: e2:
-; CHECK-NEXT: unreachable
-; CHECK: e1:
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef2
+; IS__TUNIT____-SAME: (i1 [[COND:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T1:%.*]], label [[E1:%.*]]
+; IS__TUNIT____: t1:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: t2:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e2:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e1:
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef2
+; IS__CGSCC____-SAME: (i1 [[COND:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T1:%.*]], label [[E1:%.*]]
+; IS__CGSCC____: t1:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: t2:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e2:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e1:
+; IS__CGSCC____-NEXT: ret void
;
br i1 %cond, label %t1, label %e1
t1:
@@ -264,19 +396,33 @@ e1:
}
define i1 @ret_undef() {
-; CHECK-LABEL: define {{[^@]+}}@ret_undef()
-; CHECK-NEXT: ret i1 undef
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef()
+; IS__TUNIT____-NEXT: ret i1 undef
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_undef()
+; IS__CGSCC____-NEXT: ret i1 undef
;
ret i1 undef
}
define void @cond_br_on_undef_interproc() {
-; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc()
-; CHECK-NEXT: unreachable
-; CHECK: t:
-; CHECK-NEXT: unreachable
-; CHECK: e:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc()
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc()
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: unreachable
;
%cond = call i1 @ret_undef()
br i1 %cond, label %t, label %e
@@ -287,12 +433,21 @@ e:
}
define i1 @ret_undef2() {
-; CHECK-LABEL: define {{[^@]+}}@ret_undef2()
-; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[E:%.*]]
-; CHECK: t:
-; CHECK-NEXT: ret i1 undef
-; CHECK: e:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ret_undef2()
+; IS__TUNIT____-NEXT: br i1 true, label [[T:%.*]], label [[E:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: ret i1 undef
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_undef2()
+; IS__CGSCC____-NEXT: br i1 true, label [[T:%.*]], label [[E:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: ret i1 undef
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: unreachable
;
br i1 true, label %t, label %e
t:
@@ -303,12 +458,21 @@ e:
; More complicated interproc deduction of undef
define void @cond_br_on_undef_interproc2() {
-; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2()
-; CHECK-NEXT: unreachable
-; CHECK: t:
-; CHECK-NEXT: unreachable
-; CHECK: e:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2()
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2()
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: unreachable
;
%cond = call i1 @ret_undef2()
br i1 %cond, label %t, label %e
@@ -321,12 +485,21 @@ e:
; Branch on undef that depends on propagation of
; undef of a previous instruction.
define i32 @cond_br_on_undef3() {
-; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef3()
-; CHECK-NEXT: br label [[T:%.*]]
-; CHECK: t:
-; CHECK-NEXT: ret i32 1
-; CHECK: e:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef3()
+; IS__TUNIT____-NEXT: br label [[T:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: ret i32 1
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef3()
+; IS__CGSCC____-NEXT: br label [[T:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: ret i32 1
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: unreachable
;
%cond = icmp ne i32 1, undef
br i1 %cond, label %t, label %e
@@ -339,14 +512,25 @@ e:
; Branch on undef because of uninitialized value.
; FIXME: Currently it doesn't propagate the undef.
define i32 @cond_br_on_undef_uninit() {
-; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit()
-; CHECK-NEXT: [[ALLOC:%.*]] = alloca i1, align 1
-; CHECK-NEXT: [[COND:%.*]] = load i1, i1* [[ALLOC]], align 1
-; CHECK-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
-; CHECK: t:
-; CHECK-NEXT: ret i32 1
-; CHECK: e:
-; CHECK-NEXT: ret i32 2
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit()
+; IS__TUNIT____-NEXT: [[ALLOC:%.*]] = alloca i1, align 1
+; IS__TUNIT____-NEXT: [[COND:%.*]] = load i1, i1* [[ALLOC]], align 1
+; IS__TUNIT____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: ret i32 1
+; IS__TUNIT____: e:
+; IS__TUNIT____-NEXT: ret i32 2
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit()
+; IS__CGSCC____-NEXT: [[ALLOC:%.*]] = alloca i1, align 1
+; IS__CGSCC____-NEXT: [[COND:%.*]] = load i1, i1* [[ALLOC]], align 1
+; IS__CGSCC____-NEXT: br i1 [[COND]], label [[T:%.*]], label [[E:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: ret i32 1
+; IS__CGSCC____: e:
+; IS__CGSCC____-NEXT: ret i32 2
;
%alloc = alloca i1
%cond = load i1, i1* %alloc
@@ -363,6 +547,7 @@ e:
; MODULE-NOT: @callee(
define internal i32 @callee(i1 %C, i32* %A) {
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@callee()
; IS__CGSCC____-NEXT: entry:
; IS__CGSCC____-NEXT: unreachable
@@ -383,8 +568,13 @@ F:
}
define i32 @foo() {
-; CHECK-LABEL: define {{[^@]+}}@foo()
-; CHECK-NEXT: ret i32 1
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@foo()
+; IS__TUNIT____-NEXT: ret i32 1
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@foo()
+; IS__CGSCC____-NEXT: ret i32 1
;
%X = call i32 @callee(i1 false, i32* null)
ret i32 %X
diff --git a/llvm/test/Transforms/Attributor/value-simplify.ll b/llvm/test/Transforms/Attributor/value-simplify.ll
index febfaba5b19a..24f3954b8165 100644
--- a/llvm/test/Transforms/Attributor/value-simplify.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -30,31 +30,55 @@ define void @test1_helper() {
; TEST 2 : Simplify return value
define i32 @return0() {
-; CHECK-LABEL: define {{[^@]+}}@return0()
-; CHECK-NEXT: ret i32 0
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@return0()
+; IS__TUNIT____-NEXT: ret i32 0
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@return0()
+; IS__CGSCC____-NEXT: ret i32 0
;
ret i32 0
}
define i32 @return1() {
-; CHECK-LABEL: define {{[^@]+}}@return1()
-; CHECK-NEXT: ret i32 1
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@return1()
+; IS__TUNIT____-NEXT: ret i32 1
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@return1()
+; IS__CGSCC____-NEXT: ret i32 1
;
ret i32 1
}
define i32 @test2_1(i1 %c) {
-; CHECK-LABEL: define {{[^@]+}}@test2_1
-; CHECK-SAME: (i1 [[C:%.*]])
-; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
-; CHECK: if.true:
-; CHECK-NEXT: [[RET0:%.*]] = add i32 0, 1
-; CHECK-NEXT: br label [[END:%.*]]
-; CHECK: if.false:
-; CHECK-NEXT: br label [[END]]
-; CHECK: end:
-; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
-; CHECK-NEXT: ret i32 1
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_1
+; IS__TUNIT____-SAME: (i1 [[C:%.*]])
+; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
+; IS__TUNIT____: if.true:
+; IS__TUNIT____-NEXT: [[RET0:%.*]] = add i32 0, 1
+; IS__TUNIT____-NEXT: br label [[END:%.*]]
+; IS__TUNIT____: if.false:
+; IS__TUNIT____-NEXT: br label [[END]]
+; IS__TUNIT____: end:
+; IS__TUNIT____-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
+; IS__TUNIT____-NEXT: ret i32 1
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_1
+; IS__CGSCC____-SAME: (i1 [[C:%.*]])
+; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
+; IS__CGSCC____: if.true:
+; IS__CGSCC____-NEXT: [[RET0:%.*]] = add i32 0, 1
+; IS__CGSCC____-NEXT: br label [[END:%.*]]
+; IS__CGSCC____: if.false:
+; IS__CGSCC____-NEXT: br label [[END]]
+; IS__CGSCC____: end:
+; IS__CGSCC____-NEXT: [[RET:%.*]] = phi i32 [ [[RET0]], [[IF_TRUE]] ], [ 1, [[IF_FALSE]] ]
+; IS__CGSCC____-NEXT: ret i32 1
;
br i1 %c, label %if.true, label %if.false
if.true:
@@ -74,9 +98,15 @@ end:
define i32 @test2_2(i1 %c) {
-; CHECK-LABEL: define {{[^@]+}}@test2_2
-; CHECK-SAME: (i1 [[C:%.*]])
-; CHECK-NEXT: ret i32 1
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_2
+; IS__TUNIT____-SAME: (i1 [[C:%.*]])
+; IS__TUNIT____-NEXT: ret i32 1
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_2
+; IS__CGSCC____-SAME: (i1 [[C:%.*]])
+; IS__CGSCC____-NEXT: ret i32 1
;
%ret = tail call i32 @test2_1(i1 %c)
ret i32 %ret
@@ -167,13 +197,23 @@ end:
}
define i32 @ipccp1(i32 %a) {
-; CHECK-LABEL: define {{[^@]+}}@ipccp1
-; CHECK-SAME: (i32 returned [[A:%.*]])
-; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]]
-; CHECK: t:
-; CHECK-NEXT: ret i32 [[A]]
-; CHECK: f:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp1
+; IS__TUNIT____-SAME: (i32 returned [[A:%.*]])
+; IS__TUNIT____-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: ret i32 [[A]]
+; IS__TUNIT____: f:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp1
+; IS__CGSCC____-SAME: (i32 returned [[A:%.*]])
+; IS__CGSCC____-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: ret i32 [[A]]
+; IS__CGSCC____: f:
+; IS__CGSCC____-NEXT: unreachable
;
br i1 true, label %t, label %f
t:
@@ -184,6 +224,7 @@ f:
}
define internal i1 @ipccp2i(i1 %a) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2i()
; IS__CGSCC____-NEXT: br label [[T:%.*]]
; IS__CGSCC____: t:
@@ -200,9 +241,11 @@ f:
}
define i1 @ipccp2() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp2()
; IS__TUNIT____-NEXT: ret i1 true
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2()
; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @ipccp2i()
; IS__CGSCC____-NEXT: ret i1 [[R]]
@@ -212,6 +255,7 @@ define i1 @ipccp2() {
}
define internal i1 @ipccp2ib(i1 %a) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2ib()
; IS__CGSCC____-NEXT: br label [[T:%.*]]
; IS__CGSCC____: t:
@@ -228,14 +272,20 @@ f:
}
define i1 @ipccp2b() {
-; CHECK-LABEL: define {{[^@]+}}@ipccp2b()
-; CHECK-NEXT: ret i1 true
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp2b()
+; IS__TUNIT____-NEXT: ret i1 true
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2b()
+; IS__CGSCC____-NEXT: ret i1 true
;
%r = call i1 @ipccp2ib(i1 true)
ret i1 %r
}
define internal i32 @ipccp3i(i32 %a) {
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp3i()
; IS__CGSCC____-NEXT: br label [[T:%.*]]
; IS__CGSCC____: t:
@@ -253,9 +303,11 @@ f:
}
define i32 @ipccp3() {
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp3()
; IS__TUNIT____-NEXT: ret i32 7
;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp3()
; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @ipccp3i()
; IS__CGSCC____-NEXT: ret i32 [[R]]
@@ -267,44 +319,66 @@ define i32 @ipccp3() {
; Do not touch complicated arguments (for now)
%struct.X = type { i8* }
define internal i32* @test_inalloca(i32* inalloca %a) {
-; CHECK-LABEL: define {{[^@]+}}@test_inalloca
-; CHECK-SAME: (i32* inalloca noalias nofree returned writeonly align 536870912 "no-capture-maybe-returned" [[A:%.*]])
-; CHECK-NEXT: ret i32* [[A]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_inalloca
+; IS__TUNIT____-SAME: (i32* inalloca noalias nofree returned writeonly align 536870912 "no-capture-maybe-returned" [[A:%.*]])
+; IS__TUNIT____-NEXT: ret i32* [[A]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inalloca
+; IS__CGSCC____-SAME: (i32* inalloca noalias nofree returned writeonly align 536870912 "no-capture-maybe-returned" [[A:%.*]])
+; IS__CGSCC____-NEXT: ret i32* [[A]]
;
ret i32* %a
}
define i32* @complicated_args_inalloca() {
-; CHECK-LABEL: define {{[^@]+}}@complicated_args_inalloca()
-; CHECK-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nocapture nofree writeonly align 536870912 null)
-; CHECK-NEXT: ret i32* [[CALL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_inalloca()
+; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nocapture nofree writeonly align 536870912 null)
+; IS__TUNIT____-NEXT: ret i32* [[CALL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_inalloca()
+; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nocapture nofree writeonly align 536870912 null)
+; IS__CGSCC____-NEXT: ret i32* [[CALL]]
;
%call = call i32* @test_inalloca(i32* null)
ret i32* %call
}
define internal i32* @test_preallocated(i32* preallocated(i32) %a) {
-; CHECK-LABEL: define {{[^@]+}}@test_preallocated
-; CHECK-SAME: (i32* noalias nofree returned writeonly preallocated(i32) align 536870912 "no-capture-maybe-returned" [[A:%.*]])
-; CHECK-NEXT: ret i32* [[A]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_preallocated
+; IS__TUNIT____-SAME: (i32* noalias nofree returned writeonly preallocated(i32) align 536870912 "no-capture-maybe-returned" [[A:%.*]])
+; IS__TUNIT____-NEXT: ret i32* [[A]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_preallocated
+; IS__CGSCC____-SAME: (i32* noalias nofree returned writeonly preallocated(i32) align 536870912 "no-capture-maybe-returned" [[A:%.*]])
+; IS__CGSCC____-NEXT: ret i32* [[A]]
;
ret i32* %a
}
define i32* @complicated_args_preallocated() {
+; IS__TUNIT_OPM: Function Attrs: nounwind
; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated()
; IS__TUNIT_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) #5 [ "preallocated"(token [[C]]) ]
; IS__TUNIT_OPM-NEXT: ret i32* [[CALL]]
;
+; IS__TUNIT_NPM: Function Attrs: nounwind
; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated()
; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) #4 [ "preallocated"(token [[C]]) ]
; IS__TUNIT_NPM-NEXT: ret i32* [[CALL]]
;
+; IS__CGSCC_OPM: Function Attrs: nounwind
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_preallocated()
; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) #6 [ "preallocated"(token [[C]]) ]
; IS__CGSCC_OPM-NEXT: ret i32* [[CALL]]
;
+; IS__CGSCC_NPM: Function Attrs: nounwind
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_preallocated()
; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call token @llvm.call.preallocated.setup(i32 1)
; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32* @test_preallocated(i32* noalias nocapture nofree writeonly preallocated(i32) align 536870912 null) #5 [ "preallocated"(token [[C]]) ]
@@ -317,10 +391,17 @@ define i32* @complicated_args_preallocated() {
define internal void @test_sret(%struct.X* sret %a, %struct.X** %b) {
;
-; CHECK-LABEL: define {{[^@]+}}@test_sret
-; CHECK-SAME: (%struct.X* noalias nofree nonnull sret writeonly align 536870912 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[B:%.*]])
-; CHECK-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_sret
+; IS__TUNIT____-SAME: (%struct.X* noalias nofree nonnull sret writeonly align 536870912 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[B:%.*]])
+; IS__TUNIT____-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_sret
+; IS__CGSCC____-SAME: (%struct.X* noalias nofree nonnull sret writeonly align 536870912 dereferenceable(8) [[A:%.*]], %struct.X** nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[B:%.*]])
+; IS__CGSCC____-NEXT: store %struct.X* [[A]], %struct.X** [[B]], align 8
+; IS__CGSCC____-NEXT: ret void
;
store %struct.X* %a, %struct.X** %b
ret void
@@ -328,11 +409,13 @@ define internal void @test_sret(%struct.X* sret %a, %struct.X** %b) {
; FIXME: Alignment and dereferenceability are not propagated to the argument
define void @complicated_args_sret(%struct.X** %b) {
;
+; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_sret
; IS__TUNIT____-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]])
; IS__TUNIT____-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree writeonly align 536870912 null, %struct.X** nocapture nofree writeonly align 8 [[B]])
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_sret
; IS__CGSCC____-SAME: (%struct.X** nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[B:%.*]])
; IS__CGSCC____-NEXT: call void @test_sret(%struct.X* noalias nocapture nofree nonnull writeonly align 536870912 dereferenceable(8) null, %struct.X** nocapture nofree nonnull writeonly align 8 dereferenceable(8) [[B]])
@@ -343,16 +426,28 @@ define void @complicated_args_sret(%struct.X** %b) {
}
define internal %struct.X* @test_nest(%struct.X* nest %a) {
-; CHECK-LABEL: define {{[^@]+}}@test_nest
-; CHECK-SAME: (%struct.X* nest noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[A:%.*]])
-; CHECK-NEXT: ret %struct.X* [[A]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_nest
+; IS__TUNIT____-SAME: (%struct.X* nest noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[A:%.*]])
+; IS__TUNIT____-NEXT: ret %struct.X* [[A]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_nest
+; IS__CGSCC____-SAME: (%struct.X* nest noalias nofree readnone returned align 536870912 "no-capture-maybe-returned" [[A:%.*]])
+; IS__CGSCC____-NEXT: ret %struct.X* [[A]]
;
ret %struct.X* %a
}
define %struct.X* @complicated_args_nest() {
-; CHECK-LABEL: define {{[^@]+}}@complicated_args_nest()
-; CHECK-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree readnone align 536870912 null)
-; CHECK-NEXT: ret %struct.X* [[CALL]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_nest()
+; IS__TUNIT____-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree readnone align 536870912 null)
+; IS__TUNIT____-NEXT: ret %struct.X* [[CALL]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_nest()
+; IS__CGSCC____-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nocapture nofree readnone align 536870912 null)
+; IS__CGSCC____-NEXT: ret %struct.X* [[CALL]]
;
%call = call %struct.X* @test_nest(%struct.X* null)
ret %struct.X* %call
@@ -360,12 +455,14 @@ define %struct.X* @complicated_args_nest() {
@S = external global %struct.X
define internal void @test_byval(%struct.X* byval %a) {
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test_byval
; IS__CGSCC_OPM-SAME: (%struct.X* noalias nocapture nofree nonnull writeonly byval align 8 dereferenceable(8) [[A:%.*]])
; IS__CGSCC_OPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* [[A]], i32 0, i32 0
; IS__CGSCC_OPM-NEXT: store i8* null, i8** [[G0]], align 8
; IS__CGSCC_OPM-NEXT: ret void
;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test_byval
; IS__CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[TMP0:%.*]])
; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]], align 8
@@ -380,54 +477,146 @@ define internal void @test_byval(%struct.X* byval %a) {
ret void
}
define void @complicated_args_byval() {
-; CHECK-LABEL: define {{[^@]+}}@complicated_args_byval()
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_byval()
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@complicated_args_byval()
+; IS__CGSCC_OPM-NEXT: ret void
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@complicated_args_byval()
+; IS__CGSCC_NPM-NEXT: ret void
;
call void @test_byval(%struct.X* @S)
ret void
}
define internal i8*@test_byval2(%struct.X* byval %a) {
-; CHECK-LABEL: define {{[^@]+}}@test_byval2()
-; CHECK-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0
-; CHECK-NEXT: [[L:%.*]] = load i8*, i8** [[G0]], align 8
-; CHECK-NEXT: ret i8* [[L]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@test_byval2()
+; IS__TUNIT____-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0
+; IS__TUNIT____-NEXT: [[L:%.*]] = load i8*, i8** [[G0]], align 8
+; IS__TUNIT____-NEXT: ret i8* [[L]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@test_byval2()
+; IS__CGSCC____-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* @S, i32 0, i32 0
+; IS__CGSCC____-NEXT: [[L:%.*]] = load i8*, i8** [[G0]], align 8
+; IS__CGSCC____-NEXT: ret i8* [[L]]
;
%g0 = getelementptr %struct.X, %struct.X* %a, i32 0, i32 0
%l = load i8*, i8** %g0
ret i8* %l
}
define i8* @complicated_args_byval2() {
-; CHECK-LABEL: define {{[^@]+}}@complicated_args_byval2()
-; CHECK-NEXT: [[C:%.*]] = call i8* @test_byval2()
-; CHECK-NEXT: ret i8* [[C]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readonly willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@complicated_args_byval2()
+; IS__TUNIT____-NEXT: [[C:%.*]] = call i8* @test_byval2()
+; IS__TUNIT____-NEXT: ret i8* [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readonly willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@complicated_args_byval2()
+; IS__CGSCC____-NEXT: [[C:%.*]] = call i8* @test_byval2()
+; IS__CGSCC____-NEXT: ret i8* [[C]]
;
%c = call i8* @test_byval2(%struct.X* @S)
ret i8* %c
}
define void @fixpoint_changed(i32* %p) {
-; CHECK-LABEL: define {{[^@]+}}@fixpoint_changed
-; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[FOR_COND:%.*]]
-; CHECK: for.cond:
-; CHECK-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30
-; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
-; CHECK: for.body:
-; CHECK-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [
-; CHECK-NEXT: i32 1, label [[SW_BB:%.*]]
-; CHECK-NEXT: ]
-; CHECK: sw.bb:
-; CHECK-NEXT: br label [[SW_EPILOG]]
-; CHECK: sw.epilog:
-; CHECK-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]
-; CHECK-NEXT: store i32 [[X_0]], i32* [[P]], align 4
-; CHECK-NEXT: [[INC]] = add nsw i32 [[J_0]], 1
-; CHECK-NEXT: br label [[FOR_COND]]
-; CHECK: for.end:
-; CHECK-NEXT: ret void
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree nosync nounwind writeonly
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fixpoint_changed
+; IS__TUNIT_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: br label [[FOR_COND:%.*]]
+; IS__TUNIT_OPM: for.cond:
+; IS__TUNIT_OPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]
+; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30
+; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+; IS__TUNIT_OPM: for.body:
+; IS__TUNIT_OPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [
+; IS__TUNIT_OPM-NEXT: i32 1, label [[SW_BB:%.*]]
+; IS__TUNIT_OPM-NEXT: ]
+; IS__TUNIT_OPM: sw.bb:
+; IS__TUNIT_OPM-NEXT: br label [[SW_EPILOG]]
+; IS__TUNIT_OPM: sw.epilog:
+; IS__TUNIT_OPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]
+; IS__TUNIT_OPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4
+; IS__TUNIT_OPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1
+; IS__TUNIT_OPM-NEXT: br label [[FOR_COND]]
+; IS__TUNIT_OPM: for.end:
+; IS__TUNIT_OPM-NEXT: ret void
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree nosync nounwind willreturn writeonly
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fixpoint_changed
+; IS__TUNIT_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]]
+; IS__TUNIT_NPM: for.cond:
+; IS__TUNIT_NPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]
+; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30
+; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+; IS__TUNIT_NPM: for.body:
+; IS__TUNIT_NPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [
+; IS__TUNIT_NPM-NEXT: i32 1, label [[SW_BB:%.*]]
+; IS__TUNIT_NPM-NEXT: ]
+; IS__TUNIT_NPM: sw.bb:
+; IS__TUNIT_NPM-NEXT: br label [[SW_EPILOG]]
+; IS__TUNIT_NPM: sw.epilog:
+; IS__TUNIT_NPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]
+; IS__TUNIT_NPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4
+; IS__TUNIT_NPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1
+; IS__TUNIT_NPM-NEXT: br label [[FOR_COND]]
+; IS__TUNIT_NPM: for.end:
+; IS__TUNIT_NPM-NEXT: ret void
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree norecurse nosync nounwind writeonly
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fixpoint_changed
+; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: br label [[FOR_COND:%.*]]
+; IS__CGSCC_OPM: for.cond:
+; IS__CGSCC_OPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]
+; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30
+; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+; IS__CGSCC_OPM: for.body:
+; IS__CGSCC_OPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [
+; IS__CGSCC_OPM-NEXT: i32 1, label [[SW_BB:%.*]]
+; IS__CGSCC_OPM-NEXT: ]
+; IS__CGSCC_OPM: sw.bb:
+; IS__CGSCC_OPM-NEXT: br label [[SW_EPILOG]]
+; IS__CGSCC_OPM: sw.epilog:
+; IS__CGSCC_OPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]
+; IS__CGSCC_OPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4
+; IS__CGSCC_OPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1
+; IS__CGSCC_OPM-NEXT: br label [[FOR_COND]]
+; IS__CGSCC_OPM: for.end:
+; IS__CGSCC_OPM-NEXT: ret void
+;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree norecurse nosync nounwind willreturn writeonly
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fixpoint_changed
+; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[P:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]]
+; IS__CGSCC_NPM: for.cond:
+; IS__CGSCC_NPM-NEXT: [[J_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[SW_EPILOG:%.*]] ]
+; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[J_0]], 30
+; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_END:%.*]]
+; IS__CGSCC_NPM: for.body:
+; IS__CGSCC_NPM-NEXT: switch i32 [[J_0]], label [[SW_EPILOG]] [
+; IS__CGSCC_NPM-NEXT: i32 1, label [[SW_BB:%.*]]
+; IS__CGSCC_NPM-NEXT: ]
+; IS__CGSCC_NPM: sw.bb:
+; IS__CGSCC_NPM-NEXT: br label [[SW_EPILOG]]
+; IS__CGSCC_NPM: sw.epilog:
+; IS__CGSCC_NPM-NEXT: [[X_0:%.*]] = phi i32 [ 255, [[FOR_BODY]] ], [ 253, [[SW_BB]] ]
+; IS__CGSCC_NPM-NEXT: store i32 [[X_0]], i32* [[P]], align 4
+; IS__CGSCC_NPM-NEXT: [[INC]] = add nsw i32 [[J_0]], 1
+; IS__CGSCC_NPM-NEXT: br label [[FOR_COND]]
+; IS__CGSCC_NPM: for.end:
+; IS__CGSCC_NPM-NEXT: ret void
;
entry:
br label %for.cond
@@ -458,57 +647,99 @@ for.end:
; Check we merge undef and a constant properly.
; FIXME fold the addition and return the constant.
define i8 @caller0() {
-; CHECK-LABEL: define {{[^@]+}}@caller0()
-; CHECK-NEXT: [[C:%.*]] = call i8 @callee()
-; CHECK-NEXT: ret i8 [[C]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller0()
+; IS__TUNIT____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__TUNIT____-NEXT: ret i8 [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller0()
+; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__CGSCC____-NEXT: ret i8 [[C]]
;
%c = call i8 @callee(i8 undef)
ret i8 %c
}
define i8 @caller1() {
-; CHECK-LABEL: define {{[^@]+}}@caller1()
-; CHECK-NEXT: [[C:%.*]] = call i8 @callee()
-; CHECK-NEXT: ret i8 [[C]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller1()
+; IS__TUNIT____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__TUNIT____-NEXT: ret i8 [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller1()
+; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__CGSCC____-NEXT: ret i8 [[C]]
;
%c = call i8 @callee(i8 undef)
ret i8 %c
}
define i8 @caller2() {
-; CHECK-LABEL: define {{[^@]+}}@caller2()
-; CHECK-NEXT: [[C:%.*]] = call i8 @callee()
-; CHECK-NEXT: ret i8 [[C]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2()
+; IS__TUNIT____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__TUNIT____-NEXT: ret i8 [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2()
+; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__CGSCC____-NEXT: ret i8 [[C]]
;
%c = call i8 @callee(i8 undef)
ret i8 %c
}
define i8 @caller_middle() {
-; CHECK-LABEL: define {{[^@]+}}@caller_middle()
-; CHECK-NEXT: [[C:%.*]] = call i8 @callee()
-; CHECK-NEXT: ret i8 [[C]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller_middle()
+; IS__TUNIT____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__TUNIT____-NEXT: ret i8 [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller_middle()
+; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__CGSCC____-NEXT: ret i8 [[C]]
;
%c = call i8 @callee(i8 42)
ret i8 %c
}
define i8 @caller3() {
-; CHECK-LABEL: define {{[^@]+}}@caller3()
-; CHECK-NEXT: [[C:%.*]] = call i8 @callee()
-; CHECK-NEXT: ret i8 [[C]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller3()
+; IS__TUNIT____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__TUNIT____-NEXT: ret i8 [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller3()
+; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__CGSCC____-NEXT: ret i8 [[C]]
;
%c = call i8 @callee(i8 undef)
ret i8 %c
}
define i8 @caller4() {
-; CHECK-LABEL: define {{[^@]+}}@caller4()
-; CHECK-NEXT: [[C:%.*]] = call i8 @callee()
-; CHECK-NEXT: ret i8 [[C]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@caller4()
+; IS__TUNIT____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__TUNIT____-NEXT: ret i8 [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@caller4()
+; IS__CGSCC____-NEXT: [[C:%.*]] = call i8 @callee()
+; IS__CGSCC____-NEXT: ret i8 [[C]]
;
%c = call i8 @callee(i8 undef)
ret i8 %c
}
define internal i8 @callee(i8 %a) {
-; CHECK-LABEL: define {{[^@]+}}@callee()
-; CHECK-NEXT: [[C:%.*]] = add i8 42, 7
-; CHECK-NEXT: ret i8 [[C]]
+; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@callee()
+; IS__TUNIT____-NEXT: [[C:%.*]] = add i8 42, 7
+; IS__TUNIT____-NEXT: ret i8 [[C]]
+;
+; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@callee()
+; IS__CGSCC____-NEXT: [[C:%.*]] = add i8 42, 7
+; IS__CGSCC____-NEXT: ret i8 [[C]]
;
%c = add i8 %a, 7
ret i8 %c
diff --git a/llvm/test/Transforms/Attributor/willreturn.ll b/llvm/test/Transforms/Attributor/willreturn.ll
index 296339ce99b0..c568b2a956d5 100644
--- a/llvm/test/Transforms/Attributor/willreturn.ll
+++ b/llvm/test/Transforms/Attributor/willreturn.ll
@@ -1,4 +1,4 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes --check-attributes
; RUN: opt -attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=8 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
@@ -11,11 +11,14 @@ target datalayout = "e-m:e-i54:64-f80:128-n8:16:32:64-S128"
; TEST 1 (positive case)
+define void @only_return() #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@only_return()
+; IS__TUNIT____-NEXT: ret void
+;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
-define void @only_return() #0 {
-; CHECK-LABEL: define {{[^@]+}}@only_return()
-; CHECK-NEXT: ret void
+; IS__CGSCC____-LABEL: define {{[^@]+}}@only_return()
+; IS__CGSCC____-NEXT: ret void
;
ret void
}
@@ -29,8 +32,8 @@ define void @only_return() #0 {
; }
; FIXME: missing willreturn
-; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
define i32 @fib(i32 %0) local_unnamed_addr #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
; CHECK-LABEL: define {{[^@]+}}@fib
; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2
@@ -70,26 +73,42 @@ define i32 @fib(i32 %0) local_unnamed_addr #0 {
; }
; fact_maybe_not(-1) doesn't stop.
+define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
+; IS__TUNIT____-LABEL: define {{[^@]+}}@fact_maybe_not_halt
+; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
+; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP11:%.*]], label [[TMP3:%.*]]
+; IS__TUNIT____: 3:
+; IS__TUNIT____-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP8:%.*]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
+; IS__TUNIT____-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP3]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT____-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP4]], 0
+; IS__TUNIT____-NEXT: [[TMP7:%.*]] = sext i1 [[TMP6]] to i32
+; IS__TUNIT____-NEXT: [[TMP8]] = add nsw i32 [[TMP4]], [[TMP7]]
+; IS__TUNIT____-NEXT: [[TMP9]] = mul nsw i32 [[TMP4]], [[TMP5]]
+; IS__TUNIT____-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP8]], 0
+; IS__TUNIT____-NEXT: br i1 [[TMP10]], label [[TMP11]], label [[TMP3]]
+; IS__TUNIT____: 11:
+; IS__TUNIT____-NEXT: [[TMP12:%.*]] = phi i32 [ 1, [[TMP1]] ], [ [[TMP9]], [[TMP3]] ]
+; IS__TUNIT____-NEXT: ret i32 [[TMP12]]
+;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; CHECK-NOT: willreturn
-define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@fact_maybe_not_halt
-; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
-; CHECK-NEXT: br i1 [[TMP2]], label [[TMP11:%.*]], label [[TMP3:%.*]]
-; CHECK: 3:
-; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP8:%.*]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
-; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP3]] ], [ 1, [[TMP1]] ]
-; CHECK-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP4]], 0
-; CHECK-NEXT: [[TMP7:%.*]] = sext i1 [[TMP6]] to i32
-; CHECK-NEXT: [[TMP8]] = add nsw i32 [[TMP4]], [[TMP7]]
-; CHECK-NEXT: [[TMP9]] = mul nsw i32 [[TMP4]], [[TMP5]]
-; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP8]], 0
-; CHECK-NEXT: br i1 [[TMP10]], label [[TMP11]], label [[TMP3]]
-; CHECK: 11:
-; CHECK-NEXT: [[TMP12:%.*]] = phi i32 [ 1, [[TMP1]] ], [ [[TMP9]], [[TMP3]] ]
-; CHECK-NEXT: ret i32 [[TMP12]]
+; IS__CGSCC____-LABEL: define {{[^@]+}}@fact_maybe_not_halt
+; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
+; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP11:%.*]], label [[TMP3:%.*]]
+; IS__CGSCC____: 3:
+; IS__CGSCC____-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP8:%.*]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
+; IS__CGSCC____-NEXT: [[TMP5:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP3]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC____-NEXT: [[TMP6:%.*]] = icmp sgt i32 [[TMP4]], 0
+; IS__CGSCC____-NEXT: [[TMP7:%.*]] = sext i1 [[TMP6]] to i32
+; IS__CGSCC____-NEXT: [[TMP8]] = add nsw i32 [[TMP4]], [[TMP7]]
+; IS__CGSCC____-NEXT: [[TMP9]] = mul nsw i32 [[TMP4]], [[TMP5]]
+; IS__CGSCC____-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP8]], 0
+; IS__CGSCC____-NEXT: br i1 [[TMP10]], label [[TMP11]], label [[TMP3]]
+; IS__CGSCC____: 11:
+; IS__CGSCC____-NEXT: [[TMP12:%.*]] = phi i32 [ 1, [[TMP1]] ], [ [[TMP9]], [[TMP3]] ]
+; IS__CGSCC____-NEXT: ret i32 [[TMP12]]
;
%2 = icmp eq i32 %0, 0
br i1 %2, label %11, label %3
@@ -120,23 +139,70 @@ define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr #0 {
; return ans;
; }
-; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
define i32 @fact_loop(i32 %0) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@fact_loop
-; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
-; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
-; CHECK: 3:
-; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
-; CHECK-NEXT: ret i32 [[TMP4]]
-; CHECK: 5:
-; CHECK-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
-; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
-; CHECK-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
-; CHECK-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
-; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
-; CHECK-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
+; IS__TUNIT_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fact_loop
+; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
+; IS__TUNIT_OPM: 3:
+; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
+; IS__TUNIT_OPM-NEXT: ret i32 [[TMP4]]
+; IS__TUNIT_OPM: 5:
+; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
+; IS__TUNIT_OPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
+; IS__TUNIT_OPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fact_loop
+; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
+; IS__TUNIT_NPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
+; IS__TUNIT_NPM: 3:
+; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
+; IS__TUNIT_NPM-NEXT: ret i32 [[TMP4]]
+; IS__TUNIT_NPM: 5:
+; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
+; IS__TUNIT_NPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
+; IS__TUNIT_NPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
+; IS__TUNIT_NPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
+;
+; IS__CGSCC_OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fact_loop
+; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
+; IS__CGSCC_OPM: 3:
+; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
+; IS__CGSCC_OPM-NEXT: ret i32 [[TMP4]]
+; IS__CGSCC_OPM: 5:
+; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
+; IS__CGSCC_OPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
+; IS__CGSCC_OPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@fact_loop
+; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
+; IS__CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
+; IS__CGSCC_NPM: 3:
+; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
+; IS__CGSCC_NPM-NEXT: ret i32 [[TMP4]]
+; IS__CGSCC_NPM: 5:
+; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
+; IS__CGSCC_NPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
+; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
+; IS__CGSCC_NPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
;
%2 = icmp slt i32 %0, 1
br i1 %2, label %3, label %5
@@ -165,9 +231,8 @@ define i32 @fact_loop(i32 %0) local_unnamed_addr #0 {
declare void @sink() nounwind willreturn nosync nofree
-; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable
-; CHECK-NOT: willreturn
define void @mutual_recursion1(i1 %c) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@mutual_recursion1
; CHECK-SAME: (i1 [[C:%.*]])
; CHECK-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
@@ -188,9 +253,8 @@ end:
}
-; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable
-; CHECK-NOT: willreturn
define void @mutual_recursion2(i1 %c) #0 {
+; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@mutual_recursion2
; CHECK-SAME: (i1 [[C:%.*]])
; CHECK-NEXT: call void @mutual_recursion1(i1 [[C]])
@@ -207,9 +271,8 @@ define void @mutual_recursion2(i1 %c) #0 {
; CHECK-NEXT: declare void @exit(i32) local_unnamed_add
declare void @exit(i32 %0) local_unnamed_addr noreturn
-; CHECK: Function Attrs: noinline noreturn nounwind uwtable
-; CHECK-NOT: willreturn
define void @only_exit() local_unnamed_addr #0 {
+; CHECK: Function Attrs: noinline noreturn nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@only_exit() local_unnamed_addr
; CHECK-NEXT: tail call void @exit(i32 0)
; CHECK-NEXT: unreachable
@@ -228,9 +291,8 @@ define void @only_exit() local_unnamed_addr #0 {
; }
; return;
; }
-; CHECK: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: willreturn
define void @conditional_exit(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@conditional_exit
; CHECK-SAME: (i32 [[TMP0:%.*]], i32* nocapture readonly [[TMP1:%.*]]) local_unnamed_addr
; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
@@ -274,19 +336,23 @@ define void @conditional_exit(i32 %0, i32* nocapture readonly %1) local_unnamed_
; CHECK-NEXT: declare float @llvm.floor.f32(float)
declare float @llvm.floor.f32(float)
-; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
define void @call_floor(float %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@call_floor
-; CHECK-SAME: (float [[A:%.*]])
-; CHECK-NEXT: ret void
+; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@call_floor
+; IS__TUNIT____-SAME: (float [[A:%.*]])
+; IS__TUNIT____-NEXT: ret void
+;
+; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@call_floor
+; IS__CGSCC____-SAME: (float [[A:%.*]])
+; IS__CGSCC____-NEXT: ret void
;
tail call float @llvm.floor.f32(float %a)
ret void
}
-; CHECK: Function Attrs: noinline nosync nounwind readnone uwtable willreturn
define float @call_floor2(float %a) #0 {
+; CHECK: Function Attrs: noinline nosync nounwind readnone uwtable willreturn
; CHECK-LABEL: define {{[^@]+}}@call_floor2
; CHECK-SAME: (float [[A:%.*]])
; CHECK-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]])
@@ -305,9 +371,8 @@ define float @call_floor2(float %a) #0 {
; CHECK-NEXT: declare void @maybe_noreturn()
declare void @maybe_noreturn() #0
-; CHECK: Function Attrs: noinline nounwind uwtable
-; CHECK-NOT: willreturn
define void @call_maybe_noreturn() #0 {
+; CHECK: Function Attrs: noinline nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@call_maybe_noreturn()
; CHECK-NEXT: tail call void @maybe_noreturn()
; CHECK-NEXT: ret void
@@ -324,23 +389,31 @@ define void @call_maybe_noreturn() #0 {
; CHECK-NEXT: declare void @will_return()
declare void @will_return() willreturn norecurse
+define void @f1() #0 {
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@f1()
+; IS__TUNIT____-NEXT: tail call void @will_return()
+; IS__TUNIT____-NEXT: ret void
+;
; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable willreturn
-define void @f1() #0 {
-; CHECK-LABEL: define {{[^@]+}}@f1()
-; CHECK-NEXT: tail call void @will_return()
-; CHECK-NEXT: ret void
+; IS__CGSCC____-LABEL: define {{[^@]+}}@f1()
+; IS__CGSCC____-NEXT: tail call void @will_return()
+; IS__CGSCC____-NEXT: ret void
;
tail call void @will_return()
ret void
}
+define void @f2() #0 {
; IS__TUNIT____: Function Attrs: noinline nounwind uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@f2()
+; IS__TUNIT____-NEXT: tail call void @f1()
+; IS__TUNIT____-NEXT: ret void
+;
; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable willreturn
-define void @f2() #0 {
-; CHECK-LABEL: define {{[^@]+}}@f2()
-; CHECK-NEXT: tail call void @f1()
-; CHECK-NEXT: ret void
+; IS__CGSCC____-LABEL: define {{[^@]+}}@f2()
+; IS__CGSCC____-NEXT: tail call void @f1()
+; IS__CGSCC____-NEXT: ret void
;
tail call void @f1()
ret void
@@ -350,17 +423,24 @@ define void @f2() #0 {
; TEST 9 (negative case)
; call willreturn function in endless loop.
+define void @call_will_return_but_has_loop() #0 {
; IS__TUNIT____: Function Attrs: noinline noreturn nounwind uwtable
+; IS__TUNIT____-LABEL: define {{[^@]+}}@call_will_return_but_has_loop()
+; IS__TUNIT____-NEXT: br label [[LABEL1:%.*]]
+; IS__TUNIT____: label1:
+; IS__TUNIT____-NEXT: tail call void @will_return()
+; IS__TUNIT____-NEXT: br label [[LABEL2:%.*]]
+; IS__TUNIT____: label2:
+; IS__TUNIT____-NEXT: br label [[LABEL1]]
+;
; IS__CGSCC____: Function Attrs: noinline norecurse noreturn nounwind uwtable
-; CHECK-NOT: willreturn
-define void @call_will_return_but_has_loop() #0 {
-; CHECK-LABEL: define {{[^@]+}}@call_will_return_but_has_loop()
-; CHECK-NEXT: br label [[LABEL1:%.*]]
-; CHECK: label1:
-; CHECK-NEXT: tail call void @will_return()
-; CHECK-NEXT: br label [[LABEL2:%.*]]
-; CHECK: label2:
-; CHECK-NEXT: br label [[LABEL1]]
+; IS__CGSCC____-LABEL: define {{[^@]+}}@call_will_return_but_has_loop()
+; IS__CGSCC____-NEXT: br label [[LABEL1:%.*]]
+; IS__CGSCC____: label1:
+; IS__CGSCC____-NEXT: tail call void @will_return()
+; IS__CGSCC____-NEXT: br label [[LABEL2:%.*]]
+; IS__CGSCC____: label2:
+; IS__CGSCC____-NEXT: br label [[LABEL1]]
;
br label %label1
label1:
@@ -378,8 +458,8 @@ label2:
; CHECK-NEXT: declare i1 @maybe_raise_exception()
declare i1 @maybe_raise_exception() #1 willreturn
-; CHECK: Function Attrs: nounwind willreturn
define void @invoke_test() personality i32 (...)* @__gxx_personality_v0 {
+; IS__TUNIT____: Function Attrs: nounwind willreturn
; IS__TUNIT____-LABEL: define {{[^@]+}}@invoke_test() #12 personality i32 (...)* @__gxx_personality_v0
; IS__TUNIT____-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception()
; IS__TUNIT____-NEXT: to label [[N:%.*]] unwind label [[F:%.*]]
@@ -390,6 +470,7 @@ define void @invoke_test() personality i32 (...)* @__gxx_personality_v0 {
; IS__TUNIT____-NEXT: catch i8* null
; IS__TUNIT____-NEXT: ret void
;
+; IS__CGSCC____: Function Attrs: nounwind willreturn
; IS__CGSCC____-LABEL: define {{[^@]+}}@invoke_test() #14 personality i32 (...)* @__gxx_personality_v0
; IS__CGSCC____-NEXT: [[TMP1:%.*]] = invoke i1 @maybe_raise_exception()
; IS__CGSCC____-NEXT: to label [[N:%.*]] unwind label [[F:%.*]]
@@ -423,38 +504,70 @@ declare i32 @__gxx_personality_v0(...)
; return ans;
; }
-; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable
define i32 @loop_constant_trip_count(i32* nocapture readonly %0) #0 {
-; IS________OPM-LABEL: define {{[^@]+}}@loop_constant_trip_count
-; IS________OPM-SAME: (i32* nocapture nofree readonly [[TMP0:%.*]])
-; IS________OPM-NEXT: br label [[TMP3:%.*]]
-; IS________OPM: 2:
-; IS________OPM-NEXT: ret i32 [[TMP8:%.*]]
-; IS________OPM: 3:
-; IS________OPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ]
-; IS________OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ]
-; IS________OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]]
-; IS________OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4
-; IS________OPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]]
-; IS________OPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1
-; IS________OPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10
-; IS________OPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]]
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@loop_constant_trip_count
+; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly [[TMP0:%.*]])
+; IS__TUNIT_OPM-NEXT: br label [[TMP3:%.*]]
+; IS__TUNIT_OPM: 2:
+; IS__TUNIT_OPM-NEXT: ret i32 [[TMP8:%.*]]
+; IS__TUNIT_OPM: 3:
+; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]]
+; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4
+; IS__TUNIT_OPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]]
+; IS__TUNIT_OPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1
+; IS__TUNIT_OPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]]
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@loop_constant_trip_count
+; IS__TUNIT_NPM-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[TMP0:%.*]])
+; IS__TUNIT_NPM-NEXT: br label [[TMP3:%.*]]
+; IS__TUNIT_NPM: 2:
+; IS__TUNIT_NPM-NEXT: ret i32 [[TMP8:%.*]]
+; IS__TUNIT_NPM: 3:
+; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]]
+; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4
+; IS__TUNIT_NPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]]
+; IS__TUNIT_NPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1
+; IS__TUNIT_NPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10
+; IS__TUNIT_NPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]]
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@loop_constant_trip_count
+; IS__CGSCC_OPM-SAME: (i32* nocapture nofree readonly [[TMP0:%.*]])
+; IS__CGSCC_OPM-NEXT: br label [[TMP3:%.*]]
+; IS__CGSCC_OPM: 2:
+; IS__CGSCC_OPM-NEXT: ret i32 [[TMP8:%.*]]
+; IS__CGSCC_OPM: 3:
+; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]]
+; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4
+; IS__CGSCC_OPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]]
+; IS__CGSCC_OPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1
+; IS__CGSCC_OPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]]
;
-; IS________NPM-LABEL: define {{[^@]+}}@loop_constant_trip_count
-; IS________NPM-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[TMP0:%.*]])
-; IS________NPM-NEXT: br label [[TMP3:%.*]]
-; IS________NPM: 2:
-; IS________NPM-NEXT: ret i32 [[TMP8:%.*]]
-; IS________NPM: 3:
-; IS________NPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ]
-; IS________NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ]
-; IS________NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]]
-; IS________NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4
-; IS________NPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]]
-; IS________NPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1
-; IS________NPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10
-; IS________NPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]]
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@loop_constant_trip_count
+; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly dereferenceable(4) [[TMP0:%.*]])
+; IS__CGSCC_NPM-NEXT: br label [[TMP3:%.*]]
+; IS__CGSCC_NPM: 2:
+; IS__CGSCC_NPM-NEXT: ret i32 [[TMP8:%.*]]
+; IS__CGSCC_NPM: 3:
+; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [ [[TMP9:%.*]], [[TMP3]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]], [[TMP3]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0]], i64 [[TMP4]]
+; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4
+; IS__CGSCC_NPM-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]]
+; IS__CGSCC_NPM-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1
+; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10
+; IS__CGSCC_NPM-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]]
;
br label %3
@@ -483,27 +596,44 @@ define i32 @loop_constant_trip_count(i32* nocapture readonly %0) #0 {
; }
; return ans;
; }
+define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture readonly %2, i32 %3) local_unnamed_addr #0 {
; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable
+; IS__TUNIT____-LABEL: define {{[^@]+}}@loop_trip_count_unbound
+; IS__TUNIT____-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* nocapture nofree readonly [[TMP2:%.*]], i32 [[TMP3:%.*]]) local_unnamed_addr
+; IS__TUNIT____-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+; IS__TUNIT____-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]]
+; IS__TUNIT____: 6:
+; IS__TUNIT____-NEXT: [[TMP7:%.*]] = phi i32 [ 0, [[TMP4:%.*]] ], [ [[TMP14:%.*]], [[TMP8]] ]
+; IS__TUNIT____-NEXT: ret i32 [[TMP7]]
+; IS__TUNIT____: 8:
+; IS__TUNIT____-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP15:%.*]], [[TMP8]] ], [ [[TMP0]], [[TMP4]] ]
+; IS__TUNIT____-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP14]], [[TMP8]] ], [ 0, [[TMP4]] ]
+; IS__TUNIT____-NEXT: [[TMP11:%.*]] = zext i32 [[TMP9]] to i64
+; IS__TUNIT____-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP11]]
+; IS__TUNIT____-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
+; IS__TUNIT____-NEXT: [[TMP14]] = add nsw i32 [[TMP13]], [[TMP10]]
+; IS__TUNIT____-NEXT: [[TMP15]] = add i32 [[TMP9]], [[TMP3]]
+; IS__TUNIT____-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], [[TMP1]]
+; IS__TUNIT____-NEXT: br i1 [[TMP16]], label [[TMP6]], label [[TMP8]]
+;
; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable
-; CHECK-NOT: willreturn
-define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture readonly %2, i32 %3) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@loop_trip_count_unbound
-; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* nocapture nofree readonly [[TMP2:%.*]], i32 [[TMP3:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]]
-; CHECK: 6:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ 0, [[TMP4:%.*]] ], [ [[TMP14:%.*]], [[TMP8]] ]
-; CHECK-NEXT: ret i32 [[TMP7]]
-; CHECK: 8:
-; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP15:%.*]], [[TMP8]] ], [ [[TMP0]], [[TMP4]] ]
-; CHECK-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP14]], [[TMP8]] ], [ 0, [[TMP4]] ]
-; CHECK-NEXT: [[TMP11:%.*]] = zext i32 [[TMP9]] to i64
-; CHECK-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP11]]
-; CHECK-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
-; CHECK-NEXT: [[TMP14]] = add nsw i32 [[TMP13]], [[TMP10]]
-; CHECK-NEXT: [[TMP15]] = add i32 [[TMP9]], [[TMP3]]
-; CHECK-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], [[TMP1]]
-; CHECK-NEXT: br i1 [[TMP16]], label [[TMP6]], label [[TMP8]]
+; IS__CGSCC____-LABEL: define {{[^@]+}}@loop_trip_count_unbound
+; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32* nocapture nofree readonly [[TMP2:%.*]], i32 [[TMP3:%.*]]) local_unnamed_addr
+; IS__CGSCC____-NEXT: [[TMP5:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
+; IS__CGSCC____-NEXT: br i1 [[TMP5]], label [[TMP6:%.*]], label [[TMP8:%.*]]
+; IS__CGSCC____: 6:
+; IS__CGSCC____-NEXT: [[TMP7:%.*]] = phi i32 [ 0, [[TMP4:%.*]] ], [ [[TMP14:%.*]], [[TMP8]] ]
+; IS__CGSCC____-NEXT: ret i32 [[TMP7]]
+; IS__CGSCC____: 8:
+; IS__CGSCC____-NEXT: [[TMP9:%.*]] = phi i32 [ [[TMP15:%.*]], [[TMP8]] ], [ [[TMP0]], [[TMP4]] ]
+; IS__CGSCC____-NEXT: [[TMP10:%.*]] = phi i32 [ [[TMP14]], [[TMP8]] ], [ 0, [[TMP4]] ]
+; IS__CGSCC____-NEXT: [[TMP11:%.*]] = zext i32 [[TMP9]] to i64
+; IS__CGSCC____-NEXT: [[TMP12:%.*]] = getelementptr inbounds i32, i32* [[TMP2]], i64 [[TMP11]]
+; IS__CGSCC____-NEXT: [[TMP13:%.*]] = load i32, i32* [[TMP12]], align 4
+; IS__CGSCC____-NEXT: [[TMP14]] = add nsw i32 [[TMP13]], [[TMP10]]
+; IS__CGSCC____-NEXT: [[TMP15]] = add i32 [[TMP9]], [[TMP3]]
+; IS__CGSCC____-NEXT: [[TMP16:%.*]] = icmp eq i32 [[TMP15]], [[TMP1]]
+; IS__CGSCC____-NEXT: br i1 [[TMP16]], label [[TMP6]], label [[TMP8]]
;
%5 = icmp eq i32 %0, %1
br i1 %5, label %6, label %8
@@ -536,28 +666,90 @@ define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture readonly %2,
; }
-; IS__TUNIT____: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable
-; IS__CGSCC____: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable
define i32 @loop_trip_dec(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@loop_trip_dec
-; CHECK-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1
-; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]]
-; CHECK: 4:
-; CHECK-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64
-; CHECK-NEXT: br label [[TMP6:%.*]]
-; CHECK: 6:
-; CHECK-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ]
-; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ]
-; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]]
-; CHECK-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
-; CHECK-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]]
-; CHECK-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1
-; CHECK-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0
-; CHECK-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]]
-; CHECK: 14:
-; CHECK-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ]
-; CHECK-NEXT: ret i32 [[TMP15]]
+; IS__TUNIT_OPM: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@loop_trip_dec
+; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr
+; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]]
+; IS__TUNIT_OPM: 4:
+; IS__TUNIT_OPM-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64
+; IS__TUNIT_OPM-NEXT: br label [[TMP6:%.*]]
+; IS__TUNIT_OPM: 6:
+; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]]
+; IS__TUNIT_OPM-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
+; IS__TUNIT_OPM-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]]
+; IS__TUNIT_OPM-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1
+; IS__TUNIT_OPM-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]]
+; IS__TUNIT_OPM: 14:
+; IS__TUNIT_OPM-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ]
+; IS__TUNIT_OPM-NEXT: ret i32 [[TMP15]]
+;
+; IS__TUNIT_NPM: Function Attrs: argmemonly nofree noinline nosync nounwind readonly uwtable willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@loop_trip_dec
+; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr
+; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1
+; IS__TUNIT_NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]]
+; IS__TUNIT_NPM: 4:
+; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64
+; IS__TUNIT_NPM-NEXT: br label [[TMP6:%.*]]
+; IS__TUNIT_NPM: 6:
+; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]]
+; IS__TUNIT_NPM-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
+; IS__TUNIT_NPM-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]]
+; IS__TUNIT_NPM-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1
+; IS__TUNIT_NPM-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0
+; IS__TUNIT_NPM-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]]
+; IS__TUNIT_NPM: 14:
+; IS__TUNIT_NPM-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ]
+; IS__TUNIT_NPM-NEXT: ret i32 [[TMP15]]
+;
+; IS__CGSCC_OPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@loop_trip_dec
+; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr
+; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]]
+; IS__CGSCC_OPM: 4:
+; IS__CGSCC_OPM-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64
+; IS__CGSCC_OPM-NEXT: br label [[TMP6:%.*]]
+; IS__CGSCC_OPM: 6:
+; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]]
+; IS__CGSCC_OPM-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
+; IS__CGSCC_OPM-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]]
+; IS__CGSCC_OPM-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1
+; IS__CGSCC_OPM-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]]
+; IS__CGSCC_OPM: 14:
+; IS__CGSCC_OPM-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ]
+; IS__CGSCC_OPM-NEXT: ret i32 [[TMP15]]
+;
+; IS__CGSCC_NPM: Function Attrs: argmemonly nofree noinline norecurse nosync nounwind readonly uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@loop_trip_dec
+; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i32* nocapture nofree readonly [[TMP1:%.*]]) local_unnamed_addr
+; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], -1
+; IS__CGSCC_NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP14:%.*]]
+; IS__CGSCC_NPM: 4:
+; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = sext i32 [[TMP0]] to i64
+; IS__CGSCC_NPM-NEXT: br label [[TMP6:%.*]]
+; IS__CGSCC_NPM: 6:
+; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = phi i64 [ [[TMP5]], [[TMP4]] ], [ [[TMP12:%.*]], [[TMP6]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = phi i32 [ 0, [[TMP4]] ], [ [[TMP11:%.*]], [[TMP6]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[TMP1]], i64 [[TMP7]]
+; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4
+; IS__CGSCC_NPM-NEXT: [[TMP11]] = add nsw i32 [[TMP10]], [[TMP8]]
+; IS__CGSCC_NPM-NEXT: [[TMP12]] = add nsw i64 [[TMP7]], -1
+; IS__CGSCC_NPM-NEXT: [[TMP13:%.*]] = icmp sgt i64 [[TMP7]], 0
+; IS__CGSCC_NPM-NEXT: br i1 [[TMP13]], label [[TMP6]], label [[TMP14]]
+; IS__CGSCC_NPM: 14:
+; IS__CGSCC_NPM-NEXT: [[TMP15:%.*]] = phi i32 [ 0, [[TMP2:%.*]] ], [ [[TMP11]], [[TMP6]] ]
+; IS__CGSCC_NPM-NEXT: ret i32 [[TMP15]]
;
%3 = icmp sgt i32 %0, -1
br i1 %3, label %4, label %14
@@ -584,17 +776,26 @@ define i32 @loop_trip_dec(i32 %0, i32* nocapture readonly %1) local_unnamed_addr
; TEST 14 (positive case)
; multiple return
+define i32 @multiple_return(i32 %a) #0 {
; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@multiple_return
+; IS__TUNIT____-SAME: (i32 [[A:%.*]])
+; IS__TUNIT____-NEXT: [[B:%.*]] = icmp eq i32 [[A]], 0
+; IS__TUNIT____-NEXT: br i1 [[B]], label [[T:%.*]], label [[F:%.*]]
+; IS__TUNIT____: t:
+; IS__TUNIT____-NEXT: ret i32 1
+; IS__TUNIT____: f:
+; IS__TUNIT____-NEXT: ret i32 0
+;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
-define i32 @multiple_return(i32 %a) #0 {
-; CHECK-LABEL: define {{[^@]+}}@multiple_return
-; CHECK-SAME: (i32 [[A:%.*]])
-; CHECK-NEXT: [[B:%.*]] = icmp eq i32 [[A]], 0
-; CHECK-NEXT: br i1 [[B]], label [[T:%.*]], label [[F:%.*]]
-; CHECK: t:
-; CHECK-NEXT: ret i32 1
-; CHECK: f:
-; CHECK-NEXT: ret i32 0
+; IS__CGSCC____-LABEL: define {{[^@]+}}@multiple_return
+; IS__CGSCC____-SAME: (i32 [[A:%.*]])
+; IS__CGSCC____-NEXT: [[B:%.*]] = icmp eq i32 [[A]], 0
+; IS__CGSCC____-NEXT: br i1 [[B]], label [[T:%.*]], label [[F:%.*]]
+; IS__CGSCC____: t:
+; IS__CGSCC____-NEXT: ret i32 1
+; IS__CGSCC____: f:
+; IS__CGSCC____-NEXT: ret i32 0
;
%b = icmp eq i32 %a, 0
br i1 %b, label %t, label %f
@@ -609,14 +810,20 @@ f:
; unreachable exit
; 15.1 (positive case)
-; IS__TUNIT____: Function Attrs: noinline nounwind uwtable
-; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable willreturn
define void @unreachable_exit_positive1() #0 {
-; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_positive1()
-; CHECK-NEXT: tail call void @will_return()
-; CHECK-NEXT: ret void
-; CHECK: unreachable_label:
-; CHECK-NEXT: unreachable
+; IS__TUNIT____: Function Attrs: noinline nounwind uwtable willreturn
+; IS__TUNIT____-LABEL: define {{[^@]+}}@unreachable_exit_positive1()
+; IS__TUNIT____-NEXT: tail call void @will_return()
+; IS__TUNIT____-NEXT: ret void
+; IS__TUNIT____: unreachable_label:
+; IS__TUNIT____-NEXT: unreachable
+;
+; IS__CGSCC____: Function Attrs: noinline norecurse nounwind uwtable willreturn
+; IS__CGSCC____-LABEL: define {{[^@]+}}@unreachable_exit_positive1()
+; IS__CGSCC____-NEXT: tail call void @will_return()
+; IS__CGSCC____-NEXT: ret void
+; IS__CGSCC____: unreachable_label:
+; IS__CGSCC____-NEXT: unreachable
;
tail call void @will_return()
ret void
@@ -626,25 +833,78 @@ unreachable_label:
unreachable
}
-; IS__TUNIT____: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; IS__CGSCC____: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
define i32 @unreachable_exit_positive2(i32) local_unnamed_addr #0 {
-; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_positive2
-; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
-; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
-; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
-; CHECK: 3:
-; CHECK-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
-; CHECK-NEXT: ret i32 [[TMP4]]
-; CHECK: 5:
-; CHECK-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
-; CHECK-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
-; CHECK-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
-; CHECK-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
-; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
-; CHECK-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
-; CHECK: unreachable_label:
-; CHECK-NEXT: unreachable
+; IS__TUNIT_OPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unreachable_exit_positive2
+; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
+; IS__TUNIT_OPM: 3:
+; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
+; IS__TUNIT_OPM-NEXT: ret i32 [[TMP4]]
+; IS__TUNIT_OPM: 5:
+; IS__TUNIT_OPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT_OPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
+; IS__TUNIT_OPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
+; IS__TUNIT_OPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
+; IS__TUNIT_OPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
+; IS__TUNIT_OPM: unreachable_label:
+; IS__TUNIT_OPM-NEXT: unreachable
+;
+; IS__TUNIT_NPM: Function Attrs: nofree noinline nosync nounwind readnone uwtable willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unreachable_exit_positive2
+; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
+; IS__TUNIT_NPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
+; IS__TUNIT_NPM: 3:
+; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
+; IS__TUNIT_NPM-NEXT: ret i32 [[TMP4]]
+; IS__TUNIT_NPM: 5:
+; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__TUNIT_NPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
+; IS__TUNIT_NPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
+; IS__TUNIT_NPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
+; IS__TUNIT_NPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
+; IS__TUNIT_NPM: unreachable_label:
+; IS__TUNIT_NPM-NEXT: unreachable
+;
+; IS__CGSCC_OPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@unreachable_exit_positive2
+; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
+; IS__CGSCC_OPM: 3:
+; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
+; IS__CGSCC_OPM-NEXT: ret i32 [[TMP4]]
+; IS__CGSCC_OPM: 5:
+; IS__CGSCC_OPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC_OPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
+; IS__CGSCC_OPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
+; IS__CGSCC_OPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
+; IS__CGSCC_OPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
+; IS__CGSCC_OPM: unreachable_label:
+; IS__CGSCC_OPM-NEXT: unreachable
+;
+; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@unreachable_exit_positive2
+; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
+; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 1
+; IS__CGSCC_NPM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
+; IS__CGSCC_NPM: 3:
+; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 1, [[TMP1:%.*]] ], [ [[TMP8:%.*]], [[TMP5]] ]
+; IS__CGSCC_NPM-NEXT: ret i32 [[TMP4]]
+; IS__CGSCC_NPM: 5:
+; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = phi i32 [ [[TMP9:%.*]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8]], [[TMP5]] ], [ 1, [[TMP1]] ]
+; IS__CGSCC_NPM-NEXT: [[TMP8]] = mul nsw i32 [[TMP6]], [[TMP7]]
+; IS__CGSCC_NPM-NEXT: [[TMP9]] = add nuw nsw i32 [[TMP6]], 1
+; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = icmp eq i32 [[TMP6]], [[TMP0]]
+; IS__CGSCC_NPM-NEXT: br i1 [[TMP10]], label [[TMP3]], label [[TMP5]]
+; IS__CGSCC_NPM: unreachable_label:
+; IS__CGSCC_NPM-NEXT: unreachable
;
%2 = icmp slt i32 %0, 1
br i1 %2, label %3, label %5
@@ -669,9 +929,8 @@ unreachable_label:
;15.2
-; CHECK: Function Attrs: noinline noreturn nounwind uwtable
-; CHECK-NOT: willreturn
define void @unreachable_exit_negative1() #0 {
+; CHECK: Function Attrs: noinline noreturn nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_negative1()
; CHECK-NEXT: tail call void @exit(i32 0)
; CHECK-NEXT: unreachable
@@ -686,18 +945,26 @@ unreachable_label:
unreachable
}
+define void @unreachable_exit_negative2() #0 {
; IS__TUNIT____: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
+; IS__TUNIT____-LABEL: define {{[^@]+}}@unreachable_exit_negative2()
+; IS__TUNIT____-NEXT: br label [[L1:%.*]]
+; IS__TUNIT____: L1:
+; IS__TUNIT____-NEXT: br label [[L2:%.*]]
+; IS__TUNIT____: L2:
+; IS__TUNIT____-NEXT: br label [[L1]]
+; IS__TUNIT____: unreachable_label:
+; IS__TUNIT____-NEXT: unreachable
+;
; IS__CGSCC____: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
-; CHECK-NOT: willreturn
-define void @unreachable_exit_negative2() #0 {
-; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_negative2()
-; CHECK-NEXT: br label [[L1:%.*]]
-; CHECK: L1:
-; CHECK-NEXT: br label [[L2:%.*]]
-; CHECK: L2:
-; CHECK-NEXT: br label [[L1]]
-; CHECK: unreachable_label:
-; CHECK-NEXT: unreachable
+; IS__CGSCC____-LABEL: define {{[^@]+}}@unreachable_exit_negative2()
+; IS__CGSCC____-NEXT: br label [[L1:%.*]]
+; IS__CGSCC____: L1:
+; IS__CGSCC____-NEXT: br label [[L2:%.*]]
+; IS__CGSCC____: L2:
+; IS__CGSCC____-NEXT: br label [[L1]]
+; IS__CGSCC____: unreachable_label:
+; IS__CGSCC____-NEXT: unreachable
;
br label %L1
L1:
@@ -714,9 +981,8 @@ unreachable_label:
; CHECK-NEXT: declare void @llvm.eh.sjlj.longjmp(i8*)
declare void @llvm.eh.sjlj.longjmp(i8*)
-; CHECK: Function Attrs: noinline noreturn nounwind uwtable
-; CHECK-NOT: willreturn
define void @call_longjmp(i8* nocapture readnone %0) local_unnamed_addr #0 {
+; CHECK: Function Attrs: noinline noreturn nounwind uwtable
; CHECK-LABEL: define {{[^@]+}}@call_longjmp
; CHECK-SAME: (i8* nocapture readnone [[TMP0:%.*]]) local_unnamed_addr
; CHECK-NEXT: tail call void @llvm.eh.sjlj.longjmp(i8* noalias readnone [[TMP0]])
@@ -737,29 +1003,48 @@ define void @call_longjmp(i8* nocapture readnone %0) local_unnamed_addr #0 {
; return ans;
; }
+define i32 @infinite_loop_inside_bounded_loop(i32 %n) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT____-LABEL: define {{[^@]+}}@infinite_loop_inside_bounded_loop
+; IS__TUNIT____-SAME: (i32 [[N:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[FOR_COND:%.*]]
+; IS__TUNIT____: for.cond:
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
+; IS__TUNIT____: for.cond.cleanup:
+; IS__TUNIT____-NEXT: br label [[FOR_END:%.*]]
+; IS__TUNIT____: for.body:
+; IS__TUNIT____-NEXT: br label [[WHILE_COND:%.*]]
+; IS__TUNIT____: while.cond:
+; IS__TUNIT____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__TUNIT____: while.body:
+; IS__TUNIT____-NEXT: br label [[WHILE_COND]]
+; IS__TUNIT____: for.inc:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: for.end:
+; IS__TUNIT____-NEXT: ret i32 0
+;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone
-; CHECK-NOT: willreturn
-define i32 @infinite_loop_inside_bounded_loop(i32 %n) {
-; CHECK-LABEL: define {{[^@]+}}@infinite_loop_inside_bounded_loop
-; CHECK-SAME: (i32 [[N:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[FOR_COND:%.*]]
-; CHECK: for.cond:
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0
-; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
-; CHECK: for.cond.cleanup:
-; CHECK-NEXT: br label [[FOR_END:%.*]]
-; CHECK: for.body:
-; CHECK-NEXT: br label [[WHILE_COND:%.*]]
-; CHECK: while.cond:
-; CHECK-NEXT: br label [[WHILE_BODY:%.*]]
-; CHECK: while.body:
-; CHECK-NEXT: br label [[WHILE_COND]]
-; CHECK: for.inc:
-; CHECK-NEXT: unreachable
-; CHECK: for.end:
-; CHECK-NEXT: ret i32 0
+; IS__CGSCC____-LABEL: define {{[^@]+}}@infinite_loop_inside_bounded_loop
+; IS__CGSCC____-SAME: (i32 [[N:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[FOR_COND:%.*]]
+; IS__CGSCC____: for.cond:
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[N]], 0
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
+; IS__CGSCC____: for.cond.cleanup:
+; IS__CGSCC____-NEXT: br label [[FOR_END:%.*]]
+; IS__CGSCC____: for.body:
+; IS__CGSCC____-NEXT: br label [[WHILE_COND:%.*]]
+; IS__CGSCC____: while.cond:
+; IS__CGSCC____-NEXT: br label [[WHILE_BODY:%.*]]
+; IS__CGSCC____: while.body:
+; IS__CGSCC____-NEXT: br label [[WHILE_COND]]
+; IS__CGSCC____: for.inc:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: for.end:
+; IS__CGSCC____-NEXT: ret i32 0
;
entry:
br label %for.cond
@@ -800,36 +1085,122 @@ for.end: ; preds = %for.cond.cleanup
; return ans;
; }
-; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
-; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone
define i32 @bounded_nested_loops(i32 %n) {
-; CHECK-LABEL: define {{[^@]+}}@bounded_nested_loops
-; CHECK-SAME: (i32 [[N:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[FOR_COND:%.*]]
-; CHECK: for.cond:
-; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ]
-; CHECK-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ]
-; CHECK-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ]
-; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]]
-; CHECK-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
-; CHECK: for.cond.cleanup:
-; CHECK-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ]
-; CHECK-NEXT: br label [[FOR_END:%.*]]
-; CHECK: for.body:
-; CHECK-NEXT: br label [[WHILE_COND:%.*]]
-; CHECK: while.cond:
-; CHECK-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
-; CHECK: while.body:
-; CHECK-NEXT: unreachable
-; CHECK: while.end:
-; CHECK-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]]
-; CHECK-NEXT: br label [[FOR_INC]]
-; CHECK: for.inc:
-; CHECK-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1
-; CHECK-NEXT: br label [[FOR_COND]]
-; CHECK: for.end:
-; CHECK-NEXT: ret i32 [[ANS_0_LCSSA]]
+; IS__TUNIT_OPM: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@bounded_nested_loops
+; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]])
+; IS__TUNIT_OPM-NEXT: entry:
+; IS__TUNIT_OPM-NEXT: br label [[FOR_COND:%.*]]
+; IS__TUNIT_OPM: for.cond:
+; IS__TUNIT_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ]
+; IS__TUNIT_OPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ]
+; IS__TUNIT_OPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ]
+; IS__TUNIT_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]]
+; IS__TUNIT_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
+; IS__TUNIT_OPM: for.cond.cleanup:
+; IS__TUNIT_OPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ]
+; IS__TUNIT_OPM-NEXT: br label [[FOR_END:%.*]]
+; IS__TUNIT_OPM: for.body:
+; IS__TUNIT_OPM-NEXT: br label [[WHILE_COND:%.*]]
+; IS__TUNIT_OPM: while.cond:
+; IS__TUNIT_OPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
+; IS__TUNIT_OPM: while.body:
+; IS__TUNIT_OPM-NEXT: unreachable
+; IS__TUNIT_OPM: while.end:
+; IS__TUNIT_OPM-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]]
+; IS__TUNIT_OPM-NEXT: br label [[FOR_INC]]
+; IS__TUNIT_OPM: for.inc:
+; IS__TUNIT_OPM-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1
+; IS__TUNIT_OPM-NEXT: br label [[FOR_COND]]
+; IS__TUNIT_OPM: for.end:
+; IS__TUNIT_OPM-NEXT: ret i32 [[ANS_0_LCSSA]]
+;
+; IS__TUNIT_NPM: Function Attrs: nofree nosync nounwind readnone willreturn
+; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@bounded_nested_loops
+; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]])
+; IS__TUNIT_NPM-NEXT: entry:
+; IS__TUNIT_NPM-NEXT: br label [[FOR_COND:%.*]]
+; IS__TUNIT_NPM: for.cond:
+; IS__TUNIT_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ]
+; IS__TUNIT_NPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ]
+; IS__TUNIT_NPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ]
+; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]]
+; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
+; IS__TUNIT_NPM: for.cond.cleanup:
+; IS__TUNIT_NPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ]
+; IS__TUNIT_NPM-NEXT: br label [[FOR_END:%.*]]
+; IS__TUNIT_NPM: for.body:
+; IS__TUNIT_NPM-NEXT: br label [[WHILE_COND:%.*]]
+; IS__TUNIT_NPM: while.cond:
+; IS__TUNIT_NPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
+; IS__TUNIT_NPM: while.body:
+; IS__TUNIT_NPM-NEXT: unreachable
+; IS__TUNIT_NPM: while.end:
+; IS__TUNIT_NPM-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]]
+; IS__TUNIT_NPM-NEXT: br label [[FOR_INC]]
+; IS__TUNIT_NPM: for.inc:
+; IS__TUNIT_NPM-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1
+; IS__TUNIT_NPM-NEXT: br label [[FOR_COND]]
+; IS__TUNIT_NPM: for.end:
+; IS__TUNIT_NPM-NEXT: ret i32 [[ANS_0_LCSSA]]
+;
+; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
+; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bounded_nested_loops
+; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]])
+; IS__CGSCC_OPM-NEXT: entry:
+; IS__CGSCC_OPM-NEXT: br label [[FOR_COND:%.*]]
+; IS__CGSCC_OPM: for.cond:
+; IS__CGSCC_OPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ]
+; IS__CGSCC_OPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ]
+; IS__CGSCC_OPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ]
+; IS__CGSCC_OPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]]
+; IS__CGSCC_OPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
+; IS__CGSCC_OPM: for.cond.cleanup:
+; IS__CGSCC_OPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ]
+; IS__CGSCC_OPM-NEXT: br label [[FOR_END:%.*]]
+; IS__CGSCC_OPM: for.body:
+; IS__CGSCC_OPM-NEXT: br label [[WHILE_COND:%.*]]
+; IS__CGSCC_OPM: while.cond:
+; IS__CGSCC_OPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
+; IS__CGSCC_OPM: while.body:
+; IS__CGSCC_OPM-NEXT: unreachable
+; IS__CGSCC_OPM: while.end:
+; IS__CGSCC_OPM-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]]
+; IS__CGSCC_OPM-NEXT: br label [[FOR_INC]]
+; IS__CGSCC_OPM: for.inc:
+; IS__CGSCC_OPM-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1
+; IS__CGSCC_OPM-NEXT: br label [[FOR_COND]]
+; IS__CGSCC_OPM: for.end:
+; IS__CGSCC_OPM-NEXT: ret i32 [[ANS_0_LCSSA]]
+;
+; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
+; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bounded_nested_loops
+; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]])
+; IS__CGSCC_NPM-NEXT: entry:
+; IS__CGSCC_NPM-NEXT: br label [[FOR_COND:%.*]]
+; IS__CGSCC_NPM: for.cond:
+; IS__CGSCC_NPM-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[INC1:%.*]], [[FOR_INC:%.*]] ]
+; IS__CGSCC_NPM-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[TMP:%.*]], [[FOR_INC]] ]
+; IS__CGSCC_NPM-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[FOR_INC]] ]
+; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N_ADDR_0]]
+; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[FOR_BODY:%.*]], label [[FOR_COND_CLEANUP:%.*]]
+; IS__CGSCC_NPM: for.cond.cleanup:
+; IS__CGSCC_NPM-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[FOR_COND]] ]
+; IS__CGSCC_NPM-NEXT: br label [[FOR_END:%.*]]
+; IS__CGSCC_NPM: for.body:
+; IS__CGSCC_NPM-NEXT: br label [[WHILE_COND:%.*]]
+; IS__CGSCC_NPM: while.cond:
+; IS__CGSCC_NPM-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
+; IS__CGSCC_NPM: while.body:
+; IS__CGSCC_NPM-NEXT: unreachable
+; IS__CGSCC_NPM: while.end:
+; IS__CGSCC_NPM-NEXT: [[TMP]] = add i32 [[N_ADDR_0]], [[ANS_0]]
+; IS__CGSCC_NPM-NEXT: br label [[FOR_INC]]
+; IS__CGSCC_NPM: for.inc:
+; IS__CGSCC_NPM-NEXT: [[INC1]] = add nuw nsw i32 [[I_0]], 1
+; IS__CGSCC_NPM-NEXT: br label [[FOR_COND]]
+; IS__CGSCC_NPM: for.end:
+; IS__CGSCC_NPM-NEXT: ret i32 [[ANS_0_LCSSA]]
;
entry:
br label %for.cond
@@ -878,39 +1249,68 @@ for.end: ; preds = %for.cond.cleanup
; return ans;
; }
+define i32 @bounded_loop_inside_unbounded_loop(i32 %n) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT____-LABEL: define {{[^@]+}}@bounded_loop_inside_unbounded_loop
+; IS__TUNIT____-SAME: (i32 [[N:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[WHILE_COND:%.*]]
+; IS__TUNIT____: while.cond:
+; IS__TUNIT____-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_END:%.*]] ]
+; IS__TUNIT____-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[INC:%.*]], [[FOR_END]] ]
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = icmp sgt i32 [[N_ADDR_0]], -1
+; IS__TUNIT____-NEXT: [[SMAX:%.*]] = select i1 [[TMP]], i32 [[N_ADDR_0]], i32 -1
+; IS__TUNIT____-NEXT: [[INC]] = add nsw i32 [[N_ADDR_0]], 1
+; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0
+; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
+; IS__TUNIT____: while.body:
+; IS__TUNIT____-NEXT: [[TMP1:%.*]] = add i32 [[ANS_0]], 1
+; IS__TUNIT____-NEXT: br label [[FOR_COND:%.*]]
+; IS__TUNIT____: for.cond:
+; IS__TUNIT____-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]
+; IS__TUNIT____: for.cond.cleanup:
+; IS__TUNIT____-NEXT: [[TMP2]] = add i32 [[TMP1]], [[SMAX]]
+; IS__TUNIT____-NEXT: br label [[FOR_END]]
+; IS__TUNIT____: for.body:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: for.inc:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: for.end:
+; IS__TUNIT____-NEXT: br label [[WHILE_COND]]
+; IS__TUNIT____: while.end:
+; IS__TUNIT____-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ]
+; IS__TUNIT____-NEXT: ret i32 [[ANS_0_LCSSA]]
+;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone
-; CHECK-NOT: willreturn
-define i32 @bounded_loop_inside_unbounded_loop(i32 %n) {
-; CHECK-LABEL: define {{[^@]+}}@bounded_loop_inside_unbounded_loop
-; CHECK-SAME: (i32 [[N:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[WHILE_COND:%.*]]
-; CHECK: while.cond:
-; CHECK-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_END:%.*]] ]
-; CHECK-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[INC:%.*]], [[FOR_END]] ]
-; CHECK-NEXT: [[TMP:%.*]] = icmp sgt i32 [[N_ADDR_0]], -1
-; CHECK-NEXT: [[SMAX:%.*]] = select i1 [[TMP]], i32 [[N_ADDR_0]], i32 -1
-; CHECK-NEXT: [[INC]] = add nsw i32 [[N_ADDR_0]], 1
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0
-; CHECK-NEXT: br i1 [[TOBOOL]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
-; CHECK: while.body:
-; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[ANS_0]], 1
-; CHECK-NEXT: br label [[FOR_COND:%.*]]
-; CHECK: for.cond:
-; CHECK-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]
-; CHECK: for.cond.cleanup:
-; CHECK-NEXT: [[TMP2]] = add i32 [[TMP1]], [[SMAX]]
-; CHECK-NEXT: br label [[FOR_END]]
-; CHECK: for.body:
-; CHECK-NEXT: unreachable
-; CHECK: for.inc:
-; CHECK-NEXT: unreachable
-; CHECK: for.end:
-; CHECK-NEXT: br label [[WHILE_COND]]
-; CHECK: while.end:
-; CHECK-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ]
-; CHECK-NEXT: ret i32 [[ANS_0_LCSSA]]
+; IS__CGSCC____-LABEL: define {{[^@]+}}@bounded_loop_inside_unbounded_loop
+; IS__CGSCC____-SAME: (i32 [[N:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[WHILE_COND:%.*]]
+; IS__CGSCC____: while.cond:
+; IS__CGSCC____-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[FOR_END:%.*]] ]
+; IS__CGSCC____-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ [[INC:%.*]], [[FOR_END]] ]
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = icmp sgt i32 [[N_ADDR_0]], -1
+; IS__CGSCC____-NEXT: [[SMAX:%.*]] = select i1 [[TMP]], i32 [[N_ADDR_0]], i32 -1
+; IS__CGSCC____-NEXT: [[INC]] = add nsw i32 [[N_ADDR_0]], 1
+; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0
+; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[WHILE_END:%.*]], label [[WHILE_BODY:%.*]]
+; IS__CGSCC____: while.body:
+; IS__CGSCC____-NEXT: [[TMP1:%.*]] = add i32 [[ANS_0]], 1
+; IS__CGSCC____-NEXT: br label [[FOR_COND:%.*]]
+; IS__CGSCC____: for.cond:
+; IS__CGSCC____-NEXT: br i1 true, label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]
+; IS__CGSCC____: for.cond.cleanup:
+; IS__CGSCC____-NEXT: [[TMP2]] = add i32 [[TMP1]], [[SMAX]]
+; IS__CGSCC____-NEXT: br label [[FOR_END]]
+; IS__CGSCC____: for.body:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: for.inc:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: for.end:
+; IS__CGSCC____-NEXT: br label [[WHILE_COND]]
+; IS__CGSCC____: while.end:
+; IS__CGSCC____-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ]
+; IS__CGSCC____-NEXT: ret i32 [[ANS_0_LCSSA]]
;
entry:
br label %while.cond
@@ -964,38 +1364,66 @@ while.end: ; preds = %while.cond
; return ans;
; }
+define i32 @nested_unbounded_loops(i32 %n) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT____-LABEL: define {{[^@]+}}@nested_unbounded_loops
+; IS__TUNIT____-SAME: (i32 [[N:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: br label [[WHILE_COND:%.*]]
+; IS__TUNIT____: while.cond:
+; IS__TUNIT____-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[WHILE_END10:%.*]] ]
+; IS__TUNIT____-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[WHILE_END10]] ]
+; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0
+; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[WHILE_END11:%.*]], label [[WHILE_BODY:%.*]]
+; IS__TUNIT____: while.body:
+; IS__TUNIT____-NEXT: br label [[WHILE_COND1:%.*]]
+; IS__TUNIT____: while.cond1:
+; IS__TUNIT____-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY4:%.*]]
+; IS__TUNIT____: while.body4:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: while.end:
+; IS__TUNIT____-NEXT: [[TMP:%.*]] = add i32 [[N_ADDR_0]], -2
+; IS__TUNIT____-NEXT: br label [[WHILE_COND5:%.*]]
+; IS__TUNIT____: while.cond5:
+; IS__TUNIT____-NEXT: br i1 true, label [[WHILE_END10]], label [[WHILE_BODY8:%.*]]
+; IS__TUNIT____: while.body8:
+; IS__TUNIT____-NEXT: unreachable
+; IS__TUNIT____: while.end10:
+; IS__TUNIT____-NEXT: [[TMP1]] = add i32 [[TMP]], [[ANS_0]]
+; IS__TUNIT____-NEXT: br label [[WHILE_COND]]
+; IS__TUNIT____: while.end11:
+; IS__TUNIT____-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ]
+; IS__TUNIT____-NEXT: ret i32 [[ANS_0_LCSSA]]
+;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone
-; CHECK-NOT: willreturn
-define i32 @nested_unbounded_loops(i32 %n) {
-; CHECK-LABEL: define {{[^@]+}}@nested_unbounded_loops
-; CHECK-SAME: (i32 [[N:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br label [[WHILE_COND:%.*]]
-; CHECK: while.cond:
-; CHECK-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[WHILE_END10:%.*]] ]
-; CHECK-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[WHILE_END10]] ]
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0
-; CHECK-NEXT: br i1 [[TOBOOL]], label [[WHILE_END11:%.*]], label [[WHILE_BODY:%.*]]
-; CHECK: while.body:
-; CHECK-NEXT: br label [[WHILE_COND1:%.*]]
-; CHECK: while.cond1:
-; CHECK-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY4:%.*]]
-; CHECK: while.body4:
-; CHECK-NEXT: unreachable
-; CHECK: while.end:
-; CHECK-NEXT: [[TMP:%.*]] = add i32 [[N_ADDR_0]], -2
-; CHECK-NEXT: br label [[WHILE_COND5:%.*]]
-; CHECK: while.cond5:
-; CHECK-NEXT: br i1 true, label [[WHILE_END10]], label [[WHILE_BODY8:%.*]]
-; CHECK: while.body8:
-; CHECK-NEXT: unreachable
-; CHECK: while.end10:
-; CHECK-NEXT: [[TMP1]] = add i32 [[TMP]], [[ANS_0]]
-; CHECK-NEXT: br label [[WHILE_COND]]
-; CHECK: while.end11:
-; CHECK-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ]
-; CHECK-NEXT: ret i32 [[ANS_0_LCSSA]]
+; IS__CGSCC____-LABEL: define {{[^@]+}}@nested_unbounded_loops
+; IS__CGSCC____-SAME: (i32 [[N:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: br label [[WHILE_COND:%.*]]
+; IS__CGSCC____: while.cond:
+; IS__CGSCC____-NEXT: [[ANS_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[TMP1:%.*]], [[WHILE_END10:%.*]] ]
+; IS__CGSCC____-NEXT: [[N_ADDR_0:%.*]] = phi i32 [ [[N]], [[ENTRY]] ], [ -1, [[WHILE_END10]] ]
+; IS__CGSCC____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[N_ADDR_0]], 0
+; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[WHILE_END11:%.*]], label [[WHILE_BODY:%.*]]
+; IS__CGSCC____: while.body:
+; IS__CGSCC____-NEXT: br label [[WHILE_COND1:%.*]]
+; IS__CGSCC____: while.cond1:
+; IS__CGSCC____-NEXT: br i1 true, label [[WHILE_END:%.*]], label [[WHILE_BODY4:%.*]]
+; IS__CGSCC____: while.body4:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: while.end:
+; IS__CGSCC____-NEXT: [[TMP:%.*]] = add i32 [[N_ADDR_0]], -2
+; IS__CGSCC____-NEXT: br label [[WHILE_COND5:%.*]]
+; IS__CGSCC____: while.cond5:
+; IS__CGSCC____-NEXT: br i1 true, label [[WHILE_END10]], label [[WHILE_BODY8:%.*]]
+; IS__CGSCC____: while.body8:
+; IS__CGSCC____-NEXT: unreachable
+; IS__CGSCC____: while.end10:
+; IS__CGSCC____-NEXT: [[TMP1]] = add i32 [[TMP]], [[ANS_0]]
+; IS__CGSCC____-NEXT: br label [[WHILE_COND]]
+; IS__CGSCC____: while.end11:
+; IS__CGSCC____-NEXT: [[ANS_0_LCSSA:%.*]] = phi i32 [ [[ANS_0]], [[WHILE_COND]] ]
+; IS__CGSCC____-NEXT: ret i32 [[ANS_0_LCSSA]]
;
entry:
br label %while.cond
@@ -1056,38 +1484,66 @@ while.end11: ; preds = %while.cond
; return;
; }
+define void @non_loop_cycle(i32 %n) {
; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
+; IS__TUNIT____-LABEL: define {{[^@]+}}@non_loop_cycle
+; IS__TUNIT____-SAME: (i32 [[N:%.*]])
+; IS__TUNIT____-NEXT: entry:
+; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]])
+; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5
+; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; IS__TUNIT____: if.then:
+; IS__TUNIT____-NEXT: br label [[ENTRY1:%.*]]
+; IS__TUNIT____: if.else:
+; IS__TUNIT____-NEXT: br label [[ENTRY2:%.*]]
+; IS__TUNIT____: entry1:
+; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]])
+; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5
+; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
+; IS__TUNIT____: if.then3:
+; IS__TUNIT____-NEXT: br label [[EXIT:%.*]]
+; IS__TUNIT____: if.else4:
+; IS__TUNIT____-NEXT: br label [[ENTRY2]]
+; IS__TUNIT____: entry2:
+; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]])
+; IS__TUNIT____-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5
+; IS__TUNIT____-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]]
+; IS__TUNIT____: if.then7:
+; IS__TUNIT____-NEXT: br label [[EXIT]]
+; IS__TUNIT____: if.else8:
+; IS__TUNIT____-NEXT: br label [[ENTRY1]]
+; IS__TUNIT____: exit:
+; IS__TUNIT____-NEXT: ret void
+;
; IS__CGSCC____: Function Attrs: nofree norecurse nosync nounwind readnone
-; CHECK-NOT: willreturn
-define void @non_loop_cycle(i32 %n) {
-; CHECK-LABEL: define {{[^@]+}}@non_loop_cycle
-; CHECK-SAME: (i32 [[N:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]])
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: br label [[ENTRY1:%.*]]
-; CHECK: if.else:
-; CHECK-NEXT: br label [[ENTRY2:%.*]]
-; CHECK: entry1:
-; CHECK-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]])
-; CHECK-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5
-; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
-; CHECK: if.then3:
-; CHECK-NEXT: br label [[EXIT:%.*]]
-; CHECK: if.else4:
-; CHECK-NEXT: br label [[ENTRY2]]
-; CHECK: entry2:
-; CHECK-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]])
-; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5
-; CHECK-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]]
-; CHECK: if.then7:
-; CHECK-NEXT: br label [[EXIT]]
-; CHECK: if.else8:
-; CHECK-NEXT: br label [[ENTRY1]]
-; CHECK: exit:
-; CHECK-NEXT: ret void
+; IS__CGSCC____-LABEL: define {{[^@]+}}@non_loop_cycle
+; IS__CGSCC____-SAME: (i32 [[N:%.*]])
+; IS__CGSCC____-NEXT: entry:
+; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fact_loop(i32 [[N]])
+; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[CALL]], 5
+; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; IS__CGSCC____: if.then:
+; IS__CGSCC____-NEXT: br label [[ENTRY1:%.*]]
+; IS__CGSCC____: if.else:
+; IS__CGSCC____-NEXT: br label [[ENTRY2:%.*]]
+; IS__CGSCC____: entry1:
+; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @fact_loop(i32 [[N]])
+; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp sgt i32 [[CALL1]], 5
+; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label [[IF_ELSE4:%.*]]
+; IS__CGSCC____: if.then3:
+; IS__CGSCC____-NEXT: br label [[EXIT:%.*]]
+; IS__CGSCC____: if.else4:
+; IS__CGSCC____-NEXT: br label [[ENTRY2]]
+; IS__CGSCC____: entry2:
+; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @fact_loop(i32 [[N]])
+; IS__CGSCC____-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[CALL5]], 5
+; IS__CGSCC____-NEXT: br i1 [[CMP6]], label [[IF_THEN7:%.*]], label [[IF_ELSE8:%.*]]
+; IS__CGSCC____: if.then7:
+; IS__CGSCC____-NEXT: br label [[EXIT]]
+; IS__CGSCC____: if.else8:
+; IS__CGSCC____-NEXT: br label [[ENTRY1]]
+; IS__CGSCC____: exit:
+; IS__CGSCC____-NEXT: ret void
;
entry:
%call = call i32 @fact_loop(i32 %n)
More information about the llvm-commits
mailing list