[llvm] 3ca54f4 - [Attributor] Unify testing (=updates, prefixes, run configurations,...)
Galina Kistanova via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 20 10:36:44 PDT 2020
Hello Johannes,
This commit added broken tests to the builder:
http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/23151
. . .
FAIL: LLVM::fp80.ll
FAIL: LLVM::noalias.ll
FAIL: LLVM::liveness.ll
The builder was already red and did not send notification.
Please have a look ASAP?
Thanks
Galina
On Wed, Apr 15, 2020 at 6:01 PM Johannes Doerfert via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
>
> Author: Johannes Doerfert
> Date: 2020-04-15T19:59:51-05:00
> New Revision: 3ca54f45953e4217ad764c68ee2abcbc3eead1e8
>
> URL:
> https://github.com/llvm/llvm-project/commit/3ca54f45953e4217ad764c68ee2abcbc3eead1e8
> DIFF:
> https://github.com/llvm/llvm-project/commit/3ca54f45953e4217ad764c68ee2abcbc3eead1e8.diff
>
> LOG: [Attributor] Unify testing (=updates,prefixes,run configurations,...)
>
> When the Attributor was created the test update scripts were not well
> suited to deal with the challenges of IR attribute checking. This
> partially improved.
>
> Since then we also added three additional configurations that need
> testing; in total we now have the following four:
> { TUNIT, CGSCC } x { old pass manager (OPM), new pass manager (NPM) }
>
> Finally, the number of developers and tests grew rapidly (partially due
> to the addition of ArgumentPromotion and IPConstantProp tests), which
> resulted in tests only being run in some configurations, different
> prefixes being used, and different "styles" of checks being used.
>
> Due to the above reasons I believed we needed to take another look at
> the test update scripts. While we started to use them, via UTC_ARGS:
> --enable/disable, the other problems remained. To improve the testing
> situation for *all* configurations, to simplify future updates to the
> test, and to help identify subtle effects of future changes, we now use
> the test update scripts for (almost) all Attributor tests.
>
> An exhaustive prefix list minimizes the number of check lines and makes
> it easy to identify and compare configurations.
>
> Tests have been adjusted in the process but we tried to keep their
> intend unchanged.
>
> Reviewed By: sstefan1
>
> Differential Revision: https://reviews.llvm.org/D76588
>
> 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/X86/attributes.ll
>
> llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
> llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.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/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/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/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/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/returned.ll
> llvm/test/Transforms/Attributor/undefined_behavior.ll
> llvm/test/Transforms/Attributor/value-simplify.ll
> llvm/test/Transforms/Attributor/willreturn.ll
>
> Removed:
> llvm/test/Transforms/Attributor/ArgumentPromotion/pr3085.ll
>
>
>
> ################################################################################
> 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 d6a11193a556..f17d077fce73 100644
> ---
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll
> +++
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-02-01-ReturnAttrs.ll
> @@ -1,14 +1,29 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=6 -S < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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 {
> -; CHECK-LABEL: define {{[^@]+}}@deref
> -; CHECK-SAME: (i32 [[TMP0:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[X_PRIV:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]]
> -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4
> -; CHECK-NEXT: ret i32 [[TMP2]]
> +; 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-LABEL: define {{[^@]+}}@deref
> +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP2]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@deref
> +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[X:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 4
> +; IS__CGSCC____-NEXT: ret i32 [[TMP2]]
> ;
> entry:
> %tmp2 = load i32, i32* %x, align 4
> @@ -16,14 +31,30 @@ entry:
> }
>
> define i32 @f(i32 %x) {
> -; CHECK-LABEL: define {{[^@]+}}@f
> -; CHECK-SAME: (i32 [[X:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 1
> -; CHECK-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]])
> -; CHECK-NEXT: ret i32 [[TMP1]]
> +; 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
> +; 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-LABEL: define {{[^@]+}}@f
> +; IS__TUNIT_NPM-SAME: (i32 [[X:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[X_ADDR:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 1
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = call i32 @deref(i32 [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: ret i32 [[TMP1]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@f
> +; IS__CGSCC____-SAME: (i32 [[X:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[X_ADDR:%.*]] = alloca i32
> +; IS__CGSCC____-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = call i32 @deref(i32* noalias
> nofree nonnull readonly align 4 dereferenceable(4) [[X_ADDR]])
> +; IS__CGSCC____-NEXT: ret i32 [[TMP1]]
> ;
> entry:
> %x_addr = alloca i32
>
> 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 9a4956be40a5..92eaeb0f3edc 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,20 +1,24 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 -S < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ; PR2498
>
> ; This test tries to convince CHECK about promoting the load from %A + 2,
> ; 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
> +; 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]]
> +; 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]]
> ;
> entry:
> @@ -33,9 +37,15 @@ F:
> }
>
> define i32 @foo(i32* %A) {
> -; CHECK-LABEL: define {{[^@]+}}@foo(
> -; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i32* nocapture nofree
> readonly align 4 %A)
> -; CHECK-NEXT: ret i32 [[X]]
> +; 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____-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]])
> +; IS__CGSCC____-NEXT: ret i32 [[X]]
> ;
> %X = call i32 @callee(i1 false, i32* %A) ; <i32> [#uses=1]
> ret i32 %X
>
> 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 fd2887ecea60..2854f7111867 100644
> ---
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll
> +++
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-07-CGUpdate.ll
> @@ -1,12 +1,24 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -disable-output -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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____-LABEL: define {{[^@]+}}@hash()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: unreachable
> +;
> entry:
> unreachable
> }
>
> 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
> +;
> entry:
> %0 = call fastcc i32 @hash( i32* %ts, i32 0 ) nounwind ;
> <i32> [#uses=0]
> unreachable
>
> 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 fe3f1c697436..c179dd52bbe5 100644
> ---
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll
> +++
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/2008-09-08-CGUpdateSelfEdge.ll
> @@ -1,7 +1,18 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -disable-output -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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__CGSCC____-LABEL: define {{[^@]+}}@term_SharingList()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: br i1 false, label [[BB:%.*]], label [[BB5:%.*]]
> +; IS__CGSCC____: bb:
> +; IS__CGSCC____-NEXT: unreachable
> +; IS__CGSCC____: bb5:
> +; IS__CGSCC____-NEXT: ret i32 undef
> +;
> entry:
> br i1 false, label %bb, label %bb5
>
> @@ -14,6 +25,15 @@ 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
> +;
> entry:
> br i1 false, label %bb.i, label %bb14
>
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll
> index 08e254f382ec..dc99e85c12fd 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll
> @@ -1,17 +1,27 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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 that we only promote arguments when the caller/callee have
> compatible
> ; function attrubtes.
>
> target triple = "x86_64-unknown-linux-gnu"
>
> define internal fastcc void @no_promote_avx2(<4 x i64>* %arg, <4 x i64>*
> readonly %arg1) #0 {
> -; CHECK-LABEL: define {{[^@]+}}@no_promote_avx2
> -; CHECK-SAME: (<4 x i64>* noalias nocapture nofree nonnull writeonly
> align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* noalias nocapture
> nofree nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1]], align
> 32
> -; CHECK-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32
> -; CHECK-NEXT: ret void
> +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote_avx2
> +; NOT_TUNIT_NPM-SAME: (<4 x i64>* nocapture nofree nonnull writeonly
> align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree
> nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>*
> [[ARG1]], align 32
> +; NOT_TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]],
> align 32
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote_avx2
> +; IS__TUNIT_NPM-SAME: (<4 x i64>* noalias nocapture nofree nonnull
> writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* noalias
> nocapture nofree nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>*
> [[ARG1]], align 32
> +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]],
> align 32
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <4 x i64>, <4 x i64>* %arg1
> @@ -20,17 +30,53 @@ bb:
> }
>
> define void @no_promote(<4 x i64>* %arg) #1 {
> -; CHECK-LABEL: define {{[^@]+}}@no_promote
> -; CHECK-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: call fastcc void @no_promote_avx2(<4 x i64>* noalias
> nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]],
> <4 x i64>* noalias nocapture nofree nonnull readonly align 32
> dereferenceable(32) [[TMP]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]],
> align 32
> -; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@no_promote
> +; IS__TUNIT_OPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void @no_promote_avx2(<4 x i64>*
> nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]],
> <4 x i64>* nocapture nofree nonnull readonly align 32 dereferenceable(32)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP2]], align 32
> +; IS__TUNIT_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@no_promote
> +; IS__TUNIT_NPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: call fastcc void @no_promote_avx2(<4 x i64>*
> noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32)
> [[TMP2]], <4 x i64>* noalias nocapture nofree nonnull readonly align 32
> dereferenceable(32) [[TMP]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP2]], align 32
> +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@no_promote
> +; IS__CGSCC_OPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(32) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void @no_promote_avx2(<4 x i64>*
> nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>*
> nofree nonnull readonly align 32 dereferenceable(32) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP2]], align 32
> +; IS__CGSCC_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@no_promote
> +; IS__CGSCC_NPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(32) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void @no_promote_avx2(<4 x i64>*
> noalias nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4
> x i64>* noalias nofree nonnull readonly align 32 dereferenceable(32)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP2]], align 32
> +; IS__CGSCC_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <4 x i64>, align 32
> @@ -44,14 +90,21 @@ bb:
> }
>
> define internal fastcc void @promote_avx2(<4 x i64>* %arg, <4 x i64>*
> readonly %arg1) #0 {
> -; CHECK-LABEL: define {{[^@]+}}@promote_avx2
> -; CHECK-SAME: (<4 x i64>* noalias nocapture nofree nonnull writeonly
> align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <4 x i64>
> -; CHECK-NEXT: store <4 x i64> [[TMP0]], <4 x i64>* [[ARG1_PRIV]]
> -; CHECK-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>* [[ARG1_PRIV]],
> align 32
> -; CHECK-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]], align 32
> -; CHECK-NEXT: ret void
> +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@promote_avx2
> +; NOT_TUNIT_NPM-SAME: (<4 x i64>* nocapture nofree nonnull writeonly
> align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64>* nocapture nofree
> nonnull readonly align 32 dereferenceable(32) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>*
> [[ARG1]], align 32
> +; NOT_TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]],
> align 32
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote_avx2
> +; IS__TUNIT_NPM-SAME: (<4 x i64>* noalias nocapture nofree nonnull
> writeonly align 32 dereferenceable(32) [[ARG:%.*]], <4 x i64> [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <4 x i64>
> +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP0]], <4 x i64>*
> [[ARG1_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <4 x i64>, <4 x i64>*
> [[ARG1_PRIV]], align 32
> +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP]], <4 x i64>* [[ARG]],
> align 32
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <4 x i64>, <4 x i64>* %arg1
> @@ -60,18 +113,54 @@ bb:
> }
>
> define void @promote(<4 x i64>* %arg) #0 {
> -; CHECK-LABEL: define {{[^@]+}}@promote
> -; CHECK-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i64>, <4 x i64>* [[TMP]], align
> 1
> -; CHECK-NEXT: call fastcc void @promote_avx2(<4 x i64>* noalias
> nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]],
> <4 x i64> [[TMP0]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>* [[TMP2]],
> align 32
> -; CHECK-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@promote
> +; IS__TUNIT_OPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void @promote_avx2(<4 x i64>*
> nocapture nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]],
> <4 x i64>* nocapture nofree nonnull readonly align 32 dereferenceable(32)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP2]], align 32
> +; IS__TUNIT_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote
> +; IS__TUNIT_NPM-SAME: (<4 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP]], align 1
> +; IS__TUNIT_NPM-NEXT: call fastcc void @promote_avx2(<4 x i64>*
> noalias nocapture nofree nonnull writeonly align 32 dereferenceable(32)
> [[TMP2]], <4 x i64> [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP2]], align 32
> +; IS__TUNIT_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@promote
> +; IS__CGSCC_OPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(32) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void @promote_avx2(<4 x i64>* nofree
> nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64>* nofree
> nonnull readonly align 32 dereferenceable(32) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP2]], align 32
> +; IS__CGSCC_OPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@promote
> +; IS__CGSCC_NPM-SAME: (<4 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(32) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <4 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 32 dereferenceable(32) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void @promote_avx2(<4 x i64>*
> noalias nofree nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4
> x i64>* noalias nofree nonnull readonly align 32 dereferenceable(32)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <4 x i64>, <4 x i64>*
> [[TMP2]], align 32
> +; IS__CGSCC_NPM-NEXT: store <4 x i64> [[TMP4]], <4 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <4 x i64>, align 32
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
> index b994aba78dc8..ead9a0e10f71 100644
> ---
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
> +++
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/min-legal-vector-width.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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 that we only promote arguments when the caller/callee have
> compatible
> ; function attrubtes.
>
> @@ -7,14 +10,22 @@ target triple = "x86_64-unknown-linux-gnu"
>
> ; This should promote
> define internal fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>*
> %arg, <8 x i64>* readonly %arg1) #0 {
> -; CHECK-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512
> -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]]
> -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64
> -; CHECK-NEXT: ret void
> +;
> +; NOT_TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512
> +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree
> nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull
> writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>*
> [[ARG1_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1_PRIV]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <8 x i64>, <8 x i64>* %arg1
> @@ -23,18 +34,55 @@ bb:
> }
>
> define void @avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8
> x i64>* %arg) #0 {
> -; CHECK-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512
> -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align
> 1
> -; CHECK-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512
> +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>*
> nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]],
> <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP]], align 1
> +; IS__TUNIT_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512
> +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>*
> nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>*
> nofree nonnull readonly align 64 dereferenceable(64) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer512
> +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer512(<8 x i64>*
> noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8
> x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <8 x i64>, align 32
> @@ -49,14 +97,22 @@ bb:
>
> ; This should promote
> define internal fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> %arg, <8 x i64>* readonly %arg1) #1 {
> -; CHECK-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256
> -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]]
> -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64
> -; CHECK-NEXT: ret void
> +;
> +; NOT_TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256
> +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree
> nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull
> writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>*
> [[ARG1_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1_PRIV]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <8 x i64>, <8 x i64>* %arg1
> @@ -65,18 +121,55 @@ bb:
> }
>
> define void @avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8
> x i64>* %arg) #1 {
> -; CHECK-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256
> -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align
> 1
> -; CHECK-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256
> +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]],
> <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP]], align 1
> +; IS__TUNIT_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256
> +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>*
> nofree nonnull readonly align 64 dereferenceable(64) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer256
> +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8
> x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <8 x i64>, align 32
> @@ -91,14 +184,22 @@ bb:
>
> ; This should promote
> define internal fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>*
> %arg, <8 x i64>* readonly %arg1) #1 {
> -; CHECK-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256
> -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]]
> -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64
> -; CHECK-NEXT: ret void
> +;
> +; NOT_TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256
> +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree
> nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull
> writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>*
> [[ARG1_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1_PRIV]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <8 x i64>, <8 x i64>* %arg1
> @@ -107,18 +208,55 @@ bb:
> }
>
> define void @avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8
> x i64>* %arg) #0 {
> -; CHECK-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256
> -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align
> 1
> -; CHECK-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256
> +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>*
> nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]],
> <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP]], align 1
> +; IS__TUNIT_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256
> +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>*
> nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>*
> nofree nonnull readonly align 64 dereferenceable(64) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer512_call_avx512_legal512_prefer256
> +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer512_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8
> x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <8 x i64>, align 32
> @@ -133,14 +271,22 @@ bb:
>
> ; This should promote
> define internal fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>*
> %arg, <8 x i64>* readonly %arg1) #0 {
> -; CHECK-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512
> -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]]
> -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64
> -; CHECK-NEXT: ret void
> +;
> +; NOT_TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512
> +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree
> nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull
> writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>*
> [[ARG1_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1_PRIV]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <8 x i64>, <8 x i64>* %arg1
> @@ -149,18 +295,55 @@ bb:
> }
>
> define void @avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8
> x i64>* %arg) #1 {
> -; CHECK-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512
> -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align
> 1
> -; CHECK-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512
> +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>*
> nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]],
> <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP]], align 1
> +; IS__TUNIT_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512
> +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>*
> nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>*
> nofree nonnull readonly align 64 dereferenceable(64) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal512_prefer512
> +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal512_prefer512(<8 x i64>*
> noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8
> x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <8 x i64>, align 32
> @@ -175,12 +358,20 @@ bb:
>
> ; This should not promote
> define internal fastcc void
> @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> %arg, <8 x i64>* readonly %arg1) #1 {
> -; CHECK-LABEL: define
> {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256
> -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture
> nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align
> 64
> -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64
> -; CHECK-NEXT: ret void
> +;
> +; NOT_TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256
> +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree
> nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull
> writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias
> nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <8 x i64>, <8 x i64>* %arg1
> @@ -189,17 +380,54 @@ bb:
> }
>
> define void @avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8
> x i64>* %arg) #2 {
> -; CHECK-LABEL: define
> {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256
> -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: call fastcc void
> @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64
> dereferenceable(64) [[TMP]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define
> {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256
> +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void
> @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]],
> <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: call fastcc void
> @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64
> dereferenceable(64) [[TMP]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define
> {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256
> +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void
> @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>*
> nofree nonnull readonly align 64 dereferenceable(64) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define
> {{[^@]+}}@avx512_legal256_prefer256_call_avx512_legal512_prefer256
> +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void
> @callee_avx512_legal256_prefer256_call_avx512_legal512_prefer256(<8 x i64>*
> noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8
> x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <8 x i64>, align 32
> @@ -214,12 +442,20 @@ bb:
>
> ; This should not promote
> define internal fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>*
> %arg, <8 x i64>* readonly %arg1) #2 {
> -; CHECK-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256
> -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias nocapture
> nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1]], align
> 64
> -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64
> -; CHECK-NEXT: ret void
> +;
> +; NOT_TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256
> +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree
> nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull
> writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* noalias
> nocapture nofree nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <8 x i64>, <8 x i64>* %arg1
> @@ -228,17 +464,54 @@ bb:
> }
>
> define void @avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8
> x i64>* %arg) #1 {
> -; CHECK-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256
> -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64
> dereferenceable(64) [[TMP]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256
> +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>*
> nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]],
> <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64>* noalias nocapture nofree nonnull readonly align 64
> dereferenceable(64) [[TMP]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256
> +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>*
> nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>*
> nofree nonnull readonly align 64 dereferenceable(64) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define
> {{[^@]+}}@avx512_legal512_prefer256_call_avx512_legal256_prefer256
> +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void
> @callee_avx512_legal512_prefer256_call_avx512_legal256_prefer256(<8 x i64>*
> noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8
> x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <8 x i64>, align 32
> @@ -253,14 +526,22 @@ bb:
>
> ; This should promote
> define internal fastcc void
> @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>*
> %arg, <8 x i64>* readonly %arg1) #3 {
> -; CHECK-LABEL: define
> {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256
> -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]]
> -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64
> -; CHECK-NEXT: ret void
> +;
> +; NOT_TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256
> +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree
> nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull
> writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>*
> [[ARG1_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1_PRIV]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <8 x i64>, <8 x i64>* %arg1
> @@ -269,18 +550,55 @@ bb:
> }
>
> define void @avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x
> i64>* %arg) #4 {
> -; CHECK-LABEL: define
> {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256
> -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align
> 1
> -; CHECK-NEXT: call fastcc void
> @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define
> {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256
> +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void
> @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>*
> nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]],
> <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP]], align 1
> +; IS__TUNIT_NPM-NEXT: call fastcc void
> @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define
> {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256
> +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void
> @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>*
> nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>*
> nofree nonnull readonly align 64 dereferenceable(64) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define
> {{[^@]+}}@avx2_legal256_prefer256_call_avx2_legal512_prefer256
> +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void
> @callee_avx2_legal256_prefer256_call_avx2_legal512_prefer256(<8 x i64>*
> noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8
> x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <8 x i64>, align 32
> @@ -295,14 +613,22 @@ bb:
>
> ; This should promote
> define internal fastcc void
> @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>*
> %arg, <8 x i64>* readonly %arg1) #4 {
> -; CHECK-LABEL: define
> {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256
> -; CHECK-SAME: (<8 x i64>* noalias nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> -; CHECK-NEXT: store <8 x i64> [[TMP0]], <8 x i64>* [[ARG1_PRIV]]
> -; CHECK-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>* [[ARG1_PRIV]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]], align 64
> -; CHECK-NEXT: ret void
> +;
> +; NOT_TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256
> +; NOT_TUNIT_NPM-SAME: (<8 x i64>* nocapture nofree nonnull writeonly
> align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64>* nocapture nofree
> nonnull readonly align 64 dereferenceable(64) [[ARG1:%.*]])
> +; NOT_TUNIT_NPM-NEXT: bb:
> +; NOT_TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1]], align 64
> +; NOT_TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; NOT_TUNIT_NPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* noalias nocapture nofree nonnull
> writeonly align 64 dereferenceable(64) [[ARG:%.*]], <8 x i64> [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[ARG1_PRIV:%.*]] = alloca <8 x i64>
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP0]], <8 x i64>*
> [[ARG1_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load <8 x i64>, <8 x i64>*
> [[ARG1_PRIV]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP]], <8 x i64>* [[ARG]],
> align 64
> +; IS__TUNIT_NPM-NEXT: ret void
> ;
> bb:
> %tmp = load <8 x i64>, <8 x i64>* %arg1
> @@ -311,18 +637,55 @@ bb:
> }
>
> define void @avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x
> i64>* %arg) #3 {
> -; CHECK-LABEL: define
> {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256
> -; CHECK-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> -; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull writeonly
> align 32 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> -; CHECK-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>* [[TMP]], align
> 1
> -; CHECK-NEXT: call fastcc void
> @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> -; CHECK-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>* [[TMP2]],
> align 64
> -; CHECK-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]], align 2
> -; CHECK-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define
> {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256
> +; IS__TUNIT_OPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_OPM-NEXT: bb:
> +; IS__TUNIT_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_OPM-NEXT: call fastcc void
> @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>*
> nocapture nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]],
> <8 x i64>* nocapture nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define
> {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256
> +; IS__TUNIT_NPM-SAME: (<8 x i64>* nocapture writeonly [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: bb:
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__TUNIT_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP]], align 1
> +; IS__TUNIT_NPM-NEXT: call fastcc void
> @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>*
> noalias nocapture nofree nonnull writeonly align 64 dereferenceable(64)
> [[TMP2]], <8 x i64> [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__TUNIT_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define
> {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256
> +; IS__CGSCC_OPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: bb:
> +; IS__CGSCC_OPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_OPM-NEXT: call fastcc void
> @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>*
> nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8 x i64>*
> nofree nonnull readonly align 64 dereferenceable(64) [[TMP]])
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_OPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define
> {{[^@]+}}@avx2_legal512_prefer256_call_avx2_legal256_prefer256
> +; IS__CGSCC_NPM-SAME: (<8 x i64>* nocapture nonnull writeonly align 2
> dereferenceable(64) [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: bb:
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = alloca <8 x i64>, align 32
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = bitcast <8 x i64>* [[TMP]] to i8*
> +; IS__CGSCC_NPM-NEXT: call void @llvm.memset.p0i8.i64(i8* nonnull
> writeonly align 64 dereferenceable(64) [[TMP3]], i8 0, i64 32, i1 false)
> +; IS__CGSCC_NPM-NEXT: call fastcc void
> @callee_avx2_legal512_prefer256_call_avx2_legal256_prefer256(<8 x i64>*
> noalias nofree nonnull writeonly align 64 dereferenceable(64) [[TMP2]], <8
> x i64>* noalias nofree nonnull readonly align 64 dereferenceable(64)
> [[TMP]])
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = load <8 x i64>, <8 x i64>*
> [[TMP2]], align 64
> +; IS__CGSCC_NPM-NEXT: store <8 x i64> [[TMP4]], <8 x i64>* [[ARG]],
> align 2
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> bb:
> %tmp = alloca <8 x i64>, align 32
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
> index d9f3681ba4ab..ec32b24e1b9a 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/X86/thiscall.ll
> @@ -4,8 +4,10 @@
> ; we don't do that anymore. It also verifies that the combination of
> ; globalopt and argpromotion is able to optimize the call safely.
> ;
> -; RUN: opt -S -argpromotion %s | FileCheck %s --check-prefix=ARGPROMOTION
> -; RUN: opt -S -globalopt -argpromotion %s | FileCheck %s
> --check-prefix=GLOBALOPT_ARGPROMOTION
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
> target triple = "i386-pc-windows-msvc19.11.0"
> @@ -13,25 +15,25 @@ target triple = "i386-pc-windows-msvc19.11.0"
> %struct.a = type { i8 }
>
> define internal x86_thiscallcc void @internalfun(%struct.a* %this, <{
> %struct.a }>* inalloca) {
> -; ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun
> -; ARGPROMOTION-SAME: (%struct.a* [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>*
> inalloca [[TMP0:%.*]])
> -; ARGPROMOTION-NEXT: entry:
> -; ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{
> [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0
> -; ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]]
> }>, align 4
> -; ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{
> [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0
> -; ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a*
> @copy_ctor(%struct.a* [[TMP1]], %struct.a* dereferenceable(1) [[A]])
> -; ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca
> [[ARGMEM]])
> -; ARGPROMOTION-NEXT: ret void
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@internalfun
> +; IS__TUNIT____-SAME: (%struct.a* noalias nocapture nofree readnone
> [[THIS:%.*]], <{ [[STRUCT_A:%.*]] }>* inalloca nonnull align 4
> dereferenceable(1) [[TMP0:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[A:%.*]] = getelementptr inbounds <{
> [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0
> +; IS__TUNIT____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]]
> }>, align 4
> +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{
> [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a*
> @copy_ctor(%struct.a* nonnull align 4 dereferenceable(1) [[TMP1]],
> %struct.a* nonnull align 4 dereferenceable(1) [[A]])
> +; IS__TUNIT____-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca
> nonnull align 4 dereferenceable(1) [[ARGMEM]])
> +; IS__TUNIT____-NEXT: ret void
> ;
> -; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@internalfun
> -; GLOBALOPT_ARGPROMOTION-SAME: (<{ [[STRUCT_A:%.*]] }>* [[TMP0:%.*]])
> unnamed_addr
> -; GLOBALOPT_ARGPROMOTION-NEXT: entry:
> -; GLOBALOPT_ARGPROMOTION-NEXT: [[A:%.*]] = getelementptr inbounds <{
> [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0
> -; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{
> [[STRUCT_A]] }>, align 4
> -; GLOBALOPT_ARGPROMOTION-NEXT: [[TMP1:%.*]] = getelementptr inbounds
> <{ [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0
> -; GLOBALOPT_ARGPROMOTION-NEXT: [[CALL:%.*]] = call x86_thiscallcc
> %struct.a* @copy_ctor(%struct.a* [[TMP1]], %struct.a* dereferenceable(1)
> [[A]])
> -; GLOBALOPT_ARGPROMOTION-NEXT: call void @ext(<{ [[STRUCT_A]] }>*
> inalloca [[ARGMEM]])
> -; GLOBALOPT_ARGPROMOTION-NEXT: ret void
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@internalfun
> +; IS__CGSCC____-SAME: (%struct.a* nocapture nofree readnone [[THIS:%.*]],
> <{ [[STRUCT_A:%.*]] }>* inalloca nonnull dereferenceable(1) [[TMP0:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[A:%.*]] = getelementptr inbounds <{
> [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[TMP0]], i32 0, i32 0
> +; IS__CGSCC____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_A]]
> }>, align 4
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = getelementptr inbounds <{
> [[STRUCT_A]] }>, <{ [[STRUCT_A]] }>* [[ARGMEM]], i32 0, i32 0
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call x86_thiscallcc %struct.a*
> @copy_ctor(%struct.a* nonnull align 4 dereferenceable(1) [[TMP1]],
> %struct.a* nonnull dereferenceable(1) [[A]])
> +; IS__CGSCC____-NEXT: call void @ext(<{ [[STRUCT_A]] }>* inalloca
> nonnull align 4 dereferenceable(1) [[ARGMEM]])
> +; IS__CGSCC____-NEXT: ret void
> ;
> entry:
> %a = getelementptr inbounds <{ %struct.a }>, <{ %struct.a }>* %0, i32
> 0, i32 0
> @@ -44,21 +46,21 @@ entry:
>
> ; This is here to ensure @internalfun is live.
> define void @exportedfun(%struct.a* %a) {
> -; ARGPROMOTION-LABEL: define {{[^@]+}}@exportedfun
> -; ARGPROMOTION-SAME: (%struct.a* [[A:%.*]])
> -; ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8*
> @llvm.stacksave()
> -; ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{
> [[STRUCT_A:%.*]] }>, align 4
> -; ARGPROMOTION-NEXT: call x86_thiscallcc void @internalfun(%struct.a*
> [[A]], <{ [[STRUCT_A]] }>* inalloca [[ARGMEM]])
> -; ARGPROMOTION-NEXT: call void @llvm.stackrestore(i8*
> [[INALLOCA_SAVE]])
> -; ARGPROMOTION-NEXT: ret void
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@exportedfun
> +; IS__TUNIT____-SAME: (%struct.a* nocapture nofree readnone [[A:%.*]])
> +; IS__TUNIT____-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8*
> @llvm.stacksave()
> +; IS__TUNIT____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{
> [[STRUCT_A:%.*]] }>, align 4
> +; IS__TUNIT____-NEXT: call x86_thiscallcc void @internalfun(%struct.a*
> noalias nofree readnone undef, <{ [[STRUCT_A]] }>* inalloca nonnull align 4
> dereferenceable(1) [[ARGMEM]])
> +; IS__TUNIT____-NEXT: call void @llvm.stackrestore(i8*
> [[INALLOCA_SAVE]])
> +; IS__TUNIT____-NEXT: ret void
> ;
> -; GLOBALOPT_ARGPROMOTION-LABEL: define {{[^@]+}}@exportedfun
> -; GLOBALOPT_ARGPROMOTION-SAME: (%struct.a* [[A:%.*]]) local_unnamed_addr
> -; GLOBALOPT_ARGPROMOTION-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8*
> @llvm.stacksave()
> -; GLOBALOPT_ARGPROMOTION-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{
> [[STRUCT_A:%.*]] }>, align 4
> -; GLOBALOPT_ARGPROMOTION-NEXT: call fastcc void @internalfun(<{
> [[STRUCT_A]] }>* [[ARGMEM]])
> -; GLOBALOPT_ARGPROMOTION-NEXT: call void @llvm.stackrestore(i8*
> [[INALLOCA_SAVE]])
> -; GLOBALOPT_ARGPROMOTION-NEXT: ret void
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@exportedfun
> +; IS__CGSCC____-SAME: (%struct.a* nocapture nofree readnone [[A:%.*]])
> +; IS__CGSCC____-NEXT: [[INALLOCA_SAVE:%.*]] = tail call i8*
> @llvm.stacksave()
> +; IS__CGSCC____-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{
> [[STRUCT_A:%.*]] }>, align 4
> +; IS__CGSCC____-NEXT: call x86_thiscallcc void @internalfun(%struct.a*
> noalias nocapture nofree readnone [[A]], <{ [[STRUCT_A]] }>* inalloca
> nonnull align 4 dereferenceable(1) [[ARGMEM]])
> +; IS__CGSCC____-NEXT: call void @llvm.stackrestore(i8*
> [[INALLOCA_SAVE]])
> +; IS__CGSCC____-NEXT: ret void
> ;
> %inalloca.save = tail call i8* @llvm.stacksave()
> %argmem = alloca inalloca <{ %struct.a }>, align 4
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
> index dc71592e4f9a..be64712b02bb 100644
> ---
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
> +++
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/aggregate-promote.ll
> @@ -1,14 +1,20 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -disable-output -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> %T = type { i32, i32, i32, i32 }
> @G = constant %T { i32 0, i32 0, i32 17, i32 25 }
>
> define internal i32 @test(%T* %p) {
> -; CHECK-LABEL: define {{[^@]+}}@test
> -; CHECK-SAME: (i32 [[P_0_2_VAL:%.*]], i32 [[P_0_3_VAL:%.*]])
> +; CHECK-LABEL: define {{[^@]+}}@test()
> ; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[V:%.*]] = add i32 [[P_0_3_VAL]], [[P_0_2_VAL]]
> +; 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]]
> ;
> entry:
> @@ -23,11 +29,7 @@ entry:
> define i32 @caller() {
> ; CHECK-LABEL: define {{[^@]+}}@caller()
> ; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[G_IDX:%.*]] = getelementptr [[T:%.*]], %T* @G, i64 0,
> i32 2
> -; CHECK-NEXT: [[G_IDX_VAL:%.*]] = load i32, i32* [[G_IDX]]
> -; CHECK-NEXT: [[G_IDX1:%.*]] = getelementptr [[T]], %T* @G, i64 0, i32
> 3
> -; CHECK-NEXT: [[G_IDX1_VAL:%.*]] = load i32, i32* [[G_IDX1]]
> -; CHECK-NEXT: [[V:%.*]] = call i32 @test(i32 [[G_IDX_VAL]], i32
> [[G_IDX1_VAL]])
> +; CHECK-NEXT: [[V:%.*]] = call i32 @test()
> ; CHECK-NEXT: ret i32 [[V]]
> ;
> entry:
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
> index 3b0085a019e4..21f7ead3b0a4 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/alignment.ll
> @@ -1,13 +1,28 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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 void @f() {
> -; CHECK-LABEL: define {{[^@]+}}@f()
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[A:%.*]] = alloca i32, align 1
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 1
> -; CHECK-NEXT: call void @g(i32 [[TMP0]])
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f()
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32, align 1
> +; IS__TUNIT_OPM-NEXT: call void @g(i32* noalias nocapture nonnull
> readonly dereferenceable(4) [[A]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f()
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32, align 1
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 1
> +; IS__TUNIT_NPM-NEXT: call void @g(i32 [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@f()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 1
> +; IS__CGSCC____-NEXT: call void @g(i32* noalias nonnull readonly
> dereferenceable(4) [[A]])
> +; IS__CGSCC____-NEXT: ret void
> ;
> entry:
> %a = alloca i32, align 1
> @@ -16,13 +31,25 @@ entry:
> }
>
> define internal void @g(i32* %a) {
> -; CHECK-LABEL: define {{[^@]+}}@g
> -; CHECK-SAME: (i32 [[TMP0:%.*]])
> -; CHECK-NEXT: [[A_PRIV:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]]
> -; CHECK-NEXT: [[AA:%.*]] = load i32, i32* [[A_PRIV]], align 1
> -; CHECK-NEXT: call void @z(i32 [[AA]])
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@g
> +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nonnull readonly
> dereferenceable(4) [[A:%.*]])
> +; IS__TUNIT_OPM-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1
> +; IS__TUNIT_OPM-NEXT: call void @z(i32 [[AA]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@g
> +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[AA:%.*]] = load i32, i32* [[A_PRIV]], align 1
> +; IS__TUNIT_NPM-NEXT: call void @z(i32 [[AA]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@g
> +; IS__CGSCC____-SAME: (i32* nocapture nonnull readonly dereferenceable(4)
> [[A:%.*]])
> +; IS__CGSCC____-NEXT: [[AA:%.*]] = load i32, i32* [[A]], align 1
> +; IS__CGSCC____-NEXT: call void @z(i32 [[AA]])
> +; IS__CGSCC____-NEXT: ret void
> ;
> %aa = load i32, i32* %a, align 1
> call void @z(i32 %aa)
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
> index 6e8a2e5e78f5..e28e4e592f12 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/attrs.ll
> @@ -1,28 +1,75 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=4 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> %struct.ss = type { i32, i64 }
>
> ; Don't drop 'byval' on %X here.
> define internal i32 @f(%struct.ss* byval %b, i32* byval %X, i32 %i)
> nounwind {
> -; CHECK-LABEL: define {{[^@]+}}@f
> -; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32 [[TMP2:%.*]], i32
> [[I:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[X_PRIV:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]]
> -; CHECK-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]]
> -; CHECK-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to
> i32*
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]]
> -; CHECK-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[B_PRIV]], i32 0, i32 1
> -; CHECK-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]]
> -; CHECK-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[B_PRIV]], i32 0, i32 0
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
> -; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> -; CHECK-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
> -; CHECK-NEXT: store i32 0, i32* [[X_PRIV]], align 4
> -; CHECK-NEXT: [[L:%.*]] = load i32, i32* [[X_PRIV]], align 4
> -; CHECK-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
> -; CHECK-NEXT: ret i32 [[A]]
> +;
> +; 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:
> +; 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: store i32 0, i32* [[X]], align 4
> +; IS__TUNIT_OPM-NEXT: [[L:%.*]] = load i32, i32* [[X]], align 4
> +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
> +; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@f
> +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32
> [[TMP2:%.*]], i32 [[I:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; 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]]
> +; 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]]
> +; 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: store i32 0, i32* [[X_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: [[L:%.*]] = load i32, i32* [[X_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
> +; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
> +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval
> align 4 dereferenceable(4) [[B:%.*]], i32* noalias nocapture nofree nonnull
> byval align 4 dereferenceable(4) [[X:%.*]])
> +; 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 4
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
> +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[X]], align 4
> +; IS__CGSCC_OPM-NEXT: [[L:%.*]] = load i32, i32* [[X]], align 4
> +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
> +; IS__CGSCC_OPM-NEXT: ret i32 [[A]]
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
> +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32
> [[TMP2:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32
> +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]]
> +; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; 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]]
> +; 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]]
> +; 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 4
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
> +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[X_PRIV]], align 4
> +; IS__CGSCC_NPM-NEXT: [[L:%.*]] = load i32, i32* [[X_PRIV]], align 4
> +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[L]], [[TMP2]]
> +; IS__CGSCC_NPM-NEXT: ret i32 [[A]]
> ;
> entry:
>
> @@ -39,21 +86,60 @@ entry:
>
> ; Also make sure we don't drop the call zeroext attribute.
> define i32 @test(i32* %X) {
> -; CHECK-LABEL: define {{[^@]+}}@test
> -; CHECK-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[S]], i32 0, i32 0
> -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8
> -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[S]], i32 0, i32 1
> -; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4
> -; CHECK-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32*
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1
> -; CHECK-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[S]], i32 0, i32 1
> -; CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1
> -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 1
> -; CHECK-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]], i32
> [[TMP2]], i32 zeroext 0)
> -; CHECK-NEXT: ret i32 [[C]]
> +;
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test
> +; IS__TUNIT_OPM-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]])
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__TUNIT_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; 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-LABEL: define {{[^@]+}}@test
> +; IS__TUNIT_NPM-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to
> i32*
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1
> +; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 1
> +; 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-LABEL: define {{[^@]+}}@test
> +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree nonnull readnone align 4
> dereferenceable(4) [[X:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @f(%struct.ss* noalias
> 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-LABEL: define {{[^@]+}}@test
> +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly
> dereferenceable(4) [[X:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__CGSCC_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to
> i32*
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 8
> +; IS__CGSCC_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[X]], align 1
> +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @f(i32 [[TMP0]], i64
> [[TMP1]], i32 [[TMP2]])
> +; IS__CGSCC_NPM-NEXT: ret i32 [[C]]
> ;
> entry:
> %S = alloca %struct.ss
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
> index 7739ad757337..6d2131610fb1 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/basictest.ll
> @@ -1,18 +1,35 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=7 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> 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) {
> -; CHECK-LABEL: define {{[^@]+}}@test
> -; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> -; CHECK-NEXT: [[Y_PRIV:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[TMP1]], i32* [[Y_PRIV]]
> -; CHECK-NEXT: [[X_PRIV:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]]
> -; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[X_PRIV]], align 4
> -; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[Y_PRIV]], align 4
> -; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
> -; CHECK-NEXT: ret i32 [[C]]
> +; 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
> +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = load i32, i32* [[Y]], align 4
> +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
> +; IS__TUNIT_OPM-NEXT: ret i32 [[C]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test
> +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; IS__TUNIT_NPM-NEXT: [[Y_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[Y_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[X_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = load i32, i32* [[X_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = load i32, i32* [[Y_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
> +; IS__TUNIT_NPM-NEXT: ret i32 [[C]]
> +;
> +; 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
> +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[Y]], align 4
> +; IS__CGSCC____-NEXT: [[C:%.*]] = add i32 [[A]], [[B]]
> +; IS__CGSCC____-NEXT: ret i32 [[C]]
> ;
> %A = load i32, i32* %X
> %B = load i32, i32* %Y
> @@ -21,16 +38,30 @@ define internal i32 @test(i32* %X, i32* %Y) {
> }
>
> define internal i32 @caller(i32* %B) {
> -; CHECK-LABEL: define {{[^@]+}}@caller
> -; CHECK-SAME: (i32 [[TMP0:%.*]])
> -; CHECK-NEXT: [[B_PRIV:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[B_PRIV]]
> -; CHECK-NEXT: [[A:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 1, i32* [[A]], align 4
> -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[A]], align 1
> -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[B_PRIV]], align 1
> -; CHECK-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i32 [[TMP3]])
> -; CHECK-NEXT: ret i32 [[C]]
> +; 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
> +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[A]], align 4
> +; 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-LABEL: define {{[^@]+}}@caller
> +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: [[B_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[A]], align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[A]], align 1
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[B_PRIV]], align 1
> +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = call i32 @test(i32 [[TMP2]], i32
> [[TMP3]])
> +; IS__TUNIT_NPM-NEXT: ret i32 [[C]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
> +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[B:%.*]])
> +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32
> +; IS__CGSCC____-NEXT: store i32 1, i32* [[A]], align 4
> +; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nofree
> nonnull readonly align 4 dereferenceable(4) [[A]], i32* nocapture nofree
> nonnull readonly align 4 dereferenceable(4) [[B]])
> +; IS__CGSCC____-NEXT: ret i32 [[C]]
> ;
> %A = alloca i32
> store i32 1, i32* %A
> @@ -39,12 +70,24 @@ define internal i32 @caller(i32* %B) {
> }
>
> define i32 @callercaller() {
> -; CHECK-LABEL: define {{[^@]+}}@callercaller()
> -; CHECK-NEXT: [[B:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 2, i32* [[B]], align 4
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 1
> -; CHECK-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]])
> -; CHECK-NEXT: ret i32 [[X]]
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@callercaller()
> +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32
> +; 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-LABEL: define {{[^@]+}}@callercaller()
> +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 2, i32* [[B]], align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 1
> +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @caller(i32 [[TMP1]])
> +; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller()
> +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32
> +; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4
> +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias 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 6fdfb47a825d..f867c3c36ebd 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval-2.ll
> @@ -1,9 +1,39 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> %struct.ss = type { i32, i64 }
>
> define internal void @f(%struct.ss* byval %b, i32* byval %X) nounwind {
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
> +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval
> align 4 dereferenceable(4) [[B:%.*]], i32* noalias nocapture nofree nonnull
> writeonly byval align 4 dereferenceable(4) [[X:%.*]])
> +; 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 4
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
> +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[X]], align 4
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
> +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]], i32
> [[TMP2:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[X_PRIV:%.*]] = alloca i32
> +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[X_PRIV]]
> +; IS__CGSCC_NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; 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]]
> +; 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]]
> +; 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 4
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
> +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[X_PRIV]], align 4
> +; IS__CGSCC_NPM-NEXT: ret void
> +;
> entry:
> %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
> %tmp1 = load i32, i32* %tmp, align 4
> @@ -15,15 +45,36 @@ entry:
> }
>
> define i32 @test(i32* %X) {
> -; CHECK-LABEL: define {{[^@]+}}@test
> -; CHECK-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[S]], i32 0, i32 0
> -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8
> -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[S]], i32 0, i32 1
> -; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4
> -; CHECK-NEXT: ret i32 0
> +;
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test
> +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[X:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__TUNIT____-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__TUNIT____-NEXT: ret i32 0
> +;
> +; 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:
> +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__CGSCC_OPM-NEXT: ret i32 0
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test
> +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree nonnull readonly
> dereferenceable(4) [[X:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__CGSCC_NPM-NEXT: ret i32 0
> ;
> entry:
> %S = alloca %struct.ss
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
> index 545cbc0da701..c8d1afef5709 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/byval.ll
> @@ -1,24 +1,59 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=2 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> 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"
>
> %struct.ss = type { i32, i64 }
>
> define internal i32 @f(%struct.ss* byval %b) nounwind {
> -; CHECK-LABEL: define {{[^@]+}}@f
> -; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]]
> -; CHECK-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to
> i32*
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]]
> -; CHECK-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[B_PRIV]], i32 0, i32 1
> -; CHECK-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]]
> -; CHECK-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[B_PRIV]], i32 0, i32 0
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 8
> -; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> -; CHECK-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 8
> -; CHECK-NEXT: ret i32 [[TMP1]]
> +; 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-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:%.*]]
> +; 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]]
> +; 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]]
> +; 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__CGSCC_OPM-LABEL: define {{[^@]+}}@f
> +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval
> align 4 dereferenceable(4) [[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 4
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> +; IS__CGSCC_OPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
> +; IS__CGSCC_OPM-NEXT: ret i32 [[TMP1]]
> +;
> +; 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:%.*]]
> +; 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]]
> +; 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]]
> +; 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 4
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> +; IS__CGSCC_NPM-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 4
> +; IS__CGSCC_NPM-NEXT: ret i32 [[TMP1]]
> ;
> entry:
> %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
> @@ -30,19 +65,37 @@ entry:
>
>
> define internal i32 @g(%struct.ss* byval align 32 %b) nounwind {
> -; CHECK-LABEL: define {{[^@]+}}@g
> -; CHECK-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]]
> -; CHECK-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss* [[B_PRIV]] to
> i32*
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]]
> -; CHECK-NEXT: [[B_PRIV_0_1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[B_PRIV]], i32 0, i32 1
> -; CHECK-NEXT: store i64 [[TMP1]], i64* [[B_PRIV_0_1]]
> -; CHECK-NEXT: [[TMP:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[B_PRIV]], i32 0, i32 0
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 32
> -; CHECK-NEXT: [[TMP2:%.*]] = add i32 [[TMP1]], 1
> -; CHECK-NEXT: store i32 [[TMP2]], i32* [[TMP]], align 32
> -; CHECK-NEXT: ret i32 [[TMP2]]
> +; 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________NPM-LABEL: define {{[^@]+}}@g
> +; IS________NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
> +; IS________NPM-NEXT: entry:
> +; IS________NPM-NEXT: [[B_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS________NPM-NEXT: [[B_PRIV_CAST:%.*]] = bitcast %struct.ss*
> [[B_PRIV]] to i32*
> +; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[B_PRIV_CAST]]
> +; 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]]
> +; 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-LABEL: define {{[^@]+}}@g
> +; IS__CGSCC_OPM-SAME: (%struct.ss* noalias nocapture nofree nonnull byval
> align 32 dereferenceable(4) [[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]]
> ;
> entry:
> %tmp = getelementptr %struct.ss, %struct.ss* %b, i32 0, i32 0
> @@ -54,25 +107,69 @@ entry:
>
>
> define i32 @main() nounwind {
> -; CHECK-LABEL: define {{[^@]+}}@main()
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> -; CHECK-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[S]], i32 0, i32 0
> -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 8
> -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[S]], i32 0, i32 1
> -; CHECK-NEXT: store i64 2, i64* [[TMP4]], align 4
> -; CHECK-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to i32*
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1
> -; CHECK-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]], %struct.ss*
> [[S]], i32 0, i32 1
> -; CHECK-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1
> -; CHECK-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64 [[TMP1]])
> -; CHECK-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to i32*
> -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align 1
> -; CHECK-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> -; CHECK-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 1
> -; CHECK-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64 [[TMP3]])
> -; CHECK-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
> -; CHECK-NEXT: ret i32 [[A]]
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@main()
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__TUNIT_OPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__TUNIT_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__TUNIT_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__TUNIT_OPM-NEXT: [[C0:%.*]] = call i32 @f(%struct.ss* noalias
> nocapture nofree nonnull readonly byval align 8 dereferenceable(12) [[S]])
> +; IS__TUNIT_OPM-NEXT: [[C1:%.*]] = call i32 @g(%struct.ss* noalias
> nocapture nofree nonnull readonly byval align 32 dereferenceable(12) [[S]])
> +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
> +; IS__TUNIT_OPM-NEXT: ret i32 [[A]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@main()
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__TUNIT_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__TUNIT_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to
> i32*
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 1
> +; IS__TUNIT_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1
> +; IS__TUNIT_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64
> [[TMP1]])
> +; IS__TUNIT_NPM-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to
> i32*
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align
> 1
> +; IS__TUNIT_NPM-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 1
> +; IS__TUNIT_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64
> [[TMP3]])
> +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
> +; IS__TUNIT_NPM-NEXT: ret i32 [[A]]
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@main()
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[TMP1]], align 32
> +; IS__CGSCC_OPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_OPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__CGSCC_OPM-NEXT: [[C0:%.*]] = call i32 @f(%struct.ss* noalias
> nofree nonnull readnone byval align 32 dereferenceable(12) [[S]])
> +; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = call i32 @g(%struct.ss* noalias
> nofree nonnull readnone byval align 32 dereferenceable(12) [[S]])
> +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
> +; IS__CGSCC_OPM-NEXT: ret i32 [[A]]
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@main()
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[S:%.*]] = alloca [[STRUCT_SS:%.*]]
> +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[TMP1]], align 8
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: store i64 2, i64* [[TMP4]], align 4
> +; IS__CGSCC_NPM-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss* [[S]] to
> i32*
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]], align 8
> +; IS__CGSCC_NPM-NEXT: [[S_0_1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i64, i64* [[S_0_1]], align 1
> +; IS__CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @f(i32 [[TMP0]], i64
> [[TMP1]])
> +; IS__CGSCC_NPM-NEXT: [[S_CAST1:%.*]] = bitcast %struct.ss* [[S]] to
> i32*
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[S_CAST1]], align
> 8
> +; IS__CGSCC_NPM-NEXT: [[S_0_12:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = load i64, i64* [[S_0_12]], align 1
> +; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @g(i32 [[TMP2]], i64
> [[TMP3]])
> +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = add i32 [[C0]], [[C1]]
> +; IS__CGSCC_NPM-NEXT: ret i32 [[A]]
> ;
> entry:
> %S = alloca %struct.ss
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
> index 6e9f98007e46..5684807e4745 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/chained.ll
> @@ -1,10 +1,14 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> @G1 = constant i32 0
> @G2 = constant i32* @G1
>
> define internal i32 @test(i32** %x) {
> +;
> ; CHECK-LABEL: define {{[^@]+}}@test()
> ; CHECK-NEXT: entry:
> ; CHECK-NEXT: [[Y:%.*]] = load i32*, i32** @G2, align 8
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll
> index 494107d17d8b..142df98051eb 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; Don't promote around control flow.
> define internal 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 5636a0a0e97d..773df89affb5 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/control-flow2.ll
> @@ -1,19 +1,40 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=7 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> 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) {
> -; CHECK-LABEL: define {{[^@]+}}@callee
> -; CHECK-SAME: (i1 [[C:%.*]], i32 [[TMP0:%.*]])
> -; CHECK-NEXT: [[P_PRIV:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[P_PRIV]]
> -; CHECK-NEXT: br label [[F:%.*]]
> -; CHECK: T:
> -; CHECK-NEXT: unreachable
> -; CHECK: F:
> -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[P_PRIV]], align 4
> -; CHECK-NEXT: ret i32 [[X]]
> +; 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:%.*]]
> +; IS__TUNIT_OPM: T:
> +; IS__TUNIT_OPM-NEXT: unreachable
> +; IS__TUNIT_OPM: F:
> +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = load i32, i32* [[P]], align 4
> +; IS__TUNIT_OPM-NEXT: ret i32 [[X]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@callee
> +; IS__TUNIT_NPM-SAME: (i1 [[C:%.*]], i32 [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: [[P_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[P_PRIV]]
> +; IS__TUNIT_NPM-NEXT: br label [[F:%.*]]
> +; IS__TUNIT_NPM: T:
> +; IS__TUNIT_NPM-NEXT: unreachable
> +; IS__TUNIT_NPM: F:
> +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = load i32, i32* [[P_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@callee
> +; IS__CGSCC____-SAME: (i32* nocapture nofree readonly [[P:%.*]])
> +; IS__CGSCC____-NEXT: br label [[F:%.*]]
> +; IS__CGSCC____: T:
> +; IS__CGSCC____-NEXT: unreachable
> +; IS__CGSCC____: F:
> +; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[P]]
> +; IS__CGSCC____-NEXT: ret i32 [[X]]
> ;
> br i1 %C, label %T, label %F
>
> @@ -26,12 +47,24 @@ F: ; preds = %0
> }
>
> define i32 @foo() {
> -; CHECK-LABEL: define {{[^@]+}}@foo()
> -; CHECK-NEXT: [[A:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 17, i32* [[A]], align 4
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[A]], align 1
> -; CHECK-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32 [[TMP1]])
> -; CHECK-NEXT: ret i32 [[X]]
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@foo()
> +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = alloca i32
> +; 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-LABEL: define {{[^@]+}}@foo()
> +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 17, i32* [[A]], align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[A]], align 1
> +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = call i32 @callee(i1 false, i32
> [[TMP1]])
> +; IS__TUNIT_NPM-NEXT: ret i32 [[X]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo()
> +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32
> +; IS__CGSCC____-NEXT: store i32 17, i32* [[A]], align 4
> +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @callee(i32* noalias nofree
> nonnull readonly align 4 dereferenceable(4) [[A]])
> +; IS__CGSCC____-NEXT: ret i32 [[X]]
> ;
> %A = alloca i32 ; <i32*> [#uses=2]
> store i32 17, i32* %A
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
> index db3db632e5f2..9d7fd443fe29 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/crash.ll
> @@ -1,30 +1,22 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> --check-prefixes=CHECK,ATTRIBUTOR
> -; RUN: opt -S -passes='cgscc(inline),attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> --check-prefixes=CHECK,INLINE_ATTRIBUTOR
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> %S = type { %S* }
>
> ; Inlining should nuke the invoke (and any inlined calls) here even with
> ; argument promotion running along with it.
> define void @zot() personality i32 (...)* @wibble {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@zot() #0 personality i32 (...)*
> @wibble
> -; ATTRIBUTOR-NEXT: bb:
> -; ATTRIBUTOR-NEXT: call void @hoge()
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: bb1:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: bb2:
> -; ATTRIBUTOR-NEXT: unreachable
> -;
> -; INLINE_ATTRIBUTOR-LABEL: define {{[^@]+}}@zot() #0 personality i32
> (...)* @wibble
> -; INLINE_ATTRIBUTOR-NEXT: bb:
> -; INLINE_ATTRIBUTOR-NEXT: unreachable
> -; INLINE_ATTRIBUTOR: hoge.exit:
> -; INLINE_ATTRIBUTOR-NEXT: unreachable
> -; INLINE_ATTRIBUTOR: bb1:
> -; INLINE_ATTRIBUTOR-NEXT: unreachable
> -; INLINE_ATTRIBUTOR: bb2:
> -; INLINE_ATTRIBUTOR-NEXT: unreachable
> +; 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
> ;
> bb:
> invoke void @hoge()
> @@ -40,9 +32,9 @@ bb2:
> }
>
> define internal void @hoge() {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@hoge()
> -; ATTRIBUTOR-NEXT: bb:
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@hoge()
> +; CHECK-NEXT: bb:
> +; CHECK-NEXT: unreachable
> ;
> bb:
> %tmp = call fastcc i8* @spam(i1 (i8*)* @eggs)
> @@ -51,6 +43,10 @@ bb:
> }
>
> define internal fastcc i8* @spam(i1 (i8*)* %arg) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@spam()
> +; IS__CGSCC____-NEXT: bb:
> +; IS__CGSCC____-NEXT: unreachable
> +;
> bb:
> unreachable
> }
> @@ -62,15 +58,26 @@ bb:
> }
>
> define internal i1 @barney(i8* %arg) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@barney()
> +; IS__CGSCC____-NEXT: bb:
> +; IS__CGSCC____-NEXT: ret i1 undef
> +;
> bb:
> ret i1 undef
> }
>
> define i32 @test_inf_promote_caller(i32 %arg) {
> -; CHECK-LABEL: define {{[^@]+}}@test_inf_promote_caller
> -; CHECK-SAME: (i32 [[ARG:%.*]])
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: unreachable
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test_inf_promote_caller
> +; IS__TUNIT____-SAME: (i32 [[ARG:%.*]])
> +; IS__TUNIT____-NEXT: bb:
> +; IS__TUNIT____-NEXT: unreachable
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inf_promote_caller
> +; IS__CGSCC____-SAME: (i32 [[ARG:%.*]])
> +; IS__CGSCC____-NEXT: bb:
> +; IS__CGSCC____-NEXT: [[TMP:%.*]] = alloca [[S:%.*]]
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = alloca [[S]]
> +; IS__CGSCC____-NEXT: unreachable
> ;
> bb:
> %tmp = alloca %S
> @@ -81,6 +88,10 @@ bb:
> }
>
> define internal i32 @test_inf_promote_callee(%S* %arg, %S* %arg1) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test_inf_promote_callee()
> +; IS__CGSCC____-NEXT: bb:
> +; IS__CGSCC____-NEXT: unreachable
> +;
> bb:
> %tmp = getelementptr %S, %S* %arg1, i32 0, i32 0
> %tmp2 = load %S*, %S** %tmp
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
> index 43ee9dd13d8d..8a02146d893b 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/dbg.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=2 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> declare void @sink(i32)
>
> @@ -29,11 +32,17 @@ define internal void @test_byval(%struct.pair* byval
> %P) {
> }
>
> define void @caller(i32** %Y, %struct.pair* %P) {
> -; CHECK-LABEL: define {{[^@]+}}@caller
> -; CHECK-SAME: (i32** nocapture readonly [[Y:%.*]], %struct.pair*
> nocapture nofree readnone [[P:%.*]])
> -; CHECK-NEXT: call void @test(i32** nocapture readonly align 8 [[Y]]),
> !dbg !4
> -; CHECK-NEXT: call void @test_byval(), !dbg !5
> -; CHECK-NEXT: ret void
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
> +; IS__TUNIT____-SAME: (i32** nocapture readonly [[Y:%.*]], %struct.pair*
> nocapture nofree readnone [[P:%.*]])
> +; IS__TUNIT____-NEXT: call void @test(i32** nocapture readonly align 8
> [[Y]]), !dbg !4
> +; IS__TUNIT____-NEXT: call void @test_byval(), !dbg !5
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
> +; IS__CGSCC____-SAME: (i32** nocapture nonnull readonly align 8
> dereferenceable(8) [[Y:%.*]], %struct.pair* nocapture nofree readnone
> [[P:%.*]])
> +; IS__CGSCC____-NEXT: call void @test(i32** nocapture nonnull readonly
> align 8 dereferenceable(8) [[Y]]), !dbg !4
> +; IS__CGSCC____-NEXT: call void @test_byval(), !dbg !5
> +; IS__CGSCC____-NEXT: ret void
> ;
> call void @test(i32** %Y), !dbg !1
>
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
> index b9ee30fac9b9..75935664999e 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
> @@ -26,6 +29,10 @@ entry:
> }
>
> define internal i8 @UseLongDoubleUnsafely(%union.u* byval align 16 %arg) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@UseLongDoubleUnsafely()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: ret i8 undef
> +;
> entry:
> %bitcast = bitcast %union.u* %arg to %struct.s*
> %gep = getelementptr inbounds %struct.s, %struct.s* %bitcast, i64 0,
> i32 2
> @@ -34,18 +41,53 @@ entry:
> }
>
> define internal x86_fp80 @UseLongDoubleSafely(%union.u* byval align 16
> %arg) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@UseLongDoubleSafely()
> +; IS__CGSCC____-NEXT: ret x86_fp80 undef
> +;
> %gep = getelementptr inbounds %union.u, %union.u* %arg, i64 0, i32 0
> %fp80 = load x86_fp80, x86_fp80* %gep
> ret x86_fp80 %fp80
> }
>
> define internal i64 @AccessPaddingOfStruct(%struct.Foo* byval %a) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@AccessPaddingOfStruct()
> +; IS__CGSCC____-NEXT: ret i64 undef
> +;
> %p = bitcast %struct.Foo* %a to i64*
> %v = load i64, i64* %p
> ret i64 %v
> }
>
> define internal i64 @CaptureAStruct(%struct.Foo* byval %a) {
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@CaptureAStruct
> +; IS__CGSCC_OPM-SAME: (%struct.Foo* noalias nofree byval [[A:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*
> +; IS__CGSCC_OPM-NEXT: br label [[LOOP:%.*]]
> +; IS__CGSCC_OPM: loop:
> +; IS__CGSCC_OPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null,
> [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
> +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = phi %struct.Foo* [ [[A]],
> [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
> +; IS__CGSCC_OPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo**
> [[A_PTR]], align 8
> +; IS__CGSCC_OPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO:%.*]],
> %struct.Foo* [[A]], i64 0
> +; IS__CGSCC_OPM-NEXT: br label [[LOOP]]
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@CaptureAStruct
> +; IS__CGSCC_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_FOO:%.*]]
> +; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.Foo*
> [[A_PRIV]] to i32*
> +; IS__CGSCC_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV_CAST]]
> +; IS__CGSCC_NPM-NEXT: [[A_PRIV_0_1:%.*]] = getelementptr
> [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: store i64 [[TMP1]], i64* [[A_PRIV_0_1]]
> +; IS__CGSCC_NPM-NEXT: [[A_PTR:%.*]] = alloca %struct.Foo*
> +; IS__CGSCC_NPM-NEXT: br label [[LOOP:%.*]]
> +; IS__CGSCC_NPM: loop:
> +; IS__CGSCC_NPM-NEXT: [[PHI:%.*]] = phi %struct.Foo* [ null,
> [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = phi %struct.Foo* [ [[A_PRIV]],
> [[ENTRY]] ], [ [[TMP2]], [[LOOP]] ]
> +; IS__CGSCC_NPM-NEXT: store %struct.Foo* [[PHI]], %struct.Foo**
> [[A_PTR]], align 8
> +; IS__CGSCC_NPM-NEXT: [[GEP]] = getelementptr [[STRUCT_FOO]],
> %struct.Foo* [[A_PRIV]], i64 0
> +; IS__CGSCC_NPM-NEXT: br label [[LOOP]]
> +;
> entry:
> %a_ptr = alloca %struct.Foo*
> br label %loop
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
> index c9598b348715..fc2f6ef1724e 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/inalloca.ll
> @@ -1,6 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=6 < %s | FileCheck %s --check-prefixes=ATTRIBUTOR
> -; RUN: opt -S -passes='globalopt,attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=6 < %s | FileCheck %s
> --check-prefixes=GLOBALOPT_ATTRIBUTOR
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> 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"
>
> @@ -8,30 +10,25 @@ 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) {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@f
> -; ATTRIBUTOR-SAME: (%struct.ss* inalloca noalias nocapture nofree nonnull
> align 4 dereferenceable(8) [[S:%.*]])
> -; ATTRIBUTOR-NEXT: entry:
> -; ATTRIBUTOR-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS:%.*]],
> %struct.ss* [[S]], i32 0, i32 0
> -; ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> -; ATTRIBUTOR-NEXT: [[A:%.*]] = load i32, i32* [[F0]], align 4
> -; ATTRIBUTOR-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4
> -; ATTRIBUTOR-NEXT: [[R:%.*]] = add i32 [[A]], [[B]]
> -; ATTRIBUTOR-NEXT: ret i32 [[R]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@f
> +; IS__TUNIT____-SAME: (%struct.ss* inalloca noalias nocapture nofree
> nonnull align 4 dereferenceable(8) [[S:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; 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: [[A:%.*]] = load i32, i32* [[F0]], align 4
> +; IS__TUNIT____-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4
> +; IS__TUNIT____-NEXT: [[R:%.*]] = add i32 [[A]], [[B]]
> +; IS__TUNIT____-NEXT: ret i32 [[R]]
> ;
> -; GLOBALOPT_ATTRIBUTOR-LABEL: define {{[^@]+}}@f
> -; GLOBALOPT_ATTRIBUTOR-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> unnamed_addr
> -; GLOBALOPT_ATTRIBUTOR-NEXT: entry:
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_PRIV:%.*]] = alloca [[STRUCT_SS:%.*]]
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_PRIV_CAST:%.*]] = bitcast %struct.ss*
> [[S_PRIV]] to i32*
> -; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 [[TMP0]], i32* [[S_PRIV_CAST]]
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_PRIV_0_1:%.*]] = getelementptr
> [[STRUCT_SS]], %struct.ss* [[S_PRIV]], i32 0, i32 1
> -; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 [[TMP1]], i32* [[S_PRIV_0_1]]
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S_PRIV]], i32 0, i32 0
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S_PRIV]], i32 0, i32 1
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[A:%.*]] = load i32, i32* [[F0]], align 4
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[R:%.*]] = add i32 [[A]], [[B]]
> -; GLOBALOPT_ATTRIBUTOR-NEXT: ret i32 [[R]]
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@f
> +; IS__CGSCC____-SAME: (%struct.ss* inalloca nocapture nofree nonnull
> align 4 dereferenceable(8) [[S:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; 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: [[A:%.*]] = load i32, i32* [[F0]], align 4
> +; IS__CGSCC____-NEXT: [[B:%.*]] = load i32, i32* [[F1]], align 4
> +; IS__CGSCC____-NEXT: [[R:%.*]] = add i32 [[A]], [[B]]
> +; IS__CGSCC____-NEXT: ret i32 [[R]]
> ;
> entry:
> %f0 = getelementptr %struct.ss, %struct.ss* %s, i32 0, i32 0
> @@ -43,29 +40,25 @@ entry:
> }
>
> define i32 @main() {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@main()
> -; ATTRIBUTOR-NEXT: entry:
> -; ATTRIBUTOR-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]]
> -; ATTRIBUTOR-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> -; ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> -; ATTRIBUTOR-NEXT: store i32 1, i32* [[F0]], align 4
> -; ATTRIBUTOR-NEXT: store i32 2, i32* [[F1]], align 4
> -; ATTRIBUTOR-NEXT: [[R:%.*]] = call i32 @f(%struct.ss* inalloca
> noalias nocapture nofree nonnull align 4 dereferenceable(8) [[S]])
> -; ATTRIBUTOR-NEXT: ret i32 [[R]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@main()
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]]
> +; 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]]
> ;
> -; GLOBALOPT_ATTRIBUTOR-LABEL: define {{[^@]+}}@main() local_unnamed_addr
> -; GLOBALOPT_ATTRIBUTOR-NEXT: entry:
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S:%.*]] = alloca inalloca
> [[STRUCT_SS:%.*]]
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[F0:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 0
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[F1:%.*]] = getelementptr [[STRUCT_SS]],
> %struct.ss* [[S]], i32 0, i32 1
> -; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 1, i32* [[F0]], align 4
> -; GLOBALOPT_ATTRIBUTOR-NEXT: store i32 2, i32* [[F1]], align 4
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_CAST:%.*]] = bitcast %struct.ss*
> [[S]] to i32*
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[TMP0:%.*]] = load i32, i32* [[S_CAST]],
> align 1
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[S_0_1:%.*]] = getelementptr
> [[STRUCT_SS]], %struct.ss* [[S]], i32 0, i32 1
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[TMP1:%.*]] = load i32, i32* [[S_0_1]],
> align 1
> -; GLOBALOPT_ATTRIBUTOR-NEXT: [[R:%.*]] = call fastcc i32 @f(i32
> [[TMP0]], i32 [[TMP1]])
> -; GLOBALOPT_ATTRIBUTOR-NEXT: ret i32 [[R]]
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@main()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[S:%.*]] = alloca inalloca [[STRUCT_SS:%.*]]
> +; 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 nofree nonnull align 4 dereferenceable(8) [[S]])
> +; IS__CGSCC____-NEXT: ret i32 [[R]]
> ;
> entry:
> %S = alloca inalloca %struct.ss
> @@ -79,19 +72,20 @@ 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____-LABEL: define {{[^@]+}}@g
> +; IS__CGSCC____-SAME: (%struct.ss* nocapture nofree readnone [[A:%.*]],
> %struct.ss* inalloca nocapture nofree writeonly [[B:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: ret i1 undef
> +;
> entry:
> %c = icmp eq %struct.ss* %a, %b
> ret i1 %c
> }
>
> define i32 @test() {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@test()
> -; ATTRIBUTOR-NEXT: entry:
> -; ATTRIBUTOR-NEXT: ret i32 0
> -;
> -; GLOBALOPT_ATTRIBUTOR-LABEL: define {{[^@]+}}@test() local_unnamed_addr
> -; GLOBALOPT_ATTRIBUTOR-NEXT: entry:
> -; GLOBALOPT_ATTRIBUTOR-NEXT: ret i32 0
> +; CHECK-LABEL: define {{[^@]+}}@test()
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: ret i32 0
> ;
> entry:
> %S = alloca inalloca %struct.ss
>
> 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 c69842119ec6..1f034c8404fe 100644
> ---
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
> +++
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/live_called_from_dead.ll
> @@ -1,13 +1,9 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -basicaa -attributor -attributor-disable=false
> -attributor-max-iterations-verify -attributor-max-iterations=4 < %s |
> FileCheck %s --check-prefixes=CHECK,OLDPM,OLDPM_MODULE
> -; RUN: opt -S -basicaa -attributor-cgscc -attributor-disable=false < %s |
> FileCheck %s --check-prefixes=CHECK,OLDPM,OLDPM_CGSCC
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=4 < %s | FileCheck %s
> --check-prefixes=CHECK,NEWPM,NEWPM_MODULE
> -; RUN: opt -S -passes='attributor-cgscc' -aa-pipeline='basic-aa'
> -attributor-disable=false < %s | FileCheck %s
> --check-prefixes=CHECK,NEWPM,NEWPM_CGSCC
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> -; OLDPM_MODULE-NOT: @dead
> -; NEWPM_MODULE-NOT: @dead
> -; OLDPM_CGSCC-NOT: @dead
> -; NEWPM_CGSCC-NOT: @dead
>
> define internal void @dead() {
> call i32 @test(i32* null, i32* null)
> @@ -15,23 +11,23 @@ define internal void @dead() {
> }
>
> define internal i32 @test(i32* %X, i32* %Y) {
> -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@test
> -; OLDPM_CGSCC-SAME: (i32* noalias nocapture nofree writeonly align 4
> [[X:%.*]])
> -; OLDPM_CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
> -; OLDPM_CGSCC: live:
> -; OLDPM_CGSCC-NEXT: store i32 0, i32* [[X]], align 4
> -; OLDPM_CGSCC-NEXT: ret i32 undef
> -; OLDPM_CGSCC: dead:
> -; OLDPM_CGSCC-NEXT: unreachable
> +; 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:%.*]]
> +; IS__CGSCC_OPM: live:
> +; IS__CGSCC_OPM-NEXT: store i32 0, i32* [[X]], align 4
> +; IS__CGSCC_OPM-NEXT: ret i32 undef
> +; IS__CGSCC_OPM: dead:
> +; IS__CGSCC_OPM-NEXT: unreachable
> ;
> -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@test
> -; NEWPM_CGSCC-SAME: (i32* noalias nocapture nofree nonnull writeonly
> align 4 dereferenceable(4) [[X:%.*]])
> -; NEWPM_CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
> -; NEWPM_CGSCC: live:
> -; NEWPM_CGSCC-NEXT: store i32 0, i32* [[X]], align 4
> -; NEWPM_CGSCC-NEXT: ret i32 undef
> -; NEWPM_CGSCC: dead:
> -; NEWPM_CGSCC-NEXT: unreachable
> +; 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:%.*]]
> +; IS__CGSCC_NPM: live:
> +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[X]], align 4
> +; IS__CGSCC_NPM-NEXT: ret i32 undef
> +; IS__CGSCC_NPM: dead:
> +; IS__CGSCC_NPM-NEXT: unreachable
> ;
> br i1 true, label %live, label %dead
> live:
> @@ -44,17 +40,17 @@ dead:
> }
>
> define internal i32 @caller(i32* %B) {
> -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@caller()
> -; OLDPM_CGSCC-NEXT: [[A:%.*]] = alloca i32
> -; OLDPM_CGSCC-NEXT: store i32 1, i32* [[A]], align 4
> -; OLDPM_CGSCC-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture
> nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
> -; OLDPM_CGSCC-NEXT: ret i32 0
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller()
> +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32
> +; 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
> ;
> -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@caller()
> -; NEWPM_CGSCC-NEXT: [[A:%.*]] = alloca i32
> -; NEWPM_CGSCC-NEXT: store i32 1, i32* [[A]], align 4
> -; NEWPM_CGSCC-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture
> nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
> -; NEWPM_CGSCC-NEXT: ret i32 undef
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller()
> +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32
> +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[A]], align 4
> +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* noalias
> nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
> +; IS__CGSCC_NPM-NEXT: ret i32 undef
> ;
> %A = alloca i32
> store i32 1, i32* %A
>
> 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 429a3a7b7b43..d3892d2093a0 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,13 +1,9 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -basicaa -attributor -attributor-disable=false
> -attributor-max-iterations-verify -attributor-max-iterations=7 < %s |
> FileCheck %s --check-prefixes=CHECK,OLDPM,OLDPM_MODULE
> -; RUN: opt -S -basicaa -attributor-cgscc -attributor-disable=false < %s |
> FileCheck %s --check-prefixes=CHECK,OLDPM,OLDPM_CGSCC
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=7 < %s | FileCheck %s
> --check-prefixes=CHECK,NEWPM,NEWPM_MODULE
> -; RUN: opt -S -passes='attributor-cgscc' -aa-pipeline='basic-aa'
> -attributor-disable=false < %s | FileCheck %s
> --check-prefixes=CHECK,NEWPM,NEWPM_CGSCC
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> -; OLDPM_MODULE-NOT: @dead
> -; NEWPM_MODULE-NOT: @dead
> -; OLDPM_CGSCC-NOT: @dead
> -; NEWPM_CGSCC-NOT: @dead
>
> define internal void @dead() {
> call i32 @test(i32* null, i32* null)
> @@ -15,41 +11,23 @@ define internal void @dead() {
> }
>
> define internal i32 @test(i32* %X, i32* %Y) {
> -; OLDPM_MODULE-LABEL: define {{[^@]+}}@test
> -; OLDPM_MODULE-SAME: (i32* noalias nocapture nofree writeonly align 4
> [[X:%.*]])
> -; OLDPM_MODULE-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
> -; OLDPM_MODULE: live:
> -; OLDPM_MODULE-NEXT: store i32 0, i32* [[X]], align 4
> -; OLDPM_MODULE-NEXT: ret i32 undef
> -; OLDPM_MODULE: dead:
> -; OLDPM_MODULE-NEXT: unreachable
> +; 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:%.*]]
> +; IS__TUNIT____: live:
> +; IS__TUNIT____-NEXT: store i32 0, i32* [[X]], align 4
> +; IS__TUNIT____-NEXT: ret i32 undef
> +; IS__TUNIT____: dead:
> +; IS__TUNIT____-NEXT: unreachable
> ;
> -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@test
> -; OLDPM_CGSCC-SAME: (i32* nocapture nofree writeonly [[X:%.*]])
> -; OLDPM_CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
> -; OLDPM_CGSCC: live:
> -; OLDPM_CGSCC-NEXT: store i32 0, i32* [[X]]
> -; OLDPM_CGSCC-NEXT: ret i32 undef
> -; OLDPM_CGSCC: dead:
> -; OLDPM_CGSCC-NEXT: unreachable
> -;
> -; NEWPM_MODULE-LABEL: define {{[^@]+}}@test
> -; NEWPM_MODULE-SAME: (i32* noalias nocapture nofree writeonly align 4
> [[X:%.*]])
> -; NEWPM_MODULE-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
> -; NEWPM_MODULE: live:
> -; NEWPM_MODULE-NEXT: store i32 0, i32* [[X]], align 4
> -; NEWPM_MODULE-NEXT: ret i32 undef
> -; NEWPM_MODULE: dead:
> -; NEWPM_MODULE-NEXT: unreachable
> -;
> -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@test
> -; NEWPM_CGSCC-SAME: (i32* nocapture nofree writeonly [[X:%.*]])
> -; NEWPM_CGSCC-NEXT: br i1 true, label [[LIVE:%.*]], label [[DEAD:%.*]]
> -; NEWPM_CGSCC: live:
> -; NEWPM_CGSCC-NEXT: store i32 0, i32* [[X]]
> -; NEWPM_CGSCC-NEXT: ret i32 undef
> -; NEWPM_CGSCC: dead:
> -; NEWPM_CGSCC-NEXT: unreachable
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test
> +; IS__CGSCC____-SAME: (i32* nocapture nofree writeonly [[X:%.*]])
> +; IS__CGSCC____-NEXT: br i1 true, label [[LIVE:%.*]], label
> [[DEAD:%.*]]
> +; IS__CGSCC____: live:
> +; IS__CGSCC____-NEXT: store i32 0, i32* [[X]]
> +; IS__CGSCC____-NEXT: ret i32 undef
> +; IS__CGSCC____: dead:
> +; IS__CGSCC____-NEXT: unreachable
> ;
> br i1 true, label %live, label %dead
> live:
> @@ -62,33 +40,26 @@ dead:
> }
>
> define internal i32 @caller(i32* %B) {
> -; OLDPM_MODULE-LABEL: define {{[^@]+}}@caller
> -; OLDPM_MODULE-SAME: (i32* noalias nocapture nofree nonnull writeonly
> align 4 dereferenceable(4) [[B:%.*]])
> -; OLDPM_MODULE-NEXT: [[A:%.*]] = alloca i32
> -; OLDPM_MODULE-NEXT: store i32 1, i32* [[A]], align 4
> -; OLDPM_MODULE-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture
> nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
> -; OLDPM_MODULE-NEXT: ret i32 undef
> -;
> -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@caller
> -; OLDPM_CGSCC-SAME: (i32* nocapture nofree writeonly [[B:%.*]])
> -; OLDPM_CGSCC-NEXT: [[A:%.*]] = alloca i32
> -; OLDPM_CGSCC-NEXT: store i32 1, i32* [[A]], align 4
> -; OLDPM_CGSCC-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree
> writeonly [[B]])
> -; OLDPM_CGSCC-NEXT: ret i32 0
> +; 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
> +; IS__TUNIT____-NEXT: store i32 1, i32* [[A]], align 4
> +; IS__TUNIT____-NEXT: [[C:%.*]] = call i32 @test(i32* noalias
> nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
> +; IS__TUNIT____-NEXT: ret i32 undef
> ;
> -; NEWPM_MODULE-LABEL: define {{[^@]+}}@caller
> -; NEWPM_MODULE-SAME: (i32* noalias nocapture nofree nonnull writeonly
> align 4 dereferenceable(4) [[B:%.*]])
> -; NEWPM_MODULE-NEXT: [[A:%.*]] = alloca i32
> -; NEWPM_MODULE-NEXT: store i32 1, i32* [[A]], align 4
> -; NEWPM_MODULE-NEXT: [[C:%.*]] = call i32 @test(i32* noalias nocapture
> nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
> -; NEWPM_MODULE-NEXT: ret i32 undef
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@caller
> +; IS__CGSCC_OPM-SAME: (i32* nocapture nofree writeonly [[B:%.*]])
> +; IS__CGSCC_OPM-NEXT: [[A:%.*]] = alloca i32
> +; IS__CGSCC_OPM-NEXT: store i32 1, i32* [[A]], align 4
> +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree
> writeonly [[B]])
> +; IS__CGSCC_OPM-NEXT: ret i32 0
> ;
> -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@caller
> -; NEWPM_CGSCC-SAME: (i32* nocapture nofree writeonly [[B:%.*]])
> -; NEWPM_CGSCC-NEXT: [[A:%.*]] = alloca i32
> -; NEWPM_CGSCC-NEXT: store i32 1, i32* [[A]], align 4
> -; NEWPM_CGSCC-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree
> writeonly [[B]])
> -; NEWPM_CGSCC-NEXT: ret i32 undef
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@caller
> +; IS__CGSCC_NPM-SAME: (i32* nocapture nofree writeonly [[B:%.*]])
> +; IS__CGSCC_NPM-NEXT: [[A:%.*]] = alloca i32
> +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[A]], align 4
> +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = call i32 @test(i32* nocapture nofree
> writeonly [[B]])
> +; IS__CGSCC_NPM-NEXT: ret i32 undef
> ;
> %A = alloca i32
> store i32 1, i32* %A
> @@ -97,29 +68,17 @@ define internal i32 @caller(i32* %B) {
> }
>
> define i32 @callercaller() {
> -; OLDPM_MODULE-LABEL: define {{[^@]+}}@callercaller()
> -; OLDPM_MODULE-NEXT: [[B:%.*]] = alloca i32
> -; OLDPM_MODULE-NEXT: store i32 2, i32* [[B]], align 4
> -; OLDPM_MODULE-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias
> nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
> -; OLDPM_MODULE-NEXT: ret i32 0
> -;
> -; OLDPM_CGSCC-LABEL: define {{[^@]+}}@callercaller()
> -; OLDPM_CGSCC-NEXT: [[B:%.*]] = alloca i32
> -; OLDPM_CGSCC-NEXT: store i32 2, i32* [[B]], align 4
> -; OLDPM_CGSCC-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nofree
> nonnull writeonly align 4 dereferenceable(4) [[B]])
> -; OLDPM_CGSCC-NEXT: ret i32 0
> -;
> -; NEWPM_MODULE-LABEL: define {{[^@]+}}@callercaller()
> -; NEWPM_MODULE-NEXT: [[B:%.*]] = alloca i32
> -; NEWPM_MODULE-NEXT: store i32 2, i32* [[B]], align 4
> -; NEWPM_MODULE-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias
> nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
> -; NEWPM_MODULE-NEXT: ret i32 0
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@callercaller()
> +; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32
> +; IS__TUNIT____-NEXT: store i32 2, i32* [[B]], align 4
> +; IS__TUNIT____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias
> nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[B]])
> +; IS__TUNIT____-NEXT: ret i32 0
> ;
> -; NEWPM_CGSCC-LABEL: define {{[^@]+}}@callercaller()
> -; NEWPM_CGSCC-NEXT: [[B:%.*]] = alloca i32
> -; NEWPM_CGSCC-NEXT: store i32 2, i32* [[B]], align 4
> -; NEWPM_CGSCC-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nofree
> nonnull writeonly align 4 dereferenceable(4) [[B]])
> -; NEWPM_CGSCC-NEXT: ret i32 0
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@callercaller()
> +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32
> +; IS__CGSCC____-NEXT: store i32 2, i32* [[B]], align 4
> +; IS__CGSCC____-NEXT: [[X:%.*]] = call i32 @caller(i32* noalias nofree
> nonnull writeonly align 4 dereferenceable(4) [[B]])
> +; IS__CGSCC____-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 89ee21519e78..0fc379c705f1 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/musttail.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ; PR36543
>
> ; Don't promote arguments of musttail callee
> @@ -45,6 +48,16 @@ define i32 @foo(%T* %p, i32 %v) {
> }
>
> define internal i32 @test2(%T* %p, i32 %p2) {
> +; 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
> +; 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 @foo(%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
> %a = load i32, i32* %a.gep
> @@ -55,9 +68,14 @@ define internal i32 @test2(%T* %p, i32 %p2) {
> }
>
> define i32 @caller2(%T* %g) {
> -; CHECK-LABEL: define {{[^@]+}}@caller2
> -; CHECK-SAME: (%T* nocapture nofree readnone [[G:%.*]])
> -; CHECK-NEXT: ret i32 0
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller2
> +; IS__TUNIT____-SAME: (%T* nocapture nofree readnone [[G:%.*]])
> +; IS__TUNIT____-NEXT: ret i32 0
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller2
> +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[G:%.*]])
> +; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2(%T* nocapture nofree
> readonly [[G]], i32 0)
> +; IS__CGSCC____-NEXT: ret i32 [[V]]
> ;
> %v = call i32 @test2(%T* %g, i32 0)
> ret i32 %v
> @@ -100,10 +118,15 @@ define internal i32 @test2b(%T* %p, i32 %p2) {
> }
>
> define i32 @caller2b(%T* %g) {
> -; CHECK-LABEL: define {{[^@]+}}@caller2b
> -; CHECK-SAME: (%T* nocapture nofree readonly [[G:%.*]])
> -; CHECK-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture nofree
> readonly [[G]], i32 undef)
> -; CHECK-NEXT: ret i32 0
> +; 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____-LABEL: define {{[^@]+}}@caller2b
> +; IS__CGSCC____-SAME: (%T* nocapture nofree readonly [[G:%.*]])
> +; IS__CGSCC____-NEXT: [[V:%.*]] = call i32 @test2b(%T* nocapture
> nofree readonly [[G]], i32 0)
> +; IS__CGSCC____-NEXT: ret i32 [[V]]
> ;
> %v = call i32 @test2b(%T* %g, i32 0)
> ret i32 %v
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll
> index 4bfe138f4b6e..92cb7efb7bd2 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/naked_functions.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; Don't promote paramaters of/arguments to naked functions
>
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
> index d08969c0a262..04e8bd6bdc8b 100644
> ---
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
> +++
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/nonzero-address-spaces.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; ArgumentPromotion should preserve the default function address space
> ; from the data layout.
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll
> index f2ff8dc63279..d7aafae2d158 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr27568.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> target triple = "x86_64-pc-windows-msvc"
>
> define internal void @callee(i8*) {
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr3085.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr3085.ll
> deleted file mode 100644
> index 5b8b7da46a47..000000000000
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr3085.ll
> +++ /dev/null
> @@ -1,1945 +0,0 @@
> -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -disable-output -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s
> -; PR 3085
> -
> - %struct.Lit = type { i8 }
> -
> -define fastcc %struct.Lit* @import_lit(i32 %lit) nounwind {
> -entry:
> - br i1 false, label %bb, label %bb1
> -
> -bb: ; preds = %entry
> - unreachable
> -
> -bb1: ; preds = %entry
> - br label %bb3
> -
> -bb2: ; preds = %bb3
> - br label %bb3
> -
> -bb3: ; preds = %bb2, %bb1
> - br i1 false, label %bb2, label %bb6
> -
> -bb6: ; preds = %bb3
> - br i1 false, label %bb.i.i, label %bb1.i.i
> -
> -bb.i.i: ; preds = %bb6
> - br label %int2lit.exit
> -
> -bb1.i.i: ; preds = %bb6
> - br label %int2lit.exit
> -
> -int2lit.exit: ; preds = %bb1.i.i, %bb.i.i
> - ret %struct.Lit* null
> -}
> -
> -define fastcc i32 @picosat_main(i32 %argc, i8** %argv) nounwind {
> -entry:
> - br i1 false, label %bb.i, label %picosat_time_stamp.exit
> -
> -bb.i: ; preds = %entry
> - br label %picosat_time_stamp.exit
> -
> -picosat_time_stamp.exit: ; preds = %bb.i, %entry
> - br label %bb108
> -
> -bb: ; preds = %bb108
> - br i1 false, label %bb1, label %bb2
> -
> -bb1: ; preds = %bb
> - br label %bb106
> -
> -bb2: ; preds = %bb
> - br i1 false, label %bb3, label %bb4
> -
> -bb3: ; preds = %bb2
> - br label %bb106
> -
> -bb4: ; preds = %bb2
> - br i1 false, label %bb5, label %bb6
> -
> -bb5: ; preds = %bb4
> - br label %bb106
> -
> -bb6: ; preds = %bb4
> - br i1 false, label %bb7, label %bb8
> -
> -bb7: ; preds = %bb6
> - br label %bb106
> -
> -bb8: ; preds = %bb6
> - br i1 false, label %bb106, label %bb10
> -
> -bb10: ; preds = %bb8
> - br i1 false, label %bb106, label %bb12
> -
> -bb12: ; preds = %bb10
> - br i1 false, label %bb106, label %bb14
> -
> -bb14: ; preds = %bb12
> - br i1 false, label %bb15, label %bb19
> -
> -bb15: ; preds = %bb14
> - br i1 false, label %bb16, label %bb17
> -
> -bb16: ; preds = %bb15
> - br label %bb106
> -
> -bb17: ; preds = %bb15
> - br label %bb106
> -
> -bb19: ; preds = %bb14
> - br i1 false, label %bb20, label %bb28
> -
> -bb20: ; preds = %bb19
> - br i1 false, label %bb21, label %bb22
> -
> -bb21: ; preds = %bb20
> - br label %bb106
> -
> -bb22: ; preds = %bb20
> - br i1 false, label %bb106, label %bb24
> -
> -bb24: ; preds = %bb22
> - br i1 false, label %bb106, label %bb26
> -
> -bb26: ; preds = %bb24
> - br label %bb106
> -
> -bb28: ; preds = %bb19
> - br i1 false, label %bb29, label %bb35
> -
> -bb29: ; preds = %bb28
> - br i1 false, label %bb30, label %bb31
> -
> -bb30: ; preds = %bb29
> - br label %bb106
> -
> -bb31: ; preds = %bb29
> - br i1 false, label %bb32, label %bb33
> -
> -bb32: ; preds = %bb31
> - br label %bb106
> -
> -bb33: ; preds = %bb31
> - br label %bb106
> -
> -bb35: ; preds = %bb28
> - br i1 false, label %bb36, label %bb40
> -
> -bb36: ; preds = %bb35
> - br i1 false, label %bb37, label %bb38
> -
> -bb37: ; preds = %bb36
> - br label %bb106
> -
> -bb38: ; preds = %bb36
> - br label %bb106
> -
> -bb40: ; preds = %bb35
> - br i1 false, label %bb41, label %bb49
> -
> -bb41: ; preds = %bb40
> - br i1 false, label %bb43, label %bb42
> -
> -bb42: ; preds = %bb41
> - br label %bb106
> -
> -bb43: ; preds = %bb41
> - br i1 false, label %bb44, label %bb45
> -
> -bb44: ; preds = %bb43
> - br label %bb106
> -
> -bb45: ; preds = %bb43
> - br i1 false, label %bb46, label %bb47
> -
> -bb46: ; preds = %bb45
> - br label %bb106
> -
> -bb47: ; preds = %bb45
> - br label %bb106
> -
> -bb49: ; preds = %bb40
> - br i1 false, label %bb50, label %bb56
> -
> -bb50: ; preds = %bb49
> - br i1 false, label %bb52, label %bb51
> -
> -bb51: ; preds = %bb50
> - br label %bb106
> -
> -bb52: ; preds = %bb50
> - br i1 false, label %bb53, label %bb54
> -
> -bb53: ; preds = %bb52
> - br label %bb106
> -
> -bb54: ; preds = %bb52
> - br label %bb106
> -
> -bb56: ; preds = %bb49
> - br i1 false, label %bb57, label %bb63
> -
> -bb57: ; preds = %bb56
> - br i1 false, label %bb59, label %bb58
> -
> -bb58: ; preds = %bb57
> - br label %bb106
> -
> -bb59: ; preds = %bb57
> - br i1 false, label %bb60, label %bb61
> -
> -bb60: ; preds = %bb59
> - br label %bb106
> -
> -bb61: ; preds = %bb59
> - br label %bb106
> -
> -bb63: ; preds = %bb56
> - br i1 false, label %bb64, label %bb70
> -
> -bb64: ; preds = %bb63
> - br i1 false, label %bb66, label %bb65
> -
> -bb65: ; preds = %bb64
> - br label %bb106
> -
> -bb66: ; preds = %bb64
> - br i1 false, label %bb67, label %bb68
> -
> -bb67: ; preds = %bb66
> - br label %bb106
> -
> -bb68: ; preds = %bb66
> - br label %bb106
> -
> -bb70: ; preds = %bb63
> - br i1 false, label %bb71, label %bb79
> -
> -bb71: ; preds = %bb70
> - br i1 false, label %bb73, label %bb72
> -
> -bb72: ; preds = %bb71
> - br label %bb106
> -
> -bb73: ; preds = %bb71
> - br i1 false, label %bb74, label %bb75
> -
> -bb74: ; preds = %bb73
> - br label %bb106
> -
> -bb75: ; preds = %bb73
> - br i1 false, label %bb76, label %bb77
> -
> -bb76: ; preds = %bb75
> - br label %bb106
> -
> -bb77: ; preds = %bb75
> - br label %bb106
> -
> -bb79: ; preds = %bb70
> - br i1 false, label %bb80, label %bb86
> -
> -bb80: ; preds = %bb79
> - br i1 false, label %bb82, label %bb81
> -
> -bb81: ; preds = %bb80
> - br label %bb106
> -
> -bb82: ; preds = %bb80
> - br i1 false, label %bb83, label %bb84
> -
> -bb83: ; preds = %bb82
> - br label %bb106
> -
> -bb84: ; preds = %bb82
> - br label %bb106
> -
> -bb86: ; preds = %bb79
> - br i1 false, label %bb87, label %bb93
> -
> -bb87: ; preds = %bb86
> - br i1 false, label %bb89, label %bb88
> -
> -bb88: ; preds = %bb87
> - br label %bb106
> -
> -bb89: ; preds = %bb87
> - br i1 false, label %bb90, label %bb91
> -
> -bb90: ; preds = %bb89
> - br label %bb106
> -
> -bb91: ; preds = %bb89
> - br label %bb106
> -
> -bb93: ; preds = %bb86
> - br i1 false, label %bb94, label %bb95
> -
> -bb94: ; preds = %bb93
> - br label %bb106
> -
> -bb95: ; preds = %bb93
> - br i1 false, label %bb98, label %bb97
> -
> -bb97: ; preds = %bb95
> - br label %bb106
> -
> -bb98: ; preds = %bb95
> - br i1 false, label %bb103, label %bb1.i24
> -
> -bb1.i24: ; preds = %bb98
> - br i1 false, label %bb99, label %bb103
> -
> -bb99: ; preds = %bb1.i24
> - br i1 false, label %bb101, label %bb100
> -
> -bb100: ; preds = %bb99
> - br label %bb102
> -
> -bb101: ; preds = %bb99
> - br label %bb102
> -
> -bb102: ; preds = %bb101, %bb100
> - br label %bb106
> -
> -bb103: ; preds = %bb1.i24, %bb98
> - br i1 false, label %bb104, label %bb105
> -
> -bb104: ; preds = %bb103
> - br label %bb106
> -
> -bb105: ; preds = %bb103
> - br label %bb106
> -
> -bb106: ; preds = %bb105, %bb104, %bb102, %bb97, %bb94, %bb91,
> %bb90, %bb88, %bb84, %bb83, %bb81, %bb77, %bb76, %bb74, %bb72, %bb68,
> %bb67, %bb65, %bb61, %bb60, %bb58, %bb54, %bb53, %bb51, %bb47, %bb46,
> %bb44, %bb42, %bb38, %bb37, %bb33, %bb32, %bb30, %bb26, %bb24, %bb22,
> %bb21, %bb17, %bb16, %bb12, %bb10, %bb8, %bb7, %bb5, %bb3, %bb1
> - br i1 false, label %bb108, label %bb110
> -
> -bb108: ; preds = %bb106, %picosat_time_stamp.exit
> - br i1 false, label %bb, label %bb110
> -
> -bb110: ; preds = %bb108, %bb106
> - br i1 false, label %bb112, label %bb171
> -
> -bb112: ; preds = %bb110
> - br i1 false, label %bb114, label %bb113
> -
> -bb113: ; preds = %bb112
> - br label %bb114
> -
> -bb114: ; preds = %bb113, %bb112
> - br i1 false, label %bb.i.i35, label %bb1.i.i36
> -
> -bb.i.i35: ; preds = %bb114
> - unreachable
> -
> -bb1.i.i36: ; preds = %bb114
> - br i1 false, label %bb5.i.i.i41, label %bb6.i.i.i42
> -
> -bb5.i.i.i41: ; preds = %bb1.i.i36
> - unreachable
> -
> -bb6.i.i.i42: ; preds = %bb1.i.i36
> - br i1 false, label %bb7.i.i.i43, label %bb8.i.i.i44
> -
> -bb7.i.i.i43: ; preds = %bb6.i.i.i42
> - br label %bb8.i.i.i44
> -
> -bb8.i.i.i44: ; preds = %bb7.i.i.i43, %bb6.i.i.i42
> - br i1 false, label %picosat_init.exit, label %bb14.i.i
> -
> -bb14.i.i: ; preds = %bb8.i.i.i44
> - br label %picosat_init.exit
> -
> -picosat_init.exit: ; preds = %bb14.i.i, %bb8.i.i.i44
> - br i1 false, label %bb116, label %bb115
> -
> -bb115: ; preds = %picosat_init.exit
> - br label %bb116
> -
> -bb116: ; preds = %bb115, %picosat_init.exit
> - br i1 false, label %bb119, label %bb118
> -
> -bb118: ; preds = %bb116
> - br label %bb119
> -
> -bb119: ; preds = %bb118, %bb116
> - br i1 false, label %bb121, label %bb120
> -
> -bb120: ; preds = %bb119
> - br label %bb121
> -
> -bb121: ; preds = %bb120, %bb119
> - br i1 false, label %bb126, label %bb122
> -
> -bb122: ; preds = %bb121
> - br label %bb126
> -
> -bb126: ; preds = %bb122, %bb121
> - br i1 false, label %bb128, label %bb127
> -
> -bb127: ; preds = %bb126
> - br label %bb128
> -
> -bb128: ; preds = %bb127, %bb126
> - br label %SKIP_COMMENTS.i
> -
> -SKIP_COMMENTS.i.loopexit: ; preds = %bb.i149, %bb.i149
> - br label %SKIP_COMMENTS.i.backedge
> -
> -SKIP_COMMENTS.i: ; preds = %SKIP_COMMENTS.i.backedge, %bb128
> - br i1 false, label %bb.i149.preheader, label %bb3.i152
> -
> -bb.i149.preheader: ; preds = %SKIP_COMMENTS.i
> - br label %bb.i149
> -
> -bb.i149: ; preds = %bb.i149, %bb.i149.preheader
> - switch i32 0, label %bb.i149 [
> - i32 -1, label %SKIP_COMMENTS.i.loopexit
> - i32 10, label %SKIP_COMMENTS.i.loopexit
> - ]
> -
> -bb3.i152: ; preds = %SKIP_COMMENTS.i
> - br i1 false, label %bb4.i153, label %SKIP_COMMENTS.i.backedge
> -
> -SKIP_COMMENTS.i.backedge: ; preds = %bb3.i152,
> %SKIP_COMMENTS.i.loopexit
> - br label %SKIP_COMMENTS.i
> -
> -bb4.i153: ; preds = %bb3.i152
> - br i1 false, label %bb5.i154, label %bb129
> -
> -bb5.i154: ; preds = %bb4.i153
> - br i1 false, label %bb129, label %bb6.i155.preheader
> -
> -bb6.i155.preheader: ; preds = %bb5.i154
> - br label %bb6.i155
> -
> -bb6.i155: ; preds = %bb6.i155, %bb6.i155.preheader
> - br i1 false, label %bb7.i156, label %bb6.i155
> -
> -bb7.i156: ; preds = %bb6.i155
> - br i1 false, label %bb8.i157, label %bb129
> -
> -bb8.i157: ; preds = %bb7.i156
> - br i1 false, label %bb9.i158, label %bb129
> -
> -bb9.i158: ; preds = %bb8.i157
> - br i1 false, label %bb10.i159, label %bb129
> -
> -bb10.i159: ; preds = %bb9.i158
> - br i1 false, label %bb129, label %bb11.i160.preheader
> -
> -bb11.i160.preheader: ; preds = %bb10.i159
> - br label %bb11.i160
> -
> -bb11.i160: ; preds = %bb11.i160, %bb11.i160.preheader
> - br i1 false, label %bb12.i161, label %bb11.i160
> -
> -bb12.i161: ; preds = %bb11.i160
> - br i1 false, label %bb129, label %bb15.i165.preheader
> -
> -bb15.i165.preheader: ; preds = %bb12.i161
> - br label %bb15.i165
> -
> -bb14.i163: ; preds = %bb15.i165
> - br label %bb15.i165
> -
> -bb15.i165: ; preds = %bb14.i163, %bb15.i165.preheader
> - br i1 false, label %bb16.i166, label %bb14.i163
> -
> -bb16.i166: ; preds = %bb15.i165
> - br i1 false, label %bb129, label %bb17.i167.preheader
> -
> -bb17.i167.preheader: ; preds = %bb16.i166
> - br label %bb17.i167
> -
> -bb17.i167: ; preds = %bb17.i167, %bb17.i167.preheader
> - br i1 false, label %bb18.i168, label %bb17.i167
> -
> -bb18.i168: ; preds = %bb17.i167
> - br i1 false, label %bb129, label %bb21.i172.preheader
> -
> -bb21.i172.preheader: ; preds = %bb18.i168
> - br label %bb21.i172
> -
> -bb20.i170: ; preds = %bb21.i172
> - br label %bb21.i172
> -
> -bb21.i172: ; preds = %bb20.i170, %bb21.i172.preheader
> - br i1 false, label %bb22.i173, label %bb20.i170
> -
> -bb22.i173: ; preds = %bb21.i172
> - br i1 false, label %bb24.i175, label %bb129
> -
> -bb24.i175: ; preds = %bb22.i173
> - br i1 false, label %bb26.i180, label %bb25.i176
> -
> -bb25.i176: ; preds = %bb24.i175
> - br label %bb26.i180
> -
> -bb26.i180: ; preds = %bb25.i176, %bb24.i175
> - br i1 false, label %bb.i.i181, label %bb3.i.i184.preheader
> -
> -bb.i.i181: ; preds = %bb26.i180
> - br label %bb3.i.i184.preheader
> -
> -bb3.i.i184.preheader: ; preds = %bb.i.i181, %bb26.i180
> - br label %bb3.i.i184
> -
> -bb2.i.i183: ; preds = %bb3.i.i184
> - br label %bb3.i.i184
> -
> -bb3.i.i184: ; preds = %bb2.i.i183, %bb3.i.i184.preheader
> - br i1 false, label %bb2.i.i183, label %bb4.i.i185
> -
> -bb4.i.i185: ; preds = %bb3.i.i184
> - br i1 false, label %bb.i.i.i186, label %picosat_adjust.exit.i
> -
> -bb.i.i.i186: ; preds = %bb4.i.i185
> - br label %picosat_adjust.exit.i
> -
> -picosat_adjust.exit.i: ; preds = %bb.i.i.i186, %bb4.i.i185
> - br i1 false, label %bb28.i188, label %bb27.i187
> -
> -bb27.i187: ; preds = %picosat_adjust.exit.i
> - br label %bb28.i188
> -
> -bb28.i188: ; preds = %bb27.i187, %picosat_adjust.exit.i
> - br label %READ_LITERAL.i.outer
> -
> -READ_LITERAL.i.outer: ; preds = %READ_LITERAL.i.outer.backedge,
> %bb28.i188
> - br label %READ_LITERAL.i
> -
> -READ_LITERAL.i.loopexit: ; preds = %bb29.i189, %bb29.i189
> - br label %READ_LITERAL.i.backedge
> -
> -READ_LITERAL.i: ; preds = %READ_LITERAL.i.backedge,
> %READ_LITERAL.i.outer
> - switch i32 0, label %bb39.i199 [
> - i32 99, label %bb29.i189.preheader
> - i32 -1, label %bb33.i193
> - ]
> -
> -bb29.i189.preheader: ; preds = %READ_LITERAL.i
> - br label %bb29.i189
> -
> -bb29.i189: ; preds = %bb29.i189, %bb29.i189.preheader
> - switch i32 0, label %bb29.i189 [
> - i32 -1, label %READ_LITERAL.i.loopexit
> - i32 10, label %READ_LITERAL.i.loopexit
> - ]
> -
> -bb33.i193: ; preds = %READ_LITERAL.i
> - br i1 false, label %bb35.i195, label %parse.exit
> -
> -bb35.i195: ; preds = %bb33.i193
> - br i1 false, label %bb38.i198, label %parse.exit
> -
> -bb38.i198: ; preds = %bb35.i195
> - br label %parse.exit
> -
> -bb39.i199: ; preds = %READ_LITERAL.i
> - br i1 false, label %bb40.i200, label %READ_LITERAL.i.backedge
> -
> -READ_LITERAL.i.backedge: ; preds = %bb39.i199,
> %READ_LITERAL.i.loopexit
> - br label %READ_LITERAL.i
> -
> -bb40.i200: ; preds = %bb39.i199
> - br i1 false, label %bb41.i201, label %bb42.i202
> -
> -bb41.i201: ; preds = %bb40.i200
> - br label %bb42.i202
> -
> -bb42.i202: ; preds = %bb41.i201, %bb40.i200
> - br i1 false, label %parse.exit.loopexit, label %bb46.i.preheader
> -
> -bb46.i.preheader: ; preds = %bb42.i202
> - br label %bb46.i
> -
> -bb45.i: ; preds = %bb46.i
> - br label %bb46.i
> -
> -bb46.i: ; preds = %bb45.i, %bb46.i.preheader
> - br i1 false, label %bb47.i, label %bb45.i
> -
> -bb47.i: ; preds = %bb46.i
> - br i1 false, label %parse.exit.loopexit, label %bb50.i
> -
> -bb50.i: ; preds = %bb47.i
> - br i1 false, label %bb55.i, label %bb51.i
> -
> -bb51.i: ; preds = %bb50.i
> - br i1 false, label %parse.exit.loopexit, label %bb54.i
> -
> -bb54.i: ; preds = %bb51.i
> - br label %bb56.i
> -
> -bb55.i: ; preds = %bb50.i
> - br label %bb56.i
> -
> -bb56.i: ; preds = %bb55.i, %bb54.i
> - br i1 false, label %bb3.i11.i, label %bb.i8.i
> -
> -bb.i8.i: ; preds = %bb56.i
> - br i1 false, label %bb1.i9.i, label %bb3.i11.i
> -
> -bb1.i9.i: ; preds = %bb.i8.i
> - br i1 false, label %bb3.i11.i, label %bb2.i10.i
> -
> -bb2.i10.i: ; preds = %bb1.i9.i
> - unreachable
> -
> -bb3.i11.i: ; preds = %bb1.i9.i, %bb.i8.i, %bb56.i
> - br i1 false, label %bb7.i.i208, label %bb6.i.i207
> -
> -bb6.i.i207: ; preds = %bb3.i11.i
> - br label %READ_LITERAL.i.outer.backedge
> -
> -bb7.i.i208: ; preds = %bb3.i11.i
> - br i1 false, label %bb53.i.i.i.i.preheader, label
> %bb.i.i.i.i210.preheader
> -
> -bb.i.i.i.i210.preheader: ; preds = %bb7.i.i208
> - br label %bb.i.i.i.i210
> -
> -bb.i.i.i.i210: ; preds = %bb.i.i.i.i210.backedge,
> %bb.i.i.i.i210.preheader
> - br i1 false, label %bb17.i.i.i.i, label %bb18.i.i.i.i
> -
> -bb17.i.i.i.i: ; preds = %bb.i.i.i.i210
> - br label %bb18.i.i.i.i
> -
> -bb18.i.i.i.i: ; preds = %bb17.i.i.i.i, %bb.i.i.i.i210
> - br i1 false, label %bb19.i.i.i.i, label %bb20.i.i.i.i
> -
> -bb19.i.i.i.i: ; preds = %bb18.i.i.i.i
> - br label %bb20.i.i.i.i
> -
> -bb20.i.i.i.i: ; preds = %bb19.i.i.i.i, %bb18.i.i.i.i
> - br i1 false, label %bb21.i.i.i.i, label %bb22.i.i.i.i
> -
> -bb21.i.i.i.i: ; preds = %bb20.i.i.i.i
> - br label %bb22.i.i.i.i
> -
> -bb22.i.i.i.i: ; preds = %bb21.i.i.i.i, %bb20.i.i.i.i
> - br label %bb23.i.i.i.i.outer
> -
> -bb23.i.i.i.i.outer: ; preds = %bb28.i.i.i.i, %bb22.i.i.i.i
> - br label %bb23.i.i.i.i
> -
> -bb23.i.i.i.i: ; preds = %bb23.i.i.i.i, %bb23.i.i.i.i.outer
> - br i1 false, label %bb23.i.i.i.i, label %bb26.i.i.i.i.preheader
> -
> -bb26.i.i.i.i.preheader: ; preds = %bb23.i.i.i.i
> - br label %bb26.i.i.i.i
> -
> -bb26.i.i.i.i: ; preds = %bb26.i.i.i.i, %bb26.i.i.i.i.preheader
> - br i1 false, label %bb27.i.i.i.i, label %bb26.i.i.i.i
> -
> -bb27.i.i.i.i: ; preds = %bb26.i.i.i.i
> - br i1 false, label %bb28.i.i.i.i, label %bb29.i.i.i.i
> -
> -bb28.i.i.i.i: ; preds = %bb27.i.i.i.i
> - br label %bb23.i.i.i.i.outer
> -
> -bb29.i.i.i.i: ; preds = %bb27.i.i.i.i
> - br i1 false, label %bb33.i.i.i.i, label %bb44.i.i.i.i
> -
> -bb33.i.i.i.i: ; preds = %bb29.i.i.i.i
> - br i1 false, label %bb34.i.i.i.i, label %bb38.i.i.i.i
> -
> -bb34.i.i.i.i: ; preds = %bb33.i.i.i.i
> - br i1 false, label %bb37.i.i.i.i, label %bb35.i.i.i.i
> -
> -bb35.i.i.i.i: ; preds = %bb34.i.i.i.i
> - br label %bb37.i.i.i.i
> -
> -bb37.i.i.i.i: ; preds = %bb35.i.i.i.i, %bb34.i.i.i.i
> - br label %bb38.i.i.i.i
> -
> -bb38.i.i.i.i: ; preds = %bb37.i.i.i.i, %bb33.i.i.i.i
> - br i1 false, label %bb39.i.i.i.i, label %bb43.i.i.i.i
> -
> -bb39.i.i.i.i: ; preds = %bb38.i.i.i.i
> - br i1 false, label %bb42.i.i.i.i, label %bb40.i.i.i.i
> -
> -bb40.i.i.i.i: ; preds = %bb39.i.i.i.i
> - br label %bb42.i.i.i.i
> -
> -bb42.i.i.i.i: ; preds = %bb40.i.i.i.i, %bb39.i.i.i.i
> - br label %bb43.i.i.i.i
> -
> -bb43.i.i.i.i: ; preds = %bb42.i.i.i.i, %bb38.i.i.i.i
> - br label %bb.i.i.i.i210.backedge
> -
> -bb.i.i.i.i210.backedge: ; preds = %bb47.i.i.i.i,
> %bb44.i.i.i.i, %bb43.i.i.i.i
> - br label %bb.i.i.i.i210
> -
> -bb44.i.i.i.i: ; preds = %bb29.i.i.i.i
> - br i1 false, label %bb.i.i.i.i210.backedge, label %bb46.i.i.i.i
> -
> -bb46.i.i.i.i: ; preds = %bb44.i.i.i.i
> - br i1 false, label %bb47.i.i.i.i, label %bb53.i.i.i.i.preheader.loopexit
> -
> -bb53.i.i.i.i.preheader.loopexit: ; preds = %bb46.i.i.i.i
> - br label %bb53.i.i.i.i.preheader
> -
> -bb53.i.i.i.i.preheader: ; preds =
> %bb53.i.i.i.i.preheader.loopexit, %bb7.i.i208
> - br label %bb53.i.i.i.i
> -
> -bb47.i.i.i.i: ; preds = %bb46.i.i.i.i
> - br label %bb.i.i.i.i210.backedge
> -
> -bb50.i.i.i.i: ; preds = %bb53.i.i.i.i
> - br i1 false, label %bb51.i.i.i.i, label %bb52.i.i.i.i
> -
> -bb51.i.i.i.i: ; preds = %bb50.i.i.i.i
> - br label %bb52.i.i.i.i
> -
> -bb52.i.i.i.i: ; preds = %bb51.i.i.i.i, %bb50.i.i.i.i
> - br label %bb53.i.i.i.i
> -
> -bb53.i.i.i.i: ; preds = %bb52.i.i.i.i, %bb53.i.i.i.i.preheader
> - br i1 false, label %bb50.i.i.i.i, label %bb59.i.i.i.i.preheader
> -
> -bb59.i.i.i.i.preheader: ; preds = %bb53.i.i.i.i
> - br label %bb59.i.i.i.i
> -
> -bb55.i.i.i.i: ; preds = %bb59.i.i.i.i
> - br label %bb57.i.i.i.i
> -
> -bb56.i.i.i.i: ; preds = %bb57.i.i.i.i
> - br label %bb57.i.i.i.i
> -
> -bb57.i.i.i.i: ; preds = %bb56.i.i.i.i, %bb55.i.i.i.i
> - br i1 false, label %bb56.i.i.i.i, label %bb58.i.i.i.i
> -
> -bb58.i.i.i.i: ; preds = %bb57.i.i.i.i
> - br label %bb59.i.i.i.i
> -
> -bb59.i.i.i.i: ; preds = %bb58.i.i.i.i, %bb59.i.i.i.i.preheader
> - br i1 false, label %bb60.i.i.i.i, label %bb55.i.i.i.i
> -
> -bb60.i.i.i.i: ; preds = %bb59.i.i.i.i
> - br label %bb69.i.i.i.i
> -
> -bb61.i.i.i.i: ; preds = %bb69.i.i.i.i
> - br i1 false, label %bb68.i.i.i.i, label %bb62.i.i.i.i
> -
> -bb62.i.i.i.i: ; preds = %bb61.i.i.i.i
> - br i1 false, label %bb63.i.i.i.i, label %bb65.i.i.i.i
> -
> -bb63.i.i.i.i: ; preds = %bb62.i.i.i.i
> - br i1 false, label %bb.i.i12.i, label %bb65.i.i.i.i
> -
> -bb65.i.i.i.i: ; preds = %bb63.i.i.i.i, %bb62.i.i.i.i
> - br i1 false, label %bb.i.i12.i, label %bb67.i.i.i.i
> -
> -bb67.i.i.i.i: ; preds = %bb65.i.i.i.i
> - br label %bb68.i.i.i.i
> -
> -bb68.i.i.i.i: ; preds = %bb67.i.i.i.i, %bb61.i.i.i.i
> - br label %bb69.i.i.i.i
> -
> -bb69.i.i.i.i: ; preds = %bb68.i.i.i.i, %bb60.i.i.i.i
> - br i1 false, label %bb61.i.i.i.i, label %bb70.i.i.i.i
> -
> -bb70.i.i.i.i: ; preds = %bb69.i.i.i.i
> - br label %READ_LITERAL.i.outer.backedge
> -
> -bb.i.i12.i: ; preds = %bb65.i.i.i.i, %bb63.i.i.i.i
> - br i1 false, label %bb1.i.i.i213, label %bb5.i.i.i218
> -
> -bb1.i.i.i213: ; preds = %bb.i.i12.i
> - br i1 false, label %bb4.i.i.i217, label %bb2.i.i.i214
> -
> -bb2.i.i.i214: ; preds = %bb1.i.i.i213
> - br label %bb4.i.i.i217
> -
> -bb4.i.i.i217: ; preds = %bb2.i.i.i214, %bb1.i.i.i213
> - br label %bb5.i.i.i218
> -
> -bb5.i.i.i218: ; preds = %bb4.i.i.i217, %bb.i.i12.i
> - br label %READ_LITERAL.i.outer.backedge
> -
> -READ_LITERAL.i.outer.backedge: ; preds = %bb5.i.i.i218,
> %bb70.i.i.i.i, %bb6.i.i207
> - br label %READ_LITERAL.i.outer
> -
> -parse.exit.loopexit: ; preds = %bb51.i, %bb47.i, %bb42.i202
> - br label %parse.exit
> -
> -parse.exit: ; preds = %parse.exit.loopexit, %bb38.i198,
> %bb35.i195, %bb33.i193
> - br i1 false, label %bb130, label %bb129
> -
> -bb129: ; preds = %parse.exit, %bb22.i173, %bb18.i168, %bb16.i166,
> %bb12.i161, %bb10.i159, %bb9.i158, %bb8.i157, %bb7.i156, %bb5.i154,
> %bb4.i153
> - br label %bb170
> -
> -bb130: ; preds = %parse.exit
> - br i1 false, label %bb143, label %bb142.preheader
> -
> -bb142.preheader: ; preds = %bb130
> - br label %bb142
> -
> -bb132: ; preds = %bb142
> - br i1 false, label %bb137, label %bb133
> -
> -bb133: ; preds = %bb132
> - br i1 false, label %bb137, label %bb134
> -
> -bb134: ; preds = %bb133
> - br i1 false, label %bb137, label %bb135
> -
> -bb135: ; preds = %bb134
> - br i1 false, label %bb137, label %bb136
> -
> -bb136: ; preds = %bb135
> - br i1 false, label %bb137, label %bb138
> -
> -bb137: ; preds = %bb136, %bb135, %bb134, %bb133, %bb132
> - br label %bb141
> -
> -bb138: ; preds = %bb136
> - br i1 false, label %bb139, label %bb141
> -
> -bb139: ; preds = %bb138
> - br i1 false, label %bb2.i126, label %picosat_assume.exit
> -
> -bb2.i126: ; preds = %bb139
> - br i1 false, label %bb5.i130, label %bb3.i127
> -
> -bb3.i127: ; preds = %bb2.i126
> - br label %bb5.i130
> -
> -bb5.i130: ; preds = %bb3.i127, %bb2.i126
> - br label %picosat_assume.exit
> -
> -picosat_assume.exit: ; preds = %bb5.i130, %bb139
> - br i1 false, label %bb141, label %bb140
> -
> -bb140: ; preds = %picosat_assume.exit
> - br label %bb141
> -
> -bb141: ; preds = %bb140, %picosat_assume.exit, %bb138, %bb137
> - br label %bb142
> -
> -bb142: ; preds = %bb141, %bb142.preheader
> - br i1 false, label %bb132, label %bb143.loopexit
> -
> -bb143.loopexit: ; preds = %bb142
> - br label %bb143
> -
> -bb143: ; preds = %bb143.loopexit, %bb130
> - br i1 false, label %bb145, label %bb144
> -
> -bb144: ; preds = %bb143
> - br label %bb11.i
> -
> -bb5.i114: ; preds = %bb11.i
> - br label %bb11.i
> -
> -bb11.i: ; preds = %bb5.i114, %bb144
> - br i1 false, label %bb12.i, label %bb5.i114
> -
> -bb12.i: ; preds = %bb11.i
> - br i1 false, label %bb.i.i.i118, label %bb1.i.i.i119
> -
> -bb.i.i.i118: ; preds = %bb12.i
> - br label %int2lit.exit.i
> -
> -bb1.i.i.i119: ; preds = %bb12.i
> - br label %int2lit.exit.i
> -
> -int2lit.exit.i: ; preds = %bb1.i.i.i119, %bb.i.i.i118
> - br label %bb19.i
> -
> -bb13.i: ; preds = %bb19.i
> - br label %bb17.i
> -
> -bb14.i: ; preds = %bb17.i
> - br label %bb17.i
> -
> -bb17.i: ; preds = %bb14.i, %bb13.i
> - br i1 false, label %bb14.i, label %bb18.i
> -
> -bb18.i: ; preds = %bb17.i
> - br label %bb19.i
> -
> -bb19.i: ; preds = %bb18.i, %int2lit.exit.i
> - br i1 false, label %bb20.i, label %bb13.i
> -
> -bb20.i: ; preds = %bb19.i
> - br label %bb33.i
> -
> -bb24.i: ; preds = %bb33.i
> - br i1 false, label %bb29.i, label %bb25.i
> -
> -bb25.i: ; preds = %bb24.i
> - br label %bb27.i
> -
> -bb26.i: ; preds = %bb27.i
> - br label %bb27.i
> -
> -bb27.i: ; preds = %bb26.i, %bb25.i
> - br i1 false, label %bb26.i, label %bb28.i
> -
> -bb28.i: ; preds = %bb27.i
> - br label %bb29.i
> -
> -bb29.i: ; preds = %bb28.i, %bb24.i
> - br label %bb33.i
> -
> -bb33.i: ; preds = %bb29.i, %bb20.i
> - br i1 false, label %bb34.i, label %bb24.i
> -
> -bb34.i: ; preds = %bb33.i
> - br i1 false, label %bb.i.i58.i, label %bb1.i.i59.i
> -
> -bb.i.i58.i: ; preds = %bb34.i
> - br label %int2lit.exit63.i
> -
> -bb1.i.i59.i: ; preds = %bb34.i
> - br label %int2lit.exit63.i
> -
> -int2lit.exit63.i: ; preds = %bb1.i.i59.i, %bb.i.i58.i
> - br label %bb41.i
> -
> -bb35.i: ; preds = %bb41.i
> - br label %bb39.i
> -
> -bb36.i: ; preds = %bb39.i
> - br i1 false, label %bb38.i, label %bb37.i
> -
> -bb37.i: ; preds = %bb36.i
> - br label %bb38.i
> -
> -bb38.i: ; preds = %bb37.i, %bb36.i
> - br label %bb39.i
> -
> -bb39.i: ; preds = %bb38.i, %bb35.i
> - br i1 false, label %bb36.i, label %bb40.i
> -
> -bb40.i: ; preds = %bb39.i
> - br label %bb41.i
> -
> -bb41.i: ; preds = %bb40.i, %int2lit.exit63.i
> - br i1 false, label %bb42.i, label %bb35.i
> -
> -bb42.i: ; preds = %bb41.i
> - br label %bb44.i
> -
> -bb43.i: ; preds = %bb44.i
> - br label %bb44.i
> -
> -bb44.i: ; preds = %bb43.i, %bb42.i
> - br i1 false, label %bb43.i, label %picosat_print.exit
> -
> -picosat_print.exit: ; preds = %bb44.i
> - br label %bb167
> -
> -bb145: ; preds = %bb143
> - br i1 false, label %bb147, label %bb146
> -
> -bb146: ; preds = %bb145
> - br label %bb147
> -
> -bb147: ; preds = %bb146, %bb145
> - br i1 false, label %bb149, label %bb148
> -
> -bb148: ; preds = %bb147
> - br label %bb149
> -
> -bb149: ; preds = %bb148, %bb147
> - br i1 false, label %bb.i54, label %bb1.i55
> -
> -bb.i54: ; preds = %bb149
> - unreachable
> -
> -bb1.i55: ; preds = %bb149
> - br i1 false, label %bb.i.i56, label %bb1.i.i57
> -
> -bb.i.i56: ; preds = %bb1.i55
> - br label %bb1.i.i57
> -
> -bb1.i.i57: ; preds = %bb.i.i56, %bb1.i55
> - br i1 false, label %bb3.i.i59, label %bb2.i.i58
> -
> -bb2.i.i58: ; preds = %bb1.i.i57
> - br label %bb3.i.i59
> -
> -bb3.i.i59: ; preds = %bb2.i.i58, %bb1.i.i57
> - br i1 false, label %bb5.i.i61, label %sat.exit.i
> -
> -bb5.i.i61: ; preds = %bb3.i.i59
> - br i1 false, label %bb6.i.i65, label %bb1.i.i.i63
> -
> -bb1.i.i.i63: ; preds = %bb5.i.i61
> - br i1 false, label %sat.exit.i, label %bb6.i.i65
> -
> -bb6.i.i65: ; preds = %bb1.i.i.i63, %bb5.i.i61
> - br i1 false, label %bb8.i.i67, label %bb7.i.i66
> -
> -bb7.i.i66: ; preds = %bb6.i.i65
> - br label %bb8.i.i67
> -
> -bb8.i.i67: ; preds = %bb7.i.i66, %bb6.i.i65
> - br i1 false, label %bb10.i.i69, label %sat.exit.i
> -
> -bb10.i.i69: ; preds = %bb8.i.i67
> - br i1 false, label %bb11.i.i70, label %bb1.i61.i.i
> -
> -bb1.i61.i.i: ; preds = %bb10.i.i69
> - br i1 false, label %sat.exit.i, label %bb11.i.i70
> -
> -bb11.i.i70: ; preds = %bb1.i61.i.i, %bb10.i.i69
> - br label %bb13.i.i71.outer
> -
> -bb13.i.i71.outer: ; preds = %bb42.i.i, %bb11.i.i70
> - br label %bb13.i.i71
> -
> -bb13.i.i71: ; preds = %bb13.i.i71.backedge, %bb13.i.i71.outer
> - br i1 false, label %bb14.i.i72, label %bb15.i.i73
> -
> -bb14.i.i72: ; preds = %bb13.i.i71
> - br label %bb15.i.i73
> -
> -bb15.i.i73: ; preds = %bb14.i.i72, %bb13.i.i71
> - br i1 false, label %bb19.i.i, label %bb16.i.i
> -
> -bb16.i.i: ; preds = %bb15.i.i73
> - br i1 false, label %bb.i.i79.i.i, label %incincs.exit.i.i
> -
> -bb.i.i79.i.i: ; preds = %bb16.i.i
> - br label %bb4.i.i.i85.i.i
> -
> -bb.i.i.i80.i.i: ; preds = %bb4.i.i.i85.i.i
> - br i1 false, label %bb3.i.i.i83.i.i, label %bb1.i.i.i81.i.i
> -
> -bb1.i.i.i81.i.i: ; preds = %bb.i.i.i80.i.i
> - br i1 false, label %bb2.i.i.i82.i.i, label %bb3.i.i.i83.i.i
> -
> -bb2.i.i.i82.i.i: ; preds = %bb1.i.i.i81.i.i
> - br label %bb3.i.i.i83.i.i
> -
> -bb3.i.i.i83.i.i: ; preds = %bb2.i.i.i82.i.i,
> %bb1.i.i.i81.i.i, %bb.i.i.i80.i.i
> - br label %bb4.i.i.i85.i.i
> -
> -bb4.i.i.i85.i.i: ; preds = %bb3.i.i.i83.i.i, %bb.i.i79.i.i
> - br i1 false, label %crescore.exit.i.i.i.i, label %bb.i.i.i80.i.i
> -
> -crescore.exit.i.i.i.i: ; preds = %bb4.i.i.i85.i.i
> - br label %incincs.exit.i.i
> -
> -incincs.exit.i.i: ; preds = %crescore.exit.i.i.i.i, %bb16.i.i
> - br i1 false, label %bb13.i.i71.backedge, label
> %sat.exit.i.loopexit.loopexit
> -
> -bb13.i.i71.backedge: ; preds = %bb1.i55.i.i, %bb28.i.i,
> %incincs.exit.i.i
> - br label %bb13.i.i71
> -
> -bb19.i.i: ; preds = %bb15.i.i73
> - br i1 false, label %bb20.i.i, label %bb1.i68.i.i
> -
> -bb1.i68.i.i: ; preds = %bb19.i.i
> - br i1 false, label %sat.exit.i.loopexit.loopexit, label %bb20.i.i
> -
> -bb20.i.i: ; preds = %bb1.i68.i.i, %bb19.i.i
> - br i1 false, label %bb24.i.i, label %bb21.i.i
> -
> -bb21.i.i: ; preds = %bb20.i.i
> - br i1 false, label %bb22.i.i, label %bb24.i.i
> -
> -bb22.i.i: ; preds = %bb21.i.i
> - br i1 false, label %bb23.i.i, label %bb24.i.i
> -
> -bb23.i.i: ; preds = %bb22.i.i
> - br label %bb24.i.i
> -
> -bb24.i.i: ; preds = %bb23.i.i, %bb22.i.i, %bb21.i.i,
> %bb20.i.i
> - br i1 false, label %bb26.i.i, label %sat.exit.i.loopexit.loopexit
> -
> -bb26.i.i: ; preds = %bb24.i.i
> - br i1 false, label %bb27.i.i, label %bb33.i.i.loopexit
> -
> -bb27.i.i: ; preds = %bb26.i.i
> - br i1 false, label %bb33.i.i.loopexit, label %bb28.i.i
> -
> -bb28.i.i: ; preds = %bb27.i.i
> - br i1 false, label %bb1.i55.i.i, label %bb13.i.i71.backedge
> -
> -bb1.i55.i.i: ; preds = %bb28.i.i
> - br i1 false, label %bb29.i.i, label %bb13.i.i71.backedge
> -
> -bb29.i.i: ; preds = %bb1.i55.i.i
> - br i1 false, label %bb31.i.i, label %sat.exit.i.loopexit.loopexit2
> -
> -bb31.i.i: ; preds = %bb29.i.i
> - br i1 false, label %bb33.i.i, label %bb1.i48.i.i
> -
> -bb1.i48.i.i: ; preds = %bb31.i.i
> - br i1 false, label %sat.exit.i.loopexit.loopexit2, label %bb33.i.i
> -
> -bb33.i.i.loopexit: ; preds = %bb27.i.i, %bb26.i.i
> - br label %bb33.i.i
> -
> -bb33.i.i: ; preds = %bb33.i.i.loopexit, %bb1.i48.i.i,
> %bb31.i.i
> - br i1 false, label %bb34.i.i, label %bb35.i.i
> -
> -bb34.i.i: ; preds = %bb33.i.i
> - br i1 false, label %bb35.i.i, label %bb2.i44.i.i76
> -
> -bb2.i44.i.i76: ; preds = %bb34.i.i
> - br label %bb35.i.i
> -
> -bb35.i.i: ; preds = %bb2.i44.i.i76, %bb34.i.i, %bb33.i.i
> - br i1 false, label %bb1.i37.i.i, label %bb.i35.i.i
> -
> -bb.i35.i.i: ; preds = %bb35.i.i
> - br label %bb36.i.i
> -
> -bb1.i37.i.i: ; preds = %bb35.i.i
> - br i1 false, label %bb37.i.i, label %bb36.i.i
> -
> -bb36.i.i: ; preds = %bb1.i37.i.i, %bb.i35.i.i
> - br label %bb25.i23.i.i
> -
> -bb.i18.i.i: ; preds = %bb25.i23.i.i
> - br i1 false, label %bb24.i22.i.i, label %bb22.i19.i.i
> -
> -bb22.i19.i.i: ; preds = %bb.i18.i.i
> - br label %bb24.i22.i.i
> -
> -bb24.i22.i.i: ; preds = %bb22.i19.i.i, %bb.i18.i.i
> - br label %bb25.i23.i.i
> -
> -bb25.i23.i.i: ; preds = %bb24.i22.i.i, %bb36.i.i
> - br i1 false, label %bb.i18.i.i, label %bb26.i24.i.i
> -
> -bb26.i24.i.i: ; preds = %bb25.i23.i.i
> - br i1 false, label %bb27.i25.i.i, label %bb32.i.i.i
> -
> -bb27.i25.i.i: ; preds = %bb26.i24.i.i
> - br label %bb32.i.i.i
> -
> -bb32.i.i.i: ; preds = %bb27.i25.i.i, %bb26.i24.i.i
> - br label %bb64.i.i.i
> -
> -bb33.i.i.i: ; preds = %bb64.i.i.i
> - br i1 false, label %bb60.i.i.i, label %bb34.i.i.i
> -
> -bb34.i.i.i: ; preds = %bb33.i.i.i
> - br i1 false, label %bb38.i.i.i, label %bb60.i.i.i
> -
> -bb38.i.i.i: ; preds = %bb34.i.i.i
> - br i1 false, label %bb39.i.i.i, label %bb48.i.i.i
> -
> -bb39.i.i.i: ; preds = %bb38.i.i.i
> - br i1 false, label %bb48.i.i.i, label %bb40.i.i.i
> -
> -bb40.i.i.i: ; preds = %bb39.i.i.i
> - br i1 false, label %bb60.i.i.i, label %bb45.i.i.i
> -
> -bb45.i.i.i: ; preds = %bb40.i.i.i
> - br label %bb60.i.i.i
> -
> -bb48.i.i.i: ; preds = %bb39.i.i.i, %bb38.i.i.i
> - br i1 false, label %bb53.i.i.i, label %bb60.i.i.i
> -
> -bb53.i.i.i: ; preds = %bb48.i.i.i
> - br i1 false, label %bb60.i.i.i, label %bb58.i.i.i
> -
> -bb58.i.i.i: ; preds = %bb53.i.i.i
> - br i1 false, label %bb59.i.i.i, label %bb60.i.i.i
> -
> -bb59.i.i.i: ; preds = %bb58.i.i.i
> - br label %bb60.i.i.i
> -
> -bb60.i.i.i: ; preds = %bb59.i.i.i, %bb58.i.i.i, %bb53.i.i.i,
> %bb48.i.i.i, %bb45.i.i.i, %bb40.i.i.i, %bb34.i.i.i, %bb33.i.i.i
> - %lcollect.i.i.i.1 = phi i32 [ %lcollect.i.i.i.2, %bb34.i.i.i ], [
> %lcollect.i.i.i.2, %bb48.i.i.i ], [ %lcollect.i.i.i.2, %bb58.i.i.i ], [
> %lcollect.i.i.i.2, %bb59.i.i.i ], [ %lcollect.i.i.i.2, %bb53.i.i.i ], [
> %lcollect.i.i.i.2, %bb33.i.i.i ], [ %lcollect.i.i.i.2, %bb40.i.i.i ], [ 0,
> %bb45.i.i.i ] ; <i32> [#uses=1]
> - br label %bb64.i.i.i
> -
> -bb64.i.i.i: ; preds = %bb60.i.i.i, %bb32.i.i.i
> - %lcollect.i.i.i.2 = phi i32 [ 0, %bb32.i.i.i ], [ %lcollect.i.i.i.1,
> %bb60.i.i.i ] ; <i32> [#uses=8]
> - br i1 false, label %bb65.i.i.i, label %bb33.i.i.i
> -
> -bb65.i.i.i: ; preds = %bb64.i.i.i
> - br i1 false, label %bb103.i.i.i.preheader, label %bb66.i.i.i.preheader
> -
> -bb66.i.i.i.preheader: ; preds = %bb65.i.i.i
> - br label %bb66.i.i.i
> -
> -bb66.i.i.i: ; preds = %bb66.i.i.i.backedge,
> %bb66.i.i.i.preheader
> - br i1 false, label %bb67.i.i.i, label %bb68.i.i.i
> -
> -bb67.i.i.i: ; preds = %bb66.i.i.i
> - br label %bb68.i.i.i
> -
> -bb68.i.i.i: ; preds = %bb67.i.i.i, %bb66.i.i.i
> - br i1 false, label %bb69.i.i.i, label %bb70.i.i.i
> -
> -bb69.i.i.i: ; preds = %bb68.i.i.i
> - br label %bb70.i.i.i
> -
> -bb70.i.i.i: ; preds = %bb69.i.i.i, %bb68.i.i.i
> - br i1 false, label %bb71.i.i.i, label %bb72.i.i.i
> -
> -bb71.i.i.i: ; preds = %bb70.i.i.i
> - br label %bb72.i.i.i
> -
> -bb72.i.i.i: ; preds = %bb71.i.i.i, %bb70.i.i.i
> - br label %bb73.i.i.i.outer
> -
> -bb73.i.i.i.outer: ; preds = %bb78.i.i.i, %bb72.i.i.i
> - br label %bb73.i.i.i
> -
> -bb73.i.i.i: ; preds = %bb73.i.i.i, %bb73.i.i.i.outer
> - br i1 false, label %bb73.i.i.i, label %bb76.i.i.i.preheader
> -
> -bb76.i.i.i.preheader: ; preds = %bb73.i.i.i
> - br label %bb76.i.i.i
> -
> -bb76.i.i.i: ; preds = %bb76.i.i.i, %bb76.i.i.i.preheader
> - br i1 false, label %bb77.i.i.i, label %bb76.i.i.i
> -
> -bb77.i.i.i: ; preds = %bb76.i.i.i
> - br i1 false, label %bb78.i.i.i, label %bb79.i.i.i
> -
> -bb78.i.i.i: ; preds = %bb77.i.i.i
> - br label %bb73.i.i.i.outer
> -
> -bb79.i.i.i: ; preds = %bb77.i.i.i
> - br i1 false, label %bb83.i.i.i, label %bb94.i.i.i
> -
> -bb83.i.i.i: ; preds = %bb79.i.i.i
> - br i1 false, label %bb84.i.i.i, label %bb88.i.i.i
> -
> -bb84.i.i.i: ; preds = %bb83.i.i.i
> - br i1 false, label %bb87.i.i.i, label %bb85.i.i.i
> -
> -bb85.i.i.i: ; preds = %bb84.i.i.i
> - br label %bb87.i.i.i
> -
> -bb87.i.i.i: ; preds = %bb85.i.i.i, %bb84.i.i.i
> - br label %bb88.i.i.i
> -
> -bb88.i.i.i: ; preds = %bb87.i.i.i, %bb83.i.i.i
> - br i1 false, label %bb89.i.i.i, label %bb93.i.i.i
> -
> -bb89.i.i.i: ; preds = %bb88.i.i.i
> - br i1 false, label %bb92.i.i.i, label %bb90.i.i.i
> -
> -bb90.i.i.i: ; preds = %bb89.i.i.i
> - br label %bb92.i.i.i
> -
> -bb92.i.i.i: ; preds = %bb90.i.i.i, %bb89.i.i.i
> - br label %bb93.i.i.i
> -
> -bb93.i.i.i: ; preds = %bb92.i.i.i, %bb88.i.i.i
> - br label %bb66.i.i.i.backedge
> -
> -bb66.i.i.i.backedge: ; preds = %bb97.i.i.i, %bb94.i.i.i,
> %bb93.i.i.i
> - br label %bb66.i.i.i
> -
> -bb94.i.i.i: ; preds = %bb79.i.i.i
> - br i1 false, label %bb66.i.i.i.backedge, label %bb96.i.i.i
> -
> -bb96.i.i.i: ; preds = %bb94.i.i.i
> - br i1 false, label %bb97.i.i.i, label %bb103.i.i.i.preheader.loopexit
> -
> -bb103.i.i.i.preheader.loopexit: ; preds = %bb96.i.i.i
> - br label %bb103.i.i.i.preheader
> -
> -bb103.i.i.i.preheader: ; preds = %bb103.i.i.i.preheader.loopexit,
> %bb65.i.i.i
> - br label %bb103.i.i.i
> -
> -bb97.i.i.i: ; preds = %bb96.i.i.i
> - br label %bb66.i.i.i.backedge
> -
> -bb100.i.i.i: ; preds = %bb103.i.i.i
> - br i1 false, label %bb101.i.i.i, label %bb102.i.i.i
> -
> -bb101.i.i.i: ; preds = %bb100.i.i.i
> - br label %bb102.i.i.i
> -
> -bb102.i.i.i: ; preds = %bb101.i.i.i, %bb100.i.i.i
> - br label %bb103.i.i.i
> -
> -bb103.i.i.i: ; preds = %bb102.i.i.i, %bb103.i.i.i.preheader
> - br i1 false, label %bb100.i.i.i, label %bb109.i.i.i.preheader
> -
> -bb109.i.i.i.preheader: ; preds = %bb103.i.i.i
> - br label %bb109.i.i.i
> -
> -bb105.i.i.i: ; preds = %bb109.i.i.i
> - br label %bb107.i.i.i
> -
> -bb106.i.i.i: ; preds = %bb107.i.i.i
> - br label %bb107.i.i.i
> -
> -bb107.i.i.i: ; preds = %bb106.i.i.i, %bb105.i.i.i
> - br i1 false, label %bb106.i.i.i, label %bb108.i.i.i
> -
> -bb108.i.i.i: ; preds = %bb107.i.i.i
> - br label %bb109.i.i.i
> -
> -bb109.i.i.i: ; preds = %bb108.i.i.i, %bb109.i.i.i.preheader
> - br i1 false, label %bb110.i.i.i, label %bb105.i.i.i
> -
> -bb110.i.i.i: ; preds = %bb109.i.i.i
> - %0 = sub i32 0, %lcollect.i.i.i.2 ; <i32> [#uses=1]
> - %1 = add i32 %0, 1 ; <i32> [#uses=1]
> - br label %bb113.i.i.i
> -
> -bb111.i.i.i: ; preds = %bb113.i.i.i
> - br i1 false, label %bb114.i.i.i, label %bb113.i.i.i
> -
> -bb113.i.i.i: ; preds = %bb111.i.i.i, %bb110.i.i.i
> - br i1 false, label %bb111.i.i.i, label %bb114.i.i.i
> -
> -bb114.i.i.i: ; preds = %bb113.i.i.i, %bb111.i.i.i
> - %2 = lshr i32 %1, 1 ; <i32> [#uses=2]
> - br i1 false, label %bb116.i.i.i, label %bb124.i.i.i
> -
> -bb116.i.i.i: ; preds = %bb114.i.i.i
> - br i1 false, label %bb117.i.i.i.preheader, label %bb122.i.i.i.preheader
> -
> -bb122.i.i.i.preheader: ; preds = %bb116.i.i.i
> - br label %bb122.i.i.i
> -
> -bb117.i.i.i.preheader: ; preds = %bb116.i.i.i
> - br label %bb117.i.i.i
> -
> -bb117.i.i.i: ; preds = %bb118.i.i.i, %bb117.i.i.i.preheader
> - %target.i.i.i.1 = phi i32 [ %3, %bb118.i.i.i ], [ %2,
> %bb117.i.i.i.preheader ] ; <i32> [#uses=1]
> - %3 = add i32 %target.i.i.i.1, 1 ; <i32> [#uses=2]
> - br i1 false, label %bb118.i.i.i, label %bb124.i.i.i.loopexit
> -
> -bb118.i.i.i: ; preds = %bb117.i.i.i
> - br i1 false, label %bb117.i.i.i, label %bb124.i.i.i.loopexit
> -
> -bb122.i.i.i: ; preds = %bb123.i.i.i, %bb122.i.i.i.preheader
> - %target.i.i.i.2 = phi i32 [ %4, %bb123.i.i.i ], [ %2,
> %bb122.i.i.i.preheader ] ; <i32> [#uses=2]
> - br i1 false, label %bb124.i.i.i.loopexit1, label %bb123.i.i.i
> -
> -bb123.i.i.i: ; preds = %bb122.i.i.i
> - %4 = add i32 %target.i.i.i.2, -1 ; <i32> [#uses=1]
> - br i1 false, label %bb122.i.i.i, label %bb124.i.i.i.loopexit1
> -
> -bb124.i.i.i.loopexit: ; preds = %bb118.i.i.i, %bb117.i.i.i
> - br label %bb124.i.i.i
> -
> -bb124.i.i.i.loopexit1: ; preds = %bb123.i.i.i, %bb122.i.i.i
> - br label %bb124.i.i.i
> -
> -bb124.i.i.i: ; preds = %bb124.i.i.i.loopexit1,
> %bb124.i.i.i.loopexit, %bb114.i.i.i
> - %target.i.i.i.0 = phi i32 [ 0, %bb114.i.i.i ], [ %3,
> %bb124.i.i.i.loopexit ], [ %target.i.i.i.2, %bb124.i.i.i.loopexit1 ]
> ; <i32> [#uses=0]
> - br label %bb132.i.i.i.outer
> -
> -bb125.i.i.i: ; preds = %bb132.i.i.i
> - br i1 false, label %bb132.i.i.i, label %bb130.i.i.i
> -
> -bb130.i.i.i: ; preds = %bb125.i.i.i
> - br label %bb132.i.i.i.outer
> -
> -bb132.i.i.i.outer: ; preds = %bb130.i.i.i, %bb124.i.i.i
> - br label %bb132.i.i.i
> -
> -bb132.i.i.i: ; preds = %bb132.i.i.i.outer, %bb125.i.i.i
> - br i1 false, label %bb125.i.i.i, label %bb133.i.i.i
> -
> -bb133.i.i.i: ; preds = %bb132.i.i.i
> - br i1 false, label %bb136.i.i.i, label %bb134.i.i.i
> -
> -bb134.i.i.i: ; preds = %bb133.i.i.i
> - br i1 false, label %bb136.i.i.i, label %bb135.i.i.i
> -
> -bb135.i.i.i: ; preds = %bb134.i.i.i
> - br label %bb136.i.i.i
> -
> -bb136.i.i.i: ; preds = %bb135.i.i.i, %bb134.i.i.i, %bb133.i.i.i
> - br i1 false, label %bb137.i.i.i, label %bb37.i.i
> -
> -bb137.i.i.i: ; preds = %bb136.i.i.i
> - br label %bb37.i.i
> -
> -bb37.i.i: ; preds = %bb137.i.i.i, %bb136.i.i.i, %bb1.i37.i.i
> - br i1 false, label %bb40.i.i, label %bb38.i.i
> -
> -bb38.i.i: ; preds = %bb37.i.i
> - br i1 false, label %bb39.i.i, label %bb40.i.i
> -
> -bb39.i.i: ; preds = %bb38.i.i
> - br i1 false, label %bb17.i.i.i, label %bb3.i12.i.i
> -
> -bb3.i12.i.i: ; preds = %bb39.i.i
> - br label %bb5.i14.i.i
> -
> -bb5.i14.i.i: ; preds = %bb8.i.i.i79, %bb3.i12.i.i
> - br i1 false, label %bb6.i15.i.i, label %bb9.i.i.i80
> -
> -bb6.i15.i.i: ; preds = %bb5.i14.i.i
> - br i1 false, label %bb7.i.i.i78, label %bb9.i.i.i80
> -
> -bb7.i.i.i78: ; preds = %bb6.i15.i.i
> - br i1 false, label %bb9.i.i.i80, label %bb8.i.i.i79
> -
> -bb8.i.i.i79: ; preds = %bb7.i.i.i78
> - br i1 false, label %bb9.i.i.i80, label %bb5.i14.i.i
> -
> -bb9.i.i.i80: ; preds = %bb8.i.i.i79, %bb7.i.i.i78,
> %bb6.i15.i.i, %bb5.i14.i.i
> - br i1 false, label %bb16.i.i.i, label %bb10.i.i.i81
> -
> -bb10.i.i.i81: ; preds = %bb9.i.i.i80
> - br i1 false, label %bb11.i.i.i, label %bb15.i.i.i
> -
> -bb11.i.i.i: ; preds = %bb10.i.i.i81
> - br i1 false, label %bb16.i.i.i, label %bb15.i.i.i
> -
> -bb15.i.i.i: ; preds = %bb11.i.i.i, %bb10.i.i.i81
> - br label %bb16.i.i.i
> -
> -bb16.i.i.i: ; preds = %bb15.i.i.i, %bb11.i.i.i, %bb9.i.i.i80
> - br label %bb17.i.i.i
> -
> -bb17.i.i.i: ; preds = %bb16.i.i.i, %bb39.i.i
> - br i1 false, label %bb18.i.i.i, label %bb25.i.i.i
> -
> -bb18.i.i.i: ; preds = %bb17.i.i.i
> - br i1 false, label %bb24.i.i.i, label %bb23.i.i.i
> -
> -bb23.i.i.i: ; preds = %bb18.i.i.i
> - br label %bb24.i.i.i
> -
> -bb24.i.i.i: ; preds = %bb23.i.i.i, %bb18.i.i.i
> - br label %bb29.i.i.i
> -
> -bb25.i.i.i: ; preds = %bb17.i.i.i
> - br i1 false, label %bb29.i.i.i, label %bb27.i.i.i
> -
> -bb27.i.i.i: ; preds = %bb25.i.i.i
> - br i1 false, label %bb29.i.i.i, label %bb28.i.i.i
> -
> -bb28.i.i.i: ; preds = %bb27.i.i.i
> - br i1 false, label %bb29.i.i.i, label %bb.i4.i.i.i
> -
> -bb.i4.i.i.i: ; preds = %bb28.i.i.i
> - br i1 false, label %bb4.i.i16.i.i, label %bb29.i.i.i
> -
> -bb4.i.i16.i.i: ; preds = %bb.i4.i.i.i
> - br label %bb29.i.i.i
> -
> -bb29.i.i.i: ; preds = %bb4.i.i16.i.i, %bb.i4.i.i.i,
> %bb28.i.i.i, %bb27.i.i.i, %bb25.i.i.i, %bb24.i.i.i
> - br label %bb40.i.i
> -
> -bb40.i.i: ; preds = %bb29.i.i.i, %bb38.i.i, %bb37.i.i
> - br i1 false, label %bb9.i.i.i.i.preheader, label %bb2.i.i.i87
> -
> -bb9.i.i.i.i.preheader: ; preds = %bb40.i.i
> - br label %bb9.i.i.i.i
> -
> -bb.i.i.i.i84: ; preds = %bb9.i.i.i.i
> - switch i8 0, label %bb8.i.i.i.i [
> - i8 -1, label %bb1.i.i.i.i85
> - i8 1, label %bb9.i.i.i.i
> - ]
> -
> -bb1.i.i.i.i85: ; preds = %bb.i.i.i.i84
> - br i1 false, label %bb5.i.i.i.i, label %bb2.i.i.i87
> -
> -bb5.i.i.i.i: ; preds = %bb1.i.i.i.i85
> - br label %bb2.i.i.i87
> -
> -bb8.i.i.i.i: ; preds = %bb.i.i.i.i84
> - br i1 false, label %bb2.i.i.i87, label %bb6.i.i.i95
> -
> -bb9.i.i.i.i: ; preds = %bb.i.i.i.i84, %bb9.i.i.i.i.preheader
> - br i1 false, label %bb.i.i.i.i84, label %bb10.i.i.i.i
> -
> -bb10.i.i.i.i: ; preds = %bb9.i.i.i.i
> - br label %bb2.i.i.i87
> -
> -bb2.i.i.i87: ; preds = %bb10.i.i.i.i, %bb8.i.i.i.i,
> %bb5.i.i.i.i, %bb1.i.i.i.i85, %bb40.i.i
> - br i1 false, label %bb3.i.i.i88, label %decide.exit.i.i
> -
> -bb3.i.i.i88: ; preds = %bb2.i.i.i87
> - br i1 false, label %bb4.i.i.i90, label %bb1.i23.i.i.i
> -
> -bb1.i23.i.i.i: ; preds = %bb3.i.i.i88
> - br i1 false, label %decide.exit.i.i, label %bb4.i.i.i90
> -
> -bb4.i.i.i90: ; preds = %bb1.i23.i.i.i, %bb3.i.i.i88
> - br i1 false, label %bb1.i9.i.i.i, label %bb5.i.i.i94
> -
> -bb1.i9.i.i.i: ; preds = %bb4.i.i.i90
> - br i1 false, label %bb.i.i27.i.i.i.i, label %bb1.i.i28.i.i.i.i
> -
> -bb.i.i27.i.i.i.i: ; preds = %bb1.i9.i.i.i
> - br label %int2lit.exit32.i.i.i.i
> -
> -bb1.i.i28.i.i.i.i: ; preds = %bb1.i9.i.i.i
> - br label %int2lit.exit32.i.i.i.i
> -
> -int2lit.exit32.i.i.i.i: ; preds = %bb1.i.i28.i.i.i.i,
> %bb.i.i27.i.i.i.i
> - br i1 false, label %bb8.i19.i.i.i, label %bb2.i.i.i.i91
> -
> -bb2.i.i.i.i91: ; preds = %int2lit.exit32.i.i.i.i
> - br label %bb4.i.i.i.i
> -
> -bb3.i.i.i.i92: ; preds = %gcd.exit.i.i.i.i
> - br label %bb4.i.i.i.i
> -
> -bb4.i.i.i.i: ; preds = %bb3.i.i.i.i92, %bb2.i.i.i.i91
> - br label %bb3.i.i13.i.i.i
> -
> -bb2.i.i12.i.i.i: ; preds = %bb3.i.i13.i.i.i
> - br label %bb3.i.i13.i.i.i
> -
> -bb3.i.i13.i.i.i: ; preds = %bb2.i.i12.i.i.i, %bb4.i.i.i.i
> - br i1 false, label %gcd.exit.i.i.i.i, label %bb2.i.i12.i.i.i
> -
> -gcd.exit.i.i.i.i: ; preds = %bb3.i.i13.i.i.i
> - br i1 false, label %bb5.i14.i.i.i.preheader, label %bb3.i.i.i.i92
> -
> -bb5.i14.i.i.i.preheader: ; preds = %gcd.exit.i.i.i.i
> - br label %bb5.i14.i.i.i
> -
> -bb5.i14.i.i.i: ; preds = %int2lit.exit.i.i.i.i,
> %bb5.i14.i.i.i.preheader
> - br i1 false, label %bb.i.i.i17.i.i.i, label %bb1.i.i.i18.i.i.i
> -
> -bb.i.i.i17.i.i.i: ; preds = %bb5.i14.i.i.i
> - br label %int2lit.exit.i.i.i.i
> -
> -bb1.i.i.i18.i.i.i: ; preds = %bb5.i14.i.i.i
> - br label %int2lit.exit.i.i.i.i
> -
> -int2lit.exit.i.i.i.i: ; preds = %bb1.i.i.i18.i.i.i,
> %bb.i.i.i17.i.i.i
> - br i1 false, label %bb8.i19.i.i.i.loopexit, label %bb5.i14.i.i.i
> -
> -bb8.i19.i.i.i.loopexit: ; preds = %int2lit.exit.i.i.i.i
> - br label %bb8.i19.i.i.i
> -
> -bb8.i19.i.i.i: ; preds = %bb8.i19.i.i.i.loopexit,
> %int2lit.exit32.i.i.i.i
> - br i1 false, label %bb5.i.i.i94, label %bb6.i.i.i95
> -
> -bb5.i.i.i94: ; preds = %bb8.i19.i.i.i, %bb4.i.i.i90
> - br label %bb.i2.i.i.i
> -
> -bb.i2.i.i.i: ; preds = %hpop.exit.i.i.i.i, %bb5.i.i.i94
> - br i1 false, label %hpop.exit.i.i.i.i, label %bb1.i.i.i.i.i
> -
> -bb1.i.i.i.i.i: ; preds = %bb.i2.i.i.i
> - br label %bb2.i.i.i.i.i
> -
> -bb2.i.i.i.i.i: ; preds = %bb11.i.i.i.i.i, %bb1.i.i.i.i.i
> - br i1 false, label %bb3.i.i.i.i.i, label %bb12.i.i.i.i.i
> -
> -bb3.i.i.i.i.i: ; preds = %bb2.i.i.i.i.i
> - br i1 false, label %bb4.i.i.i.i.i, label %bb1.i.i.i.i.i.i
> -
> -bb1.i.i.i.i.i.i: ; preds = %bb3.i.i.i.i.i
> - br i1 false, label %bb8.i.i.i.i.i, label %bb3.i.i.i.i.i.i
> -
> -bb3.i.i.i.i.i.i: ; preds = %bb1.i.i.i.i.i.i
> - br i1 false, label %bb4.i.i.i.i.i, label %bb8.i.i.i.i.i
> -
> -bb4.i.i.i.i.i: ; preds = %bb3.i.i.i.i.i.i, %bb3.i.i.i.i.i
> - br i1 false, label %bb5.i.i.i.i.i, label %bb11.i.i.i.i.i
> -
> -bb5.i.i.i.i.i: ; preds = %bb4.i.i.i.i.i
> - br i1 false, label %bb6.i.i.i.i.i, label %bb1.i21.i.i.i.i.i
> -
> -bb1.i21.i.i.i.i.i: ; preds = %bb5.i.i.i.i.i
> - br i1 false, label %bb11.i.i.i.i.i, label %bb3.i24.i.i.i.i.i
> -
> -bb3.i24.i.i.i.i.i: ; preds = %bb1.i21.i.i.i.i.i
> - br i1 false, label %bb6.i.i.i.i.i, label %bb11.i.i.i.i.i
> -
> -bb6.i.i.i.i.i: ; preds = %bb3.i24.i.i.i.i.i, %bb5.i.i.i.i.i
> - br label %bb11.i.i.i.i.i
> -
> -bb8.i.i.i.i.i: ; preds = %bb3.i.i.i.i.i.i, %bb1.i.i.i.i.i.i
> - br i1 false, label %bb9.i.i.i.i.i, label %bb12.i.i.i.i.i
> -
> -bb9.i.i.i.i.i: ; preds = %bb8.i.i.i.i.i
> - br i1 false, label %bb11.i.i.i.i.i, label %bb1.i8.i.i.i.i.i
> -
> -bb1.i8.i.i.i.i.i: ; preds = %bb9.i.i.i.i.i
> - br i1 false, label %bb12.i.i.i.i.i, label %bb3.i11.i.i.i.i.i
> -
> -bb3.i11.i.i.i.i.i: ; preds = %bb1.i8.i.i.i.i.i
> - br i1 false, label %bb11.i.i.i.i.i, label %bb12.i.i.i.i.i
> -
> -bb11.i.i.i.i.i: ; preds = %bb3.i11.i.i.i.i.i,
> %bb9.i.i.i.i.i, %bb6.i.i.i.i.i, %bb3.i24.i.i.i.i.i, %bb1.i21.i.i.i.i.i,
> %bb4.i.i.i.i.i
> - br label %bb2.i.i.i.i.i
> -
> -bb12.i.i.i.i.i: ; preds = %bb3.i11.i.i.i.i.i,
> %bb1.i8.i.i.i.i.i, %bb8.i.i.i.i.i, %bb2.i.i.i.i.i
> - br label %hpop.exit.i.i.i.i
> -
> -hpop.exit.i.i.i.i: ; preds = %bb12.i.i.i.i.i, %bb.i2.i.i.i
> - br i1 false, label %sdecide.exit.i.i.i, label %bb.i2.i.i.i
> -
> -sdecide.exit.i.i.i: ; preds = %hpop.exit.i.i.i.i
> - br label %bb6.i.i.i95
> -
> -bb6.i.i.i95: ; preds = %sdecide.exit.i.i.i, %bb8.i19.i.i.i,
> %bb8.i.i.i.i
> - br label %decide.exit.i.i
> -
> -decide.exit.i.i: ; preds = %bb6.i.i.i95, %bb1.i23.i.i.i,
> %bb2.i.i.i87
> - br i1 false, label %bb42.i.i, label %sat.exit.i.loopexit.loopexit2
> -
> -bb42.i.i: ; preds = %decide.exit.i.i
> - br label %bb13.i.i71.outer
> -
> -sat.exit.i.loopexit.loopexit: ; preds = %bb24.i.i, %bb1.i68.i.i,
> %incincs.exit.i.i
> - br label %sat.exit.i.loopexit
> -
> -sat.exit.i.loopexit.loopexit2: ; preds = %decide.exit.i.i,
> %bb1.i48.i.i, %bb29.i.i
> - br label %sat.exit.i.loopexit
> -
> -sat.exit.i.loopexit: ; preds = %sat.exit.i.loopexit.loopexit2,
> %sat.exit.i.loopexit.loopexit
> - br label %sat.exit.i
> -
> -sat.exit.i: ; preds = %sat.exit.i.loopexit, %bb1.i61.i.i,
> %bb8.i.i67, %bb1.i.i.i63, %bb3.i.i59
> - br i1 false, label %bb7.i, label %bb2.i96
> -
> -bb2.i96: ; preds = %sat.exit.i
> - switch i32 0, label %bb5.i99 [
> - i32 10, label %bb4.i98
> - i32 20, label %bb6.i100
> - ]
> -
> -bb4.i98: ; preds = %bb2.i96
> - br label %bb6.i100
> -
> -bb5.i99: ; preds = %bb2.i96
> - br label %bb6.i100
> -
> -bb6.i100: ; preds = %bb5.i99, %bb4.i98, %bb2.i96
> - br label %bb7.i
> -
> -bb7.i: ; preds = %bb6.i100, %sat.exit.i
> - br i1 false, label %bb.i1.i, label %picosat_sat.exit
> -
> -bb.i1.i: ; preds = %bb7.i
> - br label %picosat_sat.exit
> -
> -picosat_sat.exit: ; preds = %bb.i1.i, %bb7.i
> - switch i32 0, label %bb166 [
> - i32 20, label %bb150
> - i32 10, label %bb163
> - ]
> -
> -bb150: ; preds = %picosat_sat.exit
> - br i1 false, label %bb152, label %bb151
> -
> -bb151: ; preds = %bb150
> - br label %bb152
> -
> -bb152: ; preds = %bb151, %bb150
> - br i1 false, label %bb154, label %bb153
> -
> -bb153: ; preds = %bb152
> - br label %bb154
> -
> -bb154: ; preds = %bb153, %bb152
> - br i1 false, label %bb157, label %bb156
> -
> -bb156: ; preds = %bb154
> - br label %bb157
> -
> -bb157: ; preds = %bb156, %bb154
> - br i1 false, label %bb159, label %bb158
> -
> -bb158: ; preds = %bb157
> - br label %bb159
> -
> -bb159: ; preds = %bb158, %bb157
> - br i1 false, label %bb167, label %bb160
> -
> -bb160: ; preds = %bb159
> - br label %bb167
> -
> -bb163: ; preds = %picosat_sat.exit
> - br i1 false, label %bb167, label %bb164
> -
> -bb164: ; preds = %bb163
> - br label %bb4.i
> -
> -bb.i11: ; preds = %bb4.i
> - br i1 false, label %bb.i.i12, label %bb1.i.i14
> -
> -bb.i.i12: ; preds = %bb.i11
> - unreachable
> -
> -bb1.i.i14: ; preds = %bb.i11
> - br i1 false, label %bb3.i.i16, label %bb2.i.i15
> -
> -bb2.i.i15: ; preds = %bb1.i.i14
> - unreachable
> -
> -bb3.i.i16: ; preds = %bb1.i.i14
> - br i1 false, label %bb3.i, label %bb7.i.i
> -
> -bb7.i.i: ; preds = %bb3.i.i16
> - br i1 false, label %bb.i.i.i.i17, label %bb1.i.i.i.i18
> -
> -bb.i.i.i.i17: ; preds = %bb7.i.i
> - br label %int2lit.exit.i.i
> -
> -bb1.i.i.i.i18: ; preds = %bb7.i.i
> - br label %int2lit.exit.i.i
> -
> -int2lit.exit.i.i: ; preds = %bb1.i.i.i.i18, %bb.i.i.i.i17
> - br i1 false, label %bb3.i, label %bb9.i.i
> -
> -bb9.i.i: ; preds = %int2lit.exit.i.i
> - br label %bb3.i
> -
> -bb3.i: ; preds = %bb9.i.i, %int2lit.exit.i.i, %bb3.i.i16
> - br label %bb4.i
> -
> -bb4.i: ; preds = %bb3.i, %bb164
> - br i1 false, label %bb5.i, label %bb.i11
> -
> -bb5.i: ; preds = %bb4.i
> - br i1 false, label %bb6.i, label %bb167
> -
> -bb6.i: ; preds = %bb5.i
> - br label %bb167
> -
> -bb166: ; preds = %picosat_sat.exit
> - br label %bb167
> -
> -bb167: ; preds = %bb166, %bb6.i, %bb5.i, %bb163, %bb160, %bb159,
> %picosat_print.exit
> - br i1 false, label %bb168, label %bb170
> -
> -bb168: ; preds = %bb167
> - br i1 false, label %bb170, label %bb169
> -
> -bb169: ; preds = %bb168
> - br i1 false, label %bb.i7, label %picosat_time_stamp.exit9
> -
> -bb.i7: ; preds = %bb169
> - br label %picosat_time_stamp.exit9
> -
> -picosat_time_stamp.exit9: ; preds = %bb.i7, %bb169
> - br label %bb170
> -
> -bb170: ; preds = %picosat_time_stamp.exit9, %bb168, %bb167, %bb129
> - br i1 false, label %bb.i.i3, label %picosat_leave.exit
> -
> -bb.i.i3: ; preds = %bb170
> - br label %picosat_leave.exit
> -
> -picosat_leave.exit: ; preds = %bb.i.i3, %bb170
> - br i1 false, label %bb1.i.i, label %bb.i.i
> -
> -bb.i.i: ; preds = %picosat_leave.exit
> - unreachable
> -
> -bb1.i.i: ; preds = %picosat_leave.exit
> - br label %bb9.i.i.i
> -
> -bb3.i.i.i: ; preds = %bb9.i.i.i
> - br i1 false, label %bb5.i.i.i, label %bb4.i.i.i
> -
> -bb4.i.i.i: ; preds = %bb3.i.i.i
> - br label %bb5.i.i.i
> -
> -bb5.i.i.i: ; preds = %bb4.i.i.i, %bb3.i.i.i
> - br label %bb9.i.i.i
> -
> -bb9.i.i.i: ; preds = %bb5.i.i.i, %bb1.i.i
> - br i1 false, label %bb10.i.i.i, label %bb3.i.i.i
> -
> -bb10.i.i.i: ; preds = %bb9.i.i.i
> - br i1 false, label %delete.exit.i.i.i, label %bb1.i.i.i.i
> -
> -bb1.i.i.i.i: ; preds = %bb10.i.i.i
> - br label %delete.exit.i.i.i
> -
> -delete.exit.i.i.i: ; preds = %bb1.i.i.i.i, %bb10.i.i.i
> - br i1 false, label %delete_clauses.exit.i.i, label %bb1.i7.i.i.i
> -
> -bb1.i7.i.i.i: ; preds = %delete.exit.i.i.i
> - br label %delete_clauses.exit.i.i
> -
> -delete_clauses.exit.i.i: ; preds = %bb1.i7.i.i.i,
> %delete.exit.i.i.i
> - br label %bb3.i.i
> -
> -bb2.i.i: ; preds = %bb3.i.i
> - br i1 false, label %lrelease.exit.i.i, label %bb1.i.i23.i.i
> -
> -bb1.i.i23.i.i: ; preds = %bb2.i.i
> - br label %lrelease.exit.i.i
> -
> -lrelease.exit.i.i: ; preds = %bb1.i.i23.i.i, %bb2.i.i
> - br label %bb3.i.i
> -
> -bb3.i.i: ; preds = %lrelease.exit.i.i,
> %delete_clauses.exit.i.i
> - br i1 false, label %bb4.i.i, label %bb2.i.i
> -
> -bb4.i.i: ; preds = %bb3.i.i
> - br i1 false, label %delete.exit214.i.i, label %bb1.i208.i.i
> -
> -bb1.i208.i.i: ; preds = %bb4.i.i
> - br label %delete.exit214.i.i
> -
> -delete.exit214.i.i: ; preds = %bb1.i208.i.i, %bb4.i.i
> - br i1 false, label %delete.exit203.i.i, label %bb1.i197.i.i
> -
> -bb1.i197.i.i: ; preds = %delete.exit214.i.i
> - br label %delete.exit203.i.i
> -
> -delete.exit203.i.i: ; preds = %bb1.i197.i.i,
> %delete.exit214.i.i
> - br i1 false, label %delete.exit192.i.i, label %bb1.i186.i.i
> -
> -bb1.i186.i.i: ; preds = %delete.exit203.i.i
> - br label %delete.exit192.i.i
> -
> -delete.exit192.i.i: ; preds = %bb1.i186.i.i,
> %delete.exit203.i.i
> - br i1 false, label %delete.exit181.i.i, label %bb1.i175.i.i
> -
> -bb1.i175.i.i: ; preds = %delete.exit192.i.i
> - br label %delete.exit181.i.i
> -
> -delete.exit181.i.i: ; preds = %bb1.i175.i.i,
> %delete.exit192.i.i
> - br i1 false, label %delete.exit170.i.i, label %bb1.i164.i.i
> -
> -bb1.i164.i.i: ; preds = %delete.exit181.i.i
> - br label %delete.exit170.i.i
> -
> -delete.exit170.i.i: ; preds = %bb1.i164.i.i,
> %delete.exit181.i.i
> - br i1 false, label %delete.exit159.i.i, label %bb1.i153.i.i
> -
> -bb1.i153.i.i: ; preds = %delete.exit170.i.i
> - br label %delete.exit159.i.i
> -
> -delete.exit159.i.i: ; preds = %bb1.i153.i.i,
> %delete.exit170.i.i
> - br i1 false, label %delete.exit148.i.i, label %bb1.i142.i.i
> -
> -bb1.i142.i.i: ; preds = %delete.exit159.i.i
> - br label %delete.exit148.i.i
> -
> -delete.exit148.i.i: ; preds = %bb1.i142.i.i,
> %delete.exit159.i.i
> - br i1 false, label %delete.exit137.i.i, label %bb1.i131.i.i
> -
> -bb1.i131.i.i: ; preds = %delete.exit148.i.i
> - br label %delete.exit137.i.i
> -
> -delete.exit137.i.i: ; preds = %bb1.i131.i.i,
> %delete.exit148.i.i
> - br i1 false, label %delete.exit126.i.i, label %bb1.i120.i.i
> -
> -bb1.i120.i.i: ; preds = %delete.exit137.i.i
> - br label %delete.exit126.i.i
> -
> -delete.exit126.i.i: ; preds = %bb1.i120.i.i,
> %delete.exit137.i.i
> - br i1 false, label %delete.exit115.i.i, label %bb1.i109.i.i
> -
> -bb1.i109.i.i: ; preds = %delete.exit126.i.i
> - br label %delete.exit115.i.i
> -
> -delete.exit115.i.i: ; preds = %bb1.i109.i.i,
> %delete.exit126.i.i
> - br i1 false, label %delete.exit104.i.i, label %bb1.i98.i.i
> -
> -bb1.i98.i.i: ; preds = %delete.exit115.i.i
> - br label %delete.exit104.i.i
> -
> -delete.exit104.i.i: ; preds = %bb1.i98.i.i, %delete.exit115.i.i
> - br i1 false, label %delete.exit93.i.i, label %bb1.i87.i.i
> -
> -bb1.i87.i.i: ; preds = %delete.exit104.i.i
> - br label %delete.exit93.i.i
> -
> -delete.exit93.i.i: ; preds = %bb1.i87.i.i, %delete.exit104.i.i
> - br i1 false, label %delete.exit82.i.i, label %bb1.i76.i.i
> -
> -bb1.i76.i.i: ; preds = %delete.exit93.i.i
> - br label %delete.exit82.i.i
> -
> -delete.exit82.i.i: ; preds = %bb1.i76.i.i, %delete.exit93.i.i
> - br i1 false, label %delete.exit71.i.i, label %bb1.i65.i.i
> -
> -bb1.i65.i.i: ; preds = %delete.exit82.i.i
> - br label %delete.exit71.i.i
> -
> -delete.exit71.i.i: ; preds = %bb1.i65.i.i, %delete.exit82.i.i
> - br i1 false, label %delete.exit60.i.i, label %bb1.i54.i.i
> -
> -bb1.i54.i.i: ; preds = %delete.exit71.i.i
> - br label %delete.exit60.i.i
> -
> -delete.exit60.i.i: ; preds = %bb1.i54.i.i, %delete.exit71.i.i
> - br i1 false, label %delete.exit38.i.i, label %bb1.i32.i.i
> -
> -bb1.i32.i.i: ; preds = %delete.exit60.i.i
> - br label %delete.exit38.i.i
> -
> -delete.exit38.i.i: ; preds = %bb1.i32.i.i, %delete.exit60.i.i
> - br i1 false, label %delete.exit18.i.i, label %bb1.i12.i.i
> -
> -bb1.i12.i.i: ; preds = %delete.exit38.i.i
> - br label %delete.exit18.i.i
> -
> -delete.exit18.i.i: ; preds = %bb1.i12.i.i, %delete.exit38.i.i
> - br i1 false, label %picosat_reset.exit, label %bb1.i2.i.i
> -
> -bb1.i2.i.i: ; preds = %delete.exit18.i.i
> - br label %picosat_reset.exit
> -
> -picosat_reset.exit: ; preds = %bb1.i2.i.i, %delete.exit18.i.i
> - br label %bb171
> -
> -bb171: ; preds = %picosat_reset.exit, %bb110
> - br i1 false, label %bb173, label %bb172
> -
> -bb172: ; preds = %bb171
> - br label %bb173
> -
> -bb173: ; preds = %bb172, %bb171
> - br i1 false, label %bb175, label %bb174
> -
> -bb174: ; preds = %bb173
> - br label %bb175
> -
> -bb175: ; preds = %bb174, %bb173
> - br i1 false, label %bb177, label %bb176
> -
> -bb176: ; preds = %bb175
> - br label %bb177
> -
> -bb177: ; preds = %bb176, %bb175
> - br i1 false, label %bb179, label %bb178
> -
> -bb178: ; preds = %bb177
> - ret i32 0
> -
> -bb179: ; preds = %bb177
> - ret i32 0
> -}
> -
> -define i32 @main(i32 %argc, i8** %argv) nounwind {
> -entry:
> - br label %bb2
> -
> -bb: ; preds = %bb2
> - br i1 false, label %bb3, label %bb2
> -
> -bb2: ; preds = %bb, %entry
> - br i1 false, label %bb5.loopexit, label %bb
> -
> -bb3: ; preds = %bb
> - br i1 false, label %bb5, label %bb4
> -
> -bb4: ; preds = %bb3
> - br label %bb5
> -
> -bb5.loopexit: ; preds = %bb2
> - br label %bb5
> -
> -bb5: ; preds = %bb5.loopexit, %bb4, %bb3
> - %0 = call fastcc i32 @picosat_main(i32 %argc, i8** %argv) nounwind
> ; <i32> [#uses=2]
> - br i1 false, label %bb7, label %bb6
> -
> -bb6: ; preds = %bb5
> - ret i32 %0
> -
> -bb7: ; preds = %bb5
> - ret i32 %0
> -}
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll
> index b2bca62068a3..50bfcce5a3af 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr32917.ll
> @@ -1,17 +1,27 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ; PR 32917
>
> @b = common local_unnamed_addr global i32 0, align 4
> @a = common local_unnamed_addr global i32 0, align 4
>
> define i32 @fn2() local_unnamed_addr {
> -; CHECK-LABEL: define {{[^@]+}}@fn2() local_unnamed_addr
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* @b, align 4
> -; CHECK-NEXT: [[TMP2:%.*]] = sext i32 [[TMP1]] to i64
> -; CHECK-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32*
> -; CHECK-NEXT: call fastcc void @fn1(i32* nofree readonly align 4
> [[TMP3]])
> -; CHECK-NEXT: ret i32 undef
> +; 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
> +; IS__TUNIT____-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32*
> +; IS__TUNIT____-NEXT: call fastcc void @fn1(i32* nofree readonly align
> 4 [[TMP3]])
> +; IS__TUNIT____-NEXT: ret i32 undef
> +;
> +; 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
> +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = inttoptr i64 [[TMP2]] to i32*
> +; IS__CGSCC____-NEXT: call fastcc void @fn1(i32* nofree nonnull
> readonly align 4 [[TMP3]])
> +; IS__CGSCC____-NEXT: ret i32 undef
> ;
> %1 = load i32, i32* @b, align 4
> %2 = sext i32 %1 to i64
>
> 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 de67b8970c23..fff94d452e00 100644
> ---
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll
> +++
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/pr33641_remove_arg_dbgvalue.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; Fix for PR33641. ArgumentPromotion removed the argument to bar but left
> the call to
> ; dbg.value which still used the removed argument.
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
> index b9b10cf86005..1f50e1f9e5b1 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/profile.ll
> @@ -1,16 +1,31 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> 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"
>
> ; Checks if !prof metadata is corret in deadargelim.
>
> define void @caller() #0 {
> -; CHECK-LABEL: define {{[^@]+}}@caller()
> -; CHECK-NEXT: [[X:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 42, i32* [[X]], align 4
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[X]], align 1
> -; CHECK-NEXT: call void @promote_i32_ptr(i32 [[TMP1]]), !prof !0
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@caller()
> +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = alloca i32
> +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[X]], align 4
> +; IS__TUNIT_OPM-NEXT: call void @promote_i32_ptr(i32* noalias
> nocapture nonnull readonly align 4 dereferenceable(4) [[X]]), !prof !0
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@caller()
> +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[X]], align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[X]], align 1
> +; IS__TUNIT_NPM-NEXT: call void @promote_i32_ptr(i32 [[TMP1]]), !prof
> !0
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller()
> +; IS__CGSCC____-NEXT: [[X:%.*]] = alloca i32
> +; IS__CGSCC____-NEXT: store i32 42, i32* [[X]], align 4
> +; IS__CGSCC____-NEXT: call void @promote_i32_ptr(i32* noalias nonnull
> readonly align 4 dereferenceable(4) [[X]]), !prof !0
> +; IS__CGSCC____-NEXT: ret void
> ;
> %x = alloca i32
> store i32 42, i32* %x
> @@ -19,13 +34,25 @@ define void @caller() #0 {
> }
>
> define internal void @promote_i32_ptr(i32* %xp) {
> -; CHECK-LABEL: define {{[^@]+}}@promote_i32_ptr
> -; CHECK-SAME: (i32 [[TMP0:%.*]])
> -; CHECK-NEXT: [[XP_PRIV:%.*]] = alloca i32
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]]
> -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4
> -; CHECK-NEXT: call void @use_i32(i32 [[X]])
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@promote_i32_ptr
> +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[XP:%.*]])
> +; IS__TUNIT_OPM-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4
> +; IS__TUNIT_OPM-NEXT: call void @use_i32(i32 [[X]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@promote_i32_ptr
> +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]])
> +; IS__TUNIT_NPM-NEXT: [[XP_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[XP_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[X:%.*]] = load i32, i32* [[XP_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: call void @use_i32(i32 [[X]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@promote_i32_ptr
> +; IS__CGSCC____-SAME: (i32* nocapture nonnull readonly align 4
> dereferenceable(4) [[XP:%.*]])
> +; IS__CGSCC____-NEXT: [[X:%.*]] = load i32, i32* [[XP]], align 4
> +; IS__CGSCC____-NEXT: call void @use_i32(i32 [[X]])
> +; IS__CGSCC____-NEXT: ret void
> ;
> %x = load i32, i32* %xp
> call void @use_i32(i32 %x)
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll
> index d8d582b12563..dbceea83a4fe 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/reserve-tbaa.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; PR17906
> ; When we promote two arguments in a single function with
> diff erent types,
> @@ -14,13 +17,20 @@
> @d = global i8 0, align 1
>
> define internal fastcc void @fn(i32* nocapture readonly %p1, i64*
> nocapture readonly %p2) {
> -; CHECK-LABEL: define {{[^@]+}}@fn
> -; CHECK-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P1:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa !0
> -; CHECK-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8
> -; CHECK-NEXT: store i8 [[CONV1]], i8* @d, align 1, !tbaa !4
> -; CHECK-NEXT: ret void
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn
> +; IS__TUNIT____-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P1:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa
> !0
> +; IS__TUNIT____-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8
> +; IS__TUNIT____-NEXT: store i8 [[CONV1]], i8* @d, align 1, !tbaa !4
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* @g, align 4, !tbaa
> !0
> +; IS__CGSCC____-NEXT: [[CONV1:%.*]] = trunc i32 [[TMP0]] to i8
> +; IS__CGSCC____-NEXT: store i8 [[CONV1]], i8* @d, align 1, !tbaa !4
> +; IS__CGSCC____-NEXT: ret void
> ;
> entry:
> %0 = load i64, i64* %p2, align 8, !tbaa !1
> @@ -32,14 +42,23 @@ entry:
> }
>
> define i32 @main() {
> -; CHECK-LABEL: define {{[^@]+}}@main()
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8, !tbaa !5
> -; CHECK-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa !5
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8, !tbaa !5
> -; CHECK-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa !0
> -; CHECK-NEXT: call fastcc void @fn(i32* nofree nonnull readonly align
> 4 dereferenceable(4) @g)
> -; CHECK-NEXT: ret i32 0
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@main()
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8,
> !tbaa !5
> +; IS__TUNIT____-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa !5
> +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8,
> !tbaa !5
> +; IS__TUNIT____-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa !0
> +; IS__TUNIT____-NEXT: call fastcc void @fn(i32* nofree nonnull
> readonly align 4 dereferenceable(4) @g)
> +; IS__TUNIT____-NEXT: ret i32 0
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@main()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32**, i32*** @e, align 8,
> !tbaa !5
> +; IS__CGSCC____-NEXT: store i32* @g, i32** [[TMP0]], align 8, !tbaa !5
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32*, i32** @a, align 8,
> !tbaa !5
> +; IS__CGSCC____-NEXT: store i32 1, i32* [[TMP1]], align 4, !tbaa !0
> +; IS__CGSCC____-NEXT: call fastcc void @fn()
> +; IS__CGSCC____-NEXT: ret i32 0
> ;
> entry:
> %0 = load i32**, i32*** @e, align 8, !tbaa !8
>
> diff --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
> index 5e3e9881c509..d1d2c556b971 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/sret.ll
> @@ -1,19 +1,43 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=4 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-pc-windows-msvc"
>
> define internal void @add({i32, i32}* %this, i32* sret %r) {
> -; CHECK-LABEL: define {{[^@]+}}@add
> -; CHECK-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:%.*]])
> -; CHECK-NEXT: [[AP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }*
> [[THIS]], i32 0, i32 0
> -; CHECK-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32, i32 }*
> [[THIS]], i32 0, i32 1
> -; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8
> -; CHECK-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4
> -; CHECK-NEXT: [[AB:%.*]] = add i32 [[A]], [[B]]
> -; CHECK-NEXT: store i32 [[AB]], i32* [[R]], align 4
> -; CHECK-NEXT: ret void
> +;
> +; 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-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
> +; IS__TUNIT_NPM-NEXT: [[BP:%.*]] = getelementptr { i32, i32 }, { i32,
> i32 }* [[THIS]], i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = load i32, i32* [[AP]], align 8
> +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = load i32, i32* [[BP]], align 4
> +; 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____-LABEL: define {{[^@]+}}@add
> +; IS__CGSCC____-SAME: ({ i32, i32 }* nocapture nofree nonnull readonly
> align 4 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 4
> +; 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
> @@ -25,11 +49,29 @@ define internal void @add({i32, i32}* %this, i32* sret
> %r) {
> }
>
> define void @f() {
> -; CHECK-LABEL: define {{[^@]+}}@f()
> -; CHECK-NEXT: [[R:%.*]] = alloca i32
> -; CHECK-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }
> -; CHECK-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]])
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@f()
> +; IS__TUNIT_OPM-NEXT: [[R:%.*]] = alloca i32
> +; IS__TUNIT_OPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }
> +; 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-LABEL: define {{[^@]+}}@f()
> +; IS__TUNIT_NPM-NEXT: [[R:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }
> +; 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-LABEL: define {{[^@]+}}@f()
> +; IS__CGSCC_OPM-NEXT: [[R:%.*]] = alloca i32
> +; IS__CGSCC_OPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }
> +; IS__CGSCC_OPM-NEXT: call void @add({ i32, i32 }* nofree nonnull
> readonly align 8 dereferenceable(8) [[PAIR]], i32* nofree nonnull sret
> writeonly align 4 dereferenceable(4) [[R]])
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f()
> +; IS__CGSCC_NPM-NEXT: [[R:%.*]] = alloca i32
> +; IS__CGSCC_NPM-NEXT: [[PAIR:%.*]] = alloca { i32, i32 }
> +; IS__CGSCC_NPM-NEXT: call void @add({ i32, i32 }* noalias nofree
> nonnull readonly align 8 dereferenceable(8) [[PAIR]], i32* noalias 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 6141c5f3073b..7502ae651c4f 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/tail.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=4 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ; PR14710
>
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> @@ -9,29 +12,48 @@ target datalayout =
> "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> declare i8* @foo(%pair*)
>
> define internal void @bar(%pair* byval %Data) {
> -; CHECK-LABEL: define {{[^@]+}}@bar
> -; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> -; CHECK-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]]
> -; CHECK-NEXT: [[DATA_PRIV_CAST:%.*]] = bitcast %pair* [[DATA_PRIV]] to
> i32*
> -; CHECK-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]]
> -; CHECK-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]], %pair*
> [[DATA_PRIV]], i32 0, i32 1
> -; CHECK-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]]
> -; CHECK-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair* [[DATA_PRIV]])
> -; CHECK-NEXT: ret void
> +; IS________OPM-LABEL: define {{[^@]+}}@bar
> +; IS________OPM-SAME: (%pair* noalias byval [[DATA:%.*]])
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call i8* @foo(%pair*
> [[DATA]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@bar
> +; IS________NPM-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; IS________NPM-NEXT: [[DATA_PRIV:%.*]] = alloca [[PAIR:%.*]]
> +; IS________NPM-NEXT: [[DATA_PRIV_CAST:%.*]] = bitcast %pair*
> [[DATA_PRIV]] to i32*
> +; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[DATA_PRIV_CAST]]
> +; IS________NPM-NEXT: [[DATA_PRIV_0_1:%.*]] = getelementptr [[PAIR]],
> %pair* [[DATA_PRIV]], i32 0, i32 1
> +; IS________NPM-NEXT: store i32 [[TMP1]], i32* [[DATA_PRIV_0_1]]
> +; IS________NPM-NEXT: [[TMP3:%.*]] = call i8* @foo(%pair*
> [[DATA_PRIV]])
> +; IS________NPM-NEXT: ret void
> ;
> tail call i8* @foo(%pair* %Data)
> ret void
> }
>
> define void @zed(%pair* byval %Data) {
> -; CHECK-LABEL: define {{[^@]+}}@zed
> -; CHECK-SAME: (%pair* noalias nocapture readonly byval [[DATA:%.*]])
> -; CHECK-NEXT: [[DATA_CAST:%.*]] = bitcast %pair* [[DATA]] to i32*
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[DATA_CAST]], align 1
> -; CHECK-NEXT: [[DATA_0_1:%.*]] = getelementptr [[PAIR:%.*]], %pair*
> [[DATA]], i32 0, i32 1
> -; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[DATA_0_1]], align 1
> -; CHECK-NEXT: call void @bar(i32 [[TMP1]], i32 [[TMP2]])
> -; CHECK-NEXT: ret void
> +; IS________OPM-LABEL: define {{[^@]+}}@zed
> +; IS________OPM-SAME: (%pair* noalias nocapture readonly byval
> [[DATA:%.*]])
> +; IS________OPM-NEXT: call void @bar(%pair* noalias nocapture readonly
> byval [[DATA]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@zed
> +; IS__TUNIT_NPM-SAME: (%pair* noalias nocapture readonly byval
> [[DATA:%.*]])
> +; IS__TUNIT_NPM-NEXT: [[DATA_CAST:%.*]] = bitcast %pair* [[DATA]] to
> i32*
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[DATA_CAST]],
> align 1
> +; IS__TUNIT_NPM-NEXT: [[DATA_0_1:%.*]] = getelementptr [[PAIR:%.*]],
> %pair* [[DATA]], i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[DATA_0_1]],
> align 1
> +; IS__TUNIT_NPM-NEXT: call void @bar(i32 [[TMP1]], i32 [[TMP2]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@zed
> +; IS__CGSCC_NPM-SAME: (%pair* noalias nocapture nonnull readonly byval
> dereferenceable(8) [[DATA:%.*]])
> +; IS__CGSCC_NPM-NEXT: [[DATA_CAST:%.*]] = bitcast %pair* [[DATA]] to
> i32*
> +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[DATA_CAST]],
> align 1
> +; IS__CGSCC_NPM-NEXT: [[DATA_0_1:%.*]] = getelementptr [[PAIR:%.*]],
> %pair* [[DATA]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[DATA_0_1]],
> align 1
> +; IS__CGSCC_NPM-NEXT: call void @bar(i32 [[TMP1]], i32 [[TMP2]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> call void @bar(%pair* byval %Data)
> ret void
>
> diff --git
> a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
> index b637d39a50de..694c2ef250ef 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/variadic.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; Unused arguments from variadic functions cannot be eliminated as that
> changes
> ; their classiciation according to the SysV amd64 ABI. Clang and other
> frontends
> @@ -28,11 +31,17 @@ entry:
>
> ; Function Attrs: nounwind uwtable
> define internal void @callee_t0f(i8* nocapture readnone %tp13, i8*
> nocapture readnone %tp14, i8* nocapture readnone %tp15, i8* nocapture
> readnone %tp16, i8* nocapture readnone %tp17, ...) {
> -; CHECK-LABEL: define {{[^@]+}}@callee_t0f
> -; CHECK-SAME: (i8* noalias nocapture nofree nonnull readnone
> [[TP13:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP14:%.*]],
> i8* noalias nocapture nofree nonnull readnone [[TP15:%.*]], i8* noalias
> nocapture nofree nonnull readnone [[TP16:%.*]], i8* noalias nocapture
> nofree nonnull readnone [[TP17:%.*]], ...)
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: call void @sink(i32 0)
> -; CHECK-NEXT: ret void
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_t0f
> +; IS__TUNIT____-SAME: (i8* noalias nocapture nofree nonnull readnone
> [[TP13:%.*]], i8* noalias nocapture nofree nonnull readnone [[TP14:%.*]],
> i8* noalias nocapture nofree nonnull readnone [[TP15:%.*]], i8* noalias
> nocapture nofree nonnull readnone [[TP16:%.*]], i8* noalias nocapture
> nofree nonnull readnone [[TP17:%.*]], ...)
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: call void @sink(i32 0)
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_t0f
> +; IS__CGSCC____-SAME: (i8* nocapture nofree nonnull readnone
> [[TP13:%.*]], i8* nocapture nofree nonnull readnone [[TP14:%.*]], i8*
> nocapture nofree nonnull readnone [[TP15:%.*]], i8* nocapture nofree
> nonnull readnone [[TP16:%.*]], i8* nocapture nofree nonnull readnone
> [[TP17:%.*]], ...)
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: call void @sink(i32 0)
> +; IS__CGSCC____-NEXT: ret void
> ;
> entry:
> call void @sink(i32 0)
>
> 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 d05e3b113191..8669f0794826 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/2008-06-09-WeakProp.ll
> @@ -1,5 +1,9 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt < %s -passes=attributor -S | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> +
> ; Should not propagate the result of a weak function.
> ; PR2411
>
>
> 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 26b37d7a67eb..1b7b90d4471d 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,10 +1,41 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=6 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> +
> ; Don't constant-propagate byval pointers, since they are not pointers!
> ; PR5038
> %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-LABEL: define {{[^@]+}}@vfu1
> +; IS__CGSCC_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull
> writeonly byval align 4 dereferenceable(1) [[U:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = getelementptr
> [[STRUCT_MYSTR:%.*]], %struct.MYstr* [[U]], i32 0, i32 1
> +; IS__CGSCC_OPM-NEXT: store i32 99, i32* [[TMP0]], align 4
> +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* [[U]], i32 0, i32 0
> +; IS__CGSCC_OPM-NEXT: store i8 97, i8* [[TMP1]], align 4
> +; IS__CGSCC_OPM-NEXT: br label [[RETURN:%.*]]
> +; IS__CGSCC_OPM: return:
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@vfu1
> +; IS__CGSCC_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]]
> +; 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]]
> +; 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]]
> +; IS__CGSCC_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* [[U_PRIV]], i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: store i32 99, i32* [[TMP2]], align 4
> +; IS__CGSCC_NPM-NEXT: [[TMP3:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* [[U_PRIV]], i32 0, i32 0
> +; IS__CGSCC_NPM-NEXT: store i8 97, i8* [[TMP3]], align 4
> +; IS__CGSCC_NPM-NEXT: br label [[RETURN:%.*]]
> +; IS__CGSCC_NPM: return:
> +; IS__CGSCC_NPM-NEXT: ret void
> +;
> entry:
> %0 = getelementptr %struct.MYstr, %struct.MYstr* %u, i32 0, i32 1 ;
> <i32*> [#uses=1]
> store i32 99, i32* %0, align 4
> @@ -17,21 +48,42 @@ return: ;
> preds = %entry
> }
>
> define internal i32 @vfu2(%struct.MYstr* byval align 4 %u) nounwind
> readonly {
> -; CHECK-LABEL: define {{[^@]+}}@vfu2
> -; CHECK-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]]
> -; CHECK-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]]
> to i8*
> -; CHECK-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]]
> -; CHECK-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* [[U_PRIV]], i32 0, i32 1
> -; CHECK-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]]
> -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* @mystr, i32 0, i32 1
> -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]]
> -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* @mystr, i32 0, i32 0
> -; CHECK-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8
> -; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32
> -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]]
> -; CHECK-NEXT: ret i32 [[TMP7]]
> +; 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:
> +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = getelementptr
> [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, 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* @mystr, 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-LABEL: define {{[^@]+}}@vfu2
> +; IS__TUNIT_NPM-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]]
> +; 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]]
> +; 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]]
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* @mystr, 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* @mystr, 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____-LABEL: define {{[^@]+}}@vfu2()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = getelementptr
> [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP0]], align 4
> +; IS__CGSCC____-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* @mystr, i32 0, i32 0
> +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = load i8, i8* [[TMP2]], align 4
> +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i32
> +; IS__CGSCC____-NEXT: [[TMP5:%.*]] = add i32 [[TMP4]], [[TMP1]]
> +; IS__CGSCC____-NEXT: ret i32 [[TMP5]]
> ;
> entry:
> %0 = getelementptr %struct.MYstr, %struct.MYstr* %u, i32 0, i32 1 ;
> <i32*> [#uses=1]
> @@ -44,14 +96,24 @@ entry:
> }
>
> define i32 @unions() nounwind {
> -; CHECK-LABEL: define {{[^@]+}}@unions()
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8*
> -; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 1
> -; CHECK-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]],
> %struct.MYstr* @mystr, i32 0, i32 1
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 1
> -; CHECK-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP0]], i32
> [[TMP1]])
> -; CHECK-NEXT: ret i32 [[RESULT]]
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions()
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(%struct.MYstr*
> nofree nonnull readonly byval align 8 dereferenceable(8) @mystr)
> +; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions()
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr*
> @mystr to i8*
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]],
> align 1
> +; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr
> [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]],
> align 1
> +; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2(i8 [[TMP0]], i32
> [[TMP1]])
> +; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@unions()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[RESULT:%.*]] = call i32 @vfu2()
> +; IS__CGSCC____-NEXT: ret i32 [[RESULT]]
> ;
> entry:
> call void @vfu1(%struct.MYstr* byval align 4 @mystr) nounwind
> @@ -60,23 +122,67 @@ entry:
> }
>
> define internal i32 @vfu2_v2(%struct.MYstr* byval align 4 %u) nounwind
> readonly {
> -; CHECK-LABEL: define {{[^@]+}}@vfu2_v2
> -; CHECK-SAME: (i8 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[U_PRIV:%.*]] = alloca [[STRUCT_MYSTR:%.*]]
> -; CHECK-NEXT: [[U_PRIV_CAST:%.*]] = bitcast %struct.MYstr* [[U_PRIV]]
> to i8*
> -; CHECK-NEXT: store i8 [[TMP0]], i8* [[U_PRIV_CAST]]
> -; CHECK-NEXT: [[U_PRIV_0_1:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* [[U_PRIV]], i32 0, i32 1
> -; CHECK-NEXT: store i32 [[TMP1]], i32* [[U_PRIV_0_1]]
> -; CHECK-NEXT: [[Z:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* [[U_PRIV]], i32 0, i32 1
> -; CHECK-NEXT: store i32 99, i32* [[Z]], align 4
> -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* [[U_PRIV]], i32 0, i32 1
> -; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]]
> -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr [[STRUCT_MYSTR]],
> %struct.MYstr* [[U_PRIV]], i32 0, i32 0
> -; CHECK-NEXT: [[TMP5:%.*]] = load i8, i8* [[TMP4]], align 8
> -; CHECK-NEXT: [[TMP6:%.*]] = zext i8 [[TMP5]] to i32
> -; CHECK-NEXT: [[TMP7:%.*]] = add i32 [[TMP6]], [[TMP3]]
> -; CHECK-NEXT: ret i32 [[TMP7]]
> +; 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-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:%.*]]
> +; 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]]
> +; 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]]
> +; 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-LABEL: define {{[^@]+}}@vfu2_v2
> +; IS__CGSCC_OPM-SAME: (%struct.MYstr* noalias nocapture nofree nonnull
> byval align 4 dereferenceable(1) [[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 4
> +; 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-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:%.*]]
> +; 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]]
> +; 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]]
> +; 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 4
> +; 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
> @@ -91,14 +197,33 @@ entry:
> }
>
> define i32 @unions_v2() nounwind {
> -; CHECK-LABEL: define {{[^@]+}}@unions_v2()
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr* @mystr to i8*
> -; CHECK-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]], align 1
> -; CHECK-NEXT: [[MYSTR_0_1:%.*]] = getelementptr [[STRUCT_MYSTR:%.*]],
> %struct.MYstr* @mystr, i32 0, i32 1
> -; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]], align 1
> -; CHECK-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP0]], i32
> [[TMP1]])
> -; CHECK-NEXT: ret i32 [[RESULT]]
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@unions_v2()
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[RESULT:%.*]] = call i32
> @vfu2_v2(%struct.MYstr* nofree nonnull readonly byval align 8
> dereferenceable(8) @mystr)
> +; IS__TUNIT_OPM-NEXT: ret i32 [[RESULT]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@unions_v2()
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[MYSTR_CAST:%.*]] = bitcast %struct.MYstr*
> @mystr to i8*
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST]],
> align 1
> +; IS__TUNIT_NPM-NEXT: [[MYSTR_0_1:%.*]] = getelementptr
> [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_1]],
> align 1
> +; IS__TUNIT_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP0]],
> i32 [[TMP1]])
> +; IS__TUNIT_NPM-NEXT: ret i32 [[RESULT]]
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@unions_v2()
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[RESULT:%.*]] = call i32
> @vfu2_v2(%struct.MYstr* noalias nofree nonnull readnone byval align 8
> dereferenceable(8) @mystr)
> +; IS__CGSCC_OPM-NEXT: ret i32 [[RESULT]]
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@unions_v2()
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[MYSTR_CAST1:%.*]] = bitcast %struct.MYstr*
> @mystr to i8*
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i8, i8* [[MYSTR_CAST1]],
> align 8
> +; IS__CGSCC_NPM-NEXT: [[MYSTR_0_12:%.*]] = getelementptr
> [[STRUCT_MYSTR:%.*]], %struct.MYstr* @mystr, i32 0, i32 1
> +; IS__CGSCC_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[MYSTR_0_12]],
> align 1
> +; IS__CGSCC_NPM-NEXT: [[RESULT:%.*]] = call i32 @vfu2_v2(i8 [[TMP0]],
> i32 [[TMP1]])
> +; IS__CGSCC_NPM-NEXT: ret i32 [[RESULT]]
> ;
> entry:
> call void @vfu1(%struct.MYstr* byval align 4 @mystr) nounwind
>
> diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
> index e53d4fa4306b..786873f8dedf 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR16052.ll
> @@ -1,14 +1,22 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=2 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> define i64 @fn2() {
> -; CHECK-LABEL: define {{[^@]+}}@fn2()
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #1, !range !0
> -; CHECK-NEXT: ret i64 [[CALL2]]
> +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@fn2()
> +; NOT_TUNIT_NPM-NEXT: entry:
> +; NOT_TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef)
> +; NOT_TUNIT_NPM-NEXT: ret i64 [[CALL2]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2()
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 undef) #1,
> !range !0
> +; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
> ;
> entry:
> %conv = sext i32 undef to i64
> @@ -18,13 +26,21 @@ entry:
> }
>
> define i64 @fn2b(i32 %arg) {
> -; CHECK-LABEL: define {{[^@]+}}@fn2b
> -; CHECK-SAME: (i32 [[ARG:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
> -; CHECK-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
> -; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #1, !range !0
> -; CHECK-NEXT: ret i64 [[CALL2]]
> +; NOT_TUNIT_NPM-LABEL: define {{[^@]+}}@fn2b
> +; NOT_TUNIT_NPM-SAME: (i32 [[ARG:%.*]])
> +; NOT_TUNIT_NPM-NEXT: entry:
> +; NOT_TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
> +; NOT_TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
> +; NOT_TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]])
> +; NOT_TUNIT_NPM-NEXT: ret i64 [[CALL2]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2b
> +; IS__TUNIT_NPM-SAME: (i32 [[ARG:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = sext i32 [[ARG]] to i64
> +; IS__TUNIT_NPM-NEXT: [[DIV:%.*]] = sdiv i64 8, [[CONV]]
> +; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 [[DIV]]) #1,
> !range !0
> +; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
> ;
> entry:
> %conv = sext i32 %arg to i64
> @@ -34,10 +50,19 @@ entry:
> }
>
> define i64 @fn2c() {
> -; CHECK-LABEL: define {{[^@]+}}@fn2c()
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) #1, !range !0
> -; CHECK-NEXT: ret i64 [[CALL2]]
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@fn2c()
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42)
> +; IS__TUNIT_OPM-NEXT: ret i64 [[CALL2]]
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@fn2c()
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[CALL2:%.*]] = call i64 @fn1(i64 42) #1, !range
> !0
> +; IS__TUNIT_NPM-NEXT: ret i64 [[CALL2]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2c()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: ret i64 42
> ;
> entry:
> %conv = sext i32 undef to i64
>
> diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
> index cf77bbf78436..d4eef4c20642 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR26044.ll
> @@ -1,21 +1,42 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> target triple = "x86_64-unknown-linux-gnu"
>
> define void @fn2(i32* %P, i1 %C) {
> -; CHECK-LABEL: define {{[^@]+}}@fn2
> -; CHECK-SAME: (i32* nocapture nofree [[P:%.*]], i1 %C)
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: br label [[IF_END:%.*]]
> -; CHECK: for.cond1:
> -; CHECK-NEXT: br i1 %C, label %if.end, label %exit
> -; CHECK: if.end:
> -; CHECK-NEXT: [[E_2:%.*]] = phi i32* [ %P, %entry ], [ null,
> %for.cond1 ]
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
> -; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
> -; CHECK-NEXT: store i32 [[CALL]], i32* [[P]]
> -; CHECK-NEXT: br label %for.cond1
> +;
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn2
> +; IS__TUNIT____-SAME: (i32* nocapture nofree [[P:%.*]], i1 [[C:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: br label [[IF_END:%.*]]
> +; IS__TUNIT____: for.cond1:
> +; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
> +; IS__TUNIT____: if.end:
> +; IS__TUNIT____-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ],
> [ null, [[FOR_COND1:%.*]] ]
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
> +; IS__TUNIT____-NEXT: store i32 [[CALL]], i32* [[P]]
> +; IS__TUNIT____-NEXT: br label [[FOR_COND1]]
> +; IS__TUNIT____: exit:
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@fn2
> +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull align 4
> dereferenceable(4) [[P:%.*]], i1 [[C:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: br label [[IF_END:%.*]]
> +; IS__CGSCC____: for.cond1:
> +; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
> +; IS__CGSCC____: if.end:
> +; IS__CGSCC____-NEXT: [[E_2:%.*]] = phi i32* [ [[P]], [[ENTRY:%.*]] ],
> [ null, [[FOR_COND1:%.*]] ]
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[E_2]], align 4
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @fn1(i32 [[TMP0]])
> +; IS__CGSCC____-NEXT: store i32 [[CALL]], i32* [[P]], align 4
> +; IS__CGSCC____-NEXT: br label [[FOR_COND1]]
> +; IS__CGSCC____: exit:
> +; IS__CGSCC____-NEXT: ret void
> ;
> entry:
> br label %if.end
> @@ -48,18 +69,51 @@ entry:
> }
>
> define void @fn_no_null_opt(i32* %P, i1 %C)
> "null-pointer-is-valid"="true" {
> -; CHECK-LABEL: define {{[^@]+}}@fn_no_null_opt
> -; CHECK-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1 %C)
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: br label [[IF_END:%.*]]
> -; CHECK: for.cond1:
> -; CHECK-NEXT: br i1 %C, label %if.end, label %exit
> -; CHECK: if.end:
> -; CHECK-NEXT: [[E_2:%.*]] = phi i32* [ undef, %entry ], [ null,
> %for.cond1 ]
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
> -; CHECK-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
> -; CHECK-NEXT: store i32 [[CALL]], i32* [[P]]
> -; CHECK-NEXT: br label %for.cond1
> +;
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@fn_no_null_opt
> +; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i1
> [[C:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: br label [[IF_END:%.*]]
> +; IS__TUNIT____: for.cond1:
> +; IS__TUNIT____-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
> +; IS__TUNIT____: if.end:
> +; IS__TUNIT____-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ],
> [ null, [[FOR_COND1:%.*]] ]
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
> +; IS__TUNIT____-NEXT: store i32 [[CALL]], i32* [[P]]
> +; IS__TUNIT____-NEXT: br label [[FOR_COND1]]
> +; IS__TUNIT____: exit:
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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:
> +; IS__CGSCC_OPM-NEXT: br label [[IF_END:%.*]]
> +; IS__CGSCC_OPM: for.cond1:
> +; IS__CGSCC_OPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
> +; IS__CGSCC_OPM: if.end:
> +; IS__CGSCC_OPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ],
> [ null, [[FOR_COND1:%.*]] ]
> +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align 4
> +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
> +; IS__CGSCC_OPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
> +; IS__CGSCC_OPM-NEXT: br label [[FOR_COND1]]
> +; IS__CGSCC_OPM: exit:
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; 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:
> +; IS__CGSCC_NPM-NEXT: br label [[IF_END:%.*]]
> +; IS__CGSCC_NPM: for.cond1:
> +; IS__CGSCC_NPM-NEXT: br i1 [[C]], label [[IF_END]], label [[EXIT:%.*]]
> +; IS__CGSCC_NPM: if.end:
> +; IS__CGSCC_NPM-NEXT: [[E_2:%.*]] = phi i32* [ undef, [[ENTRY:%.*]] ],
> [ null, [[FOR_COND1:%.*]] ]
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32, i32* null, align
> 536870912
> +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @fn0(i32 [[TMP0]])
> +; IS__CGSCC_NPM-NEXT: store i32 [[CALL]], i32* [[P]], align 4
> +; IS__CGSCC_NPM-NEXT: br label [[FOR_COND1]]
> +; IS__CGSCC_NPM: exit:
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> br label %if.end
>
> diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll
> index 16f45449d38f..bb8283125ebe 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/PR43857.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -attributor-disable=false
> -attributor-max-iterations-verify -attributor-max-iterations=1 < %s |
> FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> %struct.wobble = type { i32 }
> %struct.zot = type { %struct.wobble, %struct.wobble, %struct.wobble }
> @@ -17,10 +20,16 @@ bb:
> }
>
> define void @baz(<8 x i32> %arg) local_unnamed_addr {
> -; CHECK-LABEL: define {{[^@]+}}@baz
> -; CHECK-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr
> -; CHECK-NEXT: bb:
> -; CHECK-NEXT: ret void
> +; 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____-LABEL: define {{[^@]+}}@baz
> +; IS__CGSCC____-SAME: (<8 x i32> [[ARG:%.*]]) local_unnamed_addr
> +; IS__CGSCC____-NEXT: bb:
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = extractvalue [[STRUCT_ZOT:%.*]]
> undef, 0, 0
> +; IS__CGSCC____-NEXT: ret void
> ;
> bb:
> %tmp = call %struct.zot @widget(<8 x i32> %arg)
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll
> index 64c9fce32300..2a6bd94e1daf 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/arg-count-mismatch.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; The original C source looked like this:
> ;
> @@ -76,11 +79,18 @@ define internal i16 @bar2(i16 %p1, i16 %p2) {
> ; been provided),
>
> define dso_local i16 @vararg_tests(i16 %a) {
> -; CHECK-LABEL: define {{[^@]+}}@vararg_tests
> -; CHECK-SAME: (i16 [[A:%.*]])
> -; CHECK-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16, ...)*
> @vararg_no_prop to i16 (i16)*)(i16 7)
> -; CHECK-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]]
> -; CHECK-NEXT: ret i16 [[ADD]]
> +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_tests
> +; NOT_CGSCC_OPM-SAME: (i16 [[A:%.*]])
> +; NOT_CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16,
> ...)* @vararg_no_prop to i16 (i16)*)(i16 7)
> +; NOT_CGSCC_OPM-NEXT: [[ADD:%.*]] = add i16 7, [[CALL2]]
> +; NOT_CGSCC_OPM-NEXT: ret i16 [[ADD]]
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@vararg_tests
> +; IS__CGSCC_OPM-SAME: (i16 [[A:%.*]])
> +; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i16 (i16, ...)
> @vararg_prop(i16 7, i16 8, i16 [[A]])
> +; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i16 bitcast (i16 (i16, i16,
> ...)* @vararg_no_prop to i16 (i16)*)(i16 7)
> +; IS__CGSCC_OPM-NEXT: [[ADD:%.*]] = add i16 [[CALL1]], [[CALL2]]
> +; IS__CGSCC_OPM-NEXT: ret i16 [[ADD]]
> ;
> %call1 = call i16 (i16, ...) @vararg_prop(i16 7, i16 8, i16 %a)
> %call2 = call i16 bitcast (i16 (i16, i16, ...) * @vararg_no_prop to i16
> (i16) *) (i16 7)
> @@ -89,6 +99,10 @@ define dso_local i16 @vararg_tests(i16 %a) {
> }
>
> define internal i16 @vararg_prop(i16 %p1, ...) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@vararg_prop
> +; IS__CGSCC____-SAME: (i16 returned [[P1:%.*]], ...)
> +; 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 a91e8eeee5ee..576a6fb9f084 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/arg-type-mismatch.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; This test is just to verify that we do not crash/assert due to mismatch
> in
> ; argument type between the caller and callee.
>
> diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll
> index 2fcde7a92288..41428b3ff5e4 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/comdat-ipo.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; See PR26774
>
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll
> index 679067650870..489ddb66da71 100644
> ---
> a/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll
> +++
> b/llvm/test/Transforms/Attributor/IPConstantProp/dangling-block-address.ll
> @@ -1,23 +1,51 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes='internalize,attributor' -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ; PR5569
>
> ; IPSCCP should prove that the blocks are dead and delete them, and
> ; properly handle the dangling blockaddress constants.
>
> -; CHECK: @bar.l = internal constant [2 x i8*] [i8* inttoptr (i32 1 to
> i8*), i8* inttoptr (i32 1 to i8*)]
> +; NOT_CGSCC_OPM: @bar.l = internal constant [2 x i8*] [i8* inttoptr (i32
> 1 to i8*), i8* inttoptr (i32 1 to i8*)]
> +; IS__CGSCC_OPM: @bar.l = internal constant [2 x i8*] [i8*
> blockaddress(@bar, %lab0), i8* blockaddress(@bar, %end)]
>
> @code = global [5 x i32] [i32 0, i32 0, i32 0, i32 0, i32 1], align 4 ;
> <[5 x i32]*> [#uses=0]
> @bar.l = internal constant [2 x i8*] [i8* blockaddress(@bar, %lab0), i8*
> blockaddress(@bar, %end)] ; <[2 x i8*]*> [#uses=1]
>
> -define void @foo(i32 %x) nounwind readnone {
> +define internal void @foo(i32 %x) nounwind readnone {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
> +; IS__CGSCC____-SAME: (i32 [[X:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4
> +; IS__CGSCC____-NEXT: store volatile i32 -1, i32* [[B]]
> +; IS__CGSCC____-NEXT: ret void
> +;
> entry:
> %b = alloca i32, align 4 ; <i32*> [#uses=1]
> store volatile i32 -1, i32* %b
> ret void
> }
>
> -define void @bar(i32* nocapture %pc) nounwind readonly {
> +define internal void @bar(i32* nocapture %pc) nounwind readonly {
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar
> +; IS__CGSCC_OPM-SAME: (i32* nocapture [[PC:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: br label [[INDIRECTGOTO:%.*]]
> +; IS__CGSCC_OPM: lab0:
> +; IS__CGSCC_OPM-NEXT: [[INDVAR_NEXT:%.*]] = add i32 [[INDVAR:%.*]], 1
> +; IS__CGSCC_OPM-NEXT: br label [[INDIRECTGOTO]]
> +; IS__CGSCC_OPM: end:
> +; IS__CGSCC_OPM-NEXT: ret void
> +; IS__CGSCC_OPM: indirectgoto:
> +; IS__CGSCC_OPM-NEXT: [[INDVAR]] = phi i32 [ [[INDVAR_NEXT]],
> [[LAB0:%.*]] ], [ 0, [[ENTRY:%.*]] ]
> +; IS__CGSCC_OPM-NEXT: [[PC_ADDR_0:%.*]] = getelementptr i32, i32*
> [[PC]], i32 [[INDVAR]]
> +; IS__CGSCC_OPM-NEXT: [[TMP1_PN:%.*]] = load i32, i32* [[PC_ADDR_0]]
> +; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST_IN:%.*]] = getelementptr
> inbounds [2 x i8*], [2 x i8*]* @bar.l, i32 0, i32 [[TMP1_PN]]
> +; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST:%.*]] = load i8*, i8**
> [[INDIRECT_GOTO_DEST_IN]]
> +; IS__CGSCC_OPM-NEXT: indirectbr i8* [[INDIRECT_GOTO_DEST]], [label
> [[LAB0]], label %end]
> +;
> entry:
> br label %indirectgoto
>
> @@ -38,6 +66,10 @@ indirectgoto: ;
> preds = %lab0, %entry
> }
>
> define i32 @main() nounwind readnone {
> +; CHECK-LABEL: define {{[^@]+}}@main()
> +; CHECK-NEXT: entry:
> +; CHECK-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 c84f4dee2487..b5742a49e64d 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/deadarg.ll
> @@ -1,6 +1,14 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 -disable-output < %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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 void @foo(i32 %X) {
> +; CHECK-LABEL: define {{[^@]+}}@foo
> +; CHECK-SAME: (i32 [[X:%.*]])
> +; CHECK-NEXT: call void @foo(i32 [[X]])
> +; CHECK-NEXT: ret void
> +;
> call void @foo( i32 %X )
> ret void
> }
>
> 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 8d8dd00cf53c..727785260f76 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,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> target datalayout = "E-m:e-i64:64-n32:64"
> target triple = "powerpc64-bgq-linux"
>
>
> diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/global.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/global.ll
> index 7b186f05976e..4326239f1932 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/global.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/global.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> @_ZL6test1g = internal global i32 42, align 4
>
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll
> index 3a3f0fe210f5..bbef0302b6ce 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/multiple_callbacks.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ;
> ;
> ; /---------------------------------------|
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
> index d14c06760cb7..fa2a136fcc73 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/musttail-call.ll
> @@ -1,26 +1,46 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=4 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ; PR36485
> ; musttail call result can't be replaced with a constant, unless the call
> can be removed
>
> declare i32 @external()
>
> define i8* @start(i8 %v) {
> -; CHECK-LABEL: define {{[^@]+}}@start
> -; CHECK-SAME: (i8 [[V:%.*]])
> -; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
> -; CHECK-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]]
> -; CHECK: true:
> -; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 [[V]])
> -; CHECK-NEXT: ret i8* [[CA]]
> -; CHECK: false:
> -; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
> -; CHECK-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label
> [[C2_FALSE:%.*]]
> -; CHECK: c2_true:
> -; CHECK-NEXT: ret i8* null
> -; CHECK: c2_false:
> -; CHECK-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 undef)
> -; CHECK-NEXT: ret i8* [[CA2]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@start
> +; IS__TUNIT____-SAME: (i8 [[V:%.*]])
> +; IS__TUNIT____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
> +; IS__TUNIT____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label
> [[FALSE:%.*]]
> +; IS__TUNIT____: true:
> +; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8
> [[V]])
> +; IS__TUNIT____-NEXT: ret i8* [[CA]]
> +; IS__TUNIT____: false:
> +; IS__TUNIT____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
> +; IS__TUNIT____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label
> [[C2_FALSE:%.*]]
> +; IS__TUNIT____: c2_true:
> +; IS__TUNIT____-NEXT: ret i8* null
> +; IS__TUNIT____: c2_false:
> +; IS__TUNIT____-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8
> undef)
> +; IS__TUNIT____-NEXT: ret i8* [[CA2]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@start
> +; IS__CGSCC____-SAME: (i8 [[V:%.*]])
> +; IS__CGSCC____-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0
> +; IS__CGSCC____-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label
> [[FALSE:%.*]]
> +; IS__CGSCC____: true:
> +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noalias align
> 536870912 i8* @side_effects(i8 [[V]])
> +; IS__CGSCC____-NEXT: ret i8* [[CA]]
> +; IS__CGSCC____: false:
> +; IS__CGSCC____-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1
> +; IS__CGSCC____-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label
> [[C2_FALSE:%.*]]
> +; IS__CGSCC____: c2_true:
> +; IS__CGSCC____-NEXT: [[CA1:%.*]] = musttail call noalias align
> 536870912 i8* @no_side_effects(i8 [[V]])
> +; IS__CGSCC____-NEXT: ret i8* [[CA1]]
> +; IS__CGSCC____: c2_false:
> +; IS__CGSCC____-NEXT: [[CA2:%.*]] = musttail call noalias align
> 536870912 i8* @dont_zap_me(i8 [[V]])
> +; IS__CGSCC____-NEXT: ret i8* [[CA2]]
> ;
> %c1 = icmp eq i8 %v, 0
> br i1 %c1, label %true, label %false
> @@ -41,11 +61,17 @@ c2_false:
> }
>
> define internal i8* @side_effects(i8 %v) {
> -; CHECK-LABEL: define {{[^@]+}}@side_effects
> -; CHECK-SAME: (i8 [[V:%.*]])
> -; CHECK-NEXT: [[I1:%.*]] = call i32 @external()
> -; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]])
> -; CHECK-NEXT: ret i8* [[CA]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@side_effects
> +; IS__TUNIT____-SAME: (i8 [[V:%.*]])
> +; IS__TUNIT____-NEXT: [[I1:%.*]] = call i32 @external()
> +; IS__TUNIT____-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 [[V]])
> +; IS__TUNIT____-NEXT: ret i8* [[CA]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@side_effects
> +; IS__CGSCC____-SAME: (i8 [[V:%.*]])
> +; IS__CGSCC____-NEXT: [[I1:%.*]] = call i32 @external()
> +; IS__CGSCC____-NEXT: [[CA:%.*]] = musttail call noalias align
> 536870912 i8* @start(i8 [[V]])
> +; IS__CGSCC____-NEXT: ret i8* [[CA]]
> ;
> %i1 = call i32 @external()
>
> @@ -60,14 +86,23 @@ define internal i8* @side_effects(i8 %v) {
> }
>
> define internal i8* @no_side_effects(i8 %v) readonly nounwind {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@no_side_effects
> +; IS__CGSCC____-SAME: (i8 [[V:%.*]])
> +; IS__CGSCC____-NEXT: ret i8* null
> +;
> ret i8* null
> }
>
> define internal i8* @dont_zap_me(i8 %v) {
> -; CHECK-LABEL: define {{[^@]+}}@dont_zap_me
> -; CHECK-SAME: (i8 [[V:%.*]])
> -; CHECK-NEXT: [[I1:%.*]] = call i32 @external()
> -; CHECK-NEXT: ret i8* undef
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_zap_me
> +; IS__TUNIT____-SAME: (i8 [[V:%.*]])
> +; IS__TUNIT____-NEXT: [[I1:%.*]] = call i32 @external()
> +; IS__TUNIT____-NEXT: ret i8* undef
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@dont_zap_me
> +; IS__CGSCC____-SAME: (i8 [[V:%.*]])
> +; IS__CGSCC____-NEXT: [[I1:%.*]] = call i32 @external()
> +; IS__CGSCC____-NEXT: ret i8* null
> ;
> %i1 = call i32 @external()
> ret i8* null
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll
> index 818f299142a5..badb82bd566f 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/naked-return.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> 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"
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
> index 1e662f1f199f..258bb0745b4c 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/openmp_parallel_for.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=3 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ;
> ; void bar(int, float, double);
> ;
> @@ -25,16 +28,49 @@ target datalayout =
> "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> @1 = private unnamed_addr global %struct.ident_t { i32 0, i32 2, i32 0,
> i32 0, i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str, i32 0, i32
> 0) }, align 8
>
> define dso_local void @foo(i32 %N) {
> -; CHECK-LABEL: define {{[^@]+}}@foo
> -; CHECK-SAME: (i32 [[N:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4
> -; CHECK-NEXT: [[P:%.*]] = alloca float, align 4
> -; CHECK-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
> -; CHECK-NEXT: store float 3.000000e+00, float* [[P]], align 4
> -; CHECK-NEXT: store i32 7, i32* [[N_ADDR]], align 4
> -; CHECK-NEXT: call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8
> dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* nonnull bitcast
> (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*,
> ...)*), i32* noalias nocapture nonnull readonly align 4 dereferenceable(4)
> [[N_ADDR]], float* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[P]], i64 undef)
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@foo
> +; IS__TUNIT_OPM-SAME: (i32 [[N:%.*]])
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4
> +; IS__TUNIT_OPM-NEXT: [[P:%.*]] = alloca float, align 4
> +; IS__TUNIT_OPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
> +; IS__TUNIT_OPM-NEXT: store float 3.000000e+00, float* [[P]], align 4
> +; IS__TUNIT_OPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4
> +; IS__TUNIT_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*,
> i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8
> dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* nonnull bitcast
> (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*,
> ...)*), i32* nocapture nonnull readonly align 4 dereferenceable(4)
> [[N_ADDR]], float* nocapture nonnull readonly align 4 dereferenceable(4)
> [[P]], i64 undef)
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@foo
> +; IS__TUNIT_NPM-SAME: (i32 [[N:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4
> +; IS__TUNIT_NPM-NEXT: [[P:%.*]] = alloca float, align 4
> +; IS__TUNIT_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
> +; IS__TUNIT_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4
> +; IS__TUNIT_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4
> +; IS__TUNIT_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*,
> i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8
> dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* nonnull bitcast
> (void (i32*, i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*,
> ...)*), i32* noalias nocapture nonnull readonly align 4 dereferenceable(4)
> [[N_ADDR]], float* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[P]], i64 undef)
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@foo
> +; IS__CGSCC_OPM-SAME: (i32 [[N:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4
> +; IS__CGSCC_OPM-NEXT: [[P:%.*]] = alloca float, align 4
> +; IS__CGSCC_OPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
> +; IS__CGSCC_OPM-NEXT: store float 3.000000e+00, float* [[P]], align 4
> +; IS__CGSCC_OPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4
> +; IS__CGSCC_OPM-NEXT: call void (%struct.ident_t*, i32, void (i32*,
> i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8
> dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* bitcast (void (i32*,
> i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32*
> nonnull align 4 dereferenceable(4) [[N_ADDR]], float* nonnull align 4
> dereferenceable(4) [[P]], i64 4617315517961601024)
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo
> +; IS__CGSCC_NPM-SAME: (i32 [[N:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[N_ADDR:%.*]] = alloca i32, align 4
> +; IS__CGSCC_NPM-NEXT: [[P:%.*]] = alloca float, align 4
> +; IS__CGSCC_NPM-NEXT: store i32 [[N]], i32* [[N_ADDR]], align 4
> +; IS__CGSCC_NPM-NEXT: store float 3.000000e+00, float* [[P]], align 4
> +; IS__CGSCC_NPM-NEXT: store i32 7, i32* [[N_ADDR]], align 4
> +; IS__CGSCC_NPM-NEXT: call void (%struct.ident_t*, i32, void (i32*,
> i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* nonnull align 8
> dereferenceable(24) @1, i32 3, void (i32*, i32*, ...)* bitcast (void (i32*,
> i32*, i32*, float*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i32*
> noalias nocapture nonnull readonly align 4 dereferenceable(4) [[N_ADDR]],
> float* noalias nocapture nonnull readonly align 4 dereferenceable(4) [[P]],
> i64 4617315517961601024)
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> %N.addr = alloca i32, align 4
> @@ -47,13 +83,195 @@ entry:
> }
>
> define internal void @.omp_outlined.(i32* noalias %.global_tid., i32*
> noalias %.bound_tid., i32* dereferenceable(4) %N, float* dereferenceable(4)
> %p, i64 %q) {
> +; IS________OPM-LABEL: define {{[^@]+}}@.omp_outlined.
> +; IS________OPM-SAME: (i32* noalias nocapture readonly
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]], i32* nocapture nonnull readonly align 4
> dereferenceable(4) [[N:%.*]], float* nocapture nonnull readonly align 4
> dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]])
> +; IS________OPM-NEXT: entry:
> +; IS________OPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8
> +; IS________OPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
> +; IS________OPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
> +; IS________OPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
> +; IS________OPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
> +; IS________OPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]],
> align 8
> +; IS________OPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
> +; IS________OPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4
> +; IS________OPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3
> +; IS________OPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2
> +; IS________OPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]],
> label [[OMP_PRECOND_END:%.*]]
> +; IS________OPM: omp.precond.then:
> +; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
> +; IS________OPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4
> +; IS________OPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
> +; IS________OPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
> +; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32*
> [[DOTGLOBAL_TID_]], align 4
> +; IS________OPM-NEXT: call void
> @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8
> dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4
> dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4
> dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4)
> [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]],
> i32 1, i32 1)
> +; IS________OPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS________OPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]]
> +; IS________OPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; IS________OPM: cond.true:
> +; IS________OPM-NEXT: br label [[COND_END:%.*]]
> +; IS________OPM: cond.false:
> +; IS________OPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS________OPM-NEXT: br label [[COND_END]]
> +; IS________OPM: cond.end:
> +; IS________OPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]]
> ], [ [[TMP7]], [[COND_FALSE]] ]
> +; IS________OPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
> +; IS________OPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]],
> align 4
> +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
> +; IS________OPM: omp.inner.for.cond:
> +; IS________OPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]],
> [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ]
> +; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS________OPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]],
> [[TMP9]]
> +; IS________OPM-NEXT: br i1 [[CMP8]], label
> [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]]
> +; IS________OPM: omp.inner.for.cond.cleanup:
> +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
> +; IS________OPM: omp.inner.for.body:
> +; IS________OPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
> +; IS________OPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4
> +; IS________OPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]],
> align 8
> +; IS________OPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]],
> double [[TMP11]])
> +; IS________OPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
> +; IS________OPM: omp.body.continue:
> +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_INC]]
> +; IS________OPM: omp.inner.for.inc:
> +; IS________OPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1
> +; IS________OPM-NEXT: br label [[OMP_INNER_FOR_COND]]
> +; IS________OPM: omp.inner.for.end:
> +; IS________OPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
> +; IS________OPM: omp.loop.exit:
> +; IS________OPM-NEXT: [[TMP12:%.*]] = load i32, i32*
> [[DOTGLOBAL_TID_]], align 4
> +; IS________OPM-NEXT: call void
> @__kmpc_for_static_fini(%struct.ident_t* nonnull align 8
> dereferenceable(24) @0, i32 [[TMP12]])
> +; IS________OPM-NEXT: br label [[OMP_PRECOND_END]]
> +; IS________OPM: omp.precond.end:
> +; IS________OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@.omp_outlined.
> +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture readonly
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]], i32* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[N:%.*]], float* noalias nocapture nonnull readonly
> align 4 dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8
> +; IS__TUNIT_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
> +; IS__TUNIT_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
> +; IS__TUNIT_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
> +; IS__TUNIT_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
> +; IS__TUNIT_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]],
> align 8
> +; IS__TUNIT_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
> +; IS__TUNIT_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4
> +; IS__TUNIT_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3
> +; IS__TUNIT_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2
> +; IS__TUNIT_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]],
> label [[OMP_PRECOND_END:%.*]]
> +; IS__TUNIT_NPM: omp.precond.then:
> +; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
> +; IS__TUNIT_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4
> +; IS__TUNIT_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
> +; IS__TUNIT_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP5:%.*]] = load i32, i32*
> [[DOTGLOBAL_TID_]], align 4
> +; IS__TUNIT_NPM-NEXT: call void
> @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8
> dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4
> dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4
> dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4)
> [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]],
> i32 1, i32 1)
> +; IS__TUNIT_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS__TUNIT_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]]
> +; IS__TUNIT_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; IS__TUNIT_NPM: cond.true:
> +; IS__TUNIT_NPM-NEXT: br label [[COND_END:%.*]]
> +; IS__TUNIT_NPM: cond.false:
> +; IS__TUNIT_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS__TUNIT_NPM-NEXT: br label [[COND_END]]
> +; IS__TUNIT_NPM: cond.end:
> +; IS__TUNIT_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]]
> ], [ [[TMP7]], [[COND_FALSE]] ]
> +; IS__TUNIT_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]],
> align 4
> +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
> +; IS__TUNIT_NPM: omp.inner.for.cond:
> +; IS__TUNIT_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]],
> [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ]
> +; IS__TUNIT_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS__TUNIT_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]],
> [[TMP9]]
> +; IS__TUNIT_NPM-NEXT: br i1 [[CMP8]], label
> [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]]
> +; IS__TUNIT_NPM: omp.inner.for.cond.cleanup:
> +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
> +; IS__TUNIT_NPM: omp.inner.for.body:
> +; IS__TUNIT_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
> +; IS__TUNIT_NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]],
> align 8
> +; IS__TUNIT_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]],
> double [[TMP11]])
> +; IS__TUNIT_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
> +; IS__TUNIT_NPM: omp.body.continue:
> +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_INC]]
> +; IS__TUNIT_NPM: omp.inner.for.inc:
> +; IS__TUNIT_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1
> +; IS__TUNIT_NPM-NEXT: br label [[OMP_INNER_FOR_COND]]
> +; IS__TUNIT_NPM: omp.inner.for.end:
> +; IS__TUNIT_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
> +; IS__TUNIT_NPM: omp.loop.exit:
> +; IS__TUNIT_NPM-NEXT: [[TMP12:%.*]] = load i32, i32*
> [[DOTGLOBAL_TID_]], align 4
> +; IS__TUNIT_NPM-NEXT: call void
> @__kmpc_for_static_fini(%struct.ident_t* nonnull align 8
> dereferenceable(24) @0, i32 [[TMP12]])
> +; IS__TUNIT_NPM-NEXT: br label [[OMP_PRECOND_END]]
> +; IS__TUNIT_NPM: omp.precond.end:
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@.omp_outlined.
> +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture readonly
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]], i32* nocapture nonnull readonly align 4
> dereferenceable(4) [[N:%.*]], float* nocapture nonnull readonly
> dereferenceable(4) [[P:%.*]], i64 [[Q:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[Q_ADDR:%.*]] = alloca i64, align 8
> +; IS__CGSCC_NPM-NEXT: [[DOTOMP_LB:%.*]] = alloca i32, align 4
> +; IS__CGSCC_NPM-NEXT: [[DOTOMP_UB:%.*]] = alloca i32, align 4
> +; IS__CGSCC_NPM-NEXT: [[DOTOMP_STRIDE:%.*]] = alloca i32, align 4
> +; IS__CGSCC_NPM-NEXT: [[DOTOMP_IS_LAST:%.*]] = alloca i32, align 4
> +; IS__CGSCC_NPM-NEXT: store i64 4617315517961601024, i64* [[Q_ADDR]],
> align 8
> +; IS__CGSCC_NPM-NEXT: [[CONV:%.*]] = bitcast i64* [[Q_ADDR]] to double*
> +; IS__CGSCC_NPM-NEXT: [[TMP:%.*]] = load i32, i32* [[N]], align 4
> +; IS__CGSCC_NPM-NEXT: [[SUB3:%.*]] = add nsw i32 [[TMP]], -3
> +; IS__CGSCC_NPM-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP]], 2
> +; IS__CGSCC_NPM-NEXT: br i1 [[CMP]], label [[OMP_PRECOND_THEN:%.*]],
> label [[OMP_PRECOND_END:%.*]]
> +; IS__CGSCC_NPM: omp.precond.then:
> +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[DOTOMP_LB]], align 4
> +; IS__CGSCC_NPM-NEXT: store i32 [[SUB3]], i32* [[DOTOMP_UB]], align 4
> +; IS__CGSCC_NPM-NEXT: store i32 1, i32* [[DOTOMP_STRIDE]], align 4
> +; IS__CGSCC_NPM-NEXT: store i32 0, i32* [[DOTOMP_IS_LAST]], align 4
> +; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = load i32, i32*
> [[DOTGLOBAL_TID_]], align 4
> +; IS__CGSCC_NPM-NEXT: call void
> @__kmpc_for_static_init_4(%struct.ident_t* nonnull align 8
> dereferenceable(24) @0, i32 [[TMP5]], i32 34, i32* nonnull align 4
> dereferenceable(4) [[DOTOMP_IS_LAST]], i32* nonnull align 4
> dereferenceable(4) [[DOTOMP_LB]], i32* nonnull align 4 dereferenceable(4)
> [[DOTOMP_UB]], i32* nonnull align 4 dereferenceable(4) [[DOTOMP_STRIDE]],
> i32 1, i32 1)
> +; IS__CGSCC_NPM-NEXT: [[TMP6:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS__CGSCC_NPM-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[TMP6]], [[SUB3]]
> +; IS__CGSCC_NPM-NEXT: br i1 [[CMP6]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; IS__CGSCC_NPM: cond.true:
> +; IS__CGSCC_NPM-NEXT: br label [[COND_END:%.*]]
> +; IS__CGSCC_NPM: cond.false:
> +; IS__CGSCC_NPM-NEXT: [[TMP7:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS__CGSCC_NPM-NEXT: br label [[COND_END]]
> +; IS__CGSCC_NPM: cond.end:
> +; IS__CGSCC_NPM-NEXT: [[COND:%.*]] = phi i32 [ [[SUB3]], [[COND_TRUE]]
> ], [ [[TMP7]], [[COND_FALSE]] ]
> +; IS__CGSCC_NPM-NEXT: store i32 [[COND]], i32* [[DOTOMP_UB]], align 4
> +; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = load i32, i32* [[DOTOMP_LB]],
> align 4
> +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_COND:%.*]]
> +; IS__CGSCC_NPM: omp.inner.for.cond:
> +; IS__CGSCC_NPM-NEXT: [[DOTOMP_IV_0:%.*]] = phi i32 [ [[TMP8]],
> [[COND_END]] ], [ [[ADD11:%.*]], [[OMP_INNER_FOR_INC:%.*]] ]
> +; IS__CGSCC_NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[DOTOMP_UB]],
> align 4
> +; IS__CGSCC_NPM-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[DOTOMP_IV_0]],
> [[TMP9]]
> +; IS__CGSCC_NPM-NEXT: br i1 [[CMP8]], label
> [[OMP_INNER_FOR_COND_CLEANUP:%.*]], label [[OMP_INNER_FOR_BODY:%.*]]
> +; IS__CGSCC_NPM: omp.inner.for.cond.cleanup:
> +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_END:%.*]]
> +; IS__CGSCC_NPM: omp.inner.for.body:
> +; IS__CGSCC_NPM-NEXT: [[ADD10:%.*]] = add nsw i32 [[DOTOMP_IV_0]], 2
> +; IS__CGSCC_NPM-NEXT: [[TMP10:%.*]] = load float, float* [[P]], align 4
> +; IS__CGSCC_NPM-NEXT: [[TMP11:%.*]] = load double, double* [[CONV]],
> align 8
> +; IS__CGSCC_NPM-NEXT: call void @bar(i32 [[ADD10]], float [[TMP10]],
> double [[TMP11]])
> +; IS__CGSCC_NPM-NEXT: br label [[OMP_BODY_CONTINUE:%.*]]
> +; IS__CGSCC_NPM: omp.body.continue:
> +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_INC]]
> +; IS__CGSCC_NPM: omp.inner.for.inc:
> +; IS__CGSCC_NPM-NEXT: [[ADD11]] = add nsw i32 [[DOTOMP_IV_0]], 1
> +; IS__CGSCC_NPM-NEXT: br label [[OMP_INNER_FOR_COND]]
> +; IS__CGSCC_NPM: omp.inner.for.end:
> +; IS__CGSCC_NPM-NEXT: br label [[OMP_LOOP_EXIT:%.*]]
> +; IS__CGSCC_NPM: omp.loop.exit:
> +; IS__CGSCC_NPM-NEXT: [[TMP12:%.*]] = load i32, i32*
> [[DOTGLOBAL_TID_]], align 4
> +; IS__CGSCC_NPM-NEXT: call void
> @__kmpc_for_static_fini(%struct.ident_t* nonnull align 8
> dereferenceable(24) @0, i32 [[TMP12]])
> +; IS__CGSCC_NPM-NEXT: br label [[OMP_PRECOND_END]]
> +; IS__CGSCC_NPM: omp.precond.end:
> +; IS__CGSCC_NPM-NEXT: ret void
> +;
> entry:
> %q.addr = alloca i64, align 8
> %.omp.lb = alloca i32, align 4
> %.omp.ub = alloca i32, align 4
> %.omp.stride = alloca i32, align 4
> %.omp.is_last = alloca i32, align 4
> -; CHECK: store i64 4617315517961601024, i64* %q.addr, align 8
> store i64 %q, i64* %q.addr, align 8
> %conv = bitcast i64* %q.addr to double*
> %tmp = load i32, i32* %N, align 4
>
> diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
> index 12fb1234c9c6..4399f3a37a8b 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/pthreads.ll
> @@ -1,6 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> --check-prefixes=CHECK,MODULE
> -; RUN: opt -S -passes=attributor-cgscc -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> --check-prefixes=CHECK,CGSCC
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ;
> ; #include <pthread.h>
> ;
> @@ -29,27 +31,38 @@ target datalayout =
> "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> ; FIXME: nocapture & noalias for %alloc2 in %call3
>
> define dso_local i32 @main() {
> -; MODULE-LABEL: define {{[^@]+}}@main()
> -; MODULE-NEXT: entry:
> -; MODULE-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8
> -; MODULE-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
> -; MODULE-NEXT: [[THREAD:%.*]] = alloca i64, align 8
> -; MODULE-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull
> align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align
> 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone align
> 536870912 undef)
> -; MODULE-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull
> align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align
> 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree nonnull
> readnone align 8 dereferenceable(8) undef)
> -; MODULE-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull
> align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align
> 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree
> nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
> -; MODULE-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull
> align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align
> 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree nonnull
> readnone align 8 dereferenceable(1) [[ALLOC2]])
> -; MODULE-NEXT: ret i32 0
> -;
> -; CGSCC-LABEL: define {{[^@]+}}@main()
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8
> -; CGSCC-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
> -; CGSCC-NEXT: [[THREAD:%.*]] = alloca i64, align 8
> -; CGSCC-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64* nonnull
> align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align
> 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree readnone align
> 536870912 null)
> -; CGSCC-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64* nonnull
> align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align
> 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree nonnull
> readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
> -; CGSCC-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64* nonnull
> align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align
> 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias nocapture nofree
> nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
> -; CGSCC-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64* nonnull
> align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t* noalias align
> 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree nonnull
> readnone align 8 dereferenceable(1) [[ALLOC2]])
> -; CGSCC-NEXT: ret i32 0
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@main()
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8
> +; IS__TUNIT____-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
> +; IS__TUNIT____-NEXT: [[THREAD:%.*]] = alloca i64, align 8
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree
> readnone align 536870912 undef)
> +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree
> nonnull readnone align 8 dereferenceable(8) undef)
> +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias
> nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
> +; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree
> nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned"
> [[ALLOC2]])
> +; IS__TUNIT____-NEXT: ret i32 0
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@main()
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8
> +; IS__CGSCC_OPM-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
> +; IS__CGSCC_OPM-NEXT: [[THREAD:%.*]] = alloca i64, align 8
> +; IS__CGSCC_OPM-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias align
> 536870912 null)
> +; IS__CGSCC_OPM-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* nonnull align 8
> dereferenceable(8) bitcast (i8** @GlobalVPtr to i8*))
> +; IS__CGSCC_OPM-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* nocapture
> nonnull align 8 dereferenceable(1) [[ALLOC1]])
> +; IS__CGSCC_OPM-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* nonnull align 8
> dereferenceable(1) [[ALLOC2]])
> +; IS__CGSCC_OPM-NEXT: ret i32 0
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@main()
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8
> +; IS__CGSCC_NPM-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8
> +; IS__CGSCC_NPM-NEXT: [[THREAD:%.*]] = alloca i64, align 8
> +; IS__CGSCC_NPM-NEXT: [[CALL:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @foo, i8* noalias nofree
> readnone align 536870912 null)
> +; IS__CGSCC_NPM-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @bar, i8* noalias nofree
> nonnull readnone align 8 dereferenceable(8) bitcast (i8** @GlobalVPtr to
> i8*))
> +; IS__CGSCC_NPM-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @baz, i8* noalias
> nocapture nofree nonnull readnone align 8 dereferenceable(1) [[ALLOC1]])
> +; IS__CGSCC_NPM-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(i64*
> nonnull align 8 dereferenceable(8) [[THREAD]], %union.pthread_attr_t*
> noalias align 536870912 null, i8* (i8*)* nonnull @buz, i8* noalias nofree
> nonnull readnone align 8 dereferenceable(1) [[ALLOC2]])
> +; IS__CGSCC_NPM-NEXT: ret i32 0
> ;
> entry:
> %alloc1 = alloca i8, align 8
> @@ -65,60 +78,75 @@ entry:
> declare !callback !0 dso_local i32 @pthread_create(i64*,
> %union.pthread_attr_t*, i8* (i8*)*, i8*)
>
> define internal i8* @foo(i8* %arg) {
> -; MODULE-LABEL: define {{[^@]+}}@foo
> -; MODULE-SAME: (i8* noalias nofree readnone returned align 536870912
> [[ARG:%.*]])
> -; MODULE-NEXT: entry:
> -; MODULE-NEXT: ret i8* null
> +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@foo
> +; NOT_CGSCC_NPM-SAME: (i8* noalias nofree readnone returned align
> 536870912 "no-capture-maybe-returned" [[ARG:%.*]])
> +; NOT_CGSCC_NPM-NEXT: entry:
> +; NOT_CGSCC_NPM-NEXT: ret i8* null
> ;
> -; CGSCC-LABEL: define {{[^@]+}}@foo
> -; CGSCC-SAME: (i8* noalias nofree readnone returned [[ARG:%.*]])
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: ret i8* null
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@foo
> +; IS__CGSCC_NPM-SAME: (i8* noalias nofree readnone returned
> "no-capture-maybe-returned" [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: ret i8* null
> ;
> entry:
> ret i8* %arg
> }
>
> define internal i8* @bar(i8* %arg) {
> -; MODULE-LABEL: define {{[^@]+}}@bar
> -; MODULE-SAME: (i8* noalias nofree nonnull readnone returned align 8
> dereferenceable(8) [[ARG:%.*]])
> -; MODULE-NEXT: entry:
> -; MODULE-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
> +; 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*)
> ;
> -; CGSCC-LABEL: define {{[^@]+}}@bar
> -; CGSCC-SAME: (i8* nofree readnone returned [[ARG:%.*]])
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@bar
> +; IS__CGSCC_OPM-SAME: (i8* nofree nonnull readnone returned align 8
> dereferenceable(8) "no-capture-maybe-returned" [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@bar
> +; IS__CGSCC_NPM-SAME: (i8* nofree readnone returned
> "no-capture-maybe-returned" [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: ret i8* bitcast (i8** @GlobalVPtr to i8*)
> ;
> entry:
> ret i8* %arg
> }
>
> define internal i8* @baz(i8* %arg) {
> -; MODULE-LABEL: define {{[^@]+}}@baz
> -; MODULE-SAME: (i8* noalias nofree nonnull readnone returned align 8
> dereferenceable(1) [[ARG:%.*]])
> -; MODULE-NEXT: entry:
> -; MODULE-NEXT: ret i8* [[ARG]]
> +; 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_OPM-LABEL: define {{[^@]+}}@baz
> +; IS__CGSCC_OPM-SAME: (i8* nofree nonnull readnone returned align 8
> dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: ret i8* [[ARG]]
> ;
> -; CGSCC-LABEL: define {{[^@]+}}@baz
> -; CGSCC-SAME: (i8* nofree readnone returned [[ARG:%.*]])
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: ret i8* [[ARG]]
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@baz
> +; IS__CGSCC_NPM-SAME: (i8* nofree readnone returned
> "no-capture-maybe-returned" [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: ret i8* [[ARG]]
> ;
> entry:
> ret i8* %arg
> }
>
> define internal i8* @buz(i8* %arg) {
> -; MODULE-LABEL: define {{[^@]+}}@buz
> -; MODULE-SAME: (i8* noalias nofree nonnull readnone returned align 8
> dereferenceable(1) [[ARG:%.*]])
> -; MODULE-NEXT: entry:
> -; MODULE-NEXT: ret i8* [[ARG]]
> -;
> -; CGSCC-LABEL: define {{[^@]+}}@buz
> -; CGSCC-SAME: (i8* nofree readnone returned [[ARG:%.*]])
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: ret i8* [[ARG]]
> +; 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_OPM-LABEL: define {{[^@]+}}@buz
> +; IS__CGSCC_OPM-SAME: (i8* nofree nonnull readnone returned align 8
> dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: ret i8* [[ARG]]
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@buz
> +; IS__CGSCC_NPM-SAME: (i8* nofree readnone returned
> "no-capture-maybe-returned" [[ARG:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: ret i8* [[ARG]]
> ;
> entry:
> ret i8* %arg
>
> diff --git a/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll
> index 831c0c6ebb98..1351d3117853 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/recursion.ll
> @@ -1,9 +1,15 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; CHECK-NOT: %X
>
> define internal i32 @foo(i32 %X) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo()
> +; IS__CGSCC____-NEXT: unreachable
> +;
> %Y = call i32 @foo( i32 %X ) ; <i32> [#uses=1]
> %Z = add i32 %Y, 1 ; <i32> [#uses=1]
> ret i32 %Z
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll
> index 9420f53980cb..5b11512f9b6d 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/remove-call-inst.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ; PR5596
>
> ; IPSCCP should propagate the 0 argument, eliminate the switch, and
> propagate
> @@ -18,6 +21,17 @@ entry:
> }
>
> define internal i32 @wwrite(i64 %i) nounwind readnone {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@wwrite()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
> +; IS__CGSCC____-NEXT: i64 3, label [[RETURN:%.*]]
> +; IS__CGSCC____-NEXT: i64 10, label [[RETURN]]
> +; IS__CGSCC____-NEXT: ]
> +; IS__CGSCC____: sw.default:
> +; IS__CGSCC____-NEXT: ret i32 123
> +; IS__CGSCC____: return:
> +; IS__CGSCC____-NEXT: unreachable
> +;
> entry:
> switch i64 %i, label %sw.default [
> i64 3, label %return
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
> index 05b0107a3bb4..80c0ba7b5fb7 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-argument.ll
> @@ -1,20 +1,36 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=8 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ;; This function returns its second argument on all return statements
> define internal i32* @incdec(i1 %C, i32* %V) {
> -; CHECK-LABEL: define {{[^@]+}}@incdec
> -; CHECK-SAME: (i1 [[C:%.*]], i32* noalias nofree nonnull returned align 4
> dereferenceable(4) [[V:%.*]])
> -; CHECK-NEXT: [[X:%.*]] = load i32, i32* [[V]], align 4
> -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
> -; CHECK: T:
> -; CHECK-NEXT: [[X1:%.*]] = add i32 [[X]], 1
> -; CHECK-NEXT: store i32 [[X1]], i32* [[V]], align 4
> -; CHECK-NEXT: ret i32* [[V]]
> -; CHECK: F:
> -; CHECK-NEXT: [[X2:%.*]] = sub i32 [[X]], 1
> -; CHECK-NEXT: store i32 [[X2]], i32* [[V]], align 4
> -; CHECK-NEXT: ret i32* [[V]]
> +; 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
> +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
> +; IS__TUNIT____: T:
> +; IS__TUNIT____-NEXT: [[X1:%.*]] = add i32 [[X]], 1
> +; IS__TUNIT____-NEXT: store i32 [[X1]], i32* [[V]], align 4
> +; IS__TUNIT____-NEXT: ret i32* [[V]]
> +; IS__TUNIT____: F:
> +; IS__TUNIT____-NEXT: [[X2:%.*]] = sub i32 [[X]], 1
> +; IS__TUNIT____-NEXT: store i32 [[X2]], i32* [[V]], align 4
> +; IS__TUNIT____-NEXT: ret i32* [[V]]
> +;
> +; 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
> +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
> +; IS__CGSCC____: T:
> +; IS__CGSCC____-NEXT: [[X1:%.*]] = add i32 [[X]], 1
> +; IS__CGSCC____-NEXT: store i32 [[X1]], i32* [[V]], align 4
> +; IS__CGSCC____-NEXT: ret i32* [[V]]
> +; IS__CGSCC____: F:
> +; IS__CGSCC____-NEXT: [[X2:%.*]] = sub i32 [[X]], 1
> +; IS__CGSCC____-NEXT: store i32 [[X2]], i32* [[V]], align 4
> +; IS__CGSCC____-NEXT: ret i32* [[V]]
> ;
> %X = load i32, i32* %V
> br i1 %C, label %T, label %F
> @@ -47,25 +63,43 @@ define internal { i32, i32 } @foo(i32 %A, i32 %B) {
> }
>
> define void @caller(i1 %C) personality i32 (...)* @__gxx_personality_v0 {
> -; CHECK-LABEL: define {{[^@]+}}@caller
> -; CHECK-SAME: (i1 [[C:%.*]]) #2 personality i32 (...)*
> @__gxx_personality_v0
> -; CHECK-NEXT: [[Q:%.*]] = alloca i32
> -; CHECK-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]], i32*
> noalias nofree nonnull align 4 dereferenceable(4) [[Q]])
> -; CHECK-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2)
> -; CHECK-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
> -; CHECK-NEXT: [[S2:%.*]] = invoke { i32, i32 } @foo(i32 3, i32 4)
> -; CHECK-NEXT: to label [[OK:%.*]] unwind label [[LPAD:%.*]]
> -; CHECK: OK:
> -; CHECK-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
> -; CHECK-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
> -; CHECK-NEXT: store i32 [[Z]], i32* [[W]], align 4
> -; CHECK-NEXT: br label [[RET:%.*]]
> -; CHECK: LPAD:
> -; CHECK-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 }
> -; CHECK-NEXT: cleanup
> -; CHECK-NEXT: br label [[RET]]
> -; CHECK: RET:
> -; CHECK-NEXT: ret void
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller
> +; IS__TUNIT____-SAME: (i1 [[C:%.*]]) #2 personality i32 (...)*
> @__gxx_personality_v0
> +; IS__TUNIT____-NEXT: [[Q:%.*]] = alloca i32
> +; IS__TUNIT____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]],
> i32* noalias nofree nonnull align 4 dereferenceable(4)
> "no-capture-maybe-returned" [[Q]])
> +; IS__TUNIT____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2)
> +; IS__TUNIT____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
> +; IS__TUNIT____-NEXT: [[S2:%.*]] = invoke { i32, i32 } @foo(i32 3, i32
> 4)
> +; IS__TUNIT____-NEXT: to label [[OK:%.*]] unwind label [[LPAD:%.*]]
> +; IS__TUNIT____: OK:
> +; IS__TUNIT____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
> +; IS__TUNIT____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
> +; IS__TUNIT____-NEXT: store i32 [[Z]], i32* [[W]], align 4
> +; IS__TUNIT____-NEXT: br label [[RET:%.*]]
> +; IS__TUNIT____: LPAD:
> +; IS__TUNIT____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 }
> +; IS__TUNIT____-NEXT: cleanup
> +; IS__TUNIT____-NEXT: br label [[RET]]
> +; IS__TUNIT____: RET:
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller
> +; IS__CGSCC____-SAME: (i1 [[C:%.*]]) #1 personality i32 (...)*
> @__gxx_personality_v0
> +; IS__CGSCC____-NEXT: [[Q:%.*]] = alloca i32
> +; IS__CGSCC____-NEXT: [[W:%.*]] = call align 4 i32* @incdec(i1 [[C]],
> i32* noalias nofree nonnull align 4 dereferenceable(4) [[Q]])
> +; IS__CGSCC____-NEXT: [[S1:%.*]] = call { i32, i32 } @foo(i32 1, i32 2)
> +; IS__CGSCC____-NEXT: [[X1:%.*]] = extractvalue { i32, i32 } [[S1]], 0
> +; IS__CGSCC____-NEXT: [[S2:%.*]] = call { i32, i32 } @foo(i32 3, i32 4)
> +; IS__CGSCC____-NEXT: br label [[OK:%.*]]
> +; IS__CGSCC____: OK:
> +; IS__CGSCC____-NEXT: [[X2:%.*]] = extractvalue { i32, i32 } [[S2]], 0
> +; IS__CGSCC____-NEXT: [[Z:%.*]] = add i32 [[X1]], [[X2]]
> +; IS__CGSCC____-NEXT: store i32 [[Z]], i32* [[W]], align 4
> +; IS__CGSCC____-NEXT: br label [[RET:%.*]]
> +; IS__CGSCC____: LPAD:
> +; IS__CGSCC____-NEXT: unreachable
> +; IS__CGSCC____: RET:
> +; IS__CGSCC____-NEXT: ret void
> ;
> %Q = alloca i32
> ;; Call incdec to see if %W is properly replaced by %Q
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll
> index 1810b07e7549..d7c5e9278a81 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constant.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; FIXME: icmp folding is missing
>
> @@ -24,13 +27,21 @@ FAIL:
> }
>
> define internal i32 @foo(i1 %C) {
> -; CHECK-LABEL: define {{[^@]+}}@foo
> -; CHECK-SAME: (i1 [[C:%.*]])
> -; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
> -; CHECK: T:
> -; CHECK-NEXT: ret i32 undef
> -; CHECK: F:
> -; CHECK-NEXT: ret i32 undef
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@foo
> +; IS__TUNIT____-SAME: (i1 [[C:%.*]])
> +; IS__TUNIT____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
> +; IS__TUNIT____: T:
> +; IS__TUNIT____-NEXT: ret i32 undef
> +; IS__TUNIT____: F:
> +; IS__TUNIT____-NEXT: ret i32 undef
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@foo
> +; IS__CGSCC____-SAME: (i1 [[C:%.*]])
> +; IS__CGSCC____-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
> +; IS__CGSCC____: T:
> +; IS__CGSCC____-NEXT: ret i32 52
> +; IS__CGSCC____: F:
> +; IS__CGSCC____-NEXT: ret i32 52
> ;
> br i1 %C, label %T, label %F
>
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
> index d53b11b4fc4c..51d94f7be855 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/return-constants.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=7 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ;; FIXME: support for extractvalue and insertvalue missing.
>
>
> 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 b5663c9c8c13..6ed063662dfa 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,7 +1,21 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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____-LABEL: define {{[^@]+}}@testf
> +; IS__CGSCC____-SAME: (i1 [[C:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: br i1 [[C]], label [[IF_COND:%.*]], label
> [[IF_END:%.*]]
> +; IS__CGSCC____: if.cond:
> +; IS__CGSCC____-NEXT: unreachable
> +; IS__CGSCC____: if.then:
> +; IS__CGSCC____-NEXT: unreachable
> +; IS__CGSCC____: if.end:
> +; IS__CGSCC____-NEXT: ret i32 10
> +;
> entry:
> br i1 %c, label %if.cond, label %if.end
>
> @@ -16,6 +30,17 @@ if.end: ;
> preds = %if.then1, %entry
> }
>
> define internal i32 @test1(i1 %c) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test1
> +; IS__CGSCC____-SAME: (i1 [[C:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: br label [[IF_THEN:%.*]]
> +; IS__CGSCC____: if.then:
> +; IS__CGSCC____-NEXT: br label [[RET1:%.*]]
> +; IS__CGSCC____: ret1:
> +; IS__CGSCC____-NEXT: ret i32 99
> +; IS__CGSCC____: ret2:
> +; IS__CGSCC____-NEXT: unreachable
> +;
> entry:
> br label %if.then
>
>
> diff --git
> a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll
> b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll
> index 3c11e799b3d2..10e2ac8006d5 100644
> --- a/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll
> +++ b/llvm/test/Transforms/Attributor/IPConstantProp/thread_local_acs.ll
> @@ -1,5 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-max-iterations=1 < %s | FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ;
> ; #include <threads.h>
> ; thread_local int gtl = 0;
> @@ -37,10 +40,15 @@ entry:
> }
>
> define dso_local void @caller() {
> -; CHECK-LABEL: define {{[^@]+}}@caller()
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: call void @broker(i32* nofree nonnull readonly align 4
> dereferenceable(4) @gtl, i32 (i32*, i32*)* nonnull @callee, i32* nofree
> nonnull readonly align 4 dereferenceable(4) undef)
> -; CHECK-NEXT: ret void
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@caller()
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: call void @broker(i32* nofree nonnull readonly
> align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* nonnull @callee, i32*
> nofree nonnull readonly align 4 dereferenceable(4) undef)
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@caller()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: call void @broker(i32* nofree nonnull readonly
> align 4 dereferenceable(4) @gtl, i32 (i32*, i32*)* nonnull @callee, i32*
> nofree nonnull readonly align 4 dereferenceable(4) @gsh)
> +; IS__CGSCC____-NEXT: ret void
> ;
> entry:
> call void @broker(i32* nonnull @gtl, i32 (i32*, i32*)* nonnull @callee,
> i32* nonnull @gsh)
>
> diff --git a/llvm/test/Transforms/Attributor/align.ll
> b/llvm/test/Transforms/Attributor/align.ll
> index 882d0e8b8c7f..88d070fb8768 100644
> --- a/llvm/test/Transforms/Attributor/align.ll
> +++ b/llvm/test/Transforms/Attributor/align.ll
> @@ -1,8 +1,8 @@
> -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --disable --function-signature --scrub-attributes
> -; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s |
> FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_MODULE
> -; RUN: opt -attributor-cgscc -attributor-manifest-internal
> -attributor-disable=false -attributor-annotate-decl-cs
> -attributor-max-iterations=6 -S < %s | FileCheck %s
> --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_CGSCC
> -; RUN: opt -passes=attributor -attributor-manifest-internal
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s |
> FileCheck %s --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_MODULE
> -; RUN: opt -passes=attributor-cgscc -attributor-manifest-internal
> -attributor-disable=false -attributor-annotate-decl-cs
> -attributor-max-iterations=6 -S < %s | FileCheck %s
> --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_CGSCC
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>
> @@ -11,27 +11,41 @@ target datalayout =
> "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>
>
> ; TEST 1
> -; ATTRIBUTOR: define align 8 i32* @test1(i32* nofree readnone returned
> align 8 "no-capture-maybe-returned" %0)
> 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]]
> +;
> ret i32* %0
> }
>
> ; TEST 2
> -; ATTRIBUTOR: define i32* @test2(i32* nofree readnone returned
> "no-capture-maybe-returned" %0)
> 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]]
> +;
> ret i32* %0
> }
>
> ; TEST 3
> -; ATTRIBUTOR: define align 4 i32* @test3(i32* nofree readnone align 8
> "no-capture-maybe-returned" %0, i32* nofree readnone align 4
> "no-capture-maybe-returned" %1, i1 %2)
> 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]]
> +;
> %ret = select i1 %2, i32* %0, i32* %1
> ret i32* %ret
> }
>
> ; TEST 4
> -; ATTRIBUTOR: define align 32 i32* @test4(i32* nofree readnone align 32
> "no-capture-maybe-returned" %0, i32* nofree readnone align 32
> "no-capture-maybe-returned" %1, i1 %2)
> 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]]
> +;
> %ret = select i1 %2, i32* %0, i32* %1
> ret i32* %ret
> }
> @@ -41,28 +55,38 @@ declare i32* @unknown()
> declare align 8 i32* @align8()
>
>
> -; ATTRIBUTOR: define align 8 i32* @test5_1()
> define i32* @test5_1() {
> +; CHECK-LABEL: define {{[^@]+}}@test5_1()
> +; CHECK-NEXT: [[RET:%.*]] = tail call align 8 i32* @unknown()
> +; CHECK-NEXT: ret i32* [[RET]]
> +;
> %ret = tail call align 8 i32* @unknown()
> ret i32* %ret
> }
>
> -; ATTRIBUTOR: define align 8 i32* @test5_2()
> define i32* @test5_2() {
> +; CHECK-LABEL: define {{[^@]+}}@test5_2()
> +; CHECK-NEXT: [[RET:%.*]] = tail call align 8 i32* @align8()
> +; CHECK-NEXT: ret i32* [[RET]]
> +;
> %ret = tail call i32* @align8()
> ret i32* %ret
> }
>
> ; TEST 6
> ; SCC
> -; ATTRIBUTOR: define noalias nonnull align 536870912
> dereferenceable(4294967295) i32* @test6_1()
> define i32* @test6_1() #0 {
> +; CHECK-LABEL: define {{[^@]+}}@test6_1()
> +; CHECK-NEXT: unreachable
> +;
> %ret = tail call i32* @test6_2()
> ret i32* %ret
> }
>
> -; ATTRIBUTOR: define noalias nonnull align 536870912
> dereferenceable(4294967295) i32* @test6_2()
> define i32* @test6_2() #0 {
> +; CHECK-LABEL: define {{[^@]+}}@test6_2()
> +; CHECK-NEXT: unreachable
> +;
> %ret = tail call i32* @test6_1()
> ret i32* %ret
> }
> @@ -87,6 +111,28 @@ define i32* @test6_2() #0 {
>
> ; Function Attrs: nounwind readnone ssp uwtable
> define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
> +; 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
> +; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label
> [[TMP5:%.*]]
> +; IS__TUNIT____: 3:
> +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2()
> +; IS__TUNIT____-NEXT: br label [[TMP5]]
> +; IS__TUNIT____: 5:
> +; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [
> [[TMP0]], [[TMP1:%.*]] ]
> +; IS__TUNIT____-NEXT: ret i8* [[TMP6]]
> +;
> +; 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
> +; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label
> [[TMP5:%.*]]
> +; IS__CGSCC____: 3:
> +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2()
> +; IS__CGSCC____-NEXT: br label [[TMP5]]
> +; IS__CGSCC____: 5:
> +; IS__CGSCC____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [
> [[TMP0]], [[TMP1:%.*]] ]
> +; IS__CGSCC____-NEXT: ret i8* [[TMP6]]
> +;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %3, label %5
>
> @@ -102,6 +148,19 @@ 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-LABEL: define {{[^@]+}}@f2() local_unnamed_addr
> +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null
> +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]
> +; CHECK: 2:
> +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nofree
> nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
> +; CHECK-NEXT: br label [[TMP6:%.*]]
> +; CHECK: 4:
> +; CHECK-NEXT: [[TMP5:%.*]] = tail call i8* @f3()
> +; CHECK-NEXT: br label [[TMP6]]
> +; CHECK: 6:
> +; CHECK-NEXT: [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [
> [[TMP5]], [[TMP4]] ]
> +; CHECK-NEXT: ret i8* [[TMP7]]
> +;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %5, label %3
>
> @@ -121,6 +180,16 @@ 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-LABEL: define {{[^@]+}}@f3() local_unnamed_addr
> +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null
> +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]]
> +; CHECK: 2:
> +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1(i8* noalias nofree
> nonnull readnone align 16 dereferenceable(1) @a2)
> +; CHECK-NEXT: br label [[TMP4]]
> +; CHECK: 4:
> +; CHECK-NEXT: [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1,
> [[TMP0:%.*]] ]
> +; CHECK-NEXT: ret i8* [[TMP5]]
> +;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %3, label %5
>
> @@ -133,18 +202,16 @@ define internal i8* @f3(i8* readnone %0)
> local_unnamed_addr #0 {
> ret i8* %6
> }
>
> -; UTC_ARGS: --enable
> -
> ; TEST 7
> ; Better than IR information
> define align 4 i8* @test7() #0 {
> -; ATTRIBUTOR_MODULE-LABEL: define {{[^@]+}}@test7()
> -; ATTRIBUTOR_MODULE-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias
> nofree nonnull readnone align 8 dereferenceable(1) @a1)
> -; ATTRIBUTOR_MODULE-NEXT: ret i8* [[C]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test7()
> +; IS__TUNIT____-NEXT: [[C:%.*]] = tail call i8* @f1(i8* noalias nofree
> nonnull readnone align 8 dereferenceable(1) @a1)
> +; IS__TUNIT____-NEXT: ret i8* [[C]]
> ;
> -; ATTRIBUTOR_CGSCC-LABEL: define {{[^@]+}}@test7()
> -; ATTRIBUTOR_CGSCC-NEXT: [[C:%.*]] = tail call nonnull align 8
> dereferenceable(1) i8* @f1(i8* noalias nofree nonnull readnone align 8
> dereferenceable(1) @a1)
> -; ATTRIBUTOR_CGSCC-NEXT: ret i8* [[C]]
> +; 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]]
> ;
> %c = tail call i8* @f1(i8* align 8 dereferenceable(1) @a1)
> ret i8* %c
> @@ -153,31 +220,31 @@ 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 {
> -; ATTRIBUTOR_MODULE-LABEL: define {{[^@]+}}@f1b
> -; ATTRIBUTOR_MODULE-SAME: (i8* noalias nofree nonnull readnone align 8
> dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]])
> local_unnamed_addr
> -; ATTRIBUTOR_MODULE-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
> -; ATTRIBUTOR_MODULE-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label
> [[TMP5:%.*]]
> -; ATTRIBUTOR_MODULE: 3:
> -; ATTRIBUTOR_MODULE-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b()
> -; ATTRIBUTOR_MODULE-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8
> -; ATTRIBUTOR_MODULE-NEXT: store i8 [[L]], i8* @a1, align 8
> -; ATTRIBUTOR_MODULE-NEXT: br label [[TMP5]]
> -; ATTRIBUTOR_MODULE: 5:
> -; ATTRIBUTOR_MODULE-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]]
> ], [ [[TMP0]], [[TMP1:%.*]] ]
> -; ATTRIBUTOR_MODULE-NEXT: ret i8* [[TMP6]]
> -;
> -; ATTRIBUTOR_CGSCC-LABEL: define {{[^@]+}}@f1b
> -; ATTRIBUTOR_CGSCC-SAME: (i8* nofree nonnull readnone align 8
> dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]])
> local_unnamed_addr
> -; ATTRIBUTOR_CGSCC-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
> -; ATTRIBUTOR_CGSCC-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label
> [[TMP5:%.*]]
> -; ATTRIBUTOR_CGSCC: 3:
> -; ATTRIBUTOR_CGSCC-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b()
> -; ATTRIBUTOR_CGSCC-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8
> -; ATTRIBUTOR_CGSCC-NEXT: store i8 [[L]], i8* @a1, align 8
> -; ATTRIBUTOR_CGSCC-NEXT: br label [[TMP5]]
> -; ATTRIBUTOR_CGSCC: 5:
> -; ATTRIBUTOR_CGSCC-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]]
> ], [ [[TMP0]], [[TMP1:%.*]] ]
> -; ATTRIBUTOR_CGSCC-NEXT: ret i8* [[TMP6]]
> +; 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
> +; IS__TUNIT____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label
> [[TMP5:%.*]]
> +; IS__TUNIT____: 3:
> +; IS__TUNIT____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b()
> +; IS__TUNIT____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8
> +; IS__TUNIT____-NEXT: store i8 [[L]], i8* @a1, align 8
> +; IS__TUNIT____-NEXT: br label [[TMP5]]
> +; IS__TUNIT____: 5:
> +; IS__TUNIT____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [
> [[TMP0]], [[TMP1:%.*]] ]
> +; IS__TUNIT____-NEXT: ret i8* [[TMP6]]
> +;
> +; 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
> +; IS__CGSCC____-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label
> [[TMP5:%.*]]
> +; IS__CGSCC____: 3:
> +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b()
> +; IS__CGSCC____-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8
> +; IS__CGSCC____-NEXT: store i8 [[L]], i8* @a1, align 8
> +; IS__CGSCC____-NEXT: br label [[TMP5]]
> +; IS__CGSCC____: 5:
> +; IS__CGSCC____-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [
> [[TMP0]], [[TMP1:%.*]] ]
> +; IS__CGSCC____-NEXT: ret i8* [[TMP6]]
> ;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %3, label %5
> @@ -196,18 +263,18 @@ 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 {
> ;
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@f2b() local_unnamed_addr
> -; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null
> -; ATTRIBUTOR-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label
> [[TMP2:%.*]]
> -; ATTRIBUTOR: 2:
> -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias
> nofree nonnull readnone align 8 dereferenceable(1)
> "no-capture-maybe-returned" @a1)
> -; ATTRIBUTOR-NEXT: br label [[TMP6:%.*]]
> -; ATTRIBUTOR: 4:
> -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i8* @f3b()
> -; ATTRIBUTOR-NEXT: br label [[TMP6]]
> -; ATTRIBUTOR: 6:
> -; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [
> [[TMP5]], [[TMP4]] ]
> -; ATTRIBUTOR-NEXT: ret i8* [[TMP7]]
> +; CHECK-LABEL: define {{[^@]+}}@f2b() local_unnamed_addr
> +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a1, null
> +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP4:%.*]], label [[TMP2:%.*]]
> +; CHECK: 2:
> +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree
> nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
> +; CHECK-NEXT: br label [[TMP6:%.*]]
> +; CHECK: 4:
> +; CHECK-NEXT: [[TMP5:%.*]] = tail call i8* @f3b()
> +; CHECK-NEXT: br label [[TMP6]]
> +; CHECK: 6:
> +; CHECK-NEXT: [[TMP7:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [
> [[TMP5]], [[TMP4]] ]
> +; CHECK-NEXT: ret i8* [[TMP7]]
> ;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %5, label %3
> @@ -229,15 +296,15 @@ 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 {
> ;
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@f3b() local_unnamed_addr
> -; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null
> -; ATTRIBUTOR-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label
> [[TMP4:%.*]]
> -; ATTRIBUTOR: 2:
> -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias
> nofree nonnull readnone align 16 dereferenceable(1) @a2)
> -; ATTRIBUTOR-NEXT: br label [[TMP4]]
> -; ATTRIBUTOR: 4:
> -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [
> @a1, [[TMP0:%.*]] ]
> -; ATTRIBUTOR-NEXT: ret i8* [[TMP5]]
> +; CHECK-LABEL: define {{[^@]+}}@f3b() local_unnamed_addr
> +; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8* @a2, null
> +; CHECK-NEXT: br i1 [[TMP1]], label [[TMP2:%.*]], label [[TMP4:%.*]]
> +; CHECK: 2:
> +; CHECK-NEXT: [[TMP3:%.*]] = tail call i8* @f1b(i8* noalias nofree
> nonnull readnone align 16 dereferenceable(1) @a2)
> +; CHECK-NEXT: br label [[TMP4]]
> +; CHECK: 4:
> +; CHECK-NEXT: [[TMP5:%.*]] = phi i8* [ [[TMP3]], [[TMP2]] ], [ @a1,
> [[TMP0:%.*]] ]
> +; CHECK-NEXT: ret i8* [[TMP5]]
> ;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %3, label %5
> @@ -252,36 +319,52 @@ define internal i8* @f3b(i8* readnone %0)
> local_unnamed_addr #0 {
> }
>
> define align 4 i32* @test7b(i32* align 32 %p) #0 {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7b
> -; ATTRIBUTOR-SAME: (i32* nofree readnone returned align 32
> "no-capture-maybe-returned" [[P:%.*]])
> -; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias
> nofree nonnull readnone align 8 dereferenceable(1) @a1)
> -; ATTRIBUTOR-NEXT: ret i32* [[P]]
> +; CHECK-LABEL: define {{[^@]+}}@test7b
> +; CHECK-SAME: (i32* nofree readnone returned align 32
> "no-capture-maybe-returned" [[P:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* noalias nofree
> nonnull readnone align 8 dereferenceable(1) @a1)
> +; CHECK-NEXT: ret i32* [[P]]
> ;
> tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1)
> ret i32* %p
> }
>
> -; UTC_ARGS: --disable
> -
> ; TEST 8
> define void @test8_helper() {
> +; CHECK-LABEL: define {{[^@]+}}@test8_helper()
> +; CHECK-NEXT: [[PTR0:%.*]] = tail call i32* @unknown()
> +; CHECK-NEXT: [[PTR1:%.*]] = tail call align 4 i32* @unknown()
> +; CHECK-NEXT: [[PTR2:%.*]] = tail call align 8 i32* @unknown()
> +; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 4
> [[PTR1]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone
> [[PTR0]])
> +; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 8
> [[PTR2]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone
> align 4 [[PTR1]])
> +; CHECK-NEXT: tail call void @test8(i32* noalias readnone align 8
> [[PTR2]], i32* noalias readnone align 4 [[PTR1]], i32* noalias readnone
> align 4 [[PTR1]])
> +; CHECK-NEXT: ret void
> +;
> %ptr0 = tail call i32* @unknown()
> %ptr1 = tail call align 4 i32* @unknown()
> %ptr2 = tail call align 8 i32* @unknown()
>
> tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0)
> -; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 4 %ptr1,
> i32* noalias readnone align 4 %ptr1, i32* noalias readnone %ptr0)
> tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
> -; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 8 %ptr2,
> i32* noalias readnone align 4 %ptr1, i32* noalias readnone align 4 %ptr1)
> tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
> -; ATTRIBUTOR: tail call void @test8(i32* noalias readnone align 8 %ptr2,
> i32* noalias readnone align 4 %ptr1, i32* noalias readnone align 4 %ptr1)
> ret void
> }
>
> declare void @user_i32_ptr(i32* nocapture readnone) nounwind
> define internal void @test8(i32* %a, i32* %b, i32* %c) {
> -; ATTRIBUTOR_MODULE: define internal void @test8(i32* noalias nocapture
> readnone align 4 %a, i32* noalias nocapture readnone align 4 %b, i32*
> noalias nocapture readnone %c)
> -; ATTRIBUTOR_CGSCC: define internal void @test8(i32* nocapture readnone
> align 4 %a, i32* nocapture readnone align 4 %b, i32* nocapture readnone %c)
> +; 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]])
> +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture
> readnone align 4 [[B]])
> +; IS__TUNIT____-NEXT: call void @user_i32_ptr(i32* noalias nocapture
> readnone [[C]])
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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]])
> +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture
> readnone align 4 [[B]])
> +; IS__CGSCC____-NEXT: call void @user_i32_ptr(i32* noalias nocapture
> readnone [[C]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> call void @user_i32_ptr(i32* %a)
> call void @user_i32_ptr(i32* %b)
> call void @user_i32_ptr(i32* %c)
> @@ -289,33 +372,53 @@ define internal void @test8(i32* %a, i32* %b, i32*
> %c) {
> }
>
> declare void @test9_helper(i32* %A)
> -define void @test9_traversal(i1 %c, i32* align 4 %B, i32* align 8 %C) {
> - %sel = select i1 %c, i32* %B, i32* %C
> +define void @test9_traversal(i1 %cnd, i32* align 4 %B, i32* align 8 %C) {
> +; CHECK-LABEL: define {{[^@]+}}@test9_traversal
> +; CHECK-SAME: (i1 [[CND:%.*]], i32* align 4 [[B:%.*]], i32* align 8
> [[C:%.*]])
> +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CND]], i32* [[B]], i32* [[C]]
> +; CHECK-NEXT: call void @test9_helper(i32* align 4 [[SEL]])
> +; CHECK-NEXT: ret void
> +;
> + %sel = select i1 %cnd, i32* %B, i32* %C
> call void @test9_helper(i32* %sel)
> ret void
> }
>
> ; FIXME: This will work with an upcoming patch (D66618 or similar)
> ; define align 32 i32* @test10a(i32* align 32
> "no-capture-maybe-returned" %p)
> -; ATTRIBUTOR: define i32* @test10a(i32* nofree nonnull align 32
> dereferenceable(4) "no-capture-maybe-returned" %p)
> +; FIXME: This will work with an upcoming patch (D66618 or similar)
> +; store i32 1, i32* %r, align 32
> +; 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) {
> -; ATTRIBUTOR: %l = load i32, i32* %p, align 32
> +; 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
> +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
> +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
> +; CHECK: t:
> +; CHECK-NEXT: [[R:%.*]] = call i32* @test10a(i32* nofree nonnull align
> 32 dereferenceable(4) "no-capture-maybe-returned" [[P]])
> +; CHECK-NEXT: store i32 1, i32* [[R]]
> +; CHECK-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
> +; CHECK-NEXT: br label [[E:%.*]]
> +; CHECK: f:
> +; CHECK-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 8
> +; CHECK-NEXT: store i32 -1, i32* [[G1]], align 4
> +; CHECK-NEXT: br label [[E]]
> +; CHECK: e:
> +; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]],
> [[F]] ]
> +; CHECK-NEXT: ret i32* [[PHI]]
> +;
> %l = load i32, i32* %p
> %c = icmp eq i32 %l, 0
> br i1 %c, label %t, label %f
> t:
> %r = call i32* @test10a(i32* %p)
> -; FIXME: This will work with an upcoming patch (D66618 or similar)
> -; store i32 1, i32* %r, align 32
> -; ATTRIBUTOR: store i32 1, i32* %r
> store i32 1, i32* %r
> %g0 = getelementptr i32, i32* %p, i32 8
> br label %e
> f:
> %g1 = getelementptr i32, i32* %p, i32 8
> -; FIXME: This will work with an upcoming patch (D66618 or similar)
> -; store i32 -1, i32* %g1, align 32
> -; ATTRIBUTOR: store i32 -1, i32* %g1
> store i32 -1, i32* %g1
> br label %e
> e:
> @@ -325,25 +428,39 @@ e:
>
> ; FIXME: This will work with an upcoming patch (D66618 or similar)
> ; define align 32 i32* @test10b(i32* align 32
> "no-capture-maybe-returned" %p)
> -; ATTRIBUTOR: define i32* @test10b(i32* nofree nonnull align 32
> dereferenceable(4) "no-capture-maybe-returned" %p)
> +; FIXME: This will work with an upcoming patch (D66618 or similar)
> +; store i32 1, i32* %r, align 32
> +; 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) {
> -; ATTRIBUTOR: %l = load i32, i32* %p, align 32
> +; 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
> +; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[L]], 0
> +; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
> +; CHECK: t:
> +; CHECK-NEXT: [[R:%.*]] = call i32* @test10b(i32* nofree nonnull align
> 32 dereferenceable(4) "no-capture-maybe-returned" [[P]])
> +; CHECK-NEXT: store i32 1, i32* [[R]]
> +; CHECK-NEXT: [[G0:%.*]] = getelementptr i32, i32* [[P]], i32 8
> +; CHECK-NEXT: br label [[E:%.*]]
> +; CHECK: f:
> +; CHECK-NEXT: [[G1:%.*]] = getelementptr i32, i32* [[P]], i32 -8
> +; CHECK-NEXT: store i32 -1, i32* [[G1]], align 4
> +; CHECK-NEXT: br label [[E]]
> +; CHECK: e:
> +; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[G0]], [[T]] ], [ [[G1]],
> [[F]] ]
> +; CHECK-NEXT: ret i32* [[PHI]]
> +;
> %l = load i32, i32* %p
> %c = icmp eq i32 %l, 0
> br i1 %c, label %t, label %f
> t:
> %r = call i32* @test10b(i32* %p)
> -; FIXME: This will work with an upcoming patch (D66618 or similar)
> -; store i32 1, i32* %r, align 32
> -; ATTRIBUTOR: store i32 1, i32* %r
> store i32 1, i32* %r
> %g0 = getelementptr i32, i32* %p, i32 8
> br label %e
> f:
> %g1 = getelementptr i32, i32* %p, i32 -8
> -; FIXME: This will work with an upcoming patch (D66618 or similar)
> -; store i32 -1, i32* %g1, align 32
> -; ATTRIBUTOR: store i32 -1, i32* %g1
> store i32 -1, i32* %g1
> br label %e
> e:
> @@ -352,8 +469,13 @@ e:
> }
>
>
> -; ATTRIBUTOR: define i64 @test11(i32* nocapture nofree nonnull readonly
> align 8 dereferenceable(8) %p)
> 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]]
> +;
> %p-cast = bitcast i32* %p to i64*
> %ret = load i64, i64* %p-cast, align 8
> ret i64 %ret
> @@ -363,8 +485,15 @@ define i64 @test11(i32* %p) {
> ; Test for deduction using must-be-executed-context and GEP instruction
>
> ; FXIME: %p should have nonnull
> -; ATTRIBUTOR: define i64 @test12-1(i32* nocapture nofree readonly align
> 16 %p)
> 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]]
> +;
> %p-cast = bitcast i32* %p to i64*
> %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
> %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
> @@ -372,8 +501,14 @@ define i64 @test12-1(i32* align 4 %p) {
> ret i64 %ret
> }
>
> -; ATTRIBUTOR: define i64 @test12-2(i32* nocapture nofree nonnull readonly
> align 16 dereferenceable(8) %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]]
> +;
> %p-cast = bitcast i32* %p to i64*
> %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
> %ret = load i64, i64* %arrayidx0, align 16
> @@ -381,8 +516,15 @@ define i64 @test12-2(i32* align 4 %p) {
> }
>
> ; FXIME: %p should have nonnull
> -; ATTRIBUTOR: define void @test12-3(i32* nocapture nofree writeonly align
> 16 %p)
> 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
> +;
> %p-cast = bitcast i32* %p to i64*
> %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
> %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
> @@ -390,8 +532,14 @@ define void @test12-3(i32* align 4 %p) {
> ret void
> }
>
> -; ATTRIBUTOR: define void @test12-4(i32* nocapture nofree nonnull
> writeonly align 16 dereferenceable(8) %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
> +;
> %p-cast = bitcast i32* %p to i64*
> %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
> store i64 0, i64* %arrayidx0, align 16
> @@ -400,8 +548,15 @@ define void @test12-4(i32* align 4 %p) {
>
> declare void @use(i64*) willreturn nounwind
>
> -; ATTRIBUTOR: define void @test12-5(i32* align 16 %p)
> define void @test12-5(i32* align 4 %p) {
> +; CHECK-LABEL: define {{[^@]+}}@test12-5
> +; CHECK-SAME: (i32* 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: tail call void @use(i64* align 16 [[ARRAYIDX1]])
> +; CHECK-NEXT: ret void
> +;
> %p-cast = bitcast i32* %p to i64*
> %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
> %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
> @@ -409,8 +564,14 @@ define void @test12-5(i32* align 4 %p) {
> ret void
> }
>
> -; ATTRIBUTOR: define void @test12-6(i32* align 16 %p)
> define void @test12-6(i32* align 4 %p) {
> +; CHECK-LABEL: define {{[^@]+}}@test12-6
> +; CHECK-SAME: (i32* align 16 [[P:%.*]])
> +; CHECK-NEXT: [[P_CAST:%.*]] = bitcast i32* [[P]] to i64*
> +; CHECK-NEXT: [[ARRAYIDX0:%.*]] = getelementptr i64, i64* [[P_CAST]],
> i64 0
> +; CHECK-NEXT: tail call void @use(i64* align 16 [[ARRAYIDX0]])
> +; CHECK-NEXT: ret void
> +;
> %p-cast = bitcast i32* %p to i64*
> %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
> tail call void @use(i64* align 16 %arrayidx0)
> @@ -418,17 +579,17 @@ define void @test12-6(i32* align 4 %p) {
> }
>
> define void @test13(i1 %c, i32* align 32 %dst) #0 {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@test13
> -; ATTRIBUTOR-SAME: (i1 [[C:%.*]], i32* nocapture nofree writeonly align
> 32 [[DST:%.*]])
> -; ATTRIBUTOR-NEXT: br i1 [[C]], label [[TRUEBB:%.*]], label
> [[FALSEBB:%.*]]
> -; ATTRIBUTOR: truebb:
> -; ATTRIBUTOR-NEXT: br label [[END:%.*]]
> -; ATTRIBUTOR: falsebb:
> -; ATTRIBUTOR-NEXT: br label [[END]]
> -; ATTRIBUTOR: end:
> -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = phi i32* [ [[DST]], [[TRUEBB]] ], [
> null, [[FALSEBB]] ]
> -; ATTRIBUTOR-NEXT: store i32 0, i32* [[PTR]], align 32
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> br i1 %c, label %truebb, label %falsebb
> truebb:
> @@ -442,16 +603,17 @@ end:
> }
>
> define void @test13-1(i1 %c, i32* align 32 %dst) {
> -; ATTRIBUTOR-LABEL: @test13-1(
> -; ATTRIBUTOR-NEXT: br i1 [[C:%.*]], label [[TRUEBB:%.*]], label
> [[FALSEBB:%.*]]
> -; ATTRIBUTOR: truebb:
> -; ATTRIBUTOR-NEXT: br label [[END:%.*]]
> -; ATTRIBUTOR: falsebb:
> -; ATTRIBUTOR-NEXT: br label [[END]]
> -; ATTRIBUTOR: end:
> -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ],
> [ inttoptr (i64 48 to i32*), [[FALSEBB]] ]
> -; ATTRIBUTOR-NEXT: store i32 0, i32* [[PTR]], align 16
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> br i1 %c, label %truebb, label %falsebb
> truebb:
> @@ -465,16 +627,17 @@ end:
> }
>
> define void @test13-2(i1 %c, i32* align 32 %dst) {
> -; ATTRIBUTOR-LABEL: @test13-2(
> -; ATTRIBUTOR-NEXT: br i1 [[C:%.*]], label [[TRUEBB:%.*]], label
> [[FALSEBB:%.*]]
> -; ATTRIBUTOR: truebb:
> -; ATTRIBUTOR-NEXT: br label [[END:%.*]]
> -; ATTRIBUTOR: falsebb:
> -; ATTRIBUTOR-NEXT: br label [[END]]
> -; ATTRIBUTOR: end:
> -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ],
> [ inttoptr (i64 160 to i32*), [[FALSEBB]] ]
> -; ATTRIBUTOR-NEXT: store i32 0, i32* [[PTR]], align 32
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> br i1 %c, label %truebb, label %falsebb
> truebb:
> @@ -488,16 +651,17 @@ end:
> }
>
> define void @test13-3(i1 %c, i32* align 32 %dst) {
> -; ATTRIBUTOR-LABEL: @test13-3(
> -; ATTRIBUTOR-NEXT: br i1 [[C:%.*]], label [[TRUEBB:%.*]], label
> [[FALSEBB:%.*]]
> -; ATTRIBUTOR: truebb:
> -; ATTRIBUTOR-NEXT: br label [[END:%.*]]
> -; ATTRIBUTOR: falsebb:
> -; ATTRIBUTOR-NEXT: br label [[END]]
> -; ATTRIBUTOR: end:
> -; ATTRIBUTOR-NEXT: [[PTR:%.*]] = phi i32* [ [[DST:%.*]], [[TRUEBB]] ],
> [ inttoptr (i64 128 to i32*), [[FALSEBB]] ]
> -; ATTRIBUTOR-NEXT: store i32 0, i32* [[PTR]], align 32
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> br i1 %c, label %truebb, label %falsebb
> truebb:
> @@ -512,29 +676,42 @@ 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]]
> +;
> %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]]
> +;
> %i2p = inttoptr i64 %i to i64*
> ret i64* %i2p
> }
>
> ; Use the store alignment only for the pointer operand.
> define void @aligned_store(i8* %Value, i8** %Ptr) {
> -; ATTRIBUTOR: define void @aligned_store(i8* nofree writeonly %Value,
> i8** nocapture nofree nonnull writeonly align 32 dereferenceable(8) %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
> +;
> store i8* %Value, i8** %Ptr, align 32
> ret void
> }
>
> -; UTC_ARGS: --enable
> declare i8* @some_func(i8*)
> define void @align_call_op_not_store(i8* align 2048 %arg) {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@align_call_op_not_store
> -; ATTRIBUTOR-SAME: (i8* align 2048 [[ARG:%.*]])
> -; ATTRIBUTOR-NEXT: [[UNKNOWN:%.*]] = call i8* @some_func(i8* align
> 2048 [[ARG]])
> -; ATTRIBUTOR-NEXT: store i8 0, i8* [[UNKNOWN]]
> -; ATTRIBUTOR-NEXT: ret void
> +; CHECK-LABEL: define {{[^@]+}}@align_call_op_not_store
> +; CHECK-SAME: (i8* align 2048 [[ARG:%.*]])
> +; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @some_func(i8* align 2048
> [[ARG]])
> +; CHECK-NEXT: store i8 0, i8* [[UNKNOWN]]
> +; CHECK-NEXT: ret void
> ;
> %unknown = call i8* @some_func(i8* %arg)
> store i8 0, i8* %unknown
> @@ -542,11 +719,11 @@ define void @align_call_op_not_store(i8* align 2048
> %arg) {
> }
> define void @align_store_after_bc(i32* align 2048 %arg) {
> ;
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@align_store_after_bc
> -; ATTRIBUTOR-SAME: (i32* nocapture nofree nonnull writeonly align 2048
> dereferenceable(1) [[ARG:%.*]])
> -; ATTRIBUTOR-NEXT: [[BC:%.*]] = bitcast i32* [[ARG]] to i8*
> -; ATTRIBUTOR-NEXT: store i8 0, i8* [[BC]], align 2048
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> %bc = bitcast i32* %arg to i8*
> store i8 0, i8* %bc
> @@ -557,10 +734,35 @@ 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]]
> +;
> %v = load i32, i32* %p, align 32
> ret i32 %v
> }
> define i32 @musttail_caller_1(i32* %p) {
> +; 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
> +; IS__TUNIT____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
> +; IS__TUNIT____: mt:
> +; IS__TUNIT____-NEXT: [[V:%.*]] = musttail call i32
> @musttail_callee_1(i32* nocapture nofree readonly [[P]])
> +; IS__TUNIT____-NEXT: ret i32 [[V]]
> +; IS__TUNIT____: exit:
> +; IS__TUNIT____-NEXT: ret i32 0
> +;
> +; 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
> +; IS__CGSCC____-NEXT: br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
> +; IS__CGSCC____: mt:
> +; IS__CGSCC____-NEXT: [[V:%.*]] = musttail call i32
> @musttail_callee_1(i32* nocapture nofree nonnull readonly
> dereferenceable(4) [[P]])
> +; IS__CGSCC____-NEXT: ret i32 [[V]]
> +; IS__CGSCC____: exit:
> +; IS__CGSCC____-NEXT: ret i32 0
> +;
> %c = load i1, i1* @cnd
> br i1 %c, label %mt, label %exit
> mt:
> @@ -569,7 +771,6 @@ mt:
> exit:
> ret i32 0
> }
> -; UTC_ARGS: --disable
>
> attributes #0 = { nounwind uwtable noinline }
> attributes #1 = { uwtable noinline }
>
> diff --git a/llvm/test/Transforms/Attributor/alwaysinline.ll
> b/llvm/test/Transforms/Attributor/alwaysinline.ll
> index 1be433310457..91a7e8fd21b5 100644
> --- a/llvm/test/Transforms/Attributor/alwaysinline.ll
> +++ b/llvm/test/Transforms/Attributor/alwaysinline.ll
> @@ -1,14 +1,18 @@
> -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> -; RUN: opt -attributor -attributor-disable=false
> -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s |
> FileCheck %s --check-prefix=CHECK
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ;
> ; When a function is marked `alwaysinline` and is able to be inlined,
> ; we can IPO its boundaries
>
> ; the function is not exactly defined, and marked alwaysinline and can be
> inlined,
> ; so the function can be analyzed
> -; CHECK: Function Attrs: alwaysinline nofree nosync nounwind readnone
> willreturn
> +; CHECK: Function Attrs: alwaysinline
> +; CHECK-SAME: willreturn
> define linkonce void @inner1() alwaysinline {
> -; CHECK-LABEL: @inner1(
> +; CHECK-LABEL: define {{[^@]+}}@inner1()
> ; CHECK-NEXT: entry:
> ; CHECK-NEXT: ret void
> ;
> @@ -16,9 +20,10 @@ entry:
> ret void
> }
>
> -; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn
> +; CHECK: Function Attrs:
> +; CHECK-SAME: willreturn
> define void @outer1() {
> -; CHECK-LABEL: @outer1(
> +; CHECK-LABEL: define {{[^@]+}}@outer1()
> ; CHECK-NEXT: entry:
> ; CHECK-NEXT: ret void
> ;
> @@ -31,7 +36,7 @@ entry:
> ; so it will not be analyzed
> ; CHECK-NOT: Function Attrs:
> define linkonce i32 @inner2() {
> -; CHECK-LABEL: @inner2(
> +; CHECK-LABEL: define {{[^@]+}}@inner2()
> ; CHECK-NEXT: entry:
> ; CHECK-NEXT: ret i32 1
> ;
> @@ -41,9 +46,9 @@ entry:
>
> ; CHECK-NOT: Function Attrs
> define i32 @outer2() {
> -; CHECK-LABEL: @outer2(
> +; CHECK-LABEL: define {{[^@]+}}@outer2()
> ; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[R:%.*]] = call i32 @inner2() #2
> +; CHECK-NEXT: [[R:%.*]] = call i32 @inner2()
> ; CHECK-NEXT: ret i32 [[R]]
> ;
> entry:
> @@ -55,11 +60,15 @@ entry:
> ; it is `unexactly defined` and alwaysinline but cannot be inlined.
> ; so it will not be analyzed
> ; CHECK: Function Attrs:
> -; CHECK-NOT: nofree nosync nounwind readnone
> +; CHECK-NOT: nofree
> +; CHECK-NOT: nosync
> +; CHECK-NOT: nounwind
> +; CHECK-NOT: readnone
> define linkonce i32 @inner3(i8* %addr) alwaysinline {
> -; CHECK-LABEL: @inner3(
> +; CHECK-LABEL: define {{[^@]+}}@inner3
> +; CHECK-SAME: (i8* [[ADDR:%.*]])
> ; CHECK-NEXT: entry:
> -; CHECK-NEXT: indirectbr i8* [[ADDR:%.*]], [label [[ONE:%.*]], label
> %two]
> +; CHECK-NEXT: indirectbr i8* [[ADDR]], [label [[ONE:%.*]], label %two]
> ; CHECK: one:
> ; CHECK-NEXT: ret i32 42
> ; CHECK: two:
> @@ -77,8 +86,9 @@ two:
>
> ; CHECK-NOT: Function Attrs:
> define i32 @outer3(i32 %x) {
> -; CHECK-LABEL: @outer3(
> -; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 42
> +; CHECK-LABEL: define {{[^@]+}}@outer3
> +; CHECK-SAME: (i32 [[X:%.*]])
> +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X]], 42
> ; CHECK-NEXT: [[ADDR:%.*]] = select i1 [[CMP]], i8*
> blockaddress(@inner3, [[ONE:%.*]]), i8* blockaddress(@inner3, [[TWO:%.*]])
> ; CHECK-NEXT: [[CALL:%.*]] = call i32 @inner3(i8* [[ADDR]])
> ; CHECK-NEXT: ret i32 [[CALL]]
>
> diff --git a/llvm/test/Transforms/Attributor/callbacks.ll
> b/llvm/test/Transforms/Attributor/callbacks.ll
> index 12af0c8e1a7e..d6efa5326c68 100644
> --- a/llvm/test/Transforms/Attributor/callbacks.ll
> +++ b/llvm/test/Transforms/Attributor/callbacks.ll
> @@ -1,8 +1,9 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; FIXME: Add -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations below.
> -; This flag was removed because max iterations is 2 in most cases,
> but in windows it is 1.
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s
> -; ModuleID = 'callback_simple.c'
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> +
> target datalayout =
> "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
>
> ; Test 0
> @@ -15,19 +16,54 @@ target datalayout =
> "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
> ; transfer in both directions.
>
> define void @t0_caller(i32* %a) {
> -; CHECK-LABEL: define {{[^@]+}}@t0_caller
> -; CHECK-SAME: (i32* align 256 [[A:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32
> -; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64
> -; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128
> -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> -; CHECK-NEXT: store i32 42, i32* [[B]], align 32
> -; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64
> -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...)
> @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align
> 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast
> (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*,
> i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture
> nonnull readonly align 64 dereferenceable(8) [[C]])
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t0_caller
> +; IS__TUNIT_OPM-SAME: (i32* align 256 [[A:%.*]])
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void
> (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** nocapture
> nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_caller
> +; IS__TUNIT_NPM-SAME: (i32* align 256 [[A:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void
> (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias
> nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t0_caller
> +; IS__CGSCC_OPM-SAME: (i32* [[A:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void
> (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*,
> ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t0_caller
> +; IS__CGSCC_NPM-SAME: (i32* align 256 [[A:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void
> (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*,
> ...)*), i32* align 256 [[A]], i64 99, i32** noalias nocapture nonnull
> readonly align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> -
> entry:
> %b = alloca i32, align 32
> %c = alloca i32*, align 64
> @@ -42,14 +78,33 @@ entry:
> ; Note that the first two arguments are provided by the callback_broker
> according to the callback in !1 below!
> ; The others are annotated with alignment information, amongst others, or
> even replaced by the constants passed to the call.
> define internal void @t0_callback_callee(i32* %is_not_null, i32* %ptr,
> i32* %a, i64 %b, i32** %c) {
> -; CHECK-LABEL: define {{[^@]+}}@t0_callback_callee
> -; CHECK-SAME: (i32* nocapture nonnull writeonly align 4
> dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly
> align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64
> [[B:%.*]], i32** noalias nocapture nonnull readonly align 64
> dereferenceable(8) [[C:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> -; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> -; CHECK-NEXT: tail call void @t0_check(i32* align 256 [[A]], i64 99,
> i32* [[TMP0]])
> -; CHECK-NEXT: ret void
> +;
> +; IS________OPM-LABEL: define {{[^@]+}}@t0_callback_callee
> +; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4
> dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly
> align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64
> [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8)
> [[C:%.*]])
> +; IS________OPM-NEXT: entry:
> +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> +; IS________OPM-NEXT: tail call void @t0_check(i32* align 256 [[A]],
> i64 99, i32* [[TMP0]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_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* align 256 [[A:%.*]], i64
> [[B:%.*]], i32** noalias nocapture nonnull readonly align 64
> dereferenceable(8) [[C:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> +; IS__TUNIT_NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]],
> i64 99, i32* [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t0_callback_callee
> +; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4
> dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly
> align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64
> [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8)
> [[C:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 8
> +; IS__CGSCC_NPM-NEXT: tail call void @t0_check(i32* align 256 [[A]],
> i64 99, i32* [[TMP0]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> %ptr_val = load i32, i32* %ptr, align 8
> @@ -69,17 +124,53 @@ declare !callback !0 void @t0_callback_broker(i32*,
> i32*, void (i32*, i32*, ...)
> ; we deduce and propagate noalias and others properly.
>
> define void @t1_caller(i32* noalias %a) {
> -; CHECK-LABEL: define {{[^@]+}}@t1_caller
> -; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32
> -; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64
> -; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128
> -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> -; CHECK-NEXT: store i32 42, i32* [[B]], align 32
> -; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64
> -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...)
> @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void
> (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef,
> i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t1_caller
> +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void
> (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32**
> nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_caller
> +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias
> nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)*
> nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee
> to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64
> undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8)
> [[C]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t1_caller
> +; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void
> (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*,
> ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t1_caller
> +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias
> nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)*
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void
> (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32**
> noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> %b = alloca i32, align 32
> @@ -95,14 +186,33 @@ entry:
> ; Note that the first two arguments are provided by the callback_broker
> according to the callback in !1 below!
> ; 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) {
> -; CHECK-LABEL: define {{[^@]+}}@t1_callback_callee
> -; CHECK-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:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> -; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> -; CHECK-NEXT: tail call void @t1_check(i32* nocapture align 256 [[A]],
> i64 99, i32* [[TMP0]])
> -; CHECK-NEXT: ret void
> +;
> +; IS________OPM-LABEL: define {{[^@]+}}@t1_callback_callee
> +; IS________OPM-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:%.*]])
> +; IS________OPM-NEXT: entry:
> +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> +; IS________OPM-NEXT: tail call void @t1_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS________OPM-NEXT: ret void
> +;
> +; 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:
> +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> +; IS__TUNIT_NPM-NEXT: tail call void @t1_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t1_callback_callee
> +; IS__CGSCC_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 8 dereferenceable(8)
> [[C:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 8
> +; IS__CGSCC_NPM-NEXT: tail call void @t1_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> %ptr_val = load i32, i32* %ptr, align 8
> @@ -121,17 +231,53 @@ declare !callback !0 void @t1_callback_broker(i32*
> nocapture , i32* nocapture ,
> ; Similar to test 1 but checking that the noalias is only placed if
> potential synchronization through @t2_check is preserved.
>
> define void @t2_caller(i32* noalias %a) {
> -; CHECK-LABEL: define {{[^@]+}}@t2_caller
> -; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32
> -; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64
> -; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128
> -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> -; CHECK-NEXT: store i32 42, i32* [[B]], align 32
> -; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64
> -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...)
> @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void
> (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef,
> i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t2_caller
> +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void
> (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32**
> nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_caller
> +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias
> nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)*
> nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee
> to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64
> undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8)
> [[C]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t2_caller
> +; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void
> (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*,
> ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t2_caller
> +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias
> nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)*
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void
> (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32**
> noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> %b = alloca i32, align 32
> @@ -149,14 +295,33 @@ entry:
> ;
> ; FIXME: We should derive noalias for %a and add a "fake use" of %a in
> all potentially synchronizing calls.
> define internal void @t2_callback_callee(i32* %is_not_null, i32* %ptr,
> i32* %a, i64 %b, i32** %c) {
> -; CHECK-LABEL: define {{[^@]+}}@t2_callback_callee
> -; CHECK-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** noalias nocapture nonnull readonly align 64
> dereferenceable(8) [[C:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> -; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> -; CHECK-NEXT: tail call void @t2_check(i32* nocapture align 256 [[A]],
> i64 99, i32* [[TMP0]])
> -; CHECK-NEXT: ret void
> +;
> +; IS________OPM-LABEL: define {{[^@]+}}@t2_callback_callee
> +; IS________OPM-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:%.*]])
> +; IS________OPM-NEXT: entry:
> +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> +; IS________OPM-NEXT: tail call void @t2_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_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* nocapture align 256 [[A:%.*]],
> i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64
> dereferenceable(8) [[C:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> +; IS__TUNIT_NPM-NEXT: tail call void @t2_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t2_callback_callee
> +; IS__CGSCC_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 8 dereferenceable(8)
> [[C:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 8
> +; IS__CGSCC_NPM-NEXT: tail call void @t2_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> %ptr_val = load i32, i32* %ptr, align 8
> @@ -175,18 +340,57 @@ declare !callback !0 void @t2_callback_broker(i32*
> nocapture , i32* nocapture ,
> ; Basically test 2 with the casted callback callee used twice.
>
> define void @t3_caller(i32* noalias %a) {
> -; CHECK-LABEL: define {{[^@]+}}@t3_caller
> -; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32
> -; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64
> -; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128
> -; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> -; CHECK-NEXT: store i32 42, i32* [[B]], align 32
> -; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64
> -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...)
> @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void
> (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef,
> i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> -; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...)
> @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void
> (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef,
> i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> -; CHECK-NEXT: ret void
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t3_caller
> +; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__TUNIT_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__TUNIT_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__TUNIT_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__TUNIT_OPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__TUNIT_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void
> (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32**
> nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__TUNIT_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void
> (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32**
> nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_caller
> +; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__TUNIT_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__TUNIT_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__TUNIT_NPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__TUNIT_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias
> nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)*
> nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee
> to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64
> undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8)
> [[C]])
> +; IS__TUNIT_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias
> nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)*
> nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee
> to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64
> undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8)
> [[C]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t3_caller
> +; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__CGSCC_OPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__CGSCC_OPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__CGSCC_OPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__CGSCC_OPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__CGSCC_OPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void
> (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*,
> ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_OPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull
> align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void
> (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*,
> ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t3_caller
> +; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[B:%.*]] = alloca i32, align 32
> +; IS__CGSCC_NPM-NEXT: [[C:%.*]] = alloca i32*, align 64
> +; IS__CGSCC_NPM-NEXT: [[PTR:%.*]] = alloca i32, align 128
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
> +; IS__CGSCC_NPM-NEXT: store i32 42, i32* [[B]], align 32
> +; IS__CGSCC_NPM-NEXT: store i32* [[B]], i32** [[C]], align 64
> +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias
> nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)*
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void
> (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32**
> noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_NPM-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*,
> ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias
> nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)*
> bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void
> (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32**
> noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> %b = alloca i32, align 32
> @@ -205,14 +409,33 @@ entry:
> ;
> ; FIXME: We should derive noalias for %a and add a "fake use" of %a in
> all potentially synchronizing calls.
> define internal void @t3_callback_callee(i32* %is_not_null, i32* %ptr,
> i32* %a, i64 %b, i32** %c) {
> -; CHECK-LABEL: define {{[^@]+}}@t3_callback_callee
> -; CHECK-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** noalias nocapture nonnull readonly align 64
> dereferenceable(8) [[C:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> -; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
> -; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> -; CHECK-NEXT: tail call void @t3_check(i32* nocapture align 256 [[A]],
> i64 99, i32* [[TMP0]])
> -; CHECK-NEXT: ret void
> +;
> +; IS________OPM-LABEL: define {{[^@]+}}@t3_callback_callee
> +; IS________OPM-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:%.*]])
> +; IS________OPM-NEXT: entry:
> +; IS________OPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS________OPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS________OPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> +; IS________OPM-NEXT: tail call void @t3_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_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* nocapture align 256 [[A:%.*]],
> i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64
> dereferenceable(8) [[C:%.*]])
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS__TUNIT_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS__TUNIT_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
> +; IS__TUNIT_NPM-NEXT: tail call void @t3_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS__TUNIT_NPM-NEXT: ret void
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t3_callback_callee
> +; IS__CGSCC_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 8 dereferenceable(8)
> [[C:%.*]])
> +; IS__CGSCC_NPM-NEXT: entry:
> +; IS__CGSCC_NPM-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
> +; IS__CGSCC_NPM-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]],
> align 4
> +; IS__CGSCC_NPM-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C]], align 8
> +; IS__CGSCC_NPM-NEXT: tail call void @t3_check(i32* nocapture align
> 256 [[A]], i64 99, i32* [[TMP0]])
> +; IS__CGSCC_NPM-NEXT: ret void
> ;
> entry:
> %ptr_val = load i32, i32* %ptr, align 8
>
> diff --git a/llvm/test/Transforms/Attributor/dereferenceable-1.ll
> b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
> index 7a6de53f3f69..a1da5fbe2d7c 100644
> --- a/llvm/test/Transforms/Attributor/dereferenceable-1.ll
> +++ b/llvm/test/Transforms/Attributor/dereferenceable-1.ll
> @@ -1,16 +1,22 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -attributor -attributor-manifest-internal
> --attributor-disable=false -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations=16 -S < %s |
> FileCheck %s --check-prefix=ATTRIBUTOR
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ; FIXME: Figure out why we need 16 iterations here.
>
> -; UTC_ARGS: --disable
> -
> declare void @deref_phi_user(i32* %a);
>
> ; TEST 1
> ; take mininimum of return values
> ;
> define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8)
> %1, i1 zeroext %2) local_unnamed_addr {
> -; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test1(i32* nofree
> nonnull readnone dereferenceable(4) "no-capture-maybe-returned" %0, double*
> nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %1,
> i1 zeroext %2)
> +; 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]]
> +;
> %4 = bitcast double* %1 to i32*
> %5 = select i1 %2, i32* %0, i32* %4
> ret i32* %5
> @@ -18,7 +24,12 @@ 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 {
> -; ATTRIBUTOR: define dereferenceable_or_null(4) i32* @test2(i32* nofree
> readnone dereferenceable_or_null(4) "no-capture-maybe-returned" %0, double*
> nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %1,
> i1 zeroext %2)
> +; 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]]
> +;
> %4 = bitcast double* %1 to i32*
> %5 = select i1 %2, i32* %0, i32* %4
> ret i32* %5
> @@ -27,19 +38,33 @@ 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 {
> -; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_1(i32* nofree
> nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %0)
> +; 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]]
> +;
> %ret = getelementptr inbounds i32, i32* %0, i64 1
> ret i32* %ret
> }
>
> define i32* @test3_2(i32* dereferenceable_or_null(32) %0)
> local_unnamed_addr {
> -; ATTRIBUTOR: define nonnull dereferenceable(16) i32* @test3_2(i32*
> nofree readnone dereferenceable_or_null(32) "no-capture-maybe-returned" %0)
> +; 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]]
> +;
> %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 {
> -; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_3(i32* nofree
> nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %0, i32*
> nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" %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]]
> +;
> %ret1 = getelementptr inbounds i32, i32* %0, i64 1
> %ret2 = getelementptr inbounds i32, i32* %1, i64 2
> %ret = select i1 %2, i32* %ret1, i32* %ret2
> @@ -50,20 +75,44 @@ 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 {
> -; ATTRIBUTOR: define nonnull dereferenceable(8) i32* @test4(i32* nofree
> nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" %0)
> +; 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]]
> +;
> ret i32* %0
> }
>
> ; TEST 5
> ; loop in which dereferenceabily "grows"
> define void @deref_phi_growing(i32* dereferenceable(4000) %a) {
> +; CHECK-LABEL: define {{[^@]+}}@deref_phi_growing
> +; CHECK-SAME: (i32* nonnull dereferenceable(4000) [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: br label [[FOR_COND:%.*]]
> +; CHECK: for.cond:
> +; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [
> [[INC:%.*]], [[FOR_INC:%.*]] ]
> +; CHECK-NEXT: [[A_ADDR_0:%.*]] = phi i32* [ [[A]], [[ENTRY]] ], [
> [[INCDEC_PTR:%.*]], [[FOR_INC]] ]
> +; CHECK-NEXT: call void @deref_phi_user(i32* nonnull
> dereferenceable(4000) [[A_ADDR_0]])
> +; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[A_ADDR_0]], align 4
> +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[TMP]]
> +; 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 [[FOR_INC]]
> +; CHECK: for.inc:
> +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i32, i32*
> [[A_ADDR_0]], i64 -1
> +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1
> +; CHECK-NEXT: br label [[FOR_COND]]
> +; CHECK: for.end:
> +; CHECK-NEXT: ret void
> +;
> entry:
> br label %for.cond
>
> for.cond: ; preds = %for.inc,
> %entry
> %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
> %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ]
> -; ATTRIBUTOR: call void @deref_phi_user(i32* nonnull
> dereferenceable(4000) %a.addr.0)
> call void @deref_phi_user(i32* %a.addr.0)
> %tmp = load i32, i32* %a.addr.0, align 4
> %cmp = icmp slt i32 %i.0, %tmp
> @@ -87,13 +136,34 @@ for.end: ;
> preds = %for.cond.cleanup
> ; TEST 6
> ; loop in which dereferenceabily "shrinks"
> define void @deref_phi_shrinking(i32* dereferenceable(4000) %a) {
> +; CHECK-LABEL: define {{[^@]+}}@deref_phi_shrinking
> +; CHECK-SAME: (i32* nonnull dereferenceable(4000) [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: br label [[FOR_COND:%.*]]
> +; CHECK: for.cond:
> +; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [
> [[INC:%.*]], [[FOR_INC:%.*]] ]
> +; CHECK-NEXT: [[A_ADDR_0:%.*]] = phi i32* [ [[A]], [[ENTRY]] ], [
> [[INCDEC_PTR:%.*]], [[FOR_INC]] ]
> +; CHECK-NEXT: call void @deref_phi_user(i32* nonnull [[A_ADDR_0]])
> +; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* [[A_ADDR_0]], align 4
> +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[TMP]]
> +; 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 [[FOR_INC]]
> +; CHECK: for.inc:
> +; CHECK-NEXT: [[INCDEC_PTR]] = getelementptr inbounds i32, i32*
> [[A_ADDR_0]], i64 1
> +; CHECK-NEXT: [[INC]] = add nuw nsw i32 [[I_0]], 1
> +; CHECK-NEXT: br label [[FOR_COND]]
> +; CHECK: for.end:
> +; CHECK-NEXT: ret void
> +;
> entry:
> br label %for.cond
>
> for.cond: ; preds = %for.inc,
> %entry
> %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
> %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ]
> -; ATTRIBUTOR: call void @deref_phi_user(i32* nonnull %a.addr.0)
> call void @deref_phi_user(i32* %a.addr.0)
> %tmp = load i32, i32* %a.addr.0, align 4
> %cmp = icmp slt i32 %i.0, %tmp
> @@ -119,96 +189,108 @@ 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) {
> -; ATTRIBUTOR: define nonnull dereferenceable(8) i32* @f7_0(i32* nonnull
> returned dereferenceable(8) %ptr)
> +; 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]])
> +; CHECK-NEXT: ret i32* [[PTR]]
> +;
> %T = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
> ret i32* %ptr
> }
>
> -; ATTRIBUTOR: define void @f7_1(i32* nonnull align 4 dereferenceable(4)
> %ptr, i1 %c)
> define void @f7_1(i32* %ptr, i1 %c) {
> -
> -; ATTRIBUTOR: %A = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(4) %ptr)
> +; 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]])
> +; CHECK-NEXT: [[B:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(4) [[PTR]])
> +; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label
> [[IF_FALSE:%.*]]
> +; CHECK: if.true:
> +; CHECK-NEXT: [[C:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) [[PTR]])
> +; CHECK-NEXT: [[D:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) [[PTR]])
> +; CHECK-NEXT: [[E:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) [[PTR]])
> +; CHECK-NEXT: ret void
> +; CHECK: if.false:
> +; CHECK-NEXT: ret void
> +;
> %A = tail call i32 @unkown_f(i32* %ptr)
> -
> %ptr.0 = load i32, i32* %ptr
> ; deref 4 hold
> -
> ; FIXME: this should be %B = tail call i32 @unkown_f(i32* nonnull
> dereferenceable(4) %ptr)
> -; ATTRIBUTOR: %B = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(4) %ptr)
> %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr)
> -
> br i1%c, label %if.true, label %if.false
> if.true:
> -; ATTRIBUTOR: %C = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) %ptr)
> %C = tail call i32 @unkown_f(i32* %ptr)
> -
> -; ATTRIBUTOR: %D = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) %ptr)
> %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
> -
> -; ATTRIBUTOR: %E = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) %ptr)
> %E = tail call i32 @unkown_f(i32* %ptr)
> -
> ret void
> -
> if.false:
> ret void
> }
>
> -; ATTRIBUTOR: define void @f7_2(i1 %c)
> define void @f7_2(i1 %c) {
> -
> +; CHECK-LABEL: define {{[^@]+}}@f7_2
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: [[PTR:%.*]] = tail call nonnull align 4
> dereferenceable(4) i32* @unkown_ptr()
> +; CHECK-NEXT: [[A:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(4) [[PTR]])
> +; CHECK-NEXT: [[B:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(4) [[PTR]])
> +; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label
> [[IF_FALSE:%.*]]
> +; CHECK: if.true:
> +; CHECK-NEXT: [[C:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) [[PTR]])
> +; CHECK-NEXT: [[D:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) [[PTR]])
> +; CHECK-NEXT: [[E:%.*]] = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) [[PTR]])
> +; CHECK-NEXT: ret void
> +; CHECK: if.false:
> +; CHECK-NEXT: ret void
> +;
> %ptr = tail call i32* @unkown_ptr()
> -
> -; ATTRIBUTOR: %A = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(4) %ptr)
> %A = tail call i32 @unkown_f(i32* %ptr)
> -
> %arg_a.0 = load i32, i32* %ptr
> ; deref 4 hold
> -
> -; ATTRIBUTOR: %B = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(4) %ptr)
> %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr)
> -
> br i1%c, label %if.true, label %if.false
> if.true:
> -
> -; ATTRIBUTOR: %C = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) %ptr)
> %C = tail call i32 @unkown_f(i32* %ptr)
> -
> -; ATTRIBUTOR: %D = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) %ptr)
> %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
> -
> %E = tail call i32 @unkown_f(i32* %ptr)
> -; ATTRIBUTOR: %E = tail call i32 @unkown_f(i32* nonnull align 4
> dereferenceable(8) %ptr)
> -
> ret void
> -
> if.false:
> ret void
> }
>
> define i32* @f7_3() {
> -; ATTRIBUTOR: define nonnull align 16 dereferenceable(4) i32* @f7_3()
> +; 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
> +; CHECK-NEXT: ret i32* [[PTR]]
> +;
> %ptr = tail call i32* @unkown_ptr()
> store i32 10, i32* %ptr, align 16
> ret i32* %ptr
> }
>
> -define i32* @test_for_minus_index(i32* %p) {
> ; FIXME: This should have a return dereferenceable(8) but we need to make
> sure it will work in loops as well.
> -; ATTRIBUTOR: define nonnull align 4 i32* @test_for_minus_index(i32*
> nofree nonnull writeonly align 4 "no-capture-maybe-returned" %p)
> +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]]
> +;
> %q = getelementptr inbounds i32, i32* %p, i32 -2
> store i32 1, i32* %q
> ret i32* %q
> }
>
> define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100)
> %0) {
> -; ATTRIBUTOR: define void @deref_or_null_and_nonnull(i32* nocapture
> nofree nonnull writeonly align 4 dereferenceable(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
> +;
> store i32 1, i32* %0
> ret void
> }
>
> -; UTC_ARGS: --enable
> -
> ; TEST 8
> ; Use Constant range in deereferenceable
> ; void g(int *p, long long int *range){
> @@ -223,24 +305,24 @@ define void @deref_or_null_and_nonnull(i32*
> dereferenceable_or_null(100) %0) {
> ; }
> ; }
>
> +; NOTE: %p should not be dereferenceable
> define internal void @fill_range_not_inbounds(i32* %p, i64 %start){
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@fill_range_not_inbounds
> -; ATTRIBUTOR-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64
> [[START:%.*]])
> -; ATTRIBUTOR-NEXT: entry:
> -; ATTRIBUTOR-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
> -; ATTRIBUTOR-NEXT: br label [[FOR_BODY:%.*]]
> -; ATTRIBUTOR: for.cond.cleanup:
> -; ATTRIBUTOR-NEXT: ret void
> -; ATTRIBUTOR: for.body:
> -; ATTRIBUTOR-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]]
> ], [ [[INC:%.*]], [[FOR_BODY]] ]
> -; ATTRIBUTOR-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
> -; ATTRIBUTOR-NEXT: [[ARRAYIDX:%.*]] = getelementptr i32, i32* [[P]],
> i64 [[I_06]]
> -; ATTRIBUTOR-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
> -; ATTRIBUTOR-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
> -; ATTRIBUTOR-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
> -; ATTRIBUTOR-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label
> [[FOR_COND_CLEANUP:%.*]]
> +; 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:%.*]]
> ;
> -; NOTE: %p should not be dereferenceable
> entry:
> %0 = add nsw i64 %start, 9
> br label %for.body
> @@ -257,24 +339,25 @@ for.body: ;
> preds = %entry, %for.body
> %cmp = icmp slt i64 %i.06, %0
> br i1 %cmp, label %for.body, label %for.cond.cleanup
> }
> +
> +; FIXME: %p should be dereferenceable(40)
> define internal void @fill_range_inbounds(i32* %p, i64 %start){
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@fill_range_inbounds
> -; ATTRIBUTOR-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64
> [[START:%.*]])
> -; ATTRIBUTOR-NEXT: entry:
> -; ATTRIBUTOR-NEXT: [[TMP0:%.*]] = add nsw i64 [[START]], 9
> -; ATTRIBUTOR-NEXT: br label [[FOR_BODY:%.*]]
> -; ATTRIBUTOR: for.cond.cleanup:
> -; ATTRIBUTOR-NEXT: ret void
> -; ATTRIBUTOR: for.body:
> -; ATTRIBUTOR-NEXT: [[I_06:%.*]] = phi i64 [ [[START]], [[ENTRY:%.*]]
> ], [ [[INC:%.*]], [[FOR_BODY]] ]
> -; ATTRIBUTOR-NEXT: [[CONV:%.*]] = trunc i64 [[I_06]] to i32
> -; ATTRIBUTOR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, i32*
> [[P]], i64 [[I_06]]
> -; ATTRIBUTOR-NEXT: store i32 [[CONV]], i32* [[ARRAYIDX]], align 4
> -; ATTRIBUTOR-NEXT: [[INC]] = add nsw i64 [[I_06]], 1
> -; ATTRIBUTOR-NEXT: [[CMP:%.*]] = icmp slt i64 [[I_06]], [[TMP0]]
> -; ATTRIBUTOR-NEXT: br i1 [[CMP]], label [[FOR_BODY]], label
> [[FOR_COND_CLEANUP:%.*]]
> +; 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:%.*]]
> ;
> -; FIXME: %p should be dereferenceable(40)
> entry:
> %0 = add nsw i64 %start, 9
> br label %for.body
> @@ -293,13 +376,13 @@ for.body: ;
> preds = %entry, %for.body
> }
>
> define void @call_fill_range(i32* nocapture %p, i64* nocapture readonly
> %range) {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@call_fill_range
> -; ATTRIBUTOR-SAME: (i32* nocapture nofree writeonly [[P:%.*]], i64*
> nocapture nofree nonnull readonly align 8 dereferenceable(8) [[RANGE:%.*]])
> -; ATTRIBUTOR-NEXT: entry:
> -; ATTRIBUTOR-NEXT: [[TMP0:%.*]] = load i64, i64* [[RANGE]], align 8,
> !range !0
> -; ATTRIBUTOR-NEXT: tail call void @fill_range_inbounds(i32* nocapture
> nofree writeonly [[P]], i64 [[TMP0]])
> -; ATTRIBUTOR-NEXT: tail call void @fill_range_not_inbounds(i32*
> nocapture nofree writeonly [[P]], i64 [[TMP0]])
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> entry:
> %0 = load i64, i64* %range, align 8, !range !0
> @@ -312,6 +395,7 @@ declare void @use0() willreturn nounwind
> declare void @use1(i8*) willreturn nounwind
> declare void @use2(i8*, i8*) willreturn nounwind
> declare void @use3(i8*, i8*, i8*) willreturn nounwind
> +
> ; simple path test
> ; if(..)
> ; fun2(dereferenceable(8) %a, dereferenceable(8) %b)
> @@ -319,7 +403,17 @@ 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) {
> -; ATTRIBUTOR: define void @simple-path(i8* nonnull dereferenceable(4) %a,
> i8* %b, i8 %c)
> +; CHECK-LABEL: define {{[^@]+}}@simple-path
> +; CHECK-SAME: (i8* nonnull dereferenceable(4) [[A:%.*]], i8* [[B:%.*]],
> i8 [[C:%.*]])
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
> +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_ELSE:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: tail call void @use2(i8* nonnull dereferenceable(8)
> [[A]], i8* nonnull dereferenceable(8) [[B]])
> +; CHECK-NEXT: ret void
> +; CHECK: if.else:
> +; CHECK-NEXT: tail call void @use2(i8* nonnull dereferenceable(4)
> [[A]], i8* [[B]])
> +; CHECK-NEXT: ret void
> +;
> %cmp = icmp eq i8 %c, 0
> br i1 %cmp, label %if.then, label %if.else
> if.then:
> @@ -329,6 +423,7 @@ if.else:
> tail call void @use2(i8* dereferenceable(4) %a, i8* %b)
> ret void
> }
> +
> ; More complex test
> ; {
> ; fun1(dereferenceable(4) %a)
> @@ -341,9 +436,22 @@ if.else:
> ; fun1(dereferenceable(8) %a)
> ; }
> ; %a is dereferenceable(12)
> -
> define void @complex-path(i8* %a, i8* %b, i8 %c) {
> -; ATTRIBUTOR: define void @complex-path(i8* nonnull dereferenceable(12)
> %a, i8* nocapture nofree readnone %b, i8 %c)
> +; 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
> +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(12)
> [[A]])
> +; CHECK-NEXT: br i1 [[CMP]], label [[CONT_THEN:%.*]], label
> [[CONT_ELSE:%.*]]
> +; CHECK: cont.then:
> +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(12)
> [[A]])
> +; CHECK-NEXT: br label [[CONT2:%.*]]
> +; CHECK: cont.else:
> +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(16)
> [[A]])
> +; CHECK-NEXT: br label [[CONT2]]
> +; CHECK: cont2:
> +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(12)
> [[A]])
> +; CHECK-NEXT: ret void
> +;
> %cmp = icmp eq i8 %c, 0
> tail call void @use1(i8* dereferenceable(4) %a)
> br i1 %cmp, label %cont.then, label %cont.else
> @@ -373,8 +481,33 @@ cont2:
> ; }
> ;
> ; FIXME: %ptr should be dereferenceable(4)
> -; ATTRIBUTOR: define dso_local void @rec-branch-1(i32 %a, i32 %b, i32 %c,
> i32* nocapture nofree writeonly %ptr)
> 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
> +;
> entry:
> %tobool = icmp eq i32 %a, 0
> br i1 %tobool, label %if.else3, label %if.then
> @@ -421,8 +554,33 @@ if.end8: ;
> preds = %if.then5, %if.else6
> ; }
> ; }
> ; FIXME: %ptr should be dereferenceable(4)
> -; ATTRIBUTOR: define dso_local void @rec-branch-2(i32 %a, i32 %b, i32 %c,
> i32* nocapture nofree writeonly %ptr)
> define dso_local void @rec-branch-2(i32 %a, i32 %b, i32 %c, i32* %ptr) {
> +; CHECK-LABEL: define {{[^@]+}}@rec-branch-2
> +; 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: tail call void @rec-branch-2(i32 1, i32 1, i32 1, i32*
> nocapture nofree writeonly [[PTR]])
> +; CHECK-NEXT: br label [[IF_END8]]
> +; CHECK: if.end8:
> +; CHECK-NEXT: ret void
> +;
> entry:
> %tobool = icmp eq i32 %a, 0
> br i1 %tobool, label %if.else3, label %if.then
> @@ -462,6 +620,24 @@ define void @nonnull_assume_pos(i8* %arg1, i8* %arg2,
> i8* %arg3, i8* %arg4) {
> ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #6 [ "nonnull"(i8*
> undef), "dereferenceable"(i8* undef, i64 1), "dereferenceable"(i8* undef,
> i64 2), "dereferenceable"(i8* undef, i64 101),
> "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8*
> undef, i64 42) ]
> ; ATTRIBUTOR-NEXT: call void @unknown()
> ; ATTRIBUTOR-NEXT: ret void
> +;
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
> +; IS__TUNIT_OPM-SAME: (i8* nocapture nofree nonnull readnone
> dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone
> dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull
> readnone [[ARG3:%.*]], i8* nocapture nofree readnone
> dereferenceable_or_null(42) [[ARG4:%.*]])
> +; IS__TUNIT_OPM-NEXT: call void @llvm.assume(i1 true) #6 [
> "nonnull"(i8* undef), "dereferenceable"(i8* undef, i64 1),
> "dereferenceable"(i8* undef, i64 2), "dereferenceable"(i8* undef, i64 101),
> "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8*
> undef, i64 42) ]
> +; IS__TUNIT_OPM-NEXT: call void @unknown()
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
> +; IS________NPM-SAME: (i8* nocapture nofree nonnull readnone
> dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone
> dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull
> readnone [[ARG3:%.*]], i8* nocapture nofree readnone
> dereferenceable_or_null(42) [[ARG4:%.*]])
> +; IS________NPM-NEXT: call void @llvm.assume(i1 true) #7 [
> "nonnull"(i8* undef), "dereferenceable"(i8* undef, i64 1),
> "dereferenceable"(i8* undef, i64 2), "dereferenceable"(i8* undef, i64 101),
> "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8*
> undef, i64 42) ]
> +; IS________NPM-NEXT: call void @unknown()
> +; IS________NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
> +; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone
> dereferenceable(101) [[ARG1:%.*]], i8* nocapture nofree readnone
> dereferenceable_or_null(31) [[ARG2:%.*]], i8* nocapture nofree nonnull
> readnone [[ARG3:%.*]], i8* nocapture nofree readnone
> dereferenceable_or_null(42) [[ARG4:%.*]])
> +; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #8 [
> "nonnull"(i8* undef), "dereferenceable"(i8* undef, i64 1),
> "dereferenceable"(i8* undef, i64 2), "dereferenceable"(i8* undef, i64 101),
> "dereferenceable_or_null"(i8* undef, i64 31), "dereferenceable_or_null"(i8*
> undef, i64 42) ]
> +; IS__CGSCC_OPM-NEXT: call void @unknown()
> +; IS__CGSCC_OPM-NEXT: ret void
> ;
> call void @llvm.assume(i1 true) [ "nonnull"(i8* %arg3),
> "dereferenceable"(i8* %arg1, i64 1), "dereferenceable"(i8* %arg1, i64 2),
> "dereferenceable"(i8* %arg1, i64 101), "dereferenceable_or_null"(i8* %arg2,
> i64 31), "dereferenceable_or_null"(i8* %arg4, i64 42)]
> call void @unknown()
> @@ -473,6 +649,12 @@ define void @nonnull_assume_neg(i8* %arg1, i8* %arg2,
> i8* %arg3) {
> ; ATTRIBUTOR-NEXT: call void @unknown()
> ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) [
> "dereferenceable"(i8* undef, i64 101), "dereferenceable"(i8* undef, i64
> -2), "dereferenceable_or_null"(i8* undef, i64 31) ]
> ; ATTRIBUTOR-NEXT: ret void
> +;
> +; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_neg
> +; CHECK-SAME: (i8* nocapture nofree readnone [[ARG1:%.*]], i8* nocapture
> nofree readnone [[ARG2:%.*]], i8* nocapture nofree readnone [[ARG3:%.*]])
> +; CHECK-NEXT: call void @unknown()
> +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(i8*
> undef, i64 101), "dereferenceable"(i8* undef, i64 -2),
> "dereferenceable_or_null"(i8* undef, i64 31) ]
> +; CHECK-NEXT: ret void
> ;
> call void @unknown()
> call void @llvm.assume(i1 true) ["dereferenceable"(i8* %arg1, i64 101),
> "dereferenceable"(i8* %arg2, i64 -2), "dereferenceable_or_null"(i8* %arg3,
> i64 31)]
> @@ -496,6 +678,24 @@ define void @nonnull_assume_call(i8* %arg1, i8*
> %arg2, i8* %arg3, i8* %arg4) {
> ; ATTRIBUTOR-NEXT: call void @unknown_use32(i32* nonnull
> dereferenceable(101) [[P]])
> ; ATTRIBUTOR-NEXT: call void @unknown()
> ; ATTRIBUTOR-NEXT: ret void
> +;
> +; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_call
> +; CHECK-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8*
> [[ARG4:%.*]])
> +; CHECK-NEXT: call void @unknown()
> +; CHECK-NEXT: [[P:%.*]] = call nonnull dereferenceable(101) i32*
> @unkown_ptr()
> +; CHECK-NEXT: call void @unknown_use32(i32* nonnull
> dereferenceable(101) [[P]])
> +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(42)
> [[ARG4]])
> +; CHECK-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]])
> +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(31)
> [[ARG2]])
> +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2)
> [[ARG1]])
> +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8*
> [[ARG3]]), "dereferenceable"(i8* [[ARG1]], i64 1), "dereferenceable"(i8*
> [[ARG1]], i64 2), "dereferenceable"(i32* [[P]], i64 101),
> "dereferenceable_or_null"(i8* [[ARG2]], i64 31),
> "dereferenceable_or_null"(i8* [[ARG4]], i64 42) ]
> +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(2)
> [[ARG1]])
> +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(31)
> [[ARG2]])
> +; CHECK-NEXT: call void @unknown_use8(i8* nonnull [[ARG3]])
> +; CHECK-NEXT: call void @unknown_use8(i8* nonnull dereferenceable(42)
> [[ARG4]])
> +; CHECK-NEXT: call void @unknown_use32(i32* nonnull
> dereferenceable(101) [[P]])
> +; CHECK-NEXT: call void @unknown()
> +; CHECK-NEXT: ret void
> ;
> call void @unknown()
> %p = call i32* @unkown_ptr()
>
> diff --git a/llvm/test/Transforms/Attributor/dereferenceable-2.ll
> b/llvm/test/Transforms/Attributor/dereferenceable-2.ll
> index 7ffc837caadc..3e94364a816b 100644
> --- a/llvm/test/Transforms/Attributor/dereferenceable-2.ll
> +++ b/llvm/test/Transforms/Attributor/dereferenceable-2.ll
> @@ -1,12 +1,29 @@
> -; RUN: opt < %s -attributor --attributor-disable=false -S | FileCheck %s
> --check-prefix=ATTRIBUTOR
> -; RUN: opt < %s -passes=attributor --attributor-disable=false -S |
> FileCheck %s --check-prefix=ATTRIBUTOR_CGSCC_NPM
> -; Copied from Transforms/InferFunctionAttrs/dereferenceable.ll
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; Determine dereference-ability before unused loads get deleted:
> ; https://bugs.llvm.org/show_bug.cgi?id=21780
>
> define <4 x double> @PR21780(double* %ptr) {
> -; ATTRIBUTOR-LABEL: @PR21780(double* nocapture nofree nonnull readonly
> align 8 dereferenceable(32) %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]]
> +;
>
> ; GEP of index 0 is simplified away.
> %arrayidx1 = getelementptr inbounds double, double* %ptr, i64 1
> @@ -28,7 +45,12 @@ define <4 x double> @PR21780(double* %ptr) {
>
>
> define double @PR21780_only_access3_with_inbounds(double* %ptr) {
> -; ATTRIBUTOR-LABEL: @PR21780_only_access3_with_inbounds(double* nocapture
> nofree nonnull readonly align 8 dereferenceable(32) %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]]
> +;
>
> %arrayidx3 = getelementptr inbounds double, double* %ptr, i64 3
> %t3 = load double, double* %arrayidx3, align 8
> @@ -36,14 +58,24 @@ define double
> @PR21780_only_access3_with_inbounds(double* %ptr) {
> }
>
> define double @PR21780_only_access3_without_inbounds(double* %ptr) {
> -; ATTRIBUTOR-LABEL: @PR21780_only_access3_without_inbounds(double*
> nocapture nofree readonly align 8 %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]]
> +;
> %arrayidx3 = getelementptr double, double* %ptr, i64 3
> %t3 = load double, double* %arrayidx3, align 8
> ret double %t3
> }
>
> define double @PR21780_without_inbounds(double* %ptr) {
> -; ATTRIBUTOR-LABEL: @PR21780_without_inbounds(double* nocapture nofree
> nonnull readonly align 8 dereferenceable(32) %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]]
> +;
>
> %arrayidx1 = getelementptr double, double* %ptr, i64 1
> %arrayidx2 = getelementptr double, double* %ptr, i64 2
> @@ -60,7 +92,13 @@ 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) {
> -; ATTRIBUTOR-LABEL: @gep0(i8* nocapture nofree readnone %unused, i8*
> nocapture nofree nonnull writeonly dereferenceable(1) %other, i8* nocapture
> nofree nonnull readonly dereferenceable(3) %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]]
> +; CHECK-NEXT: store i8 [[T2]], i8* [[OTHER]]
> +; CHECK-NEXT: ret void
> +;
> %arrayidx0 = getelementptr i8, i8* %ptr, i64 0
> %arrayidx1 = getelementptr i8, i8* %ptr, i64 1
> %arrayidx2 = getelementptr i8, i8* %ptr, i64 2
> @@ -75,7 +113,10 @@ define void @gep0(i8* %unused, i8* %other, i8* %ptr) {
> ; Multiple arguments may be dereferenceable.
>
> define void @ordering(i8* %ptr1, i32* %ptr2) {
> -; ATTRIBUTOR-LABEL: @ordering(i8* nocapture nofree nonnull readnone
> dereferenceable(3) %ptr1, i32* nocapture nofree nonnull readnone align 4
> dereferenceable(8) %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
> +;
> %a20 = getelementptr i32, i32* %ptr2, i64 0
> %a12 = getelementptr i8, i8* %ptr1, i64 2
> %t12 = load i8, i8* %a12
> @@ -92,7 +133,13 @@ define void @ordering(i8* %ptr1, i32* %ptr2) {
> ; Not in entry block.
>
> define void @not_entry_but_guaranteed_to_execute(i8* %ptr) {
> -; ATTRIBUTOR-LABEL: @not_entry_but_guaranteed_to_execute(i8* nocapture
> nofree nonnull readnone dereferenceable(3) %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
> +;
> entry:
> br label %exit
> exit:
> @@ -108,7 +155,15 @@ exit:
> ; Not in entry block and not guaranteed to execute.
>
> define void @not_entry_not_guaranteed_to_execute(i8* %ptr, i1 %cond) {
> -; ATTRIBUTOR-LABEL: @not_entry_not_guaranteed_to_execute(i8* nocapture
> nofree readnone %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
> +;
> entry:
> br i1 %cond, label %loads, label %exit
> loads:
> @@ -126,7 +181,15 @@ 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) {
> -; ATTRIBUTOR-LABEL: @partial_in_entry(i16* nocapture nofree nonnull
> readnone align 2 dereferenceable(4) %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
> +;
> entry:
> %arrayidx0 = getelementptr i16, i16* %ptr, i64 0
> %arrayidx1 = getelementptr i16, i16* %ptr, i64 1
> @@ -145,7 +208,12 @@ exit:
> ; The 2nd and 3rd loads may never execute.
>
> define void @volatile_is_not_dereferenceable(i16* %ptr) {
> -; ATTRIBUTOR-LABEL: @volatile_is_not_dereferenceable(i16* nofree align 2
> %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
> +;
> %arrayidx0 = getelementptr i16, i16* %ptr, i64 0
> %arrayidx1 = getelementptr i16, i16* %ptr, i64 1
> %arrayidx2 = getelementptr i16, i16* %ptr, i64 2
> @@ -158,7 +226,10 @@ 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) {
> -; ATTRIBUTOR-LABEL: @atomic_is_alright(i16* nocapture nofree nonnull
> readnone align 2 dereferenceable(6) %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@atomic_is_alright
> +; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2
> dereferenceable(6) [[PTR:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %arrayidx0 = getelementptr i16, i16* %ptr, i64 0
> %arrayidx1 = getelementptr i16, i16* %ptr, i64 1
> %arrayidx2 = getelementptr i16, i16* %ptr, i64 2
> @@ -171,7 +242,11 @@ define void @atomic_is_alright(i16* %ptr) {
> declare void @may_not_return()
>
> define void @not_guaranteed_to_transfer_execution(i16* %ptr) {
> -; ATTRIBUTOR-LABEL: @not_guaranteed_to_transfer_execution(i16* nocapture
> nofree nonnull readnone align 2 dereferenceable(2) %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@not_guaranteed_to_transfer_execution
> +; CHECK-SAME: (i16* nocapture nofree nonnull readnone align 2
> dereferenceable(2) [[PTR:%.*]])
> +; CHECK-NEXT: call void @may_not_return()
> +; CHECK-NEXT: ret void
> +;
> %arrayidx0 = getelementptr i16, i16* %ptr, i64 0
> %arrayidx1 = getelementptr i16, i16* %ptr, i64 1
> %arrayidx2 = getelementptr i16, i16* %ptr, i64 2
> @@ -185,7 +260,10 @@ 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) {
> -; ATTRIBUTOR-LABEL: @variable_gep_index(i8* nocapture nofree readnone
> %unused, i8* nocapture nofree nonnull readnone dereferenceable(1) %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
> +;
> %arrayidx1 = getelementptr i8, i8* %ptr, i64 %variable_index
> %arrayidx2 = getelementptr i8, i8* %ptr, i64 2
> %t0 = load i8, i8* %ptr
> @@ -198,7 +276,10 @@ 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)
> -; ATTRIBUTOR-LABEL: @multi_index_gep(<4 x i8>* nocapture nofree nonnull
> readnone dereferenceable(1) %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@multi_index_gep
> +; CHECK-SAME: (<4 x i8>* nocapture nofree nonnull readnone
> dereferenceable(1) [[PTR:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %arrayidx00 = getelementptr <4 x i8>, <4 x i8>* %ptr, i64 0, i64 0
> %t0 = load i8, i8* %arrayidx00
> ret void
> @@ -207,7 +288,10 @@ define void @multi_index_gep(<4 x i8>* %ptr) {
> ; Could round weird bitwidths down?
>
> define void @not_byte_multiple(i9* %ptr) {
> -; ATTRIBUTOR-LABEL: @not_byte_multiple(i9* nocapture nofree nonnull
> readnone align 2 dereferenceable(2) %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@not_byte_multiple
> +; CHECK-SAME: (i9* nocapture nofree nonnull readnone align 2
> dereferenceable(2) [[PTR:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %arrayidx0 = getelementptr i9, i9* %ptr, i64 0
> %t0 = load i9, i9* %arrayidx0
> ret void
> @@ -216,7 +300,10 @@ define void @not_byte_multiple(i9* %ptr) {
> ; Missing direct access from the pointer.
>
> define void @no_pointer_deref(i16* %ptr) {
> -; ATTRIBUTOR-LABEL: @no_pointer_deref(i16* nocapture nofree readnone
> align 2 %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@no_pointer_deref
> +; CHECK-SAME: (i16* nocapture nofree readnone align 2 [[PTR:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %arrayidx1 = getelementptr i16, i16* %ptr, i64 1
> %arrayidx2 = getelementptr i16, i16* %ptr, i64 2
> %t1 = load i16, i16* %arrayidx1
> @@ -227,7 +314,10 @@ define void @no_pointer_deref(i16* %ptr) {
> ; Out-of-order is ok, but missing access concludes dereferenceable range.
>
> define void @non_consecutive(i32* %ptr) {
> -; ATTRIBUTOR-LABEL: @non_consecutive(i32* nocapture nofree nonnull
> readnone align 4 dereferenceable(8) %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@non_consecutive
> +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4
> dereferenceable(8) [[PTR:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %arrayidx1 = getelementptr i32, i32* %ptr, i64 1
> %arrayidx0 = getelementptr i32, i32* %ptr, i64 0
> %arrayidx3 = getelementptr i32, i32* %ptr, i64 3
> @@ -240,7 +330,10 @@ define void @non_consecutive(i32* %ptr) {
> ; Improve on existing dereferenceable attribute.
>
> define void @more_bytes(i32* dereferenceable(8) %ptr) {
> -; ATTRIBUTOR-LABEL: @more_bytes(i32* nocapture nofree nonnull readnone
> align 4 dereferenceable(16) %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@more_bytes
> +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4
> dereferenceable(16) [[PTR:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %arrayidx3 = getelementptr i32, i32* %ptr, i64 3
> %arrayidx1 = getelementptr i32, i32* %ptr, i64 1
> %arrayidx0 = getelementptr i32, i32* %ptr, i64 0
> @@ -255,7 +348,10 @@ 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) {
> -; ATTRIBUTOR-LABEL: @more_bytes_and_not_null(i32* nocapture nofree
> nonnull readnone align 4 dereferenceable(16) %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
> +;
> %arrayidx3 = getelementptr i32, i32* %ptr, i64 3
> %arrayidx1 = getelementptr i32, i32* %ptr, i64 1
> %arrayidx0 = getelementptr i32, i32* %ptr, i64 0
> @@ -270,7 +366,10 @@ 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) {
> -; ATTRIBUTOR-LABEL: @better_bytes(i32* nocapture nofree nonnull readnone
> align 4 dereferenceable(100) %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@better_bytes
> +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4
> dereferenceable(100) [[PTR:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %arrayidx3 = getelementptr i32, i32* %ptr, i64 3
> %arrayidx1 = getelementptr i32, i32* %ptr, i64 1
> %arrayidx0 = getelementptr i32, i32* %ptr, i64 0
> @@ -283,7 +382,10 @@ define void @better_bytes(i32* dereferenceable(100)
> %ptr) {
> }
>
> define void @bitcast(i32* %arg) {
> -; ATTRIBUTOR-LABEL: @bitcast(i32* nocapture nofree nonnull readnone align
> 4 dereferenceable(8) %arg)
> +; CHECK-LABEL: define {{[^@]+}}@bitcast
> +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4
> dereferenceable(8) [[ARG:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %ptr = bitcast i32* %arg to float*
> %arrayidx0 = getelementptr float, float* %ptr, i64 0
> %arrayidx1 = getelementptr float, float* %ptr, i64 1
> @@ -293,7 +395,10 @@ define void @bitcast(i32* %arg) {
> }
>
> define void @bitcast_
> diff erent_sizes(double* %arg1, i8* %arg2) {
> -; ATTRIBUTOR-LABEL: @bitcast_
> diff erent_sizes(double* nocapture nofree nonnull readnone align 4
> dereferenceable(12) %arg1, i8* nocapture nofree nonnull readnone align 4
> dereferenceable(16) %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
> +;
> %ptr1 = bitcast double* %arg1 to float*
> %a10 = getelementptr float, float* %ptr1, i64 0
> %a11 = getelementptr float, float* %ptr1, i64 1
> @@ -311,7 +416,10 @@ define void @bitcast_
> diff erent_sizes(double* %arg1, i8* %arg2) {
> }
>
> define void @negative_offset(i32* %arg) {
> -; ATTRIBUTOR-LABEL: @negative_offset(i32* nocapture nofree nonnull
> readnone align 4 dereferenceable(4) %arg)
> +; CHECK-LABEL: define {{[^@]+}}@negative_offset
> +; CHECK-SAME: (i32* nocapture nofree nonnull readnone align 4
> dereferenceable(4) [[ARG:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %ptr = bitcast i32* %arg to float*
> %arrayidx0 = getelementptr float, float* %ptr, i64 0
> %arrayidx1 = getelementptr float, float* %ptr, i64 -1
> @@ -321,7 +429,15 @@ define void @negative_offset(i32* %arg) {
> }
>
> define void @stores(i32* %arg) {
> -; ATTRIBUTOR-LABEL: @stores(i32* nocapture nofree nonnull writeonly align
> 4 dereferenceable(8) %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
> +;
> %ptr = bitcast i32* %arg to float*
> %arrayidx0 = getelementptr float, float* %ptr, i64 0
> %arrayidx1 = getelementptr float, float* %ptr, i64 1
> @@ -331,7 +447,13 @@ define void @stores(i32* %arg) {
> }
>
> define void @load_store(i32* %arg) {
> -; ATTRIBUTOR-LABEL: @load_store(i32* nocapture nofree nonnull writeonly
> align 4 dereferenceable(8) %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
> +;
> %ptr = bitcast i32* %arg to float*
> %arrayidx0 = getelementptr float, float* %ptr, i64 0
> %arrayidx1 = getelementptr float, float* %ptr, i64 1
> @@ -341,7 +463,13 @@ define void @load_store(i32* %arg) {
> }
>
> define void @
> diff erent_size1(i32* %arg) {
> -; ATTRIBUTOR-LABEL: @
> diff erent_size1(i32* nocapture nofree nonnull writeonly align 8
> dereferenceable(8) %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
> +;
> %arg-cast = bitcast i32* %arg to double*
> store double 0.000000e+00, double* %arg-cast
> store i32 0, i32* %arg
> @@ -349,7 +477,13 @@ define void @
> diff erent_size1(i32* %arg) {
> }
>
> define void @
> diff erent_size2(i32* %arg) {
> -; ATTRIBUTOR-LABEL: @
> diff erent_size2(i32* nocapture nofree nonnull writeonly align 8
> dereferenceable(8) %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
> +;
> store i32 0, i32* %arg
> %arg-cast = bitcast i32* %arg to double*
> store double 0.000000e+00, double* %arg-cast
> @@ -375,12 +509,63 @@ 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]]
> +; IS________OPM-NEXT: br label [[END:%.*]]
> +; IS________OPM: l7:
> +; IS________OPM-NEXT: store i32 1, i32* [[P]]
> +; 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
> +;
> %tobool1 = icmp eq i32 %c, 0
> br i1 %tobool1, label %l1, label %l2
> -l1:
> +l1:
> %tobool2 = icmp eq i32 %c, 1
> br i1 %tobool2, label %l3, label %l4
> -l2:
> +l2:
> %tobool3 = icmp eq i32 %c, 2
> br i1 %tobool3, label %l3, label %l4
> l3:
>
> diff --git a/llvm/test/Transforms/Attributor/heap_to_stack.ll
> b/llvm/test/Transforms/Attributor/heap_to_stack.ll
> index 3adbf3812f17..3049d5154100 100644
> --- a/llvm/test/Transforms/Attributor/heap_to_stack.ll
> +++ b/llvm/test/Transforms/Attributor/heap_to_stack.ll
> @@ -1,4 +1,8 @@
> -; RUN: opt -passes=attributor --attributor-disable=false
> -attributor-annotate-decl-cs -S < %s | FileCheck %s
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> declare noalias i8* @malloc(i64)
>
> @@ -24,8 +28,13 @@ declare void @free(i8* nocapture)
>
> declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
>
> -; CHECK: @nofree_arg_only(i8* nocapture nofree %p1, i8* nocapture %p2)
> define void @nofree_arg_only(i8* %p1, i8* %p2) {
> +; CHECK-LABEL: define {{[^@]+}}@nofree_arg_only
> +; CHECK-SAME: (i8* nocapture nofree [[P1:%.*]], i8* nocapture [[P2:%.*]])
> +; CHECK-NEXT: tail call void @free(i8* nocapture [[P2]])
> +; CHECK-NEXT: tail call void @nofree_func(i8* nocapture nofree [[P1]])
> +; CHECK-NEXT: ret void
> +;
> tail call void @free(i8* %p2)
> tail call void @nofree_func(i8* %p1)
> ret void
> @@ -34,9 +43,21 @@ define void @nofree_arg_only(i8* %p1, i8* %p2) {
> ; TEST 1 - negative, pointer freed in another function.
>
> define void @test1() {
> +; IS________OPM-LABEL: define {{[^@]+}}@test1()
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: tail call void @nocapture_func_frees_pointer(i8*
> noalias [[TMP1]])
> +; IS________OPM-NEXT: tail call void (...) @func_throws()
> +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test1()
> +; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________NPM-NEXT: tail call void @nocapture_func_frees_pointer(i8*
> noalias nocapture [[TMP1]])
> +; IS________NPM-NEXT: tail call void (...) @func_throws()
> +; IS________NPM-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; IS________NPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: @malloc(i64 4)
> - ; CHECK-NEXT: @nocapture_func_frees_pointer(i8* noalias nocapture %1)
> tail call void @nocapture_func_frees_pointer(i8* %1)
> tail call void (...) @func_throws()
> tail call void @free(i8* %1)
> @@ -46,9 +67,13 @@ define void @test1() {
> ; TEST 2 - negative, call to a sync function.
>
> define void @test2() {
> +; CHECK-LABEL: define {{[^@]+}}@test2()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: tail call void @sync_func(i8* [[TMP1]])
> +; CHECK-NEXT: tail call void @free(i8* [[TMP1]])
> +; CHECK-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: @malloc(i64 4)
> - ; CHECK-NEXT: @sync_func(i8* %1)
> tail call void @sync_func(i8* %1)
> tail call void @free(i8* %1)
> ret void
> @@ -57,21 +82,46 @@ define void @test2() {
> ; TEST 3 - 1 malloc, 1 free
>
> define void @test3() {
> +; IS________OPM-LABEL: define {{[^@]+}}@test3()
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree
> [[TMP1]])
> +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test3()
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias
> nocapture nofree [[TMP1]])
> +; IS________NPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %1 = alloca i8, i64 4
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
> tail call void @no_sync_func(i8* %1)
> - ; CHECK-NOT: @free(i8* %1)
> tail call void @free(i8* %1)
> ret void
> }
>
> define void @test3a(i8* %p) {
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3a
> +; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]])
> +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture
> nofree [[TMP1]], i8* nocapture [[P]])
> +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test3a
> +; IS________NPM-SAME: (i8* nocapture [[P:%.*]])
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias
> nocapture nofree [[TMP1]], i8* nocapture [[P]])
> +; IS________NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3a
> +; IS__CGSCC_OPM-SAME: (i8* nocapture [[P:%.*]])
> +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nofree
> [[TMP1]], i8* nocapture [[P]])
> +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %1 = alloca i8, i64 4
> - ; CHECK-NEXT: tail call void @nofree_arg_only
> tail call void @nofree_arg_only(i8* %1, i8* %p)
> - ; CHECK-NOT: @free(i8* %1)
> tail call void @free(i8* %1)
> ret void
> }
> @@ -79,19 +129,41 @@ define void @test3a(i8* %p) {
> declare noalias i8* @aligned_alloc(i64, i64)
>
> define void @test3b(i8* %p) {
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test3b
> +; IS__TUNIT_OPM-SAME: (i8* nocapture [[P:%.*]])
> +; IS__TUNIT_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8*
> @aligned_alloc(i64 32, i64 128)
> +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture
> nofree [[TMP1]], i8* nocapture [[P]])
> +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test3b
> +; IS________NPM-SAME: (i8* nocapture [[P:%.*]])
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 128, align 32
> +; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias
> nocapture nofree [[TMP1]], i8* nocapture [[P]])
> +; IS________NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test3b
> +; IS__CGSCC_OPM-SAME: (i8* nocapture [[P:%.*]])
> +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8*
> @aligned_alloc(i64 32, i64 128)
> +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nofree
> [[TMP1]], i8* nocapture [[P]])
> +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @aligned_alloc(i64 32, i64 128)
> - ; CHECK: %1 = alloca i8, i64 128, align 32
> - ; CHECK-NEXT: tail call void @nofree_arg_only
> tail call void @nofree_arg_only(i8* %1, i8* %p)
> - ; CHECK-NOT: @free(i8* %1)
> tail call void @free(i8* %1)
> ret void
> }
>
> ; leave alone non-constant alignments.
> define void @test3c(i64 %alignment) {
> +; CHECK-LABEL: define {{[^@]+}}@test3c
> +; CHECK-SAME: (i64 [[ALIGNMENT:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @aligned_alloc(i64
> [[ALIGNMENT]], i64 128)
> +; CHECK-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; CHECK-NEXT: ret void
> +;
> %1 = tail call noalias i8* @aligned_alloc(i64 %alignment, i64 128)
> - ; CHECK: tail call noalias i8* @aligned_alloc
> tail call void @free(i8* %1)
> ret void
> }
> @@ -99,22 +171,38 @@ define void @test3c(i64 %alignment) {
> declare noalias i8* @calloc(i64, i64)
>
> define void @test0() {
> +; IS________OPM-LABEL: define {{[^@]+}}@test0()
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64
> 2, i64 4)
> +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree
> [[TMP1]])
> +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test0()
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 8
> +; IS________NPM-NEXT: [[CALLOC_BC:%.*]] = bitcast i8* [[TMP1]] to i8*
> +; IS________NPM-NEXT: call void @llvm.memset.p0i8.i64(i8*
> [[CALLOC_BC]], i8 0, i64 8, i1 false)
> +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias
> nocapture nofree [[TMP1]])
> +; IS________NPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @calloc(i64 2, i64 4)
> - ; CHECK: %1 = alloca i8, i64 8
> - ; CHECK-NEXT: %calloc_bc = bitcast i8* %1 to i8*
> - ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %calloc_bc, i8 0, i64
> 8, i1 false)
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
> tail call void @no_sync_func(i8* %1)
> - ; CHECK-NOT: @free(i8* %1)
> tail call void @free(i8* %1)
> ret void
> }
>
> ; TEST 4
> define void @test4() {
> +; IS________OPM-LABEL: define {{[^@]+}}@test4()
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nofree
> [[TMP1]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test4()
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias
> nocapture nofree [[TMP1]])
> +; IS________NPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %1 = alloca i8, i64 4
> - ; CHECK-NEXT: @nofree_func(i8* noalias nocapture nofree %1)
> tail call void @nofree_func(i8* %1)
> ret void
> }
> @@ -123,9 +211,51 @@ define void @test4() {
> ; are in nofree functions and are not captured
>
> define void @test5(i32, i8* %p) {
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test5
> +; IS__TUNIT_OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]])
> +; IS__TUNIT_OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS__TUNIT_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
> +; IS__TUNIT_OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label
> [[TMP4:%.*]]
> +; IS__TUNIT_OPM: 4:
> +; IS__TUNIT_OPM-NEXT: tail call void @nofree_func(i8* noalias nofree
> [[TMP2]])
> +; IS__TUNIT_OPM-NEXT: br label [[TMP6:%.*]]
> +; IS__TUNIT_OPM: 5:
> +; IS__TUNIT_OPM-NEXT: tail call void @nofree_arg_only(i8* nocapture
> nofree [[TMP2]], i8* nocapture [[P]])
> +; IS__TUNIT_OPM-NEXT: tail call void @free(i8* noalias [[TMP2]])
> +; IS__TUNIT_OPM-NEXT: br label [[TMP6]]
> +; IS__TUNIT_OPM: 6:
> +; IS__TUNIT_OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test5
> +; IS________NPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]])
> +; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
> +; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label
> [[TMP4:%.*]]
> +; IS________NPM: 4:
> +; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias
> nocapture nofree [[TMP2]])
> +; IS________NPM-NEXT: br label [[TMP6:%.*]]
> +; IS________NPM: 5:
> +; IS________NPM-NEXT: tail call void @nofree_arg_only(i8* noalias
> nocapture nofree [[TMP2]], i8* nocapture [[P]])
> +; IS________NPM-NEXT: br label [[TMP6]]
> +; IS________NPM: 6:
> +; IS________NPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test5
> +; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]], i8* nocapture [[P:%.*]])
> +; IS__CGSCC_OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS__CGSCC_OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
> +; IS__CGSCC_OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label
> [[TMP4:%.*]]
> +; IS__CGSCC_OPM: 4:
> +; IS__CGSCC_OPM-NEXT: tail call void @nofree_func(i8* noalias nofree
> [[TMP2]])
> +; IS__CGSCC_OPM-NEXT: br label [[TMP6:%.*]]
> +; IS__CGSCC_OPM: 5:
> +; IS__CGSCC_OPM-NEXT: tail call void @nofree_arg_only(i8* nofree
> [[TMP2]], i8* nocapture [[P]])
> +; IS__CGSCC_OPM-NEXT: tail call void @free(i8* noalias [[TMP2]])
> +; IS__CGSCC_OPM-NEXT: br label [[TMP6]]
> +; IS__CGSCC_OPM: 6:
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> %2 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %2 = alloca i8, i64 4
> - ; CHECK-NEXT: icmp eq i32 %0, 0
> %3 = icmp eq i32 %0, 0
> br i1 %3, label %5, label %4
>
> @@ -136,7 +266,6 @@ define void @test5(i32, i8* %p) {
> 5: ; preds = %1
> tail call void @nofree_arg_only(i8* %2, i8* %p)
> tail call void @free(i8* %2)
> - ; CHECK-NOT: @free(i8* %2)
> br label %6
>
> 6: ; preds = %5, %4
> @@ -146,21 +275,45 @@ define void @test5(i32, i8* %p) {
> ; TEST 6 - all exit paths have a call to free
>
> define void @test6(i32) {
> +; IS________OPM-LABEL: define {{[^@]+}}@test6
> +; IS________OPM-SAME: (i32 [[TMP0:%.*]])
> +; IS________OPM-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
> +; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label
> [[TMP4:%.*]]
> +; IS________OPM: 4:
> +; IS________OPM-NEXT: tail call void @nofree_func(i8* noalias nofree
> [[TMP2]])
> +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP2]])
> +; IS________OPM-NEXT: br label [[TMP6:%.*]]
> +; IS________OPM: 5:
> +; IS________OPM-NEXT: tail call void @free(i8* noalias [[TMP2]])
> +; IS________OPM-NEXT: br label [[TMP6]]
> +; IS________OPM: 6:
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test6
> +; IS________NPM-SAME: (i32 [[TMP0:%.*]])
> +; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
> +; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label
> [[TMP4:%.*]]
> +; IS________NPM: 4:
> +; IS________NPM-NEXT: tail call void @nofree_func(i8* noalias
> nocapture nofree [[TMP2]])
> +; IS________NPM-NEXT: br label [[TMP6:%.*]]
> +; IS________NPM: 5:
> +; IS________NPM-NEXT: br label [[TMP6]]
> +; IS________NPM: 6:
> +; IS________NPM-NEXT: ret void
> +;
> %2 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %2 = alloca i8, i64 4
> - ; CHECK-NEXT: icmp eq i32 %0, 0
> %3 = icmp eq i32 %0, 0
> br i1 %3, label %5, label %4
>
> 4: ; preds = %1
> tail call void @nofree_func(i8* %2)
> tail call void @free(i8* %2)
> - ; CHECK-NOT: @free(i8* %2)
> br label %6
>
> 5: ; preds = %1
> tail call void @free(i8* %2)
> - ; CHECK-NOT: @free(i8* %2)
> br label %6
>
> 6: ; preds = %5, %4
> @@ -170,11 +323,18 @@ define void @test6(i32) {
> ; TEST 7 - free is dead.
>
> define void @test7() {
> +; 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-LABEL: define {{[^@]+}}@test7()
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: [[TMP2:%.*]] = tail call i32 @no_return_call()
> +; IS________NPM-NEXT: unreachable
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: alloca i8, i64 4
> - ; CHECK-NEXT: tail call i32 @no_return_call()
> tail call i32 @no_return_call()
> - ; CHECK-NOT: @free(i8* %1)
> tail call void @free(i8* %1)
> ret void
> }
> @@ -182,30 +342,42 @@ define void @test7() {
> ; TEST 8 - Negative: bitcast pointer used in capture function
>
> define void @test8() {
> +; CHECK-LABEL: define {{[^@]+}}@test8()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture
> nofree [[TMP1]])
> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; CHECK-NEXT: tail call void @foo(i32* align 4 [[TMP2]])
> +; CHECK-NEXT: tail call void @free(i8* nonnull align 4
> dereferenceable(4) [[TMP1]])
> +; CHECK-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
> tail call void @no_sync_func(i8* %1)
> %2 = bitcast i8* %1 to i32*
> store i32 10, i32* %2
> %3 = load i32, i32* %2
> tail call void @foo(i32* %2)
> - ; CHECK: @free(i8* nonnull align 4 dereferenceable(4) %1)
> tail call void @free(i8* %1)
> ret void
> }
>
> ; TEST 9 - FIXME: malloc should be converted.
> define void @test9() {
> +; CHECK-LABEL: define {{[^@]+}}@test9()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nocapture
> nofree [[TMP1]])
> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; CHECK-NEXT: tail call void @foo_nounw(i32* nofree align 4 [[TMP2]])
> +; CHECK-NEXT: tail call void @free(i8* nonnull align 4
> dereferenceable(4) [[TMP1]])
> +; CHECK-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
> tail call void @no_sync_func(i8* %1)
> %2 = bitcast i8* %1 to i32*
> store i32 10, i32* %2
> %3 = load i32, i32* %2
> tail call void @foo_nounw(i32* %2)
> - ; CHECK: @free(i8* nonnull align 4 dereferenceable(4) %1)
> tail call void @free(i8* %1)
> ret void
> }
> @@ -213,28 +385,58 @@ define void @test9() {
> ; TEST 10 - 1 malloc, 1 free
>
> define i32 @test10() {
> +; IS________OPM-LABEL: define {{[^@]+}}@test10()
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree
> [[TMP1]])
> +; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
> +; IS________OPM-NEXT: tail call void @free(i8* noalias nonnull align 4
> dereferenceable(4) [[TMP1]])
> +; IS________OPM-NEXT: ret i32 [[TMP3]]
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test10()
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias
> nocapture nofree [[TMP1]])
> +; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
> +; IS________NPM-NEXT: ret i32 [[TMP3]]
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %1 = alloca i8, i64 4
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
> tail call void @no_sync_func(i8* %1)
> %2 = bitcast i8* %1 to i32*
> store i32 10, i32* %2
> %3 = load i32, i32* %2
> - ; CHECK-NOT: @free(i8* %1)
> tail call void @free(i8* %1)
> ret i32 %3
> }
>
> define i32 @test_lifetime() {
> +; IS________OPM-LABEL: define {{[^@]+}}@test_lifetime()
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree
> [[TMP1]])
> +; IS________OPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8*
> noalias nonnull align 4 dereferenceable(4) [[TMP1]])
> +; IS________OPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; IS________OPM-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; IS________OPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
> +; IS________OPM-NEXT: tail call void @free(i8* noalias nonnull align 4
> dereferenceable(4) [[TMP1]])
> +; IS________OPM-NEXT: ret i32 [[TMP3]]
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test_lifetime()
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias
> nocapture nofree [[TMP1]])
> +; IS________NPM-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8*
> noalias nonnull align 4 dereferenceable(4) [[TMP1]])
> +; IS________NPM-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; IS________NPM-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; IS________NPM-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
> +; IS________NPM-NEXT: ret i32 [[TMP3]]
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: %1 = alloca i8, i64 4
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
> tail call void @no_sync_func(i8* %1)
> call void @llvm.lifetime.start.p0i8(i64 4, i8* %1)
> %2 = bitcast i8* %1 to i32*
> store i32 10, i32* %2
> %3 = load i32, i32* %2
> - ; CHECK-NOT: @free(i8* %1)
> tail call void @free(i8* %1)
> ret i32 %3
> }
> @@ -242,10 +444,18 @@ define i32 @test_lifetime() {
> ; TEST 11
>
> define void @test11() {
> +; IS________OPM-LABEL: define {{[^@]+}}@test11()
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: tail call void @sync_will_return(i8* [[TMP1]])
> +; IS________OPM-NEXT: tail call void @free(i8* [[TMP1]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test11()
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: tail call void @sync_will_return(i8* [[TMP1]])
> +; IS________NPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK: test11
> - ; CHECK-NEXT: alloc
> - ; CHECK-NEXT: @sync_will_return(i8* %1)
> tail call void @sync_will_return(i8* %1)
> tail call void @free(i8* %1)
> ret void
> @@ -253,8 +463,67 @@ define void @test11() {
>
> ; TEST 12
> define i32 @irreducible_cfg(i32 %0) {
> - ; CHECK: alloca i8, i64 4
> - ; CHECK-NEXT: %3 = bitcast
> +; IS________OPM-LABEL: define {{[^@]+}}@irreducible_cfg
> +; IS________OPM-SAME: (i32 [[TMP0:%.*]])
> +; IS________OPM-NEXT: [[TMP2:%.*]] = call noalias i8* @malloc(i64 4)
> +; IS________OPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
> +; IS________OPM-NEXT: store i32 10, i32* [[TMP3]], align 4
> +; IS________OPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
> +; IS________OPM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label
> [[TMP7:%.*]]
> +; IS________OPM: 5:
> +; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
> +; IS________OPM-NEXT: br label [[TMP13:%.*]]
> +; IS________OPM: 7:
> +; IS________OPM-NEXT: br label [[TMP8:%.*]]
> +; IS________OPM: 8:
> +; IS________OPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]],
> [[TMP13]] ], [ 1, [[TMP7]] ]
> +; IS________OPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
> +; IS________OPM-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
> +; IS________OPM-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4
> +; IS________OPM-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
> +; IS________OPM-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label
> [[TMP15:%.*]]
> +; IS________OPM: 12:
> +; IS________OPM-NEXT: br label [[TMP13]]
> +; IS________OPM: 13:
> +; IS________OPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [
> [[DOT0]], [[TMP12]] ]
> +; IS________OPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1
> +; IS________OPM-NEXT: br label [[TMP8]]
> +; IS________OPM: 15:
> +; IS________OPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8*
> +; IS________OPM-NEXT: call void @free(i8* [[TMP16]])
> +; IS________OPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
> +; IS________OPM-NEXT: ret i32 [[TMP17]]
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@irreducible_cfg
> +; IS________NPM-SAME: (i32 [[TMP0:%.*]])
> +; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: [[TMP3:%.*]] = bitcast i8* [[TMP2]] to i32*
> +; IS________NPM-NEXT: store i32 10, i32* [[TMP3]], align 4
> +; IS________NPM-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP0]], 1
> +; IS________NPM-NEXT: br i1 [[TMP4]], label [[TMP5:%.*]], label
> [[TMP7:%.*]]
> +; IS________NPM: 5:
> +; IS________NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], 5
> +; IS________NPM-NEXT: br label [[TMP13:%.*]]
> +; IS________NPM: 7:
> +; IS________NPM-NEXT: br label [[TMP8:%.*]]
> +; IS________NPM: 8:
> +; IS________NPM-NEXT: [[DOT0:%.*]] = phi i32 [ [[TMP14:%.*]],
> [[TMP13]] ], [ 1, [[TMP7]] ]
> +; IS________NPM-NEXT: [[TMP9:%.*]] = load i32, i32* [[TMP3]], align 4
> +; IS________NPM-NEXT: [[TMP10:%.*]] = add nsw i32 [[TMP9]], -1
> +; IS________NPM-NEXT: store i32 [[TMP10]], i32* [[TMP3]], align 4
> +; IS________NPM-NEXT: [[TMP11:%.*]] = icmp ne i32 [[TMP9]], 0
> +; IS________NPM-NEXT: br i1 [[TMP11]], label [[TMP12:%.*]], label
> [[TMP15:%.*]]
> +; IS________NPM: 12:
> +; IS________NPM-NEXT: br label [[TMP13]]
> +; IS________NPM: 13:
> +; IS________NPM-NEXT: [[DOT1:%.*]] = phi i32 [ [[TMP6]], [[TMP5]] ], [
> [[DOT0]], [[TMP12]] ]
> +; IS________NPM-NEXT: [[TMP14]] = add nsw i32 [[DOT1]], 1
> +; IS________NPM-NEXT: br label [[TMP8]]
> +; IS________NPM: 15:
> +; IS________NPM-NEXT: [[TMP16:%.*]] = bitcast i32* [[TMP3]] to i8*
> +; IS________NPM-NEXT: [[TMP17:%.*]] = load i32, i32* [[TMP3]], align 4
> +; IS________NPM-NEXT: ret i32 [[TMP17]]
> +;
> %2 = call noalias i8* @malloc(i64 4)
> %3 = bitcast i8* %2 to i32*
> store i32 10, i32* %3, align 4
> @@ -294,6 +563,46 @@ define i32 @irreducible_cfg(i32 %0) {
>
>
> define i32 @malloc_in_loop(i32 %0) {
> +; IS________OPM-LABEL: define {{[^@]+}}@malloc_in_loop
> +; IS________OPM-SAME: (i32 [[TMP0:%.*]])
> +; IS________OPM-NEXT: [[TMP2:%.*]] = alloca i32, align 4
> +; IS________OPM-NEXT: [[TMP3:%.*]] = alloca i32*, align 8
> +; IS________OPM-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4
> +; IS________OPM-NEXT: br label [[TMP4:%.*]]
> +; IS________OPM: 4:
> +; IS________OPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4
> +; IS________OPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1
> +; IS________OPM-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4
> +; IS________OPM-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0
> +; IS________OPM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label
> [[TMP11:%.*]]
> +; IS________OPM: 8:
> +; IS________OPM-NEXT: [[TMP9:%.*]] = call noalias i8* @malloc(i64 4)
> +; IS________OPM-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32*
> +; IS________OPM-NEXT: store i32 1, i32* [[TMP10]], align 8
> +; IS________OPM-NEXT: br label [[TMP4]]
> +; IS________OPM: 11:
> +; IS________OPM-NEXT: ret i32 5
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@malloc_in_loop
> +; IS________NPM-SAME: (i32 [[TMP0:%.*]])
> +; IS________NPM-NEXT: [[TMP2:%.*]] = alloca i32, align 4
> +; IS________NPM-NEXT: [[TMP3:%.*]] = alloca i32*, align 8
> +; IS________NPM-NEXT: store i32 [[TMP0]], i32* [[TMP2]], align 4
> +; IS________NPM-NEXT: br label [[TMP4:%.*]]
> +; IS________NPM: 4:
> +; IS________NPM-NEXT: [[TMP5:%.*]] = load i32, i32* [[TMP2]], align 4
> +; IS________NPM-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP5]], -1
> +; IS________NPM-NEXT: store i32 [[TMP6]], i32* [[TMP2]], align 4
> +; IS________NPM-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[TMP6]], 0
> +; IS________NPM-NEXT: br i1 [[TMP7]], label [[TMP8:%.*]], label
> [[TMP11:%.*]]
> +; IS________NPM: 8:
> +; IS________NPM-NEXT: [[TMP9:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: [[TMP10:%.*]] = bitcast i8* [[TMP9]] to i32*
> +; IS________NPM-NEXT: store i32 1, i32* [[TMP10]], align 8
> +; IS________NPM-NEXT: br label [[TMP4]]
> +; IS________NPM: 11:
> +; IS________NPM-NEXT: ret i32 5
> +;
> %2 = alloca i32, align 4
> %3 = alloca i32*, align 8
> store i32 %0, i32* %2, align 4
> @@ -308,7 +617,6 @@ define i32 @malloc_in_loop(i32 %0) {
>
> 8: ; preds = %4
> %9 = call noalias i8* @malloc(i64 4)
> - ; CHECK: alloca i8, i64 4
> %10 = bitcast i8* %9 to i32*
> store i32 1, i32* %10, align 8
> br label %4
> @@ -319,104 +627,167 @@ define i32 @malloc_in_loop(i32 %0) {
>
> ; Malloc/Calloc too large
> define i32 @test13() {
> +; CHECK-LABEL: define {{[^@]+}}@test13()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 256)
> +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
> +; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4
> dereferenceable(4) [[TMP1]])
> +; CHECK-NEXT: ret i32 [[TMP3]]
> +;
> %1 = tail call noalias i8* @malloc(i64 256)
> - ; CHECK: %1 = tail call noalias i8* @malloc(i64 256)
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1)
> tail call void @no_sync_func(i8* %1)
> %2 = bitcast i8* %1 to i32*
> store i32 10, i32* %2
> %3 = load i32, i32* %2
> tail call void @free(i8* %1)
> - ; CHECK: tail call void @free(i8* noalias nonnull align 4
> dereferenceable(4) %1)
> ret i32 %3
> }
>
> define i32 @test_sle() {
> +; CHECK-LABEL: define {{[^@]+}}@test_sle()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 -1)
> +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
> +; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4
> dereferenceable(4) [[TMP1]])
> +; CHECK-NEXT: ret i32 [[TMP3]]
> +;
> %1 = tail call noalias i8* @malloc(i64 -1)
> - ; CHECK: %1 = tail call noalias i8* @malloc(i64 -1)
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1)
> tail call void @no_sync_func(i8* %1)
> %2 = bitcast i8* %1 to i32*
> store i32 10, i32* %2
> %3 = load i32, i32* %2
> tail call void @free(i8* %1)
> - ; CHECK: tail call void @free(i8* noalias nonnull align 4
> dereferenceable(4) %1)
> ret i32 %3
> }
>
> define i32 @test_overflow() {
> +; CHECK-LABEL: define {{[^@]+}}@test_overflow()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 65537,
> i64 65537)
> +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[TMP1]] to i32*
> +; CHECK-NEXT: store i32 10, i32* [[TMP2]], align 4
> +; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4
> +; CHECK-NEXT: tail call void @free(i8* noalias nonnull align 4
> dereferenceable(4) [[TMP1]])
> +; CHECK-NEXT: ret i32 [[TMP3]]
> +;
> %1 = tail call noalias i8* @calloc(i64 65537, i64 65537)
> - ; CHECK: %1 = tail call noalias i8* @calloc(i64 65537, i64 65537)
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1)
> tail call void @no_sync_func(i8* %1)
> %2 = bitcast i8* %1 to i32*
> store i32 10, i32* %2
> %3 = load i32, i32* %2
> tail call void @free(i8* %1)
> - ; CHECK: tail call void @free(i8* noalias nonnull align 4
> dereferenceable(4) %1)
> ret i32 %3
> }
>
> define void @test14() {
> +; CHECK-LABEL: define {{[^@]+}}@test14()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @calloc(i64 64, i64
> 4)
> +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
> +; CHECK-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; CHECK-NEXT: ret void
> +;
> %1 = tail call noalias i8* @calloc(i64 64, i64 4)
> - ; CHECK: %1 = tail call noalias i8* @calloc(i64 64, i64 4)
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1)
> tail call void @no_sync_func(i8* %1)
> tail call void @free(i8* %1)
> - ; CHECK: tail call void @free(i8* noalias %1)
> ret void
> }
>
> define void @test15(i64 %S) {
> - ; CHECK: %1 = tail call noalias i8* @malloc(i64 %S)
> +; CHECK-LABEL: define {{[^@]+}}@test15
> +; CHECK-SAME: (i64 [[S:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 [[S]])
> +; CHECK-NEXT: tail call void @no_sync_func(i8* noalias nofree [[TMP1]])
> +; CHECK-NEXT: tail call void @free(i8* noalias [[TMP1]])
> +; CHECK-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 %S)
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1)
> tail call void @no_sync_func(i8* %1)
> - ; CHECK-NEXT: @free(i8* noalias %1)
> tail call void @free(i8* %1)
> ret void
> }
>
> define void @test16a(i8 %v, i8** %P) {
> - ; CHECK: %1 = alloca
> +; IS________OPM-LABEL: define {{[^@]+}}@test16a
> +; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone
> [[P:%.*]])
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: store i8 [[V]], i8* [[TMP1]]
> +; IS________OPM-NEXT: tail call void @no_sync_func(i8* noalias nofree
> nonnull dereferenceable(1) [[TMP1]])
> +; IS________OPM-NEXT: tail call void @free(i8* noalias nonnull
> dereferenceable(1) [[TMP1]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test16a
> +; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture nofree readnone
> [[P:%.*]])
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: store i8 [[V]], i8* [[TMP1]]
> +; IS________NPM-NEXT: tail call void @no_sync_func(i8* noalias
> nocapture nofree nonnull dereferenceable(1) [[TMP1]])
> +; IS________NPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK-NEXT: store i8 %v, i8* %1
> store i8 %v, i8* %1
> - ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree nonnull
> dereferenceable(1) %1)
> tail call void @no_sync_func(i8* %1)
> - ; CHECK-NOT: @free(i8* %1)
> tail call void @free(i8* nonnull dereferenceable(1) %1)
> ret void
> }
>
> define void @test16b(i8 %v, i8** %P) {
> - ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
> +; IS________OPM-LABEL: define {{[^@]+}}@test16b
> +; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: store i8* [[TMP1]], i8** [[P]]
> +; IS________OPM-NEXT: tail call void @no_sync_func(i8* nofree [[TMP1]])
> +; IS________OPM-NEXT: tail call void @free(i8* [[TMP1]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test16b
> +; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
> +; IS________NPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________NPM-NEXT: store i8* [[TMP1]], i8** [[P]]
> +; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture
> nofree [[TMP1]])
> +; IS________NPM-NEXT: tail call void @free(i8* [[TMP1]])
> +; IS________NPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK-NEXT: store i8* %1, i8** %P
> store i8* %1, i8** %P
> - ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1)
> tail call void @no_sync_func(i8* %1)
> - ; CHECK-NEXT: @free(i8* %1)
> tail call void @free(i8* %1)
> ret void
> }
>
> define void @test16c(i8 %v, i8** %P) {
> - ; CHECK: %1 = alloca
> +; IS________OPM-LABEL: define {{[^@]+}}@test16c
> +; IS________OPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
> +; IS________OPM-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64
> 4)
> +; IS________OPM-NEXT: store i8* [[TMP1]], i8** [[P]]
> +; IS________OPM-NEXT: tail call void @no_sync_func(i8* nofree [[TMP1]])
> +; IS________OPM-NEXT: tail call void @free(i8* [[TMP1]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test16c
> +; IS________NPM-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
> +; IS________NPM-NEXT: [[TMP1:%.*]] = alloca i8, i64 4
> +; IS________NPM-NEXT: store i8* [[TMP1]], i8** [[P]]
> +; IS________NPM-NEXT: tail call void @no_sync_func(i8* nocapture
> nofree [[TMP1]])
> +; IS________NPM-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK-NEXT: store i8* %1, i8** %P
> store i8* %1, i8** %P
> - ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1)
> tail call void @no_sync_func(i8* %1) nounwind
> - ; CHECK-NOT: @free
> tail call void @free(i8* %1)
> ret void
> }
>
> define void @test16d(i8 %v, i8** %P) {
> - ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
> +; CHECK-LABEL: define {{[^@]+}}@test16d
> +; CHECK-SAME: (i8 [[V:%.*]], i8** nocapture writeonly [[P:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: store i8* [[TMP1]], i8** [[P]]
> +; CHECK-NEXT: ret void
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> - ; CHECK-NEXT: store i8* %1, i8** %P
> store i8* %1, i8** %P
> ret void
> }
>
> diff --git a/llvm/test/Transforms/Attributor/internal-noalias.ll
> b/llvm/test/Transforms/Attributor/internal-noalias.ll
> index 600da85001bd..2df1c11d9bb9 100644
> --- a/llvm/test/Transforms/Attributor/internal-noalias.ll
> +++ b/llvm/test/Transforms/Attributor/internal-noalias.ll
> @@ -1,6 +1,26 @@
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations=7 < %s | FileCheck
> %s
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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____-LABEL: define {{[^@]+}}@visible
> +; IS__TUNIT____-SAME: (i32* noalias nocapture nofree readonly [[A:%.*]],
> i32* noalias nocapture nofree readonly [[B:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32*
> noalias nocapture nofree readonly align 4 [[A]], i32* noalias nocapture
> nofree readonly align 4 [[B]])
> +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32
> @noalias_args_argmem(i32* noalias nocapture nofree readonly align 4 [[A]],
> i32* noalias nocapture nofree readonly align 4 [[B]])
> +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]]
> +; IS__TUNIT____-NEXT: ret i32 [[ADD]]
> +;
> +; 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:
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(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: [[CALL2:%.*]] = call i32
> @noalias_args_argmem(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: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]]
> +; IS__CGSCC____-NEXT: ret i32 [[ADD]]
> +;
> entry:
> %call1 = call i32 @noalias_args(i32* %A, i32* %B)
> %call2 = call i32 @noalias_args_argmem(i32* %A, i32* %B)
> @@ -8,9 +28,27 @@ entry:
> ret i32 %add
> }
>
> -; CHECK: define private i32 @noalias_args(i32* nocapture nofree nonnull
> readonly align 4 dereferenceable(4) %A, i32* noalias nocapture nofree
> nonnull readonly align 4 dereferenceable(4) %B)
> -
> define private i32 @noalias_args(i32* %A, i32* %B) #0 {
> +; 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:
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4
> +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4
> +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32
> @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[A]], i32* noalias nocapture nofree nonnull readonly
> align 4 dereferenceable(4) [[B]])
> +; IS__TUNIT____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]]
> +; IS__TUNIT____-NEXT: ret i32 [[ADD2]]
> +;
> +; 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:
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4
> +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32
> @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[A]], i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[B]])
> +; IS__CGSCC____-NEXT: [[ADD2:%.*]] = add nsw i32 [[ADD]], [[CALL]]
> +; IS__CGSCC____-NEXT: ret i32 [[ADD2]]
> +;
> entry:
> %0 = load i32, i32* %A, align 4
> %1 = load i32, i32* %B, align 4
> @@ -21,8 +59,23 @@ entry:
> }
>
>
> -; CHECK: define internal i32 @noalias_args_argmem(i32* nocapture nofree
> nonnull readonly align 4 dereferenceable(4) %A, i32* noalias nocapture
> nofree nonnull readonly align 4 dereferenceable(4) %B)
> define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 {
> +; 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:
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4
> +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4
> +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
> +; IS__TUNIT____-NEXT: ret i32 [[ADD]]
> +;
> +; 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:
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = load i32, i32* [[A]], align 4
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 4
> +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
> +; IS__CGSCC____-NEXT: ret i32 [[ADD]]
> +;
> entry:
> %0 = load i32, i32* %A, align 4
> %1 = load i32, i32* %B, align 4
> @@ -31,6 +84,26 @@ entry:
> }
>
> define dso_local i32 @visible_local(i32* %A) #0 {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@visible_local
> +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly [[A:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[B:%.*]] = alloca i32, align 4
> +; IS__TUNIT____-NEXT: store i32 5, i32* [[B]], align 4
> +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32*
> nocapture nofree readonly align 4 [[A]], i32* noalias nocapture nofree
> nonnull readonly align 4 dereferenceable(4) [[B]])
> +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32
> @noalias_args_argmem(i32* nocapture nofree readonly align 4 [[A]], i32*
> noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) [[B]])
> +; IS__TUNIT____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]]
> +; IS__TUNIT____-NEXT: ret i32 [[ADD]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@visible_local
> +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[A:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[B:%.*]] = alloca i32, align 4
> +; IS__CGSCC____-NEXT: store i32 5, i32* [[B]], align 4
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @noalias_args(i32*
> nocapture nofree nonnull readonly align 4 dereferenceable(4) [[A]], i32*
> noalias nofree nonnull readonly align 4 dereferenceable(4) [[B]])
> +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32
> @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[A]], i32* noalias nofree nonnull readonly align 4
> dereferenceable(4) [[B]])
> +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[CALL1]], [[CALL2]]
> +; IS__CGSCC____-NEXT: ret i32 [[ADD]]
> +;
> entry:
> %B = alloca i32, align 4
> store i32 5, i32* %B, align 4
> @@ -40,8 +113,32 @@ entry:
> ret i32 %add
> }
>
> -; CHECK: define internal i32 @noalias_args_argmem_ro(i32 %0, i32 %1)
> define internal i32 @noalias_args_argmem_ro(i32* %A, i32* %B) #1 {
> +; 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
> +; IS__TUNIT_OPM-NEXT: [[T1:%.*]] = load i32, i32* [[B]], align 4
> +; IS__TUNIT_OPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]]
> +; IS__TUNIT_OPM-NEXT: ret i32 [[ADD]]
> +;
> +; 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
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP1]], i32* [[B_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[A_PRIV:%.*]] = alloca i32
> +; IS__TUNIT_NPM-NEXT: store i32 [[TMP0]], i32* [[A_PRIV]]
> +; IS__TUNIT_NPM-NEXT: [[T0:%.*]] = load i32, i32* [[A_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: [[T1:%.*]] = load i32, i32* [[B_PRIV]], align 4
> +; IS__TUNIT_NPM-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]]
> +; IS__TUNIT_NPM-NEXT: ret i32 [[ADD]]
> +;
> +; 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
> +; IS__CGSCC____-NEXT: [[T1:%.*]] = load i32, i32* [[B]], align 4
> +; IS__CGSCC____-NEXT: [[ADD:%.*]] = add nsw i32 [[T0]], [[T1]]
> +; IS__CGSCC____-NEXT: ret i32 [[ADD]]
> +;
> %t0 = load i32, i32* %A, align 4
> %t1 = load i32, i32* %B, align 4
> %add = add nsw i32 %t0, %t1
> @@ -49,20 +146,63 @@ define internal i32 @noalias_args_argmem_ro(i32* %A,
> i32* %B) #1 {
> }
>
> define i32 @visible_local_2() {
> +; 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-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
> +; IS__TUNIT_NPM-NEXT: [[TMP1:%.*]] = load i32, i32* [[B]], align 1
> +; IS__TUNIT_NPM-NEXT: [[TMP2:%.*]] = load i32, i32* [[B]], align 1
> +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32
> @noalias_args_argmem_ro(i32 [[TMP1]], i32 [[TMP2]])
> +; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
> +;
> +; 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 nofree nonnull readonly align 4
> dereferenceable(4) [[B]], i32* noalias 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
> %call = call i32 @noalias_args_argmem_ro(i32* %B, i32* %B)
> ret i32 %call
> }
>
> -; CHECK: define internal i32 @noalias_args_argmem_rn(i32* noalias
> nocapture nofree nonnull align 4 dereferenceable(4) %B)
> define internal i32 @noalias_args_argmem_rn(i32* %A, i32* %B) #1 {
> +; 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____-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
> +; IS__CGSCC____-NEXT: store i32 0, i32* [[B]], align 4
> +; IS__CGSCC____-NEXT: ret i32 [[T0]]
> +;
> %t0 = load i32, i32* %B, align 4
> store i32 0, i32* %B
> ret i32 %t0
> }
>
> define i32 @visible_local_3() {
> +; 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____-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 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
> %call = call i32 @noalias_args_argmem_rn(i32* %B, i32* %B)
>
> diff --git a/llvm/test/Transforms/Attributor/liveness.ll
> b/llvm/test/Transforms/Attributor/liveness.ll
> index 5b5aabb1ddcc..bfacc9a9dac0 100644
> --- a/llvm/test/Transforms/Attributor/liveness.ll
> +++ b/llvm/test/Transforms/Attributor/liveness.ll
> @@ -1,15 +1,11 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=7 -S < %s | FileCheck %s
> --check-prefixes=CHECK,MODULE,MODULE_OLD
> -; RUN: opt -attributor-cgscc --attributor-disable=false
> -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s |
> FileCheck %s --check-prefixes=CHECK,CGSCC,CGSCC_OLD
> -; RUN: opt -passes=attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=7 -S < %s | FileCheck %s
> --check-prefixes=CHECK,MODULE,MODULE_NEW
> -; RUN: opt -passes='attributor-cgscc' --attributor-disable=false
> -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s |
> FileCheck %s --check-prefixes=CHECK,CGSCC,CGSCC_NEW
> -; XFAIL: *
> -; UTC_ARGS: --disable
> -
> -; MODULE_OLD: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8*
> inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
> -; MODULE_NEW: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8*
> inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
> -; CGSCC_OLD: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8*
> blockaddress(@dead_with_blockaddress_users, %lab0), i8*
> blockaddress(@dead_with_blockaddress_users, %end)]
> -; CGSCC_NEW: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8*
> inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> +
> +; NOT_CGSCC_OPM: @dead_with_blockaddress_users.l = constant [2 x i8*]
> [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
> +; IS__CGSCC_OPM: @dead_with_blockaddress_users.l = constant [2 x i8*]
> [i8* blockaddress(@dead_with_blockaddress_users, %lab0), i8*
> blockaddress(@dead_with_blockaddress_users, %end)]
> @dead_with_blockaddress_users.l = constant [2 x i8*] [i8*
> blockaddress(@dead_with_blockaddress_users, %lab0), i8*
> blockaddress(@dead_with_blockaddress_users, %end)]
>
> declare void @no_return_call() nofree noreturn nounwind nosync
> @@ -29,8 +25,19 @@ declare i32 @bar() nosync readnone
> ; This internal function has no live call sites, so all its BBs are
> considered dead,
> ; and nothing should be deduced for it.
>
> -; MODULE-NOT: define internal i32 @dead_internal_func(i32 %0)
> define internal i32 @dead_internal_func(i32 %0) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@dead_internal_func()
> +; IS__CGSCC____-NEXT: br label [[TMP2:%.*]]
> +; IS__CGSCC____: 1:
> +; IS__CGSCC____-NEXT: ret i32 undef
> +; IS__CGSCC____: 2:
> +; IS__CGSCC____-NEXT: [[TMP3:%.*]] = phi i32 [ [[TMP6:%.*]], [[TMP2]]
> ], [ 1, [[TMP0:%.*]] ]
> +; IS__CGSCC____-NEXT: [[TMP4:%.*]] = phi i32 [ [[TMP5:%.*]], [[TMP2]]
> ], [ 1, [[TMP0]] ]
> +; IS__CGSCC____-NEXT: [[TMP5]] = mul nsw i32 [[TMP3]], [[TMP4]]
> +; IS__CGSCC____-NEXT: [[TMP6]] = add nuw nsw i32 [[TMP3]], 1
> +; IS__CGSCC____-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP3]], 10
> +; IS__CGSCC____-NEXT: br i1 [[TMP7]], label [[TMP1:%.*]], label
> [[TMP2]]
> +;
> %2 = icmp slt i32 %0, 1
> br i1 %2, label %3, label %5
>
> @@ -49,26 +56,41 @@ define internal i32 @dead_internal_func(i32 %0) {
>
> ; CHECK: Function Attrs: argmemonly nofree norecurse nounwind uwtable
> willreturn
> define i32 @volatile_load(i32*) norecurse nounwind uwtable {
> +; CHECK-LABEL: define {{[^@]+}}@volatile_load
> +; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]])
> +; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4
> +; CHECK-NEXT: ret i32 [[TMP2]]
> +;
> %2 = load volatile i32, i32* %0, align 4
> ret i32 %2
> }
>
> -; MODULE-NOT: internal_load
> define internal i32 @internal_load(i32*) norecurse nounwind uwtable {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_load()
> +; IS__CGSCC____-NEXT: ret i32 undef
> +;
> %2 = load i32, i32* %0, align 4
> ret i32 %2
> }
> ; TEST 1: Only first block is live.
>
> ; CHECK: Function Attrs: nofree noreturn nosync nounwind
> -; MODULE-NEXT: define i32 @first_block_no_return(i32 %a, i32* nocapture
> nofree nonnull readnone %ptr1, i32* nocapture nofree readnone %ptr2)
> -; CGSCC-NEXT: define i32 @first_block_no_return(i32 %a, i32* nocapture
> nofree nonnull readnone %ptr1, i32* nocapture nofree readnone %ptr2)
> define i32 @first_block_no_return(i32 %a, i32* nonnull %ptr1, i32* %ptr2)
> #0 {
> +; 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:
> +; CHECK-NEXT: call void @no_return_call()
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.true:
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.false:
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.end:
> +; CHECK-NEXT: unreachable
> +;
> entry:
> call i32 @internal_load(i32* %ptr1)
> call void @no_return_call()
> - ; CHECK: call void @no_return_call()
> - ; CHECK-NEXT: unreachable
> call i32 @dead_internal_func(i32 10)
> %cmp = icmp eq i32 %a, 0
> br i1 %cmp, label %cond.true, label %cond.false
> @@ -96,16 +118,28 @@ cond.end: ;
> preds = %cond.false, %cond.t
> ; dead block and check if it is deduced.
>
> ; CHECK: Function Attrs: nosync
> -; CHECK-NEXT: define i32 @dead_block_present(i32 %a, i32* nocapture
> nofree readnone %ptr1)
> define i32 @dead_block_present(i32 %a, i32* %ptr1) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@dead_block_present
> +; CHECK-SAME: (i32 [[A:%.*]], i32* nocapture nofree readnone [[PTR1:%.*]])
> +; 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: call void @no_return_call()
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.false:
> +; CHECK-NEXT: call void @normal_call()
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar()
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: ret i32 [[CALL1]]
> +;
> entry:
> %cmp = icmp eq i32 %a, 0
> br i1 %cmp, label %cond.true, label %cond.false
>
> cond.true: ; preds = %entry
> call void @no_return_call()
> - ; CHECK: call void @no_return_call()
> - ; CHECK-NEXT: unreachable
> %call = call i32 @volatile_load(i32* %ptr1)
> br label %cond.end
>
> @@ -115,8 +149,6 @@ cond.false: ;
> preds = %entry
> br label %cond.end
>
> cond.end: ; preds = %cond.false,
> %cond.true
> -; CHECK: cond.end:
> -; CHECK-NEXT: ret i32 %call1
> %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ]
> ret i32 %cond
> }
> @@ -124,23 +156,32 @@ 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-LABEL: define {{[^@]+}}@all_dead
> +; 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: call void @no_return_call()
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.false:
> +; CHECK-NEXT: call void @no_return_call()
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.end:
> +; CHECK-NEXT: unreachable
> +;
> entry:
> %cmp = icmp eq i32 %a, 0
> br i1 %cmp, label %cond.true, label %cond.false
>
> cond.true: ; preds = %entry
> call void @no_return_call()
> - ; CHECK: call void @no_return_call()
> - ; CHECK-NEXT: unreachable
> call i32 @dead_internal_func(i32 10)
> - ; CHECK-NOT: call
> %call = call i32 @foo()
> br label %cond.end
>
> cond.false: ; preds = %entry
> call void @no_return_call()
> - ; CHECK: call void @no_return_call()
> - ; CHECK-NEXT: unreachable
> call i32 @dead_internal_func(i32 10)
> %call1 = call i32 @bar()
> br label %cond.end
> @@ -154,8 +195,23 @@ declare i32 @__gxx_personality_v0(...)
>
> ; TEST 4: All blocks are live.
>
> -; CHECK: define i32 @all_live(i32 %a)
> define i32 @all_live(i32 %a) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@all_live
> +; 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: call void @normal_call()
> +; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn()
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.false:
> +; CHECK-NEXT: call void @normal_call()
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar()
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: ret i32 [[CALL1]]
> +;
> entry:
> %cmp = icmp eq i32 %a, 0
> br i1 %cmp, label %cond.true, label %cond.false
> @@ -177,8 +233,29 @@ cond.end: ;
> preds = %cond.false, %cond.t
>
> ; TEST 5.1 noreturn invoke instruction with a unreachable normal
> successor block.
>
> -; CHECK: define i32 @invoke_noreturn(i32 %a)
> define i32 @invoke_noreturn(i32 %a) personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*) {
> +; CHECK-LABEL: define {{[^@]+}}@invoke_noreturn
> +; CHECK-SAME: (i32 [[A:%.*]]) personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*)
> +; 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: call void @normal_call()
> +; CHECK-NEXT: [[CALL:%.*]] = invoke i32 @foo_noreturn()
> +; CHECK-NEXT: to label [[CONTINUE:%.*]] unwind label [[CLEANUP:%.*]]
> +; CHECK: cond.false:
> +; CHECK-NEXT: call void @normal_call()
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar()
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: ret i32 [[CALL1]]
> +; CHECK: continue:
> +; CHECK-NEXT: unreachable
> +; CHECK: cleanup:
> +; CHECK-NEXT: [[RES:%.*]] = landingpad { i8*, i32 }
> +; CHECK-NEXT: catch i8* null
> +; CHECK-NEXT: ret i32 0
> +;
> entry:
> %cmp = icmp eq i32 %a, 0
> br i1 %cmp, label %cond.true, label %cond.false
> @@ -186,9 +263,7 @@ entry:
> cond.true: ; preds = %entry
> call void @normal_call()
> %call = invoke i32 @foo_noreturn() to label %continue
> - unwind label %cleanup
> - ; CHECK: %call = invoke i32 @foo_noreturn()
> - ; CHECK-NEXT: to label %continue unwind label %cleanup
> + unwind label %cleanup
>
> cond.false: ; preds = %entry
> call void @normal_call()
> @@ -200,8 +275,6 @@ cond.end: ;
> preds = %cond.false, %contin
> ret i32 %cond
>
> continue:
> - ; CHECK: continue:
> - ; CHECK-NEXT: unreachable
> br label %cond.end
>
> cleanup:
> @@ -213,8 +286,27 @@ cleanup:
> ; TEST 5.2 noreturn invoke instruction replaced by a call and an
> unreachable instruction
> ; put after it.
>
> -; CHECK: define i32 @invoke_noreturn_nounwind(i32 %a)
> define i32 @invoke_noreturn_nounwind(i32 %a) personality i8* bitcast (i32
> (...)* @__gxx_personality_v0 to i8*) {
> +; CHECK-LABEL: define {{[^@]+}}@invoke_noreturn_nounwind
> +; CHECK-SAME: (i32 [[A:%.*]]) personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*)
> +; 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: call void @normal_call()
> +; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_noreturn_nounwind()
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.false:
> +; CHECK-NEXT: call void @normal_call()
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar()
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: ret i32 [[CALL1]]
> +; CHECK: continue:
> +; CHECK-NEXT: unreachable
> +; CHECK: cleanup:
> +; CHECK-NEXT: unreachable
> +;
> entry:
> %cmp = icmp eq i32 %a, 0
> br i1 %cmp, label %cond.true, label %cond.false
> @@ -222,12 +314,8 @@ entry:
> cond.true: ; preds = %entry
> call void @normal_call()
> %call = invoke i32 @foo_noreturn_nounwind() to label %continue
> - unwind label %cleanup
> - ; CHECK: call void @normal_call()
> - ; CHECK-NEXT: call i32 @foo_noreturn_nounwind()
> - ; CHECK-NEXT: unreachable
> + unwind label %cleanup
>
> - ; CHECK-NOT: @foo_noreturn_nounwind()
>
> cond.false: ; preds = %entry
> call void @normal_call()
> @@ -250,12 +338,25 @@ cleanup:
> ; TEST 5.3 unounwind invoke instruction replaced by a call and a branch
> instruction put after it.
> define i32 @invoke_nounwind(i32 %a) personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*) {
> ; CHECK-LABEL: define {{[^@]+}}@invoke_nounwind
> +; CHECK-SAME: (i32 [[A:%.*]]) personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*)
> +; 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: call void @normal_call()
> ; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_nounwind()
> ; CHECK-NEXT: br label [[CONTINUE:%.*]]
> -; CHECK: continue:
> +; CHECK: cond.false:
> +; CHECK-NEXT: call void @normal_call()
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @bar()
> ; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[CALL]], [[CONTINUE]] ], [
> [[CALL1]], [[COND_FALSE]] ]
> +; CHECK-NEXT: ret i32 [[COND]]
> +; CHECK: continue:
> +; CHECK-NEXT: br label [[COND_END]]
> +; CHECK: cleanup:
> +; CHECK-NEXT: unreachable
> ;
> entry:
> %cmp = icmp eq i32 %a, 0
> @@ -284,8 +385,6 @@ cleanup:
> ret i32 0
> }
>
> -; UTC_ARGS: --enable
> -
> ; TEST 5.4 unounwind invoke instruction replaced by a call and a branch
> instruction put after it.
> define i32 @invoke_nounwind_phi(i32 %a) personality i8* bitcast (i32
> (...)* @__gxx_personality_v0 to i8*) {
> ; CHECK-LABEL: define {{[^@]+}}@invoke_nounwind_phi
> @@ -374,13 +473,18 @@ cleanup:
> ret i32 0
> }
>
> -; UTC_ARGS: --disable
> -
> ; TEST 6: Undefined behvior, taken from LangRef.
> ; FIXME: Should be able to detect undefined behavior.
>
> -; CHECK: define void @ub(i32* nocapture nofree writeonly %0)
> 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
> +;
> %poison = sub nuw i32 0, 1 ; Results in a poison value.
> %still_poison = and i32 %poison, 0 ; 0, but also poison.
> %poison_yet_again = getelementptr i32, i32* %0, i32 %still_poison
> @@ -389,6 +493,12 @@ 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]]
> +;
> entry:
> br label %while.body
>
> @@ -400,6 +510,20 @@ while.body: ;
> preds = %entry, %while.body
> ; FIXME: Detect infloops, and mark affected blocks dead.
>
> define i32 @test5(i32, i32) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@test5
> +; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]]
> +; CHECK-NEXT: br i1 [[TMP3]], label [[COND_IF:%.*]], label
> [[COND_ELSEIF:%.*]]
> +; CHECK: cond.if:
> +; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 @bar()
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.elseif:
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.else:
> +; CHECK-NEXT: unreachable
> +; CHECK: cond.end:
> +; CHECK-NEXT: ret i32 0
> +;
> %3 = icmp sgt i32 %0, %1
> br i1 %3, label %cond.if, label %cond.elseif
>
> @@ -422,6 +546,10 @@ cond.end:
> ; preds = %cond.if, %con
> }
>
> define void @rec() #0 {
> +; CHECK-LABEL: define {{[^@]+}}@rec()
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: unreachable
> +;
> entry:
> call void @rec()
> ret void
> @@ -432,6 +560,18 @@ 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
> +;
> call void @rec()
> %3 = icmp sgt i32 %0, %1
> br i1 %3, label %cond.if, label %cond.elseif
> @@ -457,6 +597,24 @@ cond.end:
> ; preds = %cond.if, %con
> ; FIXME: contains recursive call to itself in cond.elseif block
>
> define i32 @test7(i32, i32) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@test7
> +; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]]
> +; CHECK-NEXT: br i1 [[TMP3]], label [[COND_IF:%.*]], label
> [[COND_ELSEIF:%.*]]
> +; CHECK: cond.if:
> +; CHECK-NEXT: [[TMP4:%.*]] = tail call i32 @bar()
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.elseif:
> +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @test7(i32 [[TMP0]], i32
> [[TMP1]])
> +; CHECK-NEXT: [[TMP6:%.*]] = icmp slt i32 [[TMP0]], [[TMP1]]
> +; CHECK-NEXT: br i1 [[TMP6]], label [[COND_END]], label
> [[COND_ELSE:%.*]]
> +; CHECK: cond.else:
> +; CHECK-NEXT: [[TMP7:%.*]] = tail call i32 @foo()
> +; CHECK-NEXT: br label [[COND_END]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: [[TMP8:%.*]] = phi i32 [ [[TMP1]], [[COND_ELSEIF]] ], [
> 0, [[COND_ELSE]] ], [ 0, [[COND_IF]] ]
> +; CHECK-NEXT: ret i32 [[TMP8]]
> +;
> %3 = icmp sgt i32 %0, %1
> br i1 %3, label %cond.if, label %cond.elseif
>
> @@ -498,12 +656,21 @@ cond.end:
> ; preds = %cond.if, %con
> @a2 = common global i8 0, align 16
>
> define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
> -; ATTRIBUTOR: define internal i8* @f1(i8* readnone %0)
> +; CHECK-LABEL: define {{[^@]+}}@f1
> +; CHECK-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr
> +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
> +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
> +; CHECK: 3:
> +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @f2(i8* nonnull @a1)
> +; CHECK-NEXT: br label [[TMP5]]
> +; CHECK: 5:
> +; CHECK-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [
> [[TMP0]], [[TMP1:%.*]] ]
> +; CHECK-NEXT: ret i8* [[TMP6]]
> +;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %3, label %5
>
> ; <label>:3: ; preds = %1
> -; ATTRIBUTOR: %4 = tail call i8* undef(i8* nonnull align 8 @a1)
> %4 = tail call i8* @f2(i8* nonnull @a1)
> br label %5
>
> @@ -513,18 +680,29 @@ define internal i8* @f1(i8* readnone %0)
> local_unnamed_addr #0 {
> }
>
> define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
> -; ATTRIBUTOR: define internal i8* @f2(i8* readnone %0)
> +; CHECK-LABEL: define {{[^@]+}}@f2
> +; CHECK-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr
> +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
> +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
> +; CHECK: 3:
> +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @f1(i8* nonnull [[TMP0]])
> +; CHECK-NEXT: br label [[TMP7:%.*]]
> +; CHECK: 5:
> +; CHECK-NEXT: [[TMP6:%.*]] = tail call i8* @f3(i8* nonnull @a2)
> +; CHECK-NEXT: br label [[TMP7]]
> +; CHECK: 7:
> +; CHECK-NEXT: [[TMP8:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [
> [[TMP6]], [[TMP5]] ]
> +; CHECK-NEXT: ret i8* [[TMP8]]
> +;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %5, label %3
>
> ; <label>:3: ; preds = %1
>
> -; ATTRIBUTOR: %4 = tail call i8* undef(i8* nonnull align 8 %0)
> %4 = tail call i8* @f1(i8* nonnull %0)
> br label %7
>
> ; <label>:5: ; preds = %1
> -; ATTRIBUTOR: %6 = tail call i8* undef(i8* nonnull align 16 @a2)
> %6 = tail call i8* @f3(i8* nonnull @a2)
> br label %7
>
> @@ -534,12 +712,21 @@ define internal i8* @f2(i8* readnone %0)
> local_unnamed_addr #0 {
> }
>
> define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
> -; ATTRIBUTOR: define internal i8* @f3(i8* readnone %0)
> +; CHECK-LABEL: define {{[^@]+}}@f3
> +; CHECK-SAME: (i8* readnone [[TMP0:%.*]]) local_unnamed_addr
> +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
> +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
> +; CHECK: 3:
> +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @f1(i8* nonnull @a2)
> +; CHECK-NEXT: br label [[TMP5]]
> +; CHECK: 5:
> +; CHECK-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ @a1,
> [[TMP1:%.*]] ]
> +; CHECK-NEXT: ret i8* [[TMP6]]
> +;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %3, label %5
>
> ; <label>:3: ; preds = %1
> -; ATTRIBUTOR: %4 = tail call i8* undef(i8* nonnull align 16 @a2)
> %4 = tail call i8* @f1(i8* nonnull @a2)
> br label %5
>
> @@ -550,17 +737,37 @@ define internal i8* @f3(i8* readnone %0)
> local_unnamed_addr #0 {
>
> declare void @sink() nofree nosync nounwind willreturn
> define void @test_unreachable() {
> -; CHECK: define void @test_unreachable()
> +; CHECK-LABEL: define {{[^@]+}}@test_unreachable()
> ; CHECK-NEXT: call void @sink()
> ; CHECK-NEXT: call void @test_unreachable()
> ; CHECK-NEXT: unreachable
> -; CHECK-NEXT: }
> +;
> call void @sink()
> call void @test_unreachable()
> unreachable
> }
>
> define linkonce_odr void @non_exact1() {
> +; CHECK-LABEL: define {{[^@]+}}@non_exact1()
> +; CHECK-NEXT: call void @non_dead_a0()
> +; CHECK-NEXT: call void @non_dead_a1()
> +; CHECK-NEXT: call void @non_dead_a2()
> +; CHECK-NEXT: call void @non_dead_a3()
> +; CHECK-NEXT: call void @non_dead_a4()
> +; CHECK-NEXT: call void @non_dead_a5()
> +; CHECK-NEXT: call void @non_dead_a6()
> +; CHECK-NEXT: call void @non_dead_a7()
> +; CHECK-NEXT: call void @non_dead_a8()
> +; CHECK-NEXT: call void @non_dead_a9()
> +; CHECK-NEXT: call void @non_dead_a10()
> +; CHECK-NEXT: call void @non_dead_a11()
> +; CHECK-NEXT: call void @non_dead_a12()
> +; CHECK-NEXT: call void @non_dead_a13()
> +; CHECK-NEXT: call void @non_dead_a14()
> +; CHECK-NEXT: call void @non_dead_a15()
> +; CHECK-NEXT: call void @middle()
> +; CHECK-NEXT: ret void
> +;
> call void @non_dead_a0()
> call void @non_dead_a1()
> call void @non_dead_a2()
> @@ -581,6 +788,35 @@ define linkonce_odr void @non_exact1() {
> ret void
> }
> define internal void @middle() {
> +; CHECK-LABEL: define {{[^@]+}}@middle()
> +; CHECK-NEXT: bb0:
> +; CHECK-NEXT: call void @non_dead_b0()
> +; CHECK-NEXT: call void @non_dead_b1()
> +; CHECK-NEXT: call void @non_dead_b2()
> +; CHECK-NEXT: call void @non_dead_b3()
> +; CHECK-NEXT: br label [[BB1:%.*]]
> +; CHECK: bb1:
> +; CHECK-NEXT: call void @non_dead_b4()
> +; CHECK-NEXT: call void @non_dead_b5()
> +; CHECK-NEXT: call void @non_dead_b6()
> +; CHECK-NEXT: call void @non_dead_b7()
> +; CHECK-NEXT: br label [[BB2:%.*]]
> +; CHECK: bb2:
> +; CHECK-NEXT: call void @non_dead_b8()
> +; CHECK-NEXT: call void @non_dead_b9()
> +; CHECK-NEXT: call void @non_dead_b10()
> +; CHECK-NEXT: call void @non_dead_b11()
> +; CHECK-NEXT: br label [[BB3:%.*]]
> +; CHECK: bb3:
> +; CHECK-NEXT: call void @non_dead_b12()
> +; CHECK-NEXT: call void @non_dead_b13()
> +; CHECK-NEXT: call void @non_dead_b14()
> +; CHECK-NEXT: call void @non_dead_b15()
> +; CHECK-NEXT: br label [[BB4:%.*]]
> +; CHECK: bb4:
> +; CHECK-NEXT: call void @non_exact2()
> +; CHECK-NEXT: ret void
> +;
> bb0:
> call void @non_dead_b0()
> call void @non_dead_b1()
> @@ -610,6 +846,26 @@ bb4:
> ret void
> }
> define linkonce_odr void @non_exact2() {
> +; CHECK-LABEL: define {{[^@]+}}@non_exact2()
> +; CHECK-NEXT: call void @non_dead_c0()
> +; CHECK-NEXT: call void @non_dead_c1()
> +; CHECK-NEXT: call void @non_dead_c2()
> +; CHECK-NEXT: call void @non_dead_c3()
> +; CHECK-NEXT: call void @non_dead_c4()
> +; CHECK-NEXT: call void @non_dead_c5()
> +; CHECK-NEXT: call void @non_dead_c6()
> +; CHECK-NEXT: call void @non_dead_c7()
> +; CHECK-NEXT: call void @non_dead_c8()
> +; CHECK-NEXT: call void @non_dead_c9()
> +; CHECK-NEXT: call void @non_dead_c10()
> +; CHECK-NEXT: call void @non_dead_c11()
> +; CHECK-NEXT: call void @non_dead_c12()
> +; CHECK-NEXT: call void @non_dead_c13()
> +; CHECK-NEXT: call void @non_dead_c14()
> +; CHECK-NEXT: call void @non_dead_c15()
> +; CHECK-NEXT: call void @non_exact3()
> +; CHECK-NEXT: ret void
> +;
> call void @non_dead_c0()
> call void @non_dead_c1()
> call void @non_dead_c2()
> @@ -630,6 +886,26 @@ define linkonce_odr void @non_exact2() {
> ret void
> }
> define linkonce_odr void @non_exact3() {
> +; CHECK-LABEL: define {{[^@]+}}@non_exact3()
> +; CHECK-NEXT: call void @non_dead_d0()
> +; CHECK-NEXT: call void @non_dead_d1()
> +; CHECK-NEXT: call void @non_dead_d2()
> +; CHECK-NEXT: call void @non_dead_d3()
> +; CHECK-NEXT: call void @non_dead_d4()
> +; CHECK-NEXT: call void @non_dead_d5()
> +; CHECK-NEXT: call void @non_dead_d6()
> +; CHECK-NEXT: call void @non_dead_d7()
> +; CHECK-NEXT: call void @non_dead_d8()
> +; CHECK-NEXT: call void @non_dead_d9()
> +; CHECK-NEXT: call void @non_dead_d10()
> +; CHECK-NEXT: call void @non_dead_d11()
> +; CHECK-NEXT: call void @non_dead_d12()
> +; CHECK-NEXT: call void @non_dead_d13()
> +; CHECK-NEXT: call void @non_dead_d14()
> +; CHECK-NEXT: call void @non_dead_d15()
> +; CHECK-NEXT: [[NR:%.*]] = call i32 @foo_noreturn()
> +; CHECK-NEXT: unreachable
> +;
> call void @non_dead_d0()
> call void @non_dead_d1()
> call void @non_dead_d2()
> @@ -650,370 +926,531 @@ define linkonce_odr void @non_exact3() {
> call void @dead_e1()
> ret void
> }
> -; CHECK: define linkonce_odr void @non_exact3() {
> -; CHECK-NEXT: call void @non_dead_d0()
> -; CHECK-NEXT: call void @non_dead_d1()
> -; CHECK-NEXT: call void @non_dead_d2()
> -; CHECK-NEXT: call void @non_dead_d3()
> -; CHECK-NEXT: call void @non_dead_d4()
> -; CHECK-NEXT: call void @non_dead_d5()
> -; CHECK-NEXT: call void @non_dead_d6()
> -; CHECK-NEXT: call void @non_dead_d7()
> -; CHECK-NEXT: call void @non_dead_d8()
> -; CHECK-NEXT: call void @non_dead_d9()
> -; CHECK-NEXT: call void @non_dead_d10()
> -; CHECK-NEXT: call void @non_dead_d11()
> -; CHECK-NEXT: call void @non_dead_d12()
> -; CHECK-NEXT: call void @non_dead_d13()
> -; CHECK-NEXT: call void @non_dead_d14()
> -; CHECK-NEXT: call void @non_dead_d15()
> -; CHECK-NEXT: %nr = call i32 @foo_noreturn()
> -; CHECK-NEXT: unreachable
>
> define internal void @non_dead_a0() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a0()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a1() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a1()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a2() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a2()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a3() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a3()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a4() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a4()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a5() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a5()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a6() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a6()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a7() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a7()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a8() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a8()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a9() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a9()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a10() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a10()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a11() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a11()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a12() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a12()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a13() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a13()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a14() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a14()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_a15() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_a15()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b0() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b0()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b1() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b1()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b2() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b2()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b3() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b3()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b4() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b4()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b5() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b5()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b6() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b6()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b7() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b7()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b8() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b8()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b9() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b9()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b10() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b10()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b11() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b11()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b12() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b12()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b13() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b13()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b14() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b14()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_b15() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_b15()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c0() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c0()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c1() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c1()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c2() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c2()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c3() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c3()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c4() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c4()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c5() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c5()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c6() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c6()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c7() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c7()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c8() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c8()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c9() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c9()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c10() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c10()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c11() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c11()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c12() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c12()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c13() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c13()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c14() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c14()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_c15() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_c15()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d0() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d0()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d1() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d1()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d2() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d2()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d3() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d3()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d4() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d4()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d5() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d5()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d6() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d6()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d7() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d7()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d8() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d8()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d9() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d9()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d10() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d10()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d11() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d11()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d12() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d12()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d13() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d13()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d14() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d14()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @non_dead_d15() {
> +; CHECK-LABEL: define {{[^@]+}}@non_dead_d15()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
> define internal void @dead_e0() { call void @dead_e1() ret void }
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@dead_e0()
> +; IS__CGSCC____-NEXT: call void @dead_e1()
> +; IS__CGSCC____-NEXT: ret void
> +;
> define internal void @dead_e1() { call void @dead_e2() ret void }
> define internal void @dead_e2() { ret void }
>
> -; CHECK: define internal void @non_dead_a0()
> -; CHECK: define internal void @non_dead_a1()
> -; CHECK: define internal void @non_dead_a2()
> -; CHECK: define internal void @non_dead_a3()
> -; CHECK: define internal void @non_dead_a4()
> -; CHECK: define internal void @non_dead_a5()
> -; CHECK: define internal void @non_dead_a6()
> -; CHECK: define internal void @non_dead_a7()
> -; CHECK: define internal void @non_dead_a8()
> -; CHECK: define internal void @non_dead_a9()
> -; CHECK: define internal void @non_dead_a10()
> -; CHECK: define internal void @non_dead_a11()
> -; CHECK: define internal void @non_dead_a12()
> -; CHECK: define internal void @non_dead_a13()
> -; CHECK: define internal void @non_dead_a14()
> -; CHECK: define internal void @non_dead_a15()
> -; CHECK: define internal void @non_dead_b0()
> -; CHECK: define internal void @non_dead_b1()
> -; CHECK: define internal void @non_dead_b2()
> -; CHECK: define internal void @non_dead_b3()
> -; CHECK: define internal void @non_dead_b4()
> -; CHECK: define internal void @non_dead_b5()
> -; CHECK: define internal void @non_dead_b6()
> -; CHECK: define internal void @non_dead_b7()
> -; CHECK: define internal void @non_dead_b8()
> -; CHECK: define internal void @non_dead_b9()
> -; CHECK: define internal void @non_dead_b10()
> -; CHECK: define internal void @non_dead_b11()
> -; CHECK: define internal void @non_dead_b12()
> -; CHECK: define internal void @non_dead_b13()
> -; CHECK: define internal void @non_dead_b14()
> -; CHECK: define internal void @non_dead_b15()
> -; CHECK: define internal void @non_dead_c0()
> -; CHECK: define internal void @non_dead_c1()
> -; CHECK: define internal void @non_dead_c2()
> -; CHECK: define internal void @non_dead_c3()
> -; CHECK: define internal void @non_dead_c4()
> -; CHECK: define internal void @non_dead_c5()
> -; CHECK: define internal void @non_dead_c6()
> -; CHECK: define internal void @non_dead_c7()
> -; CHECK: define internal void @non_dead_c8()
> -; CHECK: define internal void @non_dead_c9()
> -; CHECK: define internal void @non_dead_c10()
> -; CHECK: define internal void @non_dead_c11()
> -; CHECK: define internal void @non_dead_c12()
> -; CHECK: define internal void @non_dead_c13()
> -; CHECK: define internal void @non_dead_c14()
> -; CHECK: define internal void @non_dead_c15()
> -; CHECK: define internal void @non_dead_d0()
> -; CHECK: define internal void @non_dead_d1()
> -; CHECK: define internal void @non_dead_d2()
> -; CHECK: define internal void @non_dead_d3()
> -; CHECK: define internal void @non_dead_d4()
> -; CHECK: define internal void @non_dead_d5()
> -; CHECK: define internal void @non_dead_d6()
> -; CHECK: define internal void @non_dead_d7()
> -; CHECK: define internal void @non_dead_d8()
> -; CHECK: define internal void @non_dead_d9()
> -; CHECK: define internal void @non_dead_d10()
> -; CHECK: define internal void @non_dead_d11()
> -; CHECK: define internal void @non_dead_d12()
> -; CHECK: define internal void @non_dead_d13()
> -; CHECK: define internal void @non_dead_d14()
> ; Verify we actually deduce information for these functions.
> -; MODULE: Function Attrs: nofree nosync nounwind willreturn
> -; MODULE-NEXT: define internal void @non_dead_d15()
> -; MODULE-NOT: define internal void @dead_e
> -; CGSCC: Function Attrs: nofree nosync nounwind willreturn
> -; CGSCC-NEXT: define internal void @non_dead_d15()
>
> declare void @blowup() noreturn
> define void @live_with_dead_entry() personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*) {
> -; CHECK: define void @live_with_dead_entry(
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: invoke void @blowup()
> -; CHECK-NEXT: to label %live_with_dead_entry.dead unwind label
> %lpad
> -; CHECK: lpad: ; preds =
> %entry
> -; CHECK-NEXT: %0 = landingpad { i8*, i32 }
> -; CHECK-NEXT: catch i8* null
> -; CHECK-NEXT: br label %live_with_dead_entry
> -; CHECK: live_with_dead_entry.dead: ; preds =
> %entry
> -; CHECK-NEXT: unreachable
> -; CHECK: live_with_dead_entry: ; preds =
> %lpad
> -; CHECK-NEXT: ret void
> entry:
> invoke void @blowup() to label %live_with_dead_entry unwind label %lpad
> lpad:
> @@ -1024,25 +1461,26 @@ live_with_dead_entry:
> }
>
> define void @live_with_dead_entry_lp() personality i8* bitcast (i32
> (...)* @__gxx_personality_v0 to i8*) {
> -; CHECK: define void @live_with_dead_entry_lp(
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: invoke void @blowup()
> -; CHECK-NEXT: to label %[[LIVE_WITH_DEAD_ENTRY_DEAD1:.*]] unwind label
> %[[LP1:.*]]
> -; CHECK: [[LP1]]: ;
> preds = %entry
> -; CHECK-NEXT: %lp = landingpad { i8*, i32 }
> -; CHECK-NEXT: catch i8* null
> -; CHECK-NEXT: invoke void @blowup()
> -; CHECK-NEXT: to label %[[LIVE_WITH_DEAD_ENTRY_DEAD2:.*]] unwind label
> %[[LP2:.*]]
> -; CHECK: [[LP2]]: ;
> preds = %lp1
> -; CHECK-NEXT: %0 = landingpad { i8*, i32 }
> -; CHECK-NEXT: catch i8* null
> -; CHECK-NEXT: br label %live_with_dead_entry
> -; CHECK: [[LIVE_WITH_DEAD_ENTRY_DEAD1]]:
> -; CHECK-NEXT: unreachable
> -; CHECK: [[LIVE_WITH_DEAD_ENTRY_DEAD2]]:
> -; CHECK-NEXT: unreachable
> -; CHECK: live_with_dead_entry: ; preds =
> %lp2
> -; CHECK-NEXT: ret void
> +; 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()
> +; CHECK-NEXT: to label [[LIVE_WITH_DEAD_ENTRY_DEAD:%.*]] unwind label
> [[LP1:%.*]]
> +; CHECK: lp1:
> +; CHECK-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
> +; CHECK-NEXT: catch i8* null
> +; CHECK-NEXT: invoke void @blowup()
> +; CHECK-NEXT: to label [[LIVE_WITH_DEAD_ENTRY_DEAD1:%.*]] unwind label
> [[LP2:%.*]]
> +; CHECK: lp2:
> +; CHECK-NEXT: [[TMP0:%.*]] = landingpad { i8*, i32 }
> +; CHECK-NEXT: catch i8* null
> +; CHECK-NEXT: br label [[LIVE_WITH_DEAD_ENTRY:%.*]]
> +; CHECK: live_with_dead_entry.dead:
> +; CHECK-NEXT: unreachable
> +; CHECK: live_with_dead_entry.dead1:
> +; CHECK-NEXT: unreachable
> +; CHECK: live_with_dead_entry:
> +; CHECK-NEXT: ret void
> +;
> entry:
> invoke void @blowup() to label %live_with_dead_entry unwind label %lp1
> lp1:
> @@ -1055,68 +1493,81 @@ live_with_dead_entry:
> ret void
> }
>
> -; CHECK: define internal void @useless_arg_sink()
> define internal void @useless_arg_sink(i32* %a) {
> +; CHECK-LABEL: define {{[^@]+}}@useless_arg_sink()
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: ret void
> +;
> call void @sink()
> ret void
> }
>
> -; CHECK: define internal void @useless_arg_almost_sink()
> define internal void @useless_arg_almost_sink(i32* %a) {
> -; CHECK: call void @useless_arg_sink()
> +; CHECK-LABEL: define {{[^@]+}}@useless_arg_almost_sink()
> +; CHECK-NEXT: call void @useless_arg_sink()
> +; CHECK-NEXT: ret void
> +;
> call void @useless_arg_sink(i32* %a)
> ret void
> }
>
> ; Check we do not annotate the function interface of this weak function.
> -; CHECK: define weak_odr void @useless_arg_ext(i32* %a)
> define weak_odr void @useless_arg_ext(i32* %a) {
> -; CHECK: call void @useless_arg_almost_sink()
> +; CHECK-LABEL: define {{[^@]+}}@useless_arg_ext
> +; CHECK-SAME: (i32* [[A:%.*]])
> +; CHECK-NEXT: call void @useless_arg_almost_sink()
> +; CHECK-NEXT: ret void
> +;
> call void @useless_arg_almost_sink(i32* %a)
> ret void
> }
>
> -; CHECK: define internal void @useless_arg_ext_int(i32* %a)
> define internal void @useless_arg_ext_int(i32* %a) {
> -; CHECK: call void @useless_arg_ext(i32* %a)
> +; CHECK-LABEL: define {{[^@]+}}@useless_arg_ext_int
> +; CHECK-SAME: (i32* [[A:%.*]])
> +; CHECK-NEXT: call void @useless_arg_ext(i32* [[A]])
> +; CHECK-NEXT: ret void
> +;
> call void @useless_arg_ext(i32* %a)
> ret void
> }
>
> define void @useless_arg_ext_int_ext(i32* %a) {
> -; CHECK: call void @useless_arg_ext_int(i32* %a)
> +; CHECK-LABEL: define {{[^@]+}}@useless_arg_ext_int_ext
> +; CHECK-SAME: (i32* [[A:%.*]])
> +; CHECK-NEXT: call void @useless_arg_ext_int(i32* [[A]])
> +; CHECK-NEXT: ret void
> +;
> call void @useless_arg_ext_int(i32* %a)
> ret void
> }
>
> -; UTC_ARGS: --enable
> -
> ; FIXME: We should fold terminators.
>
> define internal i32 @switch_default(i64 %i) nounwind {
> -; MODULE-LABEL: define {{[^@]+}}@switch_default()
> -; MODULE-NEXT: entry:
> -; MODULE-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
> -; MODULE-NEXT: i64 3, label [[RETURN:%.*]]
> -; MODULE-NEXT: i64 10, label [[RETURN]]
> -; MODULE-NEXT: ]
> -; MODULE: sw.default:
> -; MODULE-NEXT: call void @sink()
> -; MODULE-NEXT: ret i32 undef
> -; MODULE: return:
> -; MODULE-NEXT: unreachable
> -;
> -; CGSCC-LABEL: define {{[^@]+}}@switch_default()
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
> -; CGSCC-NEXT: i64 3, label [[RETURN:%.*]]
> -; CGSCC-NEXT: i64 10, label [[RETURN]]
> -; CGSCC-NEXT: ]
> -; CGSCC: sw.default:
> -; CGSCC-NEXT: call void @sink()
> -; CGSCC-NEXT: ret i32 123
> -; CGSCC: return:
> -; CGSCC-NEXT: unreachable
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@switch_default()
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
> +; IS__TUNIT____-NEXT: i64 3, label [[RETURN:%.*]]
> +; IS__TUNIT____-NEXT: i64 10, label [[RETURN]]
> +; IS__TUNIT____-NEXT: ]
> +; IS__TUNIT____: sw.default:
> +; IS__TUNIT____-NEXT: call void @sink()
> +; IS__TUNIT____-NEXT: ret i32 undef
> +; IS__TUNIT____: return:
> +; IS__TUNIT____-NEXT: unreachable
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@switch_default()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
> +; IS__CGSCC____-NEXT: i64 3, label [[RETURN:%.*]]
> +; IS__CGSCC____-NEXT: i64 10, label [[RETURN]]
> +; IS__CGSCC____-NEXT: ]
> +; IS__CGSCC____: sw.default:
> +; IS__CGSCC____-NEXT: call void @sink()
> +; IS__CGSCC____-NEXT: ret i32 123
> +; IS__CGSCC____: return:
> +; IS__CGSCC____-NEXT: unreachable
> ;
> entry:
> switch i64 %i, label %sw.default [
> @@ -1142,16 +1593,16 @@ define i32 @switch_default_caller() {
> }
>
> define internal i32 @switch_default_dead(i64 %i) nounwind {
> -; CGSCC-LABEL: define {{[^@]+}}@switch_default_dead()
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
> -; CGSCC-NEXT: i64 3, label [[RETURN:%.*]]
> -; CGSCC-NEXT: i64 10, label [[RETURN]]
> -; CGSCC-NEXT: ]
> -; CGSCC: sw.default:
> -; CGSCC-NEXT: ret i32 123
> -; CGSCC: return:
> -; CGSCC-NEXT: unreachable
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@switch_default_dead()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
> +; IS__CGSCC____-NEXT: i64 3, label [[RETURN:%.*]]
> +; IS__CGSCC____-NEXT: i64 10, label [[RETURN]]
> +; IS__CGSCC____-NEXT: ]
> +; IS__CGSCC____: sw.default:
> +; IS__CGSCC____-NEXT: ret i32 123
> +; IS__CGSCC____: return:
> +; IS__CGSCC____-NEXT: unreachable
> ;
> entry:
> switch i64 %i, label %sw.default [
> @@ -1185,79 +1636,45 @@ define void @call_via_pointer_with_dead_args(i32*
> %a, i32* %b, void (i32*, i32*,
> }
> ; FIXME: We have to prevent the propagation of %fp in the new pm CGSCC
> pass until the CallGraphUpdater can handle the new call edge.
> define internal void @call_via_pointer_with_dead_args_internal_a(i32* %a,
> i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) {
> -; MODULE-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
> -; MODULE-SAME: (i32* [[A:%.*]], i32* nonnull align 128 dereferenceable(4)
> [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull
> [[FP:%.*]])
> -; MODULE-NEXT: call void @called_via_pointer(i32* [[A]], i32* nonnull
> align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null)
> -; MODULE-NEXT: ret void
> +; IS__TUNIT____-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
> +; IS__TUNIT____-SAME: (i32* [[A:%.*]], i32* nonnull align 128
> dereferenceable(4) [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)*
> nocapture nofree nonnull [[FP:%.*]])
> +; IS__TUNIT____-NEXT: call void @called_via_pointer(i32* [[A]], i32*
> nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32** null)
> +; IS__TUNIT____-NEXT: ret void
> ;
> -; CGSCC_OLD-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
> -; CGSCC_OLD-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
> -; CGSCC_OLD-NEXT: call void @called_via_pointer(i32* [[A]], i32*
> [[B]], i32* [[A]], i64 -1, i32** null)
> -; CGSCC_OLD-NEXT: ret void
> -;
> -; CGSCC_NEW-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
> -; CGSCC_NEW-SAME: (i32* [[A:%.*]], i32* [[B:%.*]], void (i32*, i32*,
> i32*, i64, i32**)* nocapture nofree nonnull [[FP:%.*]])
> -; CGSCC_NEW-NEXT: call void [[FP]](i32* [[A]], i32* [[B]], i32* [[A]],
> i64 -1, i32** null)
> -; CGSCC_NEW-NEXT: ret void
> +; IS__CGSCC____-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_a
> +; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* [[B:%.*]], void (i32*, i32*,
> i32*, i64, i32**)* nocapture nofree nonnull [[FP:%.*]])
> +; IS__CGSCC____-NEXT: call void [[FP]](i32* [[A]], i32* [[B]], i32*
> [[A]], i64 -1, i32** null)
> +; IS__CGSCC____-NEXT: ret void
> ;
> call void %fp(i32* %a, i32* %b, i32* %a, i64 -1, i32** null)
> ret void
> }
> define internal void @call_via_pointer_with_dead_args_internal_b(i32* %a,
> i32* %b, void (i32*, i32*, i32*, i64, i32**)* %fp) {
> -; MODULE-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_b
> -; MODULE-SAME: (i32* [[A:%.*]], i32* nonnull align 128 dereferenceable(4)
> [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)* nocapture nofree nonnull
> [[FP:%.*]])
> -; MODULE-NEXT: call void @called_via_pointer_internal_2(i32* [[A]],
> i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1, i32**
> null)
> -; MODULE-NEXT: ret void
> -;
> -; CGSCC_OLD-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_b
> -; CGSCC_OLD-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
> -; CGSCC_OLD-NEXT: call void @called_via_pointer_internal_2(i32* [[A]])
> -; CGSCC_OLD-NEXT: ret void
> +; IS__TUNIT____-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_b
> +; IS__TUNIT____-SAME: (i32* [[A:%.*]], i32* nonnull align 128
> dereferenceable(4) [[B:%.*]], void (i32*, i32*, i32*, i64, i32**)*
> nocapture nofree nonnull [[FP:%.*]])
> +; IS__TUNIT____-NEXT: call void @called_via_pointer_internal_2(i32*
> [[A]], i32* nonnull align 128 dereferenceable(4) [[B]], i32* [[A]], i64 -1,
> i32** null)
> +; IS__TUNIT____-NEXT: ret void
> ;
> -; CGSCC_NEW-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_b
> -; CGSCC_NEW-SAME: (i32* [[A:%.*]], i32* [[B:%.*]], void (i32*, i32*,
> i32*, i64, i32**)* nocapture nofree nonnull [[FP:%.*]])
> -; CGSCC_NEW-NEXT: call void [[FP]](i32* [[A]], i32* [[B]], i32* [[A]],
> i64 -1, i32** null)
> -; CGSCC_NEW-NEXT: ret void
> +; IS__CGSCC____-LABEL: define
> {{[^@]+}}@call_via_pointer_with_dead_args_internal_b
> +; IS__CGSCC____-SAME: (i32* [[A:%.*]], i32* [[B:%.*]], void (i32*, i32*,
> i32*, i64, i32**)* nocapture nofree nonnull [[FP:%.*]])
> +; IS__CGSCC____-NEXT: call void [[FP]](i32* [[A]], i32* [[B]], i32*
> [[A]], i64 -1, i32** null)
> +; IS__CGSCC____-NEXT: ret void
> ;
> call void %fp(i32* %a, i32* %b, i32* %a, i64 -1, i32** null)
> ret void
> }
> define void @call_via_pointer_with_dead_args_caller(i32* %a, i32* %b) {
> -; MODULE-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
> -; MODULE-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
> -; MODULE-NEXT: [[PTR1:%.*]] = alloca i32, align 128
> -; MODULE-NEXT: [[PTR2:%.*]] = alloca i32, align 128
> -; MODULE-NEXT: [[PTR3:%.*]] = alloca i32, align 128
> -; MODULE-NEXT: [[PTR4:%.*]] = alloca i32, align 128
> -; MODULE-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]],
> i32* nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*,
> i64, i32**)* nofree nonnull @called_via_pointer)
> -; MODULE-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]],
> i32* nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*,
> i64, i32**)* nofree nonnull @called_via_pointer_internal_1)
> -; MODULE-NEXT: call void
> @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* nonnull align
> 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)*
> nofree nonnull @called_via_pointer)
> -; MODULE-NEXT: call void
> @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* nonnull align
> 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)*
> nofree nonnull @called_via_pointer_internal_2)
> -; MODULE-NEXT: ret void
> -;
> -; CGSCC_OLD-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
> -; CGSCC_OLD-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
> -; CGSCC_OLD-NEXT: [[PTR1:%.*]] = alloca i32, align 128
> -; CGSCC_OLD-NEXT: [[PTR2:%.*]] = alloca i32, align 128
> -; CGSCC_OLD-NEXT: [[PTR3:%.*]] = alloca i32, align 128
> -; CGSCC_OLD-NEXT: [[PTR4:%.*]] = alloca i32, align 128
> -; CGSCC_OLD-NEXT: call void @call_via_pointer_with_dead_args(i32*
> [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*,
> i32*, i32*, i64, i32**)* nofree nonnull @called_via_pointer)
> -; CGSCC_OLD-NEXT: call void @call_via_pointer_with_dead_args(i32*
> [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*,
> i32*, i32*, i64, i32**)* nofree nonnull @called_via_pointer_internal_1)
> -; CGSCC_OLD-NEXT: call void
> @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* nonnull align
> 128 dereferenceable(4) [[PTR3]])
> -; CGSCC_OLD-NEXT: call void
> @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* nonnull align
> 128 dereferenceable(4) [[PTR4]])
> -; CGSCC_OLD-NEXT: ret void
> -;
> -; CGSCC_NEW-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
> -; CGSCC_NEW-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
> -; CGSCC_NEW-NEXT: [[PTR1:%.*]] = alloca i32, align 128
> -; CGSCC_NEW-NEXT: [[PTR2:%.*]] = alloca i32, align 128
> -; CGSCC_NEW-NEXT: [[PTR3:%.*]] = alloca i32, align 128
> -; CGSCC_NEW-NEXT: [[PTR4:%.*]] = alloca i32, align 128
> -; CGSCC_NEW-NEXT: call void @call_via_pointer_with_dead_args(i32*
> [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*,
> i32*, i32*, i64, i32**)* nofree nonnull @called_via_pointer)
> -; CGSCC_NEW-NEXT: call void @call_via_pointer_with_dead_args(i32*
> [[A]], i32* nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*,
> i32*, i32*, i64, i32**)* nofree nonnull @called_via_pointer_internal_1)
> -; CGSCC_NEW-NEXT: call void
> @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* nonnull align
> 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)*
> nofree nonnull @called_via_pointer)
> -; CGSCC_NEW-NEXT: call void
> @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* nonnull align
> 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)*
> nofree nonnull @called_via_pointer_internal_2)
> -; CGSCC_NEW-NEXT: ret void
> +; CHECK-LABEL: define {{[^@]+}}@call_via_pointer_with_dead_args_caller
> +; CHECK-SAME: (i32* [[A:%.*]], i32* [[B:%.*]])
> +; CHECK-NEXT: [[PTR1:%.*]] = alloca i32, align 128
> +; CHECK-NEXT: [[PTR2:%.*]] = alloca i32, align 128
> +; CHECK-NEXT: [[PTR3:%.*]] = alloca i32, align 128
> +; CHECK-NEXT: [[PTR4:%.*]] = alloca i32, align 128
> +; CHECK-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]],
> i32* nonnull align 128 dereferenceable(4) [[PTR1]], void (i32*, i32*, i32*,
> i64, i32**)* nofree nonnull @called_via_pointer)
> +; CHECK-NEXT: call void @call_via_pointer_with_dead_args(i32* [[A]],
> i32* nonnull align 128 dereferenceable(4) [[PTR2]], void (i32*, i32*, i32*,
> i64, i32**)* nofree nonnull @called_via_pointer_internal_1)
> +; CHECK-NEXT: call void
> @call_via_pointer_with_dead_args_internal_a(i32* [[B]], i32* nonnull align
> 128 dereferenceable(4) [[PTR3]], void (i32*, i32*, i32*, i64, i32**)*
> nofree nonnull @called_via_pointer)
> +; CHECK-NEXT: call void
> @call_via_pointer_with_dead_args_internal_b(i32* [[B]], i32* nonnull align
> 128 dereferenceable(4) [[PTR4]], void (i32*, i32*, i32*, i64, i32**)*
> nofree nonnull @called_via_pointer_internal_2)
> +; CHECK-NEXT: ret void
> ;
> %ptr1 = alloca i32, align 128
> %ptr2 = alloca i32, align 128
> @@ -1297,26 +1714,12 @@ entry:
> }
> ; FIXME: Figure out why the MODULE has the unused arguments still
> define internal void @called_via_pointer_internal_2(i32* %a, i32* %b,
> i32* %c, i64 %d, i32** %e) {
> -; MODULE-LABEL: define {{[^@]+}}@called_via_pointer_internal_2
> -; MODULE-SAME: (i32* [[A:%.*]], i32* nocapture nofree readnone [[B:%.*]],
> i32* nocapture nofree readnone [[C:%.*]], i64 [[D:%.*]], i32** nocapture
> nofree readnone [[E:%.*]])
> -; MODULE-NEXT: entry:
> -; MODULE-NEXT: tail call void @use_i32p(i32* [[A]])
> -; MODULE-NEXT: tail call void @use_i32p(i32* [[A]])
> -; MODULE-NEXT: ret void
> -;
> -; CGSCC_OLD-LABEL: define {{[^@]+}}@called_via_pointer_internal_2
> -; CGSCC_OLD-SAME: (i32* [[A:%.*]])
> -; CGSCC_OLD-NEXT: entry:
> -; CGSCC_OLD-NEXT: tail call void @use_i32p(i32* [[A]])
> -; CGSCC_OLD-NEXT: tail call void @use_i32p(i32* [[A]])
> -; CGSCC_OLD-NEXT: ret void
> -;
> -; CGSCC_NEW-LABEL: define {{[^@]+}}@called_via_pointer_internal_2
> -; CGSCC_NEW-SAME: (i32* [[A:%.*]], i32* nocapture nofree readnone
> [[B:%.*]], i32* nocapture nofree readnone [[C:%.*]], i64 [[D:%.*]], i32**
> nocapture nofree readnone [[E:%.*]])
> -; CGSCC_NEW-NEXT: entry:
> -; CGSCC_NEW-NEXT: tail call void @use_i32p(i32* [[A]])
> -; CGSCC_NEW-NEXT: tail call void @use_i32p(i32* [[A]])
> -; CGSCC_NEW-NEXT: ret void
> +; CHECK-LABEL: define {{[^@]+}}@called_via_pointer_internal_2
> +; CHECK-SAME: (i32* [[A:%.*]], i32* nocapture nofree readnone [[B:%.*]],
> i32* nocapture nofree readnone [[C:%.*]], i64 [[D:%.*]], i32** nocapture
> nofree readnone [[E:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: tail call void @use_i32p(i32* [[A]])
> +; CHECK-NEXT: tail call void @use_i32p(i32* [[A]])
> +; CHECK-NEXT: ret void
> ;
> entry:
> tail call void @use_i32p(i32* %a)
> @@ -1325,13 +1728,26 @@ entry:
> }
> declare void @use_i32p(i32*)
>
> -; UTC_ARGS: --disable
> -
> ; Allow blockaddress users
> -; MODULE-NOT: @dead_with_blockaddress_users
> -; CGSCC_NEW-NOT: @dead_with_blockaddress_users
> -; CGSCC_OLD: @dead_with_blockaddress_users
> +; NOT_CGSCC_OPM-NOT: @dead_with_blockaddress_users
> define internal void @dead_with_blockaddress_users(i32* nocapture %pc)
> nounwind readonly {
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@dead_with_blockaddress_users
> +; IS__CGSCC_OPM-SAME: (i32* nocapture [[PC:%.*]])
> +; IS__CGSCC_OPM-NEXT: entry:
> +; IS__CGSCC_OPM-NEXT: br label [[INDIRECTGOTO:%.*]]
> +; IS__CGSCC_OPM: lab0:
> +; IS__CGSCC_OPM-NEXT: [[INDVAR_NEXT:%.*]] = add i32 [[INDVAR:%.*]], 1
> +; IS__CGSCC_OPM-NEXT: br label [[INDIRECTGOTO]]
> +; IS__CGSCC_OPM: end:
> +; IS__CGSCC_OPM-NEXT: ret void
> +; IS__CGSCC_OPM: indirectgoto:
> +; IS__CGSCC_OPM-NEXT: [[INDVAR]] = phi i32 [ [[INDVAR_NEXT]],
> [[LAB0:%.*]] ], [ 0, [[ENTRY:%.*]] ]
> +; IS__CGSCC_OPM-NEXT: [[PC_ADDR_0:%.*]] = getelementptr i32, i32*
> [[PC]], i32 [[INDVAR]]
> +; IS__CGSCC_OPM-NEXT: [[TMP1_PN:%.*]] = load i32, i32* [[PC_ADDR_0]]
> +; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST_IN:%.*]] = getelementptr
> inbounds [2 x i8*], [2 x i8*]* @dead_with_blockaddress_users.l, i32 0, i32
> [[TMP1_PN]]
> +; IS__CGSCC_OPM-NEXT: [[INDIRECT_GOTO_DEST:%.*]] = load i8*, i8**
> [[INDIRECT_GOTO_DEST_IN]]
> +; IS__CGSCC_OPM-NEXT: indirectbr i8* [[INDIRECT_GOTO_DEST]], [label
> [[LAB0]], label %end]
> +;
> entry:
> br label %indirectgoto
>
>
> diff --git a/llvm/test/Transforms/Attributor/liveness_chains.ll
> b/llvm/test/Transforms/Attributor/liveness_chains.ll
> index c9ab99f904f8..3ba97f2a6c78 100644
> --- a/llvm/test/Transforms/Attributor/liveness_chains.ll
> +++ b/llvm/test/Transforms/Attributor/liveness_chains.ll
> @@ -1,8 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=1 -S < %s | FileCheck %s
> -; RUN: opt -attributor-cgscc --attributor-disable=false
> -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s |
> FileCheck %s
> -; RUN: opt -passes=attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=1 -S < %s | FileCheck %s
> -; RUN: opt -passes='attributor-cgscc' --attributor-disable=false
> -attributor-annotate-decl-cs -attributor-max-iterations=1 -S < %s |
> FileCheck %s
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; Make sure we need a single iteration to determine the chains are
> dead/alive.
>
>
> diff --git a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
> b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
> index 7dbf8d073f65..1511cd3124eb 100644
> --- a/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
> +++ b/llvm/test/Transforms/Attributor/lvi-after-jumpthreading.ll
> @@ -1,20 +1,38 @@
> -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> -; RUN: opt -passes=attributor -attributor-disable=false -S < %s |
> FileCheck %s
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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) {
> -; CHECK-LABEL: define {{[^@]+}}@test1
> -; CHECK-SAME: (i32 [[A:%.*]], i32 [[LENGTH:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: br label [[LOOP:%.*]]
> -; CHECK: loop:
> -; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [
> [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
> -; CHECK-NEXT: br label [[BACKEDGE]]
> -; CHECK: backedge:
> -; CHECK-NEXT: [[IV_NEXT]] = add nsw i32 [[IV]], 1
> -; CHECK-NEXT: [[CONT:%.*]] = icmp slt i32 [[IV_NEXT]], 400
> -; CHECK-NEXT: br i1 [[CONT]], label [[LOOP]], label [[EXIT:%.*]]
> -; CHECK: exit:
> -; CHECK-NEXT: ret i8 0
> +; 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________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
> ;
> entry:
> br label %loop
> @@ -40,7 +58,7 @@ define i8 @test2(i32 %n) {
> ; 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: [[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]]
> @@ -81,25 +99,46 @@ exit:
>
> ; Merging cont block into do block.
> define i32 @test3(i32 %i, i1 %f, i32 %n) {
> -; CHECK-LABEL: define {{[^@]+}}@test3
> -; CHECK-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I:%.*]], -2134
> -; CHECK-NEXT: br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
> -; CHECK: exit:
> -; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[I]], -42
> -; CHECK-NEXT: br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
> -; CHECK: cont:
> -; CHECK-NEXT: [[COND_3:%.*]] = icmp sgt i32 [[I]], [[N:%.*]]
> -; CHECK-NEXT: br i1 [[COND_3]], label [[EXIT2]], label [[EXIT]]
> -; CHECK: do:
> -; CHECK-NEXT: [[COND_0:%.*]] = icmp sgt i32 [[I]], 0
> -; CHECK-NEXT: [[CONSUME:%.*]] = call i32 @consume(i1 [[COND_0]])
> -; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[I]], 0
> -; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1
> [[COND]]) [ "deopt"() ]
> -; CHECK-NEXT: br label [[CONT:%.*]]
> -; CHECK: exit2:
> -; CHECK-NEXT: ret i32 30
> +; IS________OPM-LABEL: define {{[^@]+}}@test3
> +; IS________OPM-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]])
> +; IS________OPM-NEXT: entry:
> +; IS________OPM-NEXT: [[C:%.*]] = icmp ne i32 [[I]], -2134
> +; IS________OPM-NEXT: br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
> +; IS________OPM: exit:
> +; IS________OPM-NEXT: [[C1:%.*]] = icmp ne i32 [[I]], -42
> +; IS________OPM-NEXT: br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
> +; IS________OPM: cont:
> +; IS________OPM-NEXT: [[COND_3:%.*]] = icmp sgt i32 [[I]], [[N]]
> +; IS________OPM-NEXT: br i1 [[COND_3]], label [[EXIT2]], label [[EXIT]]
> +; IS________OPM: do:
> +; IS________OPM-NEXT: [[COND_0:%.*]] = icmp sgt i32 [[I]], 0
> +; IS________OPM-NEXT: [[CONSUME:%.*]] = call i32 @consume(i1
> [[COND_0]])
> +; IS________OPM-NEXT: [[COND:%.*]] = icmp eq i32 [[I]], 0
> +; IS________OPM-NEXT: call void (i1, ...) @llvm.experimental.guard(i1
> [[COND]]) [ "deopt"() ]
> +; IS________OPM-NEXT: [[COND_2:%.*]] = icmp sgt i32 [[I]], 0
> +; IS________OPM-NEXT: br i1 [[COND_2]], label [[EXIT]], label
> [[CONT:%.*]]
> +; IS________OPM: exit2:
> +; IS________OPM-NEXT: ret i32 30
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test3
> +; IS________NPM-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]])
> +; IS________NPM-NEXT: entry:
> +; IS________NPM-NEXT: [[C:%.*]] = icmp ne i32 [[I]], -2134
> +; IS________NPM-NEXT: br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
> +; IS________NPM: exit:
> +; IS________NPM-NEXT: [[C1:%.*]] = icmp ne i32 [[I]], -42
> +; IS________NPM-NEXT: br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
> +; IS________NPM: cont:
> +; IS________NPM-NEXT: [[COND_3:%.*]] = icmp sgt i32 [[I]], [[N]]
> +; IS________NPM-NEXT: br i1 [[COND_3]], label [[EXIT2]], label [[EXIT]]
> +; IS________NPM: do:
> +; IS________NPM-NEXT: [[COND_0:%.*]] = icmp sgt i32 [[I]], 0
> +; IS________NPM-NEXT: [[CONSUME:%.*]] = call i32 @consume(i1
> [[COND_0]])
> +; IS________NPM-NEXT: [[COND:%.*]] = icmp eq i32 [[I]], 0
> +; IS________NPM-NEXT: call void (i1, ...) @llvm.experimental.guard(i1
> [[COND]]) [ "deopt"() ]
> +; IS________NPM-NEXT: br label [[CONT:%.*]]
> +; IS________NPM: exit2:
> +; IS________NPM-NEXT: ret i32 30
> ;
> entry:
> %c = icmp ne i32 %i, -2134
> @@ -129,17 +168,18 @@ exit2:
> }
>
> ; FIXME: We should be able to merge cont into do.
> +; FIXME: COND should be replaced with false. This will be fixed by
> improving LVI.
> define i32 @test4(i32 %i, i1 %f, i32 %n) {
> ; CHECK-LABEL: define {{[^@]+}}@test4
> ; CHECK-SAME: (i32 [[I:%.*]], i1 [[F:%.*]], i32 [[N:%.*]])
> ; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I:%.*]], -2134
> +; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[I]], -2134
> ; CHECK-NEXT: br i1 [[C]], label [[DO:%.*]], label [[EXIT:%.*]]
> ; CHECK: exit:
> ; CHECK-NEXT: [[C1:%.*]] = icmp ne i32 [[I]], -42
> ; CHECK-NEXT: br i1 [[C1]], label [[EXIT2:%.*]], label [[EXIT]]
> ; CHECK: cont:
> -; CHECK-NEXT: call void @dummy(i1 [[F:%.*]])
> +; CHECK-NEXT: call void @dummy(i1 [[F]])
> ; CHECK-NEXT: br label [[EXIT2]]
> ; CHECK: do:
> ; CHECK-NEXT: call void @dummy(i1 [[F]])
> @@ -150,7 +190,6 @@ define i32 @test4(i32 %i, i1 %f, i32 %n) {
> ; CHECK: exit2:
> ; CHECK-NEXT: ret i32 30
> ;
> -; FIXME: COND should be replaced with false. This will be fixed by
> improving LVI.
> entry:
> %c = icmp ne i32 %i, -2134
> br i1 %c, label %do, label %exit
>
> diff --git a/llvm/test/Transforms/Attributor/lvi-for-ashr.ll
> b/llvm/test/Transforms/Attributor/lvi-for-ashr.ll
> index ccc5aba33a45..729ff66f0735 100644
> --- a/llvm/test/Transforms/Attributor/lvi-for-ashr.ll
> +++ b/llvm/test/Transforms/Attributor/lvi-for-ashr.ll
> @@ -1,10 +1,16 @@
> -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> -; RUN: opt -passes=attributor -attributor-disable=false -S < %s |
> FileCheck %s
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> +
> +; 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: [[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
> @@ -21,7 +27,6 @@ define i32 @test-ashr(i32 %c) {
> ; CHECK-NEXT: [[RETVAL:%.*]] = phi i32 [ 0, [[CHK65:%.*]] ], [ 1,
> [[CHK0]] ], [ [[DOT]], [[BB_THEN]] ], [ 4, [[BB_IF]] ]
> ; CHECK-NEXT: ret i32 [[RETVAL]]
> ;
> -; FIXME: DOT should be replaced with 3
> chk65:
> %cmp = icmp sgt i32 %c, 65
> br i1 %cmp, label %return, label %chk0
>
> diff --git a/llvm/test/Transforms/Attributor/memory_locations.ll
> b/llvm/test/Transforms/Attributor/memory_locations.ll
> index de997a729131..c3222367360a 100644
> --- a/llvm/test/Transforms/Attributor/memory_locations.ll
> +++ b/llvm/test/Transforms/Attributor/memory_locations.ll
> @@ -1,15 +1,15 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=7 -S < %s | FileCheck %s
> --check-prefixes=CHECK,MODULE,OLD_MODULE
> -; RUN: opt -attributor-cgscc --attributor-disable=false
> -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s |
> FileCheck %s --check-prefixes=CHECK,CGSCC,OLD_CGSCC
> -; RUN: opt -passes=attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=7 -S < %s | FileCheck %s
> --check-prefixes=CHECK,MODULE,NEW_MODULE
> -; RUN: opt -passes='attributor-cgscc' --attributor-disable=false
> -attributor-annotate-decl-cs -attributor-max-iterations=7 -S < %s |
> FileCheck %s --check-prefixes=CHECK,CGSCC,NEW_CGSCC
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> target datalayout =
> "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
>
> ; CHECK: Function Attrs: inaccessiblememonly
> declare noalias i8* @malloc(i64) inaccessiblememonly
>
> -define dso_local i8* @internal_only(i32 %arg) {
> ; CHECK: Function Attrs: inaccessiblememonly
> +define dso_local i8* @internal_only(i32 %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@internal_only
> ; CHECK-SAME: (i32 [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -23,8 +23,8 @@ entry:
> ret i8* %call
> }
>
> -define dso_local i8* @internal_only_rec(i32 %arg) {
> ; CHECK: Function Attrs: inaccessiblememonly
> +define dso_local i8* @internal_only_rec(i32 %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec
> ; CHECK-SAME: (i32 [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -63,8 +63,8 @@ return: ;
> preds = %if.end, %if.then
> ret i8* %retval.0
> }
>
> -define dso_local i8* @internal_only_rec_static_helper(i32 %arg) {
> ; CHECK: Function Attrs: inaccessiblememonly
> +define dso_local i8* @internal_only_rec_static_helper(i32 %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_helper
> ; CHECK-SAME: (i32 [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -76,8 +76,8 @@ entry:
> ret i8* %call
> }
>
> -define internal i8* @internal_only_rec_static(i32 %arg) {
> ; CHECK: Function Attrs: inaccessiblememonly
> +define internal i8* @internal_only_rec_static(i32 %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static
> ; CHECK-SAME: (i32 [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -118,7 +118,6 @@ return: ;
> preds = %if.end, %if.then
>
> define dso_local i8* @internal_only_rec_static_helper_malloc_noescape(i32
> %arg) {
> ; FIXME: This is actually inaccessiblememonly because the malloced memory
> does not escape
> -; CHECK-NOT: inaccessiblememonly
> ; CHECK-LABEL: define
> {{[^@]+}}@internal_only_rec_static_helper_malloc_noescape
> ; CHECK-SAME: (i32 [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -132,7 +131,6 @@ entry:
>
> define internal i8* @internal_only_rec_static_malloc_noescape(i32 %arg) {
> ; FIXME: This is actually inaccessiblememonly because the malloced memory
> does not escape
> -; CHECK-NOT: inaccessiblememonly
> ; CHECK-LABEL: define {{[^@]+}}@internal_only_rec_static_malloc_noescape
> ; CHECK-SAME: (i32 [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -173,8 +171,8 @@ return: ;
> preds = %if.end, %if.then
> ret i8* %retval.0
> }
>
> -define dso_local i8* @internal_argmem_only_read(i32* %arg) {
> ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
> +define dso_local i8* @internal_argmem_only_read(i32* %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_read
> ; CHECK-SAME: (i32* nocapture nonnull readonly align 4 dereferenceable(4)
> [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -190,8 +188,8 @@ entry:
> ret i8* %call
> }
>
> -define dso_local i8* @internal_argmem_only_write(i32* %arg) {
> ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
> +define dso_local i8* @internal_argmem_only_write(i32* %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_write
> ; CHECK-SAME: (i32* nocapture nonnull writeonly align 4
> dereferenceable(4) [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -205,27 +203,27 @@ entry:
> ret i8* %call
> }
>
> -define dso_local i8* @internal_argmem_only_rec(i32* %arg) {
> ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
> -; MODULE-LABEL: define {{[^@]+}}@internal_argmem_only_rec
> -; MODULE-SAME: (i32* nocapture align 4 [[ARG:%.*]])
> -; MODULE-NEXT: entry:
> -; MODULE-NEXT: [[CALL:%.*]] = call noalias i8*
> @internal_argmem_only_rec_1(i32* nocapture align 4 [[ARG]])
> -; MODULE-NEXT: ret i8* [[CALL]]
> +define dso_local i8* @internal_argmem_only_rec(i32* %arg) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_argmem_only_rec
> +; IS__TUNIT____-SAME: (i32* nocapture align 4 [[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]]
> ;
> -; CGSCC-LABEL: define {{[^@]+}}@internal_argmem_only_rec
> -; CGSCC-SAME: (i32* nocapture nonnull align 4 dereferenceable(4)
> [[ARG:%.*]])
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: [[CALL:%.*]] = call noalias i8*
> @internal_argmem_only_rec_1(i32* nocapture nonnull align 4
> dereferenceable(4) [[ARG]])
> -; CGSCC-NEXT: ret i8* [[CALL]]
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_argmem_only_rec
> +; IS__CGSCC____-SAME: (i32* nocapture nonnull align 4 dereferenceable(4)
> [[ARG:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call noalias i8*
> @internal_argmem_only_rec_1(i32* nocapture nonnull align 4
> dereferenceable(4) [[ARG]])
> +; IS__CGSCC____-NEXT: ret i8* [[CALL]]
> ;
> entry:
> %call = call i8* @internal_argmem_only_rec_1(i32* %arg)
> ret i8* %call
> }
>
> -define internal i8* @internal_argmem_only_rec_1(i32* %arg) {
> ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
> +define internal i8* @internal_argmem_only_rec_1(i32* %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_1
> ; CHECK-SAME: (i32* nocapture nonnull align 4 dereferenceable(4)
> [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -280,8 +278,8 @@ return: ;
> preds = %if.end3, %if.then2,
> ret i8* %retval.0
> }
>
> -define internal i8* @internal_argmem_only_rec_2(i32* %arg) {
> ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
> +define internal i8* @internal_argmem_only_rec_2(i32* %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@internal_argmem_only_rec_2
> ; CHECK-SAME: (i32* nocapture nonnull align 4 dereferenceable(4)
> [[ARG:%.*]])
> ; CHECK-NEXT: entry:
> @@ -302,8 +300,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
>
> -define void @callerA1(i8* %arg) {
> ; CHECK: Function Attrs: argmemonly
> +define void @callerA1(i8* %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@callerA1
> ; CHECK-SAME: (i8* [[ARG:%.*]])
> ; CHECK-NEXT: [[TMP1:%.*]] = call i8* @argmem_only(i8* [[ARG]])
> @@ -312,8 +310,8 @@ define void @callerA1(i8* %arg) {
> call i8* @argmem_only(i8* %arg)
> ret void
> }
> -define void @callerA2(i8* %arg) {
> ; CHECK: Function Attrs: inaccessiblemem_or_argmemonly
> +define void @callerA2(i8* %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@callerA2
> ; CHECK-SAME: (i8* [[ARG:%.*]])
> ; CHECK-NEXT: [[TMP1:%.*]] = call i8*
> @inaccesible_argmem_only_decl(i8* [[ARG]])
> @@ -322,8 +320,8 @@ define void @callerA2(i8* %arg) {
> call i8* @inaccesible_argmem_only_decl(i8* %arg)
> ret void
> }
> -define void @callerB1() {
> ; CHECK: Function Attrs: readnone
> +define void @callerB1() {
> ; CHECK-LABEL: define {{[^@]+}}@callerB1()
> ; CHECK-NEXT: [[STACK:%.*]] = alloca i8
> ; CHECK-NEXT: [[TMP1:%.*]] = call i8* @argmem_only(i8* nonnull
> dereferenceable(1) [[STACK]])
> @@ -333,8 +331,8 @@ define void @callerB1() {
> call i8* @argmem_only(i8* %stack)
> ret void
> }
> -define void @callerB2() {
> ; CHECK: Function Attrs: inaccessiblememonly
> +define void @callerB2() {
> ; CHECK-LABEL: define {{[^@]+}}@callerB2()
> ; CHECK-NEXT: [[STACK:%.*]] = alloca i8
> ; CHECK-NEXT: [[TMP1:%.*]] = call i8*
> @inaccesible_argmem_only_decl(i8* nonnull dereferenceable(1) [[STACK]])
> @@ -344,8 +342,8 @@ define void @callerB2() {
> call i8* @inaccesible_argmem_only_decl(i8* %stack)
> ret void
> }
> -define void @callerC1() {
> ; CHECK-NOT: Function Attrs
> +define void @callerC1() {
> ; CHECK-LABEL: define {{[^@]+}}@callerC1()
> ; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @unknown_ptr()
> ; CHECK-NEXT: [[TMP1:%.*]] = call i8* @argmem_only(i8* [[UNKNOWN]])
> @@ -355,8 +353,8 @@ define void @callerC1() {
> call i8* @argmem_only(i8* %unknown)
> ret void
> }
> -define void @callerC2() {
> ; CHECK-NOT: Function Attrs
> +define void @callerC2() {
> ; CHECK-LABEL: define {{[^@]+}}@callerC2()
> ; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @unknown_ptr()
> ; CHECK-NEXT: [[TMP1:%.*]] = call i8*
> @inaccesible_argmem_only_decl(i8* [[UNKNOWN]])
> @@ -366,8 +364,8 @@ define void @callerC2() {
> call i8* @inaccesible_argmem_only_decl(i8* %unknown)
> ret void
> }
> -define void @callerD1() {
> ; CHECK-NOT: Function Attrs
> +define void @callerD1() {
> ; CHECK-LABEL: define {{[^@]+}}@callerD1()
> ; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8* @argmem_only(i8* noalias
> align 536870912 null)
> ; CHECK-NEXT: store i8 0, i8* [[UNKNOWN]]
> @@ -377,8 +375,8 @@ define void @callerD1() {
> store i8 0, i8* %unknown
> ret void
> }
> -define void @callerD2() {
> ; CHECK-NOT: Function Attrs
> +define void @callerD2() {
> ; CHECK-LABEL: define {{[^@]+}}@callerD2()
> ; CHECK-NEXT: [[UNKNOWN:%.*]] = call i8*
> @inaccesible_argmem_only_decl(i8* noalias align 536870912 null)
> ; CHECK-NEXT: store i8 0, i8* [[UNKNOWN]]
> @@ -388,8 +386,8 @@ define void @callerD2() {
> store i8 0, i8* %unknown
> ret void
> }
> -define void @callerE(i8* %arg) {
> ; CHECK: Function Attrs: argmemonly nounwind willreturn
> +define void @callerE(i8* %arg) {
> ; CHECK-LABEL: define {{[^@]+}}@callerE
> ; CHECK-SAME: (i8* nocapture [[ARG:%.*]])
> ; CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 4, i8* nocapture
> [[ARG]])
>
> diff --git a/llvm/test/Transforms/Attributor/misc.ll
> b/llvm/test/Transforms/Attributor/misc.ll
> index b660300bcc20..07149471565b 100644
> --- a/llvm/test/Transforms/Attributor/misc.ll
> +++ b/llvm/test/Transforms/Attributor/misc.ll
> @@ -1,35 +1,39 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -S -attributor -attributor-disable=false < %s | FileCheck %s
> --check-prefixes=ALL,CHECK
> -; RUN: opt -S -aa-pipeline='basic-aa' -passes=attributor
> -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s
> --check-prefixes=ALL,DECL_CS
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ;
> ; Mostly check we do not crash on these uses
>
> define internal void @internal(void (i8*)* %fp) {
> -; CHECK-LABEL: define {{[^@]+}}@internal
> -; CHECK-SAME: (void (i8*)* nonnull [[FP:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
> -; CHECK-NEXT: call void @foo(i32* noalias nocapture nofree nonnull
> writeonly align 4 dereferenceable(4) [[A]])
> -; CHECK-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
> -; CHECK-NEXT: call void @callback1(void (i32*)* nonnull @foo)
> -; CHECK-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)*
> @foo to void (i8*)*))
> -; CHECK-NEXT: call void @callback2(void (i8*)* [[FP]])
> -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
> -; CHECK-NEXT: call void [[FP]](i8* [[TMP1]])
> -; CHECK-NEXT: ret void
> ;
> -; DECL_CS-LABEL: define {{[^@]+}}@internal
> -; DECL_CS-SAME: (void (i8*)* nonnull [[FP:%.*]])
> -; DECL_CS-NEXT: entry:
> -; DECL_CS-NEXT: [[A:%.*]] = alloca i32, align 4
> -; DECL_CS-NEXT: call void @foo(i32* noalias nocapture nofree nonnull
> writeonly align 4 dereferenceable(4) [[A]])
> -; DECL_CS-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to
> i8*))
> -; DECL_CS-NEXT: call void @callback1(void (i32*)* nonnull @foo)
> -; DECL_CS-NEXT: call void @callback2(void (i8*)* nonnull bitcast (void
> (i32*)* @foo to void (i8*)*))
> -; DECL_CS-NEXT: call void @callback2(void (i8*)* nonnull [[FP]])
> -; DECL_CS-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
> -; DECL_CS-NEXT: call void [[FP]](i8* [[TMP1]])
> -; DECL_CS-NEXT: ret void
> +;
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@internal
> +; IS__TUNIT____-SAME: (void (i8*)* nonnull [[FP:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4
> +; IS__TUNIT____-NEXT: call void @foo(i32* noalias nocapture nofree
> nonnull writeonly align 4 dereferenceable(4) [[A]])
> +; IS__TUNIT____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo
> to i8*))
> +; IS__TUNIT____-NEXT: call void @callback1(void (i32*)* nonnull @foo)
> +; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* nonnull bitcast
> (void (i32*)* @foo to void (i8*)*))
> +; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* nonnull [[FP]])
> +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
> +; IS__TUNIT____-NEXT: call void [[FP]](i8* [[TMP1]])
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@internal
> +; IS__CGSCC____-SAME: (void (i8*)* nonnull [[FP:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4
> +; IS__CGSCC____-NEXT: call void @foo(i32* noalias nocapture nofree
> nonnull writeonly align 4 dereferenceable(4) [[A]])
> +; IS__CGSCC____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo
> to i8*))
> +; IS__CGSCC____-NEXT: call void @callback1(void (i32*)* nonnull @foo)
> +; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* bitcast (void
> (i32*)* @foo to void (i8*)*))
> +; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* nonnull [[FP]])
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
> +; IS__CGSCC____-NEXT: call void [[FP]](i8* [[TMP1]])
> +; IS__CGSCC____-NEXT: ret void
> ;
> entry:
> %a = alloca i32, align 4
> @@ -45,33 +49,35 @@ entry:
> }
>
> define void @external(void (i8*)* %fp) {
> -; CHECK-LABEL: define {{[^@]+}}@external
> -; CHECK-SAME: (void (i8*)* [[FP:%.*]])
> -; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
> -; CHECK-NEXT: call void @foo(i32* noalias nocapture nofree nonnull
> writeonly align 4 dereferenceable(4) [[A]])
> -; CHECK-NEXT: call void @callback1(void (i32*)* nonnull @foo)
> -; CHECK-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)*
> @foo to void (i8*)*))
> -; CHECK-NEXT: call void @callback2(void (i8*)* [[FP]])
> -; CHECK-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
> -; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
> -; CHECK-NEXT: call void [[FP]](i8* [[TMP1]])
> -; CHECK-NEXT: call void @internal(void (i8*)* nonnull [[FP]])
> -; CHECK-NEXT: ret void
> ;
> -; DECL_CS-LABEL: define {{[^@]+}}@external
> -; DECL_CS-SAME: (void (i8*)* [[FP:%.*]])
> -; DECL_CS-NEXT: entry:
> -; DECL_CS-NEXT: [[A:%.*]] = alloca i32, align 4
> -; DECL_CS-NEXT: call void @foo(i32* noalias nocapture nofree nonnull
> writeonly align 4 dereferenceable(4) [[A]])
> -; DECL_CS-NEXT: call void @callback1(void (i32*)* nonnull @foo)
> -; DECL_CS-NEXT: call void @callback2(void (i8*)* nonnull bitcast (void
> (i32*)* @foo to void (i8*)*))
> -; DECL_CS-NEXT: call void @callback2(void (i8*)* [[FP]])
> -; DECL_CS-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to
> i8*))
> -; DECL_CS-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
> -; DECL_CS-NEXT: call void [[FP]](i8* [[TMP1]])
> -; DECL_CS-NEXT: call void @internal(void (i8*)* nonnull [[FP]])
> -; DECL_CS-NEXT: ret void
> +;
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@external
> +; IS__TUNIT____-SAME: (void (i8*)* [[FP:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[A:%.*]] = alloca i32, align 4
> +; IS__TUNIT____-NEXT: call void @foo(i32* noalias nocapture nofree
> nonnull writeonly align 4 dereferenceable(4) [[A]])
> +; IS__TUNIT____-NEXT: call void @callback1(void (i32*)* nonnull @foo)
> +; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* nonnull bitcast
> (void (i32*)* @foo to void (i8*)*))
> +; IS__TUNIT____-NEXT: call void @callback2(void (i8*)* [[FP]])
> +; IS__TUNIT____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo
> to i8*))
> +; IS__TUNIT____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
> +; IS__TUNIT____-NEXT: call void [[FP]](i8* [[TMP1]])
> +; IS__TUNIT____-NEXT: call void @internal(void (i8*)* nonnull [[FP]])
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@external
> +; IS__CGSCC____-SAME: (void (i8*)* [[FP:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[A:%.*]] = alloca i32, align 4
> +; IS__CGSCC____-NEXT: call void @foo(i32* noalias nocapture nofree
> nonnull writeonly align 4 dereferenceable(4) [[A]])
> +; IS__CGSCC____-NEXT: call void @callback1(void (i32*)* nonnull @foo)
> +; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* bitcast (void
> (i32*)* @foo to void (i8*)*))
> +; IS__CGSCC____-NEXT: call void @callback2(void (i8*)* [[FP]])
> +; IS__CGSCC____-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo
> to i8*))
> +; IS__CGSCC____-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
> +; IS__CGSCC____-NEXT: call void [[FP]](i8* [[TMP1]])
> +; IS__CGSCC____-NEXT: call void @internal(void (i8*)* nonnull [[FP]])
> +; IS__CGSCC____-NEXT: ret void
> ;
> entry:
> %a = alloca i32, align 4
> @@ -88,11 +94,12 @@ entry:
> }
>
> define internal void @foo(i32* %a) {
> -; ALL-LABEL: define {{[^@]+}}@foo
> -; ALL-SAME: (i32* nocapture nofree nonnull writeonly align 4
> dereferenceable(4) [[A:%.*]])
> -; ALL-NEXT: entry:
> -; ALL-NEXT: store i32 0, i32* [[A]], align 4
> -; ALL-NEXT: ret void
> +;
> +; 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
> ;
> entry:
> store i32 0, i32* %a
>
> diff --git a/llvm/test/Transforms/Attributor/noalias.ll
> b/llvm/test/Transforms/Attributor/noalias.ll
> index 678d7f7f8ccf..d91705697638 100644
> --- a/llvm/test/Transforms/Attributor/noalias.ll
> +++ b/llvm/test/Transforms/Attributor/noalias.ll
> @@ -1,4 +1,8 @@
> -; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa'
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations=7 < %s | FileCheck
> %s
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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 - negative.
>
> @@ -11,8 +15,12 @@
>
> @G = external global i8*
>
> -; CHECK: define i8* @foo()
> define i8* @foo() {
> +; CHECK-LABEL: define {{[^@]+}}@foo()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: store i8* [[TMP1]], i8** @G, align 8
> +; CHECK-NEXT: ret i8* [[TMP1]]
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> store i8* %1, i8** @G, align 8
> ret i8* %1
> @@ -23,25 +31,39 @@ declare noalias i8* @malloc(i64)
> ; TEST 2
> ; call noalias function in return instruction.
>
> -; CHECK: define noalias i8* @return_noalias()
> define i8* @return_noalias(){
> +; CHECK-LABEL: define {{[^@]+}}@return_noalias()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: ret i8* [[TMP1]]
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> ret i8* %1
> }
>
> define void @nocapture(i8* %a){
> +; CHECK-LABEL: define {{[^@]+}}@nocapture
> +; CHECK-SAME: (i8* nocapture nofree readnone [[A:%.*]])
> +; CHECK-NEXT: ret void
> +;
> ret void
> }
>
> -; CHECK: define noalias i8* @return_noalias_looks_like_capture()
> define i8* @return_noalias_looks_like_capture(){
> +; CHECK-LABEL: define {{[^@]+}}@return_noalias_looks_like_capture()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: ret i8* [[TMP1]]
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> call void @nocapture(i8* %1)
> ret i8* %1
> }
>
> -; CHECK: define noalias i16* @return_noalias_casted()
> define i16* @return_noalias_casted(){
> +; CHECK-LABEL: define {{[^@]+}}@return_noalias_casted()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: [[C:%.*]] = bitcast i8* [[TMP1]] to i16*
> +; CHECK-NEXT: ret i16* [[C]]
> +;
> %1 = tail call noalias i8* @malloc(i64 4)
> %c = bitcast i8* %1 to i16*
> ret i16* %c
> @@ -50,9 +72,11 @@ define i16* @return_noalias_casted(){
> declare i8* @alias()
>
> ; TEST 3
> -; CHECK: define i8* @call_alias()
> -; CHECK-NOT: noalias
> define i8* @call_alias(){
> +; CHECK-LABEL: define {{[^@]+}}@call_alias()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* @alias()
> +; CHECK-NEXT: ret i8* [[TMP1]]
> +;
> %1 = tail call i8* @alias()
> ret i8* %1
> }
> @@ -72,14 +96,27 @@ define i8* @call_alias(){
> ; return malloc(4);
> ; }
>
> -; CHECK: define i8* @bar()
> define i8* @bar() nounwind uwtable {
> +; CHECK-LABEL: define {{[^@]+}}@bar()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call i8* (...) @baz()
> +; CHECK-NEXT: ret i8* [[TMP1]]
> +;
> %1 = tail call i8* (...) @baz()
> ret i8* %1
> }
>
> -; CHECK: define noalias i8* @foo1(i32 %0)
> define i8* @foo1(i32 %0) nounwind uwtable {
> +; CHECK-LABEL: define {{[^@]+}}@foo1
> +; CHECK-SAME: (i32 [[TMP0:%.*]])
> +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP0]], 0
> +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
> +; CHECK: 3:
> +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* (...) @baz()
> +; CHECK-NEXT: br label [[TMP5]]
> +; CHECK: 5:
> +; CHECK-NEXT: [[TMP6:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: ret i8* [[TMP6]]
> +;
> %2 = icmp eq i32 %0, 0
> br i1 %2, label %5, label %3
>
> @@ -97,14 +134,18 @@ declare i8* @baz(...) nounwind uwtable
> ; TEST 5
>
> ; Returning global pointer. Should not be noalias.
> -; CHECK: define nonnull align 8 dereferenceable(8) i8** @getter()
> define i8** @getter() {
> +; CHECK-LABEL: define {{[^@]+}}@getter()
> +; CHECK-NEXT: ret i8** @G
> +;
> ret i8** @G
> }
>
> ; Returning global pointer. Should not be noalias.
> -; CHECK: define nonnull align 8 dereferenceable(8) i8** @calle1()
> define i8** @calle1(){
> +; CHECK-LABEL: define {{[^@]+}}@calle1()
> +; CHECK-NEXT: ret i8** @G
> +;
> %1 = call i8** @getter()
> ret i8** %1
> }
> @@ -112,8 +153,16 @@ define i8** @calle1(){
> ; TEST 6
> declare noalias i8* @strdup(i8* nocapture) nounwind
>
> -; CHECK: define noalias i8* @test6()
> define i8* @test6() nounwind uwtable ssp {
> +; 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
> +; CHECK-NEXT: store i8 97, i8* [[ARRAYIDX]], align 1
> +; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x i8], [2
> x i8]* [[X]], i64 0, i64 1
> +; CHECK-NEXT: store i8 0, i8* [[ARRAYIDX1]], align 1
> +; CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @strdup(i8* nonnull
> dereferenceable(2) [[ARRAYIDX]])
> +; CHECK-NEXT: ret i8* [[CALL]]
> +;
> %x = alloca [2 x i8], align 1
> %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 0
> store i8 97, i8* %arrayidx, align 1
> @@ -125,8 +174,19 @@ define i8* @test6() nounwind uwtable ssp {
>
> ; TEST 7
>
> -; CHECK: define noalias i8* @test7()
> define i8* @test7() nounwind {
> +; CHECK-LABEL: define {{[^@]+}}@test7()
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[A:%.*]] = call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[A]], null
> +; CHECK-NEXT: br i1 [[TOBOOL]], label [[RETURN:%.*]], label
> [[IF_END:%.*]]
> +; CHECK: if.end:
> +; CHECK-NEXT: store i8 7, i8* [[A]]
> +; CHECK-NEXT: br label [[RETURN]]
> +; CHECK: return:
> +; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i8* [ [[A]], [[IF_END]] ], [
> null, [[ENTRY:%.*]] ]
> +; CHECK-NEXT: ret i8* [[RETVAL_0]]
> +;
> entry:
> %A = call noalias i8* @malloc(i64 4) nounwind
> %tobool = icmp eq i8* %A, null
> @@ -143,8 +203,18 @@ return:
>
> ; TEST 8
>
> -; CHECK: define noalias i8* @test8(i32* %0)
> define i8* @test8(i32* %0) nounwind uwtable {
> +; CHECK-LABEL: define {{[^@]+}}@test8
> +; CHECK-SAME: (i32* [[TMP0:%.*]])
> +; CHECK-NEXT: [[TMP2:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; CHECK-NEXT: [[TMP3:%.*]] = icmp ne i32* [[TMP0]], null
> +; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
> +; CHECK: 4:
> +; CHECK-NEXT: store i8 10, i8* [[TMP2]]
> +; CHECK-NEXT: br label [[TMP5]]
> +; CHECK: 5:
> +; CHECK-NEXT: ret i8* [[TMP2]]
> +;
> %2 = tail call noalias i8* @malloc(i64 4)
> %3 = icmp ne i32* %0, null
> br i1 %3, label %4, label %5
> @@ -161,32 +231,59 @@ define i8* @test8(i32* %0) nounwind uwtable {
> ; Simple Argument Test
> declare void @use_i8(i8* nocapture)
> define internal void @test9a(i8* %a, i8* %b) {
> -; CHECK: define internal void @test9a()
> +; CHECK-LABEL: define {{[^@]+}}@test9a()
> +; CHECK-NEXT: call void @use_i8(i8* noalias align 536870912 null)
> +; CHECK-NEXT: ret void
> +;
> call void @use_i8(i8* null)
> ret void
> }
> define internal void @test9b(i8* %a, i8* %b) {
> ; FIXME: %b should be noalias
> -; CHECK: define internal void @test9b(i8* noalias nocapture %a, i8*
> nocapture %b)
> +; CHECK-LABEL: define {{[^@]+}}@test9b
> +; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* nocapture [[B:%.*]])
> +; CHECK-NEXT: call void @use_i8(i8* noalias nocapture [[A]])
> +; CHECK-NEXT: call void @use_i8(i8* nocapture [[B]])
> +; CHECK-NEXT: ret void
> +;
> call void @use_i8(i8* %a)
> call void @use_i8(i8* %b)
> ret void
> }
> define internal void @test9c(i8* %a, i8* %b, i8* %c) {
> -; CHECK: define internal void @test9c(i8* noalias nocapture %a, i8*
> nocapture %b, i8* nocapture %c)
> +; CHECK-LABEL: define {{[^@]+}}@test9c
> +; CHECK-SAME: (i8* noalias nocapture [[A:%.*]], i8* nocapture [[B:%.*]],
> i8* nocapture [[C:%.*]])
> +; CHECK-NEXT: call void @use_i8(i8* noalias nocapture [[A]])
> +; CHECK-NEXT: call void @use_i8(i8* nocapture [[B]])
> +; CHECK-NEXT: call void @use_i8(i8* nocapture [[C]])
> +; CHECK-NEXT: ret void
> +;
> call void @use_i8(i8* %a)
> call void @use_i8(i8* %b)
> call void @use_i8(i8* %c)
> ret void
> }
> define void @test9_helper(i8* %a, i8* %b) {
> -; CHECK: define void @test9_helper(i8* nocapture %a, i8* nocapture %b)
> -; CHECK: tail call void @test9a()
> -; CHECK: tail call void @test9a()
> -; CHECK: tail call void @test9b(i8* noalias nocapture %a, i8* nocapture
> %b)
> -; CHECK: tail call void @test9b(i8* noalias nocapture %b, i8* noalias
> nocapture %a)
> -; CHECK: tail call void @test9c(i8* noalias nocapture %a, i8* nocapture
> %b, i8* nocapture %b)
> -; CHECK: tail call void @test9c(i8* noalias nocapture %b, i8* noalias
> nocapture %a, i8* noalias nocapture %a)
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test9_helper
> +; IS__TUNIT____-SAME: (i8* nocapture [[A:%.*]], i8* nocapture [[B:%.*]])
> +; IS__TUNIT____-NEXT: tail call void @test9a()
> +; IS__TUNIT____-NEXT: tail call void @test9a()
> +; IS__TUNIT____-NEXT: tail call void @test9b(i8* noalias nocapture
> [[A]], i8* nocapture [[B]])
> +; IS__TUNIT____-NEXT: tail call void @test9b(i8* noalias nocapture
> [[B]], i8* noalias nocapture [[A]])
> +; IS__TUNIT____-NEXT: tail call void @test9c(i8* noalias nocapture
> [[A]], i8* nocapture [[B]], i8* nocapture [[B]])
> +; IS__TUNIT____-NEXT: tail call void @test9c(i8* noalias nocapture
> [[B]], i8* noalias nocapture [[A]], i8* noalias nocapture [[A]])
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test9_helper
> +; IS__CGSCC____-SAME: (i8* nocapture [[A:%.*]], i8* nocapture [[B:%.*]])
> +; IS__CGSCC____-NEXT: tail call void @test9a()
> +; IS__CGSCC____-NEXT: tail call void @test9a()
> +; IS__CGSCC____-NEXT: tail call void @test9b(i8* noalias [[A]], i8*
> [[B]])
> +; IS__CGSCC____-NEXT: tail call void @test9b(i8* noalias [[B]], i8*
> noalias [[A]])
> +; IS__CGSCC____-NEXT: tail call void @test9c(i8* noalias [[A]], i8*
> [[B]], i8* [[B]])
> +; IS__CGSCC____-NEXT: tail call void @test9c(i8* noalias nocapture
> [[B]], i8* noalias [[A]], i8* noalias nocapture [[A]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> tail call void @test9a(i8* noalias %a, i8* %b)
> tail call void @test9a(i8* noalias %b, i8* noalias %a)
> tail call void @test9b(i8* noalias %a, i8* %b)
> @@ -202,17 +299,24 @@ define void @test9_helper(i8* %a, i8* %b) {
>
> declare void @test10_helper_1(i8* %a)
> define void @test10_helper_2(i8* noalias %a) {
> -; CHECK: tail call void @test10_helper_1(i8* %a)
> +; CHECK-LABEL: define {{[^@]+}}@test10_helper_2
> +; CHECK-SAME: (i8* noalias [[A:%.*]])
> +; CHECK-NEXT: tail call void @test10_helper_1(i8* [[A]])
> +; CHECK-NEXT: ret void
> +;
> tail call void @test10_helper_1(i8* %a)
> ret void
> }
> define void @test10(i8* noalias %a) {
> -; CHECK: define void @test10(i8* noalias %a)
> +; CHECK-LABEL: define {{[^@]+}}@test10
> +; CHECK-SAME: (i8* noalias [[A:%.*]])
> +; CHECK-NEXT: tail call void @test10_helper_1(i8* [[A]])
> +; CHECK-NEXT: tail call void @test10_helper_2(i8* noalias [[A]])
> +; CHECK-NEXT: ret void
> +;
> ; FIXME: missing noalias
> -; CHECK-NEXT: tail call void @test10_helper_1(i8* %a)
> tail call void @test10_helper_1(i8* %a)
>
> -; CHECK-NEXT: tail call void @test10_helper_2(i8* noalias %a)
> tail call void @test10_helper_2(i8* %a)
> ret void
> }
> @@ -222,8 +326,11 @@ define void @test10(i8* noalias %a) {
>
> declare void @test11_helper(i8* %a, i8 *%b)
> define void @test11(i8* noalias %a) {
> -; CHECK: define void @test11(i8* noalias %a)
> -; CHECK-NEXT: tail call void @test11_helper(i8* %a, i8* %a)
> +; CHECK-LABEL: define {{[^@]+}}@test11
> +; CHECK-SAME: (i8* noalias [[A:%.*]])
> +; CHECK-NEXT: tail call void @test11_helper(i8* [[A]], i8* [[A]])
> +; CHECK-NEXT: ret void
> +;
> tail call void @test11_helper(i8* %a, i8* %a)
> ret void
> }
> @@ -234,14 +341,23 @@ define void @test11(i8* noalias %a) {
> declare void @use_nocapture(i8* nocapture)
> declare void @use(i8*)
> define void @test12_1() {
> -; CHECK-LABEL: @test12_1(
> -; CHECK-NEXT: [[A:%.*]] = alloca i8, align 4
> -; CHECK-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 4)
> -; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nonnull align
> 4 dereferenceable(1) [[A]])
> -; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nonnull align
> 4 dereferenceable(1) [[A]])
> -; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture
> [[B]])
> -; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture
> [[B]])
> -; CHECK-NEXT: ret void
> +; IS________OPM-LABEL: define {{[^@]+}}@test12_1()
> +; IS________OPM-NEXT: [[A:%.*]] = alloca i8, align 4
> +; IS________OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________OPM-NEXT: tail call void @use_nocapture(i8* noalias
> nonnull align 4 dereferenceable(1) [[A]])
> +; IS________OPM-NEXT: tail call void @use_nocapture(i8* noalias
> nonnull align 4 dereferenceable(1) [[A]])
> +; IS________OPM-NEXT: tail call void @use_nocapture(i8* noalias [[B]])
> +; IS________OPM-NEXT: tail call void @use_nocapture(i8* noalias [[B]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test12_1()
> +; IS________NPM-NEXT: [[A:%.*]] = alloca i8, align 4
> +; IS________NPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________NPM-NEXT: tail call void @use_nocapture(i8* noalias
> nonnull align 4 dereferenceable(1) [[A]])
> +; IS________NPM-NEXT: tail call void @use_nocapture(i8* noalias
> nonnull align 4 dereferenceable(1) [[A]])
> +; IS________NPM-NEXT: tail call void @use_nocapture(i8* noalias
> nocapture [[B]])
> +; IS________NPM-NEXT: tail call void @use_nocapture(i8* noalias
> nocapture [[B]])
> +; IS________NPM-NEXT: ret void
> ;
> %A = alloca i8, align 4
> %B = tail call noalias i8* @malloc(i64 4)
> @@ -253,14 +369,24 @@ define void @test12_1() {
> }
>
> define void @test12_2(){
> -; CHECK-LABEL: @test12_2(
> -; CHECK-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
> -; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture
> [[A]])
> -; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture
> [[A]])
> -; CHECK-NEXT: tail call void @use(i8* [[A]])
> -; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture [[A]])
> -; CHECK-NEXT: ret void
> +; IS________OPM-LABEL: define {{[^@]+}}@test12_2()
> +; IS________OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________OPM-NEXT: tail call void @use_nocapture(i8* noalias
> nocapture [[A]])
> +; IS________OPM-NEXT: tail call void @use_nocapture(i8* noalias
> nocapture [[A]])
> +; IS________OPM-NEXT: tail call void @use(i8* [[A]])
> +; IS________OPM-NEXT: tail call void @use_nocapture(i8* [[A]])
> +; IS________OPM-NEXT: ret void
> ;
> +; IS________NPM-LABEL: define {{[^@]+}}@test12_2()
> +; IS________NPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________NPM-NEXT: tail call void @use_nocapture(i8* noalias
> nocapture [[A]])
> +; IS________NPM-NEXT: tail call void @use_nocapture(i8* noalias
> nocapture [[A]])
> +; IS________NPM-NEXT: tail call void @use(i8* [[A]])
> +; IS________NPM-NEXT: tail call void @use_nocapture(i8* nocapture
> [[A]])
> +; IS________NPM-NEXT: ret void
> +;
> +; FIXME: This should be @use_nocapture(i8* noalias [[A]])
> +; FIXME: This should be @use_nocapture(i8* noalias nocapture [[A]])
> %A = tail call noalias i8* @malloc(i64 4)
> tail call void @use_nocapture(i8* %A)
> tail call void @use_nocapture(i8* %A)
> @@ -271,58 +397,119 @@ define void @test12_2(){
>
> declare void @two_args(i8* nocapture , i8* nocapture)
> define void @test12_3(){
> -; CHECK-LABEL: @test12_3(
> +; IS________OPM-LABEL: define {{[^@]+}}@test12_3()
> +; IS________OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________OPM-NEXT: tail call void @two_args(i8* [[A]], i8* [[A]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test12_3()
> +; IS________NPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________NPM-NEXT: tail call void @two_args(i8* nocapture [[A]],
> i8* nocapture [[A]])
> +; IS________NPM-NEXT: ret void
> +;
> %A = tail call noalias i8* @malloc(i64 4)
> -; CHECK: tail call void @two_args(i8* nocapture %A, i8* nocapture %A)
> tail call void @two_args(i8* %A, i8* %A)
> ret void
> }
>
> define void @test12_4(){
> -; CHECK-LABEL: @test12_4(
> +; IS________OPM-LABEL: define {{[^@]+}}@test12_4()
> +; IS________OPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________OPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________OPM-NEXT: [[A_0:%.*]] = getelementptr i8, i8* [[A]], i64 0
> +; IS________OPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
> +; IS________OPM-NEXT: [[B_0:%.*]] = getelementptr i8, i8* [[B]], i64 0
> +; IS________OPM-NEXT: tail call void @two_args(i8* [[A]], i8* [[B]])
> +; IS________OPM-NEXT: tail call void @two_args(i8* [[A]], i8* [[A_0]])
> +; IS________OPM-NEXT: tail call void @two_args(i8* [[A]], i8* [[A_1]])
> +; IS________OPM-NEXT: tail call void @two_args(i8* [[A_0]], i8*
> [[B_0]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test12_4()
> +; IS________NPM-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________NPM-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________NPM-NEXT: [[A_0:%.*]] = getelementptr i8, i8* [[A]], i64 0
> +; IS________NPM-NEXT: [[A_1:%.*]] = getelementptr i8, i8* [[A]], i64 1
> +; IS________NPM-NEXT: [[B_0:%.*]] = getelementptr i8, i8* [[B]], i64 0
> +; IS________NPM-NEXT: tail call void @two_args(i8* noalias nocapture
> [[A]], i8* noalias nocapture [[B]])
> +; IS________NPM-NEXT: tail call void @two_args(i8* nocapture [[A]],
> i8* nocapture [[A_0]])
> +; IS________NPM-NEXT: tail call void @two_args(i8* nocapture [[A]],
> i8* nocapture [[A_1]])
> +; IS________NPM-NEXT: tail call void @two_args(i8* nocapture [[A_0]],
> i8* nocapture [[B_0]])
> +; IS________NPM-NEXT: ret void
> +;
> %A = tail call noalias i8* @malloc(i64 4)
> %B = tail call noalias i8* @malloc(i64 4)
> %A_0 = getelementptr i8, i8* %A, i64 0
> %A_1 = getelementptr i8, i8* %A, i64 1
> %B_0 = getelementptr i8, i8* %B, i64 0
>
> -; CHECK: tail call void @two_args(i8* noalias nocapture %A, i8* noalias
> nocapture %B)
> tail call void @two_args(i8* %A, i8* %B)
>
> -; CHECK: tail call void @two_args(i8* nocapture %A, i8* nocapture %A_0)
> tail call void @two_args(i8* %A, i8* %A_0)
>
> -; CHECK: tail call void @two_args(i8* nocapture %A, i8* nocapture %A_1)
> tail call void @two_args(i8* %A, i8* %A_1)
>
> ; FIXME: This should be @two_args(i8* noalias nocapture %A_0, i8* noalias
> nocapture %B_0)
> -; CHECK: tail call void @two_args(i8* nocapture %A_0, i8* nocapture %B_0)
> tail call void @two_args(i8* %A_0, i8* %B_0)
> ret void
> }
>
> ; TEST 13
> define void @use_i8_internal(i8* %a) {
> +; CHECK-LABEL: define {{[^@]+}}@use_i8_internal
> +; CHECK-SAME: (i8* nocapture [[A:%.*]])
> +; CHECK-NEXT: call void @use_i8(i8* nocapture [[A]])
> +; CHECK-NEXT: ret void
> +;
> call void @use_i8(i8* %a)
> ret void
> }
>
> define void @test13_use_noalias(){
> +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias()
> +; NOT_CGSCC_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; NOT_CGSCC_OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
> +; NOT_CGSCC_OPM-NEXT: [[C2:%.*]] = bitcast i16* [[C1]] to i8*
> +; NOT_CGSCC_OPM-NEXT: call void @use_i8_internal(i8* noalias nocapture
> [[C2]])
> +; NOT_CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test13_use_noalias()
> +; IS__CGSCC_OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS__CGSCC_OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
> +; IS__CGSCC_OPM-NEXT: [[C2:%.*]] = bitcast i16* [[C1]] to i8*
> +; IS__CGSCC_OPM-NEXT: call void @use_i8_internal(i8* noalias [[C2]])
> +; IS__CGSCC_OPM-NEXT: ret void
> +;
> %m1 = tail call noalias i8* @malloc(i64 4)
> %c1 = bitcast i8* %m1 to i16*
> %c2 = bitcast i16* %c1 to i8*
> -; CHECK: call void @use_i8_internal(i8* noalias nocapture %c2)
> call void @use_i8_internal(i8* %c2)
> ret void
> }
>
> define void @test13_use_alias(){
> +; IS________OPM-LABEL: define {{[^@]+}}@test13_use_alias()
> +; IS________OPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________OPM-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
> +; IS________OPM-NEXT: [[C2A:%.*]] = bitcast i16* [[C1]] to i8*
> +; IS________OPM-NEXT: [[C2B:%.*]] = bitcast i16* [[C1]] to i8*
> +; IS________OPM-NEXT: call void @use_i8_internal(i8* [[C2A]])
> +; IS________OPM-NEXT: call void @use_i8_internal(i8* [[C2B]])
> +; IS________OPM-NEXT: ret void
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@test13_use_alias()
> +; IS________NPM-NEXT: [[M1:%.*]] = tail call noalias i8* @malloc(i64 4)
> +; IS________NPM-NEXT: [[C1:%.*]] = bitcast i8* [[M1]] to i16*
> +; IS________NPM-NEXT: [[C2A:%.*]] = bitcast i16* [[C1]] to i8*
> +; IS________NPM-NEXT: [[C2B:%.*]] = bitcast i16* [[C1]] to i8*
> +; IS________NPM-NEXT: call void @use_i8_internal(i8* nocapture [[C2A]])
> +; IS________NPM-NEXT: call void @use_i8_internal(i8* nocapture [[C2B]])
> +; IS________NPM-NEXT: ret void
> +;
> %m1 = tail call noalias i8* @malloc(i64 4)
> %c1 = bitcast i8* %m1 to i16*
> %c2a = bitcast i16* %c1 to i8*
> %c2b = bitcast i16* %c1 to i8*
> -; CHECK: call void @use_i8_internal(i8* nocapture %c2a)
> -; CHECK: call void @use_i8_internal(i8* nocapture %c2b)
> call void @use_i8_internal(i8* %c2a)
> call void @use_i8_internal(i8* %c2b)
> ret void
> @@ -330,11 +517,37 @@ define void @test13_use_alias(){
>
> ; TEST 14 i2p casts
> define internal i32 @p2i(i32* %arg) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@p2i
> +; IS__TUNIT____-SAME: (i32* noalias nofree readnone [[ARG:%.*]])
> +; IS__TUNIT____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32
> +; IS__TUNIT____-NEXT: ret i32 [[P2I]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@p2i
> +; IS__CGSCC____-SAME: (i32* nofree readnone [[ARG:%.*]])
> +; IS__CGSCC____-NEXT: [[P2I:%.*]] = ptrtoint i32* [[ARG]] to i32
> +; IS__CGSCC____-NEXT: ret i32 [[P2I]]
> +;
> %p2i = ptrtoint i32* %arg to i32
> ret i32 %p2i
> }
>
> define i32 @i2p(i32* %arg) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@i2p
> +; IS__TUNIT____-SAME: (i32* nofree readonly [[ARG:%.*]])
> +; IS__TUNIT____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree
> readnone [[ARG]])
> +; IS__TUNIT____-NEXT: [[I2P:%.*]] = inttoptr i32 [[C]] to i8*
> +; IS__TUNIT____-NEXT: [[BC:%.*]] = bitcast i8* [[I2P]] to i32*
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nofree
> readonly align 4 [[BC]])
> +; IS__TUNIT____-NEXT: ret i32 [[CALL]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@i2p
> +; IS__CGSCC____-SAME: (i32* nofree readonly [[ARG:%.*]])
> +; IS__CGSCC____-NEXT: [[C:%.*]] = call i32 @p2i(i32* noalias nofree
> readnone [[ARG]])
> +; IS__CGSCC____-NEXT: [[I2P:%.*]] = inttoptr i32 [[C]] to i8*
> +; IS__CGSCC____-NEXT: [[BC:%.*]] = bitcast i8* [[I2P]] to i32*
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @ret(i32* nofree nonnull
> readonly align 4 dereferenceable(4) [[BC]])
> +; IS__CGSCC____-NEXT: ret i32 [[CALL]]
> +;
> %c = call i32 @p2i(i32* %arg)
> %i2p = inttoptr i32 %c to i8*
> %bc = bitcast i8* %i2p to i32*
> @@ -342,6 +555,11 @@ 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]]
> +;
> %l = load i32, i32* %arg
> ret i32 %l
> }
> @@ -355,8 +573,31 @@ define internal i32 @ret(i32* %arg) {
> %struct.__locale_map = type opaque
>
> ; Function Attrs: nounwind optsize
> -; CHECK: define internal fastcc double @strtox(i8* noalias %s)
> unnamed_addr
> define internal fastcc double @strtox(i8* %s, i8** %p, i32 %prec)
> unnamed_addr {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@strtox
> +; IS__TUNIT____-SAME: (i8* noalias [[S:%.*]]) unnamed_addr
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]],
> align 8
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]]
> to i8*
> +; IS__TUNIT____-NEXT: call void @llvm.lifetime.start.p0i8(i64 144, i8*
> nonnull align 8 dereferenceable(240) [[TMP0]])
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)*
> @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull
> align 8 dereferenceable(240) [[F]], i8* [[S]])
> +; IS__TUNIT____-NEXT: call void @__shlim(%struct._IO_FILE* nonnull
> align 8 dereferenceable(240) [[F]], i64 0)
> +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double
> @__floatscan(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]],
> i32 1, i32 1)
> +; IS__TUNIT____-NEXT: call void @llvm.lifetime.end.p0i8(i64 144, i8*
> nonnull align 8 dereferenceable(240) [[TMP0]])
> +; IS__TUNIT____-NEXT: ret double [[CALL1]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@strtox
> +; IS__CGSCC____-SAME: (i8* [[S:%.*]]) unnamed_addr
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[F:%.*]] = alloca [[STRUCT__IO_FILE:%.*]],
> align 8
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = bitcast %struct._IO_FILE* [[F]]
> to i8*
> +; IS__CGSCC____-NEXT: call void @llvm.lifetime.start.p0i8(i64 144, i8*
> nonnull align 8 dereferenceable(240) [[TMP0]])
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 bitcast (i32 (...)*
> @sh_fromstring to i32 (%struct._IO_FILE*, i8*)*)(%struct._IO_FILE* nonnull
> align 8 dereferenceable(240) [[F]], i8* [[S]])
> +; IS__CGSCC____-NEXT: call void @__shlim(%struct._IO_FILE* nonnull
> align 8 dereferenceable(240) [[F]], i64 0)
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double
> @__floatscan(%struct._IO_FILE* nonnull align 8 dereferenceable(240) [[F]],
> i32 1, i32 1)
> +; IS__CGSCC____-NEXT: call void @llvm.lifetime.end.p0i8(i64 144, i8*
> nonnull align 8 dereferenceable(240) [[TMP0]])
> +; IS__CGSCC____-NEXT: ret double [[CALL1]]
> +;
> entry:
> %f = alloca %struct._IO_FILE, align 8
> %0 = bitcast %struct._IO_FILE* %f to i8*
> @@ -371,8 +612,13 @@ entry:
>
> ; Function Attrs: nounwind optsize
> define dso_local double @strtod(i8* noalias %s, i8** noalias %p) {
> +; CHECK-LABEL: define {{[^@]+}}@strtod
> +; CHECK-SAME: (i8* noalias [[S:%.*]], i8** noalias nocapture nofree
> readnone [[P:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = tail call fastcc double @strtox(i8*
> noalias [[S]])
> +; CHECK-NEXT: ret double [[CALL]]
> +;
> entry:
> -; CHECK: %call = tail call fastcc double @strtox(i8* noalias %s)
> %call = tail call fastcc double @strtox(i8* %s, i8** %p, i32 1)
> ret double %call
> }
> @@ -393,27 +639,56 @@ declare dso_local double
> @__floatscan(%struct._IO_FILE*, i32, i32) local_unnamed
> declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)
>
> ; Test 15
> -; propagate noalias to some callsite arguments that there is no possibly
> reachable capture before it
> +; propagate noalias to some callsite arguments that there is no possibly
> reachable capture before it
>
> @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
> +;
> 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
> +;
> store i32 0, i32* %p
> ret void
> }
>
> -; CHECK-LABEL: define void @test15_caller(i32* noalias nofree writeonly
> %p, i32 %c)
> define void @test15_caller(i32* noalias %p, i32 %c) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test15_caller
> +; IS__TUNIT____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32
> [[C:%.*]])
> +; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C]], 0
> +; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label
> [[IF_THEN:%.*]]
> +; IS__TUNIT____: if.then:
> +; IS__TUNIT____-NEXT: tail call void @only_store(i32* noalias
> nocapture nofree writeonly align 4 [[P]])
> +; IS__TUNIT____-NEXT: br label [[IF_END]]
> +; IS__TUNIT____: if.end:
> +; IS__TUNIT____-NEXT: tail call void @make_alias(i32* nofree writeonly
> [[P]])
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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
> +; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label
> [[IF_THEN:%.*]]
> +; IS__CGSCC____: if.then:
> +; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias
> nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P]])
> +; IS__CGSCC____-NEXT: br label [[IF_END]]
> +; IS__CGSCC____: if.end:
> +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree writeonly
> [[P]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> %tobool = icmp eq i32 %c, 0
> br i1 %tobool, label %if.end, label %if.then
>
> -; CHECK: tail call void @only_store(i32* noalias nocapture nofree
> writeonly align 4 %p)
> -; CHECK: tail call void @make_alias(i32* nofree writeonly %p)
>
> if.then:
> tail call void @only_store(i32* %p)
> @@ -438,26 +713,58 @@ if.end:
> ; void test16_caller(int * restrict p, int c) {
> ; test16_sub(p, c, c);
> ; }
> +;
> +; FIXME: this should be tail @only_store(i32* noalias %p)
> +; when test16_caller is called, c1 always equals to c2. (Note that
> linkage is internal)
> +; Therefore, only one of the two conditions of if statementes will
> be fulfilled.
>
> -; CHECK-LABEL: define internal void @test16_sub(i32* noalias nofree
> writeonly %p, i32 %c1, i32 %c2)
> define internal void @test16_sub(i32* noalias %p, i32 %c1, i32 %c2) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test16_sub
> +; IS__TUNIT____-SAME: (i32* noalias nofree writeonly [[P:%.*]], i32
> [[C1:%.*]], i32 [[C2:%.*]])
> +; IS__TUNIT____-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[C1]], 0
> +; IS__TUNIT____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label
> [[IF_THEN:%.*]]
> +; IS__TUNIT____: if.then:
> +; IS__TUNIT____-NEXT: tail call void @only_store(i32* noalias
> nocapture nofree writeonly align 4 [[P]])
> +; IS__TUNIT____-NEXT: tail call void @make_alias(i32* nofree writeonly
> align 4 [[P]])
> +; IS__TUNIT____-NEXT: br label [[IF_END]]
> +; IS__TUNIT____: if.end:
> +; IS__TUNIT____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0
> +; IS__TUNIT____-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label
> [[IF_END3:%.*]]
> +; IS__TUNIT____: if.then2:
> +; IS__TUNIT____-NEXT: tail call void @only_store(i32* nofree writeonly
> align 4 [[P]])
> +; IS__TUNIT____-NEXT: br label [[IF_END3]]
> +; IS__TUNIT____: if.end3:
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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
> +; IS__CGSCC____-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label
> [[IF_THEN:%.*]]
> +; IS__CGSCC____: if.then:
> +; IS__CGSCC____-NEXT: tail call void @only_store(i32* noalias
> nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[P]])
> +; IS__CGSCC____-NEXT: tail call void @make_alias(i32* nofree nonnull
> writeonly align 4 dereferenceable(4) [[P]])
> +; IS__CGSCC____-NEXT: br label [[IF_END]]
> +; IS__CGSCC____: if.end:
> +; IS__CGSCC____-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[C2]], 0
> +; IS__CGSCC____-NEXT: br i1 [[TOBOOL1]], label [[IF_THEN2:%.*]], label
> [[IF_END3:%.*]]
> +; IS__CGSCC____: if.then2:
> +; IS__CGSCC____-NEXT: tail call void @only_store(i32* nofree nonnull
> writeonly align 4 dereferenceable(4) [[P]])
> +; IS__CGSCC____-NEXT: br label [[IF_END3]]
> +; IS__CGSCC____: if.end3:
> +; IS__CGSCC____-NEXT: ret void
> +;
> %tobool = icmp eq i32 %c1, 0
> br i1 %tobool, label %if.end, label %if.then
>
> -; CHECK: tail call void @only_store(i32* noalias nocapture nofree
> writeonly align 4 %p)
> if.then:
> - tail call void @only_store(i32* %p)
> - tail call void @make_alias(i32* %p)
> + tail call void @only_store(i32* %p)
> + tail call void @make_alias(i32* %p)
> br label %if.end
> if.end:
>
> %tobool1 = icmp eq i32 %c2, 0
> br i1 %tobool1, label %if.then2, label %if.end3
>
> -; FIXME: this should be tail @only_store(i32* noalias %p)
> -; when test16_caller is called, c1 always equals to c2. (Note that
> linkage is internal)
> -; Therefore, only one of the two conditions of if statementes will
> be fulfilled.
> -; CHECK: tail call void @only_store(i32* nofree writeonly align 4 %p)
> if.then2:
> tail call void @only_store(i32* %p)
> br label %if.end3
> @@ -467,6 +774,11 @@ 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
> +;
> 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 98c4228c3099..9a16f5e8ad3d 100644
> --- a/llvm/test/Transforms/Attributor/nocapture-1.ll
> +++ b/llvm/test/Transforms/Attributor/nocapture-1.ll
> @@ -1,166 +1,297 @@
> -; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -S -attributor-annotate-decl-cs < %s | FileCheck
> %s --check-prefixes=ATTRIBUTOR
> -; RUN: opt -passes=attributor -attributor-manifest-internal
> -attributor-disable=false -S -attributor-annotate-decl-cs < %s | FileCheck
> %s --check-prefixes=ATTRIBUTOR
> -; Copied from Transforms/FunctoinAttrs/nocapture.ll
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> @g = global i32* null ; <i32**> [#uses=1]
>
> -; ATTRIBUTOR: define i32* @c1(i32* nofree readnone returned
> "no-capture-maybe-returned" %q)
> define i32* @c1(i32* %q) {
> - ret i32* %q
> +; CHECK-LABEL: define {{[^@]+}}@c1
> +; CHECK-SAME: (i32* nofree readnone returned "no-capture-maybe-returned"
> [[Q:%.*]])
> +; CHECK-NEXT: ret i32* [[Q]]
> +;
> + ret i32* %q
> }
>
> -; ATTRIBUTOR: define void @c2(i32* nofree writeonly %q)
> ; It would also be acceptable to mark %q as readnone. Update @c3 too.
> define void @c2(i32* %q) {
> - store i32* %q, i32** @g
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@c2
> +; CHECK-SAME: (i32* nofree writeonly [[Q:%.*]])
> +; CHECK-NEXT: store i32* [[Q]], i32** @g, align 8
> +; CHECK-NEXT: ret void
> +;
> + store i32* %q, i32** @g
> + ret void
> }
>
> -; ATTRIBUTOR: define void @c3(i32* nofree writeonly %q)
> define void @c3(i32* %q) {
> - call void @c2(i32* %q)
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@c3
> +; CHECK-SAME: (i32* nofree writeonly [[Q:%.*]])
> +; CHECK-NEXT: call void @c2(i32* nofree writeonly [[Q]])
> +; CHECK-NEXT: ret void
> +;
> + call void @c2(i32* %q)
> + ret void
> }
>
> -; ATTRIBUTOR: define i1 @c4(i32* nofree readnone %q, i32 %bitno)
> define i1 @c4(i32* %q, i32 %bitno) {
> - %tmp = ptrtoint i32* %q to i32
> - %tmp2 = lshr i32 %tmp, %bitno
> - %bit = trunc i32 %tmp2 to i1
> - br i1 %bit, label %l1, label %l0
> +; 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
> +;
> + %tmp = ptrtoint i32* %q to i32
> + %tmp2 = lshr i32 %tmp, %bitno
> + %bit = trunc i32 %tmp2 to i1
> + br i1 %bit, label %l1, label %l0
> l0:
> - ret i1 0 ; escaping value not caught by def-use chaining.
> + ret i1 0 ; escaping value not caught by def-use chaining.
> l1:
> - ret i1 1 ; escaping value not caught by def-use chaining.
> + ret i1 1 ; escaping value not caught by def-use chaining.
> }
>
> ; c4b is c4 but without the escaping part
> -; ATTRIBUTOR: define i1 @c4b(i32* nocapture nofree readnone %q, i32
> %bitno)
> define i1 @c4b(i32* %q, i32 %bitno) {
> - %tmp = ptrtoint i32* %q to i32
> - %tmp2 = lshr i32 %tmp, %bitno
> - %bit = trunc i32 %tmp2 to i1
> - br i1 %bit, label %l1, label %l0
> +; 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
> +;
> + %tmp = ptrtoint i32* %q to i32
> + %tmp2 = lshr i32 %tmp, %bitno
> + %bit = trunc i32 %tmp2 to i1
> + br i1 %bit, label %l1, label %l0
> l0:
> - ret i1 0 ; not escaping!
> + ret i1 0 ; not escaping!
> l1:
> - ret i1 0 ; not escaping!
> + ret i1 0 ; not escaping!
> }
>
> @lookup_table = global [2 x i1] [ i1 0, i1 1 ]
>
> -; ATTRIBUTOR: define i1 @c5(i32* nofree readonly %q, i32 %bitno)
> define i1 @c5(i32* %q, i32 %bitno) {
> - %tmp = ptrtoint i32* %q to i32
> - %tmp2 = lshr i32 %tmp, %bitno
> - %bit = and i32 %tmp2, 1
> - ; subtle escape mechanism follows
> - %lookup = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0,
> i32 %bit
> - %val = load i1, i1* %lookup
> - ret i1 %val
> +; 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]]
> +; CHECK-NEXT: ret i1 [[VAL]]
> +;
> + %tmp = ptrtoint i32* %q to i32
> + %tmp2 = lshr i32 %tmp, %bitno
> + %bit = and i32 %tmp2, 1
> + ; subtle escape mechanism follows
> + %lookup = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32
> %bit
> + %val = load i1, i1* %lookup
> + ret i1 %val
> }
>
> declare void @throw_if_bit_set(i8*, i8) readonly
>
> -; ATTRIBUTOR: define i1 @c6(i8* readonly %q, i8 %bit)
> define i1 @c6(i8* %q, i8 %bit) personality i32 (...)*
> @__gxx_personality_v0 {
> - invoke void @throw_if_bit_set(i8* %q, i8 %bit)
> - to label %ret0 unwind label %ret1
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@c6
> +; IS__TUNIT____-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #5
> personality i32 (...)* @__gxx_personality_v0
> +; IS__TUNIT____-NEXT: invoke void @throw_if_bit_set(i8* readonly
> [[Q]], i8 [[BIT]])
> +; IS__TUNIT____-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]]
> +; IS__TUNIT____: ret0:
> +; IS__TUNIT____-NEXT: ret i1 false
> +; IS__TUNIT____: ret1:
> +; IS__TUNIT____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 }
> +; IS__TUNIT____-NEXT: cleanup
> +; IS__TUNIT____-NEXT: ret i1 true
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@c6
> +; IS__CGSCC____-SAME: (i8* readonly [[Q:%.*]], i8 [[BIT:%.*]]) #4
> personality i32 (...)* @__gxx_personality_v0
> +; IS__CGSCC____-NEXT: invoke void @throw_if_bit_set(i8* readonly
> [[Q]], i8 [[BIT]])
> +; IS__CGSCC____-NEXT: to label [[RET0:%.*]] unwind label [[RET1:%.*]]
> +; IS__CGSCC____: ret0:
> +; IS__CGSCC____-NEXT: ret i1 false
> +; IS__CGSCC____: ret1:
> +; IS__CGSCC____-NEXT: [[EXN:%.*]] = landingpad { i8*, i32 }
> +; IS__CGSCC____-NEXT: cleanup
> +; IS__CGSCC____-NEXT: ret i1 true
> +;
> + invoke void @throw_if_bit_set(i8* %q, i8 %bit)
> + to label %ret0 unwind label %ret1
> ret0:
> - ret i1 0
> + ret i1 0
> ret1:
> - %exn = landingpad {i8*, i32}
> - cleanup
> - ret i1 1
> + %exn = landingpad {i8*, i32}
> + cleanup
> + ret i1 1
> }
>
> declare i32 @__gxx_personality_v0(...)
>
> define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind {
> - %tmp = ptrtoint i32* %q to i32
> - %tmp2 = lshr i32 %tmp, %bitno
> - %bit = and i32 %tmp2, 1
> - %lookup = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0,
> i32 %bit
> - ret i1* %lookup
> +; 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]]
> +;
> + %tmp = ptrtoint i32* %q to i32
> + %tmp2 = lshr i32 %tmp, %bitno
> + %bit = and i32 %tmp2, 1
> + %lookup = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32
> %bit
> + ret i1* %lookup
> }
>
> -; ATTRIBUTOR: define i1 @c7(i32* nofree readonly %q, i32 %bitno)
> define i1 @c7(i32* %q, i32 %bitno) {
> - %ptr = call i1* @lookup_bit(i32* %q, i32 %bitno)
> - %val = load i1, i1* %ptr
> - ret i1 %val
> +; 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]]
> +; CHECK-NEXT: ret i1 [[VAL]]
> +;
> + %ptr = call i1* @lookup_bit(i32* %q, i32 %bitno)
> + %val = load i1, i1* %ptr
> + ret i1 %val
> }
>
>
> -; ATTRIBUTOR: define i32 @nc1(i32* nofree %q, i32* nocapture nofree %p,
> i1 %b)
> 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]]
> +;
> e:
> - br label %l
> + br label %l
> l:
> - %x = phi i32* [ %p, %e ]
> - %y = phi i32* [ %q, %e ]
> - %tmp = bitcast i32* %x to i32* ; <i32*> [#uses=2]
> - %tmp2 = select i1 %b, i32* %tmp, i32* %y
> - %val = load i32, i32* %tmp2 ; <i32> [#uses=1]
> - store i32 0, i32* %tmp
> - store i32* %y, i32** @g
> - ret i32 %val
> + %x = phi i32* [ %p, %e ]
> + %y = phi i32* [ %q, %e ]
> + %tmp = bitcast i32* %x to i32* ; <i32*> [#uses=2]
> + %tmp2 = select i1 %b, i32* %tmp, i32* %y
> + %val = load i32, i32* %tmp2 ; <i32> [#uses=1]
> + store i32 0, i32* %tmp
> + store i32* %y, i32** @g
> + ret i32 %val
> }
>
> -; ATTRIBUTOR: define i32 @nc1_addrspace(i32* nofree %q, i32 addrspace(1)*
> nocapture nofree %p, i1 %b)
> 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]]
> +;
> e:
> - br label %l
> + br label %l
> l:
> - %x = phi i32 addrspace(1)* [ %p, %e ]
> - %y = phi i32* [ %q, %e ]
> - %tmp = addrspacecast i32 addrspace(1)* %x to i32* ;
> <i32*> [#uses=2]
> - %tmp2 = select i1 %b, i32* %tmp, i32* %y
> - %val = load i32, i32* %tmp2 ; <i32> [#uses=1]
> - store i32 0, i32* %tmp
> - store i32* %y, i32** @g
> - ret i32 %val
> + %x = phi i32 addrspace(1)* [ %p, %e ]
> + %y = phi i32* [ %q, %e ]
> + %tmp = addrspacecast i32 addrspace(1)* %x to i32* ; <i32*>
> [#uses=2]
> + %tmp2 = select i1 %b, i32* %tmp, i32* %y
> + %val = load i32, i32* %tmp2 ; <i32> [#uses=1]
> + store i32 0, i32* %tmp
> + store i32* %y, i32** @g
> + ret i32 %val
> }
>
> -; ATTRIBUTOR: define void @nc2(i32* nocapture nofree %p, i32* nofree %q)
> define void @nc2(i32* %p, i32* %q) {
> - %1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32>
> [#uses=0]
> - ret void
> +; 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
> +;
> + %1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32> [#uses=0]
> + ret void
> }
>
>
> -; ATTRIBUTOR: define void @nc3(void ()* nocapture nofree nonnull %p)
> define void @nc3(void ()* %p) {
> - call void %p()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@nc3
> +; CHECK-SAME: (void ()* nocapture nofree nonnull [[P:%.*]])
> +; CHECK-NEXT: call void [[P]]()
> +; CHECK-NEXT: ret void
> +;
> + call void %p()
> + ret void
> }
>
> ; The following test is tricky because improvements to AAIsDead can cause
> the call to be removed.
> ; FIXME: readonly and nocapture missing on the pointer.
> declare void @external(i8* readonly) nounwind argmemonly
> -; ATTRIBUTOR: define void @nc4(i8* %p)
> define void @nc4(i8* %p) {
> - call void @external(i8* %p)
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@nc4
> +; CHECK-SAME: (i8* [[P:%.*]])
> +; CHECK-NEXT: call void @external(i8* readonly [[P]])
> +; CHECK-NEXT: ret void
> +;
> + call void @external(i8* %p)
> + ret void
> }
>
> -; ATTRIBUTOR: define void @nc5(void (i8*)* nocapture nofree nonnull %f,
> i8* nocapture %p)
> define void @nc5(void (i8*)* %f, i8* %p) {
> - call void %f(i8* %p) readonly nounwind
> - call void %f(i8* nocapture %p)
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@nc5
> +; CHECK-SAME: (void (i8*)* nocapture nofree nonnull [[F:%.*]], i8*
> nocapture [[P:%.*]])
> +; CHECK-NEXT: call void [[F]](i8* nocapture [[P]])
> +; CHECK-NEXT: ret void
> +;
> + call void %f(i8* %p) readonly nounwind
> + call void %f(i8* nocapture %p)
> + ret void
> }
>
> -; ATTRIBUTOR: define void @test1_1(i8* nocapture nofree readnone %x1_1,
> i8* nocapture nofree readnone %y1_1, i1 %c)
> ; 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-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 nofree
> readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned"
> [[Y1_1]], i1 [[C]])
> +; CHECK-NEXT: store i32* null, i32** @g, align 8
> +; CHECK-NEXT: ret void
> +;
> call i8* @test1_2(i8* %x1_1, i8* %y1_1, i1 %c)
> store i32* null, i32** @g
> ret void
> }
>
> -; ATTRIBUTOR: define i8* @test1_2(i8* nocapture nofree readnone %x1_2,
> i8* nofree readnone returned "no-capture-maybe-returned" %y1_2, i1 %c)
> define i8* @test1_2(i8* %x1_2, i8* %y1_2, i1 %c) {
> +; 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:%.*]]
> +; CHECK: t:
> +; CHECK-NEXT: call void @test1_1(i8* noalias nofree readnone undef,
> i8* noalias nocapture nofree readnone [[Y1_2]], i1 [[C]])
> +; CHECK-NEXT: store i32* null, i32** @g, align 8
> +; CHECK-NEXT: br label [[F]]
> +; CHECK: f:
> +; CHECK-NEXT: ret i8* [[Y1_2]]
> +;
> br i1 %c, label %t, label %f
> t:
> call void @test1_1(i8* %x1_2, i8* %y1_2, i1 %c)
> @@ -170,29 +301,49 @@ f:
> ret i8* %y1_2
> }
>
> -; ATTRIBUTOR: define void @test2(i8* nocapture nofree readnone %x2)
> define void @test2(i8* %x2) {
> +; CHECK-LABEL: define {{[^@]+}}@test2
> +; CHECK-SAME: (i8* nocapture nofree readnone [[X2:%.*]])
> +; CHECK-NEXT: unreachable
> +;
> call void @test2(i8* %x2)
> store i32* null, i32** @g
> ret void
> }
>
> -; ATTRIBUTOR: define void @test3(i8* nocapture nofree readnone %x3, i8*
> nocapture nofree readnone %y3, i8* nocapture nofree readnone %z3)
> 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
> +;
> call void @test3(i8* %z3, i8* %y3, i8* %x3)
> store i32* null, i32** @g
> ret void
> }
>
> -; ATTRIBUTOR: define void @test4_1(i8* nocapture nofree readnone %x4_1,
> i1 %c)
> define void @test4_1(i8* %x4_1, i1 %c) {
> +; CHECK-LABEL: define {{[^@]+}}@test4_1
> +; CHECK-SAME: (i8* nocapture nofree readnone [[X4_1:%.*]], i1 [[C:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test4_2(i8* noalias nofree
> readnone undef, i8* noalias nofree readnone "no-capture-maybe-returned"
> [[X4_1]], i8* noalias nofree readnone undef, i1 [[C]])
> +; CHECK-NEXT: store i32* null, i32** @g, align 8
> +; CHECK-NEXT: ret void
> +;
> call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1, i1 %c)
> store i32* null, i32** @g
> ret void
> }
>
> -; ATTRIBUTOR: define i8* @test4_2(i8* nocapture nofree readnone %x4_2,
> i8* nofree readnone returned "no-capture-maybe-returned" %y4_2, i8*
> nocapture nofree readnone %z4_2, i1 %c)
> define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2, i1 %c) {
> +; 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:%.*]]
> +; CHECK: t:
> +; CHECK-NEXT: call void @test4_1(i8* noalias nofree readnone align
> 536870912 null, i1 [[C]])
> +; CHECK-NEXT: store i32* null, i32** @g, align 8
> +; CHECK-NEXT: br label [[F]]
> +; CHECK: f:
> +; CHECK-NEXT: ret i8* [[Y4_2]]
> +;
> br i1 %c, label %t, label %f
> t:
> call void @test4_1(i8* null, i1 %c)
> @@ -204,8 +355,13 @@ f:
>
> declare i8* @test5_1(i8* %x5_1)
>
> -; ATTRIBUTOR: define void @test5_2(i8* %x5_2)
> define void @test5_2(i8* %x5_2) {
> +; CHECK-LABEL: define {{[^@]+}}@test5_2
> +; CHECK-SAME: (i8* [[X5_2:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test5_1(i8* [[X5_2]])
> +; CHECK-NEXT: store i32* null, i32** @g, align 8
> +; CHECK-NEXT: ret void
> +;
> call i8* @test5_1(i8* %x5_2)
> store i32* null, i32** @g
> ret void
> @@ -213,41 +369,70 @@ define void @test5_2(i8* %x5_2) {
>
> declare void @test6_1(i8* %x6_1, i8* nocapture %y6_1, ...)
>
> -; ATTRIBUTOR: define void @test6_2(i8* %x6_2, i8* nocapture %y6_2, i8*
> %z6_2)
> define void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) {
> +; CHECK-LABEL: define {{[^@]+}}@test6_2
> +; CHECK-SAME: (i8* [[X6_2:%.*]], i8* nocapture [[Y6_2:%.*]], i8*
> [[Z6_2:%.*]])
> +; CHECK-NEXT: call void (i8*, i8*, ...) @test6_1(i8* [[X6_2]], i8*
> nocapture [[Y6_2]], i8* [[Z6_2]])
> +; CHECK-NEXT: store i32* null, i32** @g, align 8
> +; CHECK-NEXT: ret void
> +;
> call void (i8*, i8*, ...) @test6_1(i8* %x6_2, i8* %y6_2, i8* %z6_2)
> store i32* null, i32** @g
> ret void
> }
>
> -; ATTRIBUTOR: define void @test_cmpxchg(i32* nocapture nofree nonnull
> dereferenceable(4) %p)
> 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
> +;
> cmpxchg i32* %p, i32 0, i32 1 acquire monotonic
> ret void
> }
>
> -; ATTRIBUTOR: define void @test_cmpxchg_ptr(i32** nocapture nofree
> nonnull dereferenceable(8) %p, i32* nofree %q)
> 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
> +;
> cmpxchg i32** %p, i32* null, i32* %q acquire monotonic
> ret void
> }
>
> -; ATTRIBUTOR: define void @test_atomicrmw(i32* nocapture nofree nonnull
> dereferenceable(4) %p)
> 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
> +;
> atomicrmw add i32* %p, i32 1 seq_cst
> ret void
> }
>
> -; ATTRIBUTOR: define void @test_volatile(i32* nofree align 4 %x)
> 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
> +;
> entry:
> %gep = getelementptr i32, i32* %x, i64 1
> store volatile i32 0, i32* %gep, align 4
> ret void
> }
>
> -; ATTRIBUTOR: nocaptureLaunder(i8* nocapture %p)
> define void @nocaptureLaunder(i8* %p) {
> +; CHECK-LABEL: define {{[^@]+}}@nocaptureLaunder
> +; CHECK-SAME: (i8* nocapture [[P:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[B:%.*]] = call i8*
> @llvm.launder.invariant.group.p0i8(i8* [[P]])
> +; CHECK-NEXT: store i8 42, i8* [[B]]
> +; CHECK-NEXT: ret void
> +;
> entry:
> %b = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
> store i8 42, i8* %b
> @@ -255,15 +440,26 @@ entry:
> }
>
> @g2 = global i8* null
> -; ATTRIBUTOR: define void @captureLaunder(i8* %p)
> define void @captureLaunder(i8* %p) {
> +; CHECK-LABEL: define {{[^@]+}}@captureLaunder
> +; CHECK-SAME: (i8* [[P:%.*]])
> +; CHECK-NEXT: [[B:%.*]] = call i8*
> @llvm.launder.invariant.group.p0i8(i8* [[P]])
> +; CHECK-NEXT: store i8* [[B]], i8** @g2, align 8
> +; CHECK-NEXT: ret void
> +;
> %b = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
> store i8* %b, i8** @g2
> ret void
> }
>
> -; ATTRIBUTOR: @nocaptureStrip(i8* nocapture writeonly %p)
> define void @nocaptureStrip(i8* %p) {
> +; CHECK-LABEL: define {{[^@]+}}@nocaptureStrip
> +; CHECK-SAME: (i8* nocapture writeonly [[P:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[B:%.*]] = call i8*
> @llvm.strip.invariant.group.p0i8(i8* noalias readnone [[P]])
> +; CHECK-NEXT: store i8 42, i8* [[B]]
> +; CHECK-NEXT: ret void
> +;
> entry:
> %b = call i8* @llvm.strip.invariant.group.p0i8(i8* %p)
> store i8 42, i8* %b
> @@ -271,74 +467,123 @@ entry:
> }
>
> @g3 = global i8* null
> -; ATTRIBUTOR: define void @captureStrip(i8* writeonly %p)
> define void @captureStrip(i8* %p) {
> +; CHECK-LABEL: define {{[^@]+}}@captureStrip
> +; CHECK-SAME: (i8* writeonly [[P:%.*]])
> +; CHECK-NEXT: [[B:%.*]] = call i8*
> @llvm.strip.invariant.group.p0i8(i8* noalias readnone [[P]])
> +; CHECK-NEXT: store i8* [[B]], i8** @g3, align 8
> +; CHECK-NEXT: ret void
> +;
> %b = call i8* @llvm.strip.invariant.group.p0i8(i8* %p)
> store i8* %b, i8** @g3
> ret void
> }
>
> -; ATTRIBUTOR: define i1 @captureICmp(i32* nofree readnone %x)
> 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]]
> +;
> %1 = icmp eq i32* %x, null
> ret i1 %1
> }
>
> -; ATTRIBUTOR: define i1 @captureICmpRev(i32* nofree readnone %x)
> 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]]
> +;
> %1 = icmp eq i32* null, %x
> ret i1 %1
> }
>
> -; ATTRIBUTOR: define i1 @nocaptureInboundsGEPICmp(i32* nocapture nofree
> readnone %x)
> 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]]
> +;
> %1 = getelementptr inbounds i32, i32* %x, i32 5
> %2 = bitcast i32* %1 to i8*
> %3 = icmp eq i8* %2, null
> ret i1 %3
> }
>
> -; ATTRIBUTOR: define i1 @nocaptureInboundsGEPICmpRev(i32* nocapture
> nofree readnone %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]]
> +;
> %1 = getelementptr inbounds i32, i32* %x, i32 5
> %2 = bitcast i32* %1 to i8*
> %3 = icmp eq i8* null, %2
> ret i1 %3
> }
>
> -; ATTRIBUTOR: define i1 @nocaptureDereferenceableOrNullICmp(i32*
> nocapture nofree readnone dereferenceable_or_null(4) %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]]
> +;
> %1 = bitcast i32* %x to i8*
> %2 = icmp eq i8* %1, null
> ret i1 %2
> }
>
> -; ATTRIBUTOR: define i1 @captureDereferenceableOrNullICmp(i32* nofree
> readnone dereferenceable_or_null(4) %x)
> define i1 @captureDereferenceableOrNullICmp(i32*
> dereferenceable_or_null(4) %x) "null-pointer-is-valid"="true" {
> +; 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]]
> +;
> %1 = bitcast i32* %x to i8*
> %2 = icmp eq i8* %1, null
> ret i1 %2
> }
>
> declare void @unknown(i8*)
> +; We know that 'null' in AS 0 does not alias anything and cannot be
> captured. Though the latter is not qurried -> derived atm.
> define void @test_callsite() {
> +; CHECK-LABEL: define {{[^@]+}}@test_callsite()
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: call void @unknown(i8* noalias align 536870912 null)
> +; CHECK-NEXT: ret void
> +;
> entry:
> -; We know that 'null' in AS 0 does not alias anything and cannot be
> captured. Though the latter is not qurried -> derived atm.
> -; ATTRIBUTOR: call void @unknown(i8* noalias align 536870912 null)
> call void @unknown(i8* null)
> ret void
> }
>
> declare i8* @unknownpi8pi8(i8*,i8* returned)
> define i8* @test_returned1(i8* %A, i8* returned %B) nounwind readonly {
> -; ATTRIBUTOR: define i8* @test_returned1(i8* nocapture readonly %A, i8*
> readonly returned %B)
> +; CHECK-LABEL: define {{[^@]+}}@test_returned1
> +; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned
> [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* [[A]], i8* [[B]])
> +; CHECK-NEXT: ret i8* [[P]]
> +;
> entry:
> %p = call i8* @unknownpi8pi8(i8* %A, i8* %B)
> ret i8* %p
> }
>
> define i8* @test_returned2(i8* %A, i8* %B) {
> -; ATTRIBUTOR: define i8* @test_returned2(i8* nocapture readonly %A, i8*
> readonly returned %B)
> +; CHECK-LABEL: define {{[^@]+}}@test_returned2
> +; CHECK-SAME: (i8* nocapture readonly [[A:%.*]], i8* readonly returned
> [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[P:%.*]] = call i8* @unknownpi8pi8(i8* readonly [[A]],
> i8* readonly [[B]])
> +; CHECK-NEXT: ret i8* [[P]]
> +;
> entry:
> %p = call i8* @unknownpi8pi8(i8* %A, i8* %B) nounwind readonly
> ret i8* %p
> @@ -350,7 +595,11 @@ declare void @val_use(i8 %ptr) readonly nounwind
>
> ; FIXME: Both pointers should be nocapture
> define void @ptr_uses(i8* %ptr, i8* %wptr) {
> -; CHECK: define void @ptr_uses(i8* %ptr, i8* nocapture nonnull writeonly
> dereferenceable(1) %wptr)
> +; CHECK-LABEL: define {{[^@]+}}@ptr_uses
> +; CHECK-SAME: (i8* [[PTR:%.*]], i8* nocapture nonnull writeonly
> dereferenceable(1) [[WPTR:%.*]])
> +; CHECK-NEXT: store i8 0, i8* [[WPTR]]
> +; CHECK-NEXT: ret void
> +;
> %call_ptr = call i8* @maybe_returned_ptr(i8* %ptr)
> %call_val = call i8 @maybe_returned_val(i8* %call_ptr)
> call void @val_use(i8 %call_val)
>
> diff --git a/llvm/test/Transforms/Attributor/nocapture-2.ll
> b/llvm/test/Transforms/Attributor/nocapture-2.ll
> index d0f03b852f16..c43df44d770f 100644
> --- a/llvm/test/Transforms/Attributor/nocapture-2.ll
> +++ b/llvm/test/Transforms/Attributor/nocapture-2.ll
> @@ -1,9 +1,14 @@
> -; RUN: opt -functionattrs -attributor -attributor-manifest-internal
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s |
> FileCheck %s
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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 cases specifically designed for the "no-capture" argument
> attribute.
> ; We use FIXME's to indicate problems and missing attributes.
> ;
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> +declare i32* @unknown()
>
> ; TEST comparison against NULL
> ;
> @@ -11,9 +16,15 @@ target datalayout =
> "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> ; return p == 0;
> ; }
> ;
> -; FIXME: no-capture missing for %p
> -; CHECK: define i32 @is_null_return(i32* nofree readnone %p)
> +; 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]]
> +;
> entry:
> %cmp = icmp eq i32* %p, null
> %conv = zext i1 %cmp to i32
> @@ -30,9 +41,30 @@ entry:
> ; return 0;
> ; }
> ;
> -; FIXME: no-capture missing for %p
> -; CHECK: define i32 @is_null_control(i32* nofree readnone %p)
> +; 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]]
> +;
> entry:
> %retval = alloca i32, align 4
> %cmp = icmp eq i32* %p, null
> @@ -66,8 +98,12 @@ return: ;
> preds = %if.end3, %if.then2,
> ; return 0;
> ; }
> ;
> -; CHECK: define noalias nonnull align 536870912
> dereferenceable(4294967295) double* @srec0(double* nocapture nofree
> readnone %a)
> define double* @srec0(double* %a) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@srec0
> +; CHECK-SAME: (double* nocapture nofree readnone [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: unreachable
> +;
> entry:
> %call = call double* @srec0(double* %a)
> ret double* null
> @@ -86,12 +122,14 @@ entry:
> ;
> ; Other arguments are possible here due to the no-return behavior.
> ;
> -; CHECK: define noalias nonnull align 536870912
> dereferenceable(4294967295) i32* @srec16(i32* nocapture nofree readnone %a)
> define i32* @srec16(i32* %a) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@srec16
> +; CHECK-SAME: (i32* nocapture nofree readnone [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: unreachable
> +;
> entry:
> %call = call i32* @srec16(i32* %a)
> -; CHECK-NOT: %call
> -; CHECK: unreachable
> %call1 = call i32* @srec16(i32* %call)
> %call2 = call i32* @srec16(i32* %call1)
> %call3 = call i32* @srec16(i32* %call2)
> @@ -112,12 +150,6 @@ entry:
>
> ; TEST SCC with various calls, casts, and comparisons agains NULL
> ;
> -; CHECK: define dereferenceable_or_null(4) float* @scc_A(i32* nofree
> readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" %a)
> -;
> -; CHECK: define dereferenceable_or_null(8) i64* @scc_B(double* nofree
> readnone returned dereferenceable_or_null(8) "no-capture-maybe-returned" %a)
> -;
> -; CHECK: define dereferenceable_or_null(4) i8* @scc_C(i16* nofree
> readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" %a)
> -;
> ; float *scc_A(int *a) {
> ; return (float*)(a ?
> (int*)scc_A((int*)scc_B((double*)scc_C((short*)a))) : a);
> ; }
> @@ -130,6 +162,27 @@ 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-LABEL: define {{[^@]+}}@scc_A
> +; CHECK-SAME: (i32* nofree readnone returned dereferenceable_or_null(4)
> "no-capture-maybe-returned" [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32* [[A]], null
> +; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; CHECK: cond.true:
> +; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[A]] to i16*
> +; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) i8*
> @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4)
> "no-capture-maybe-returned" [[TMP0]])
> +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to double*
> +; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64*
> @scc_B(double* noalias nofree nonnull readnone dereferenceable(8)
> "no-capture-maybe-returned" [[TMP1]])
> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i32*
> +; CHECK-NEXT: [[CALL2:%.*]] = call float* @scc_A(i32* noalias nofree
> nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP2]])
> +; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL2]] to i32*
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.false:
> +; CHECK-NEXT: br label [[COND_END]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: [[COND:%.*]] = phi i32* [ [[TMP3]], [[COND_TRUE]] ], [
> [[A]], [[COND_FALSE]] ]
> +; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32* [[COND]] to float*
> +; CHECK-NEXT: ret float* [[TMP4]]
> +;
> entry:
> %tobool = icmp ne i32* %a, null
> br i1 %tobool, label %cond.true, label %cond.false
> @@ -154,6 +207,27 @@ cond.end: ;
> preds = %cond.false, %cond.t
> }
>
> define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
> +; CHECK-LABEL: define {{[^@]+}}@scc_B
> +; CHECK-SAME: (double* nofree readnone returned
> dereferenceable_or_null(8) "no-capture-maybe-returned" [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne double* [[A]], null
> +; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; CHECK: cond.true:
> +; CHECK-NEXT: [[TMP0:%.*]] = bitcast double* [[A]] to i32*
> +; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float*
> @scc_A(i32* noalias nofree nonnull readnone dereferenceable(8)
> "no-capture-maybe-returned" [[TMP0]])
> +; CHECK-NEXT: [[TMP1:%.*]] = bitcast float* [[CALL]] to double*
> +; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64*
> @scc_B(double* noalias nofree nonnull readnone dereferenceable(8)
> "no-capture-maybe-returned" [[TMP1]])
> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i64* [[CALL1]] to i16*
> +; CHECK-NEXT: [[CALL2:%.*]] = call i8* @scc_C(i16* noalias nofree
> nonnull readnone dereferenceable(8) "no-capture-maybe-returned" [[TMP2]])
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.false:
> +; CHECK-NEXT: [[TMP3:%.*]] = bitcast double* [[A]] to i8*
> +; CHECK-NEXT: br label [[COND_END]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: [[COND:%.*]] = phi i8* [ [[CALL2]], [[COND_TRUE]] ], [
> [[TMP3]], [[COND_FALSE]] ]
> +; CHECK-NEXT: [[TMP4:%.*]] = bitcast i8* [[COND]] to i64*
> +; CHECK-NEXT: ret i64* [[TMP4]]
> +;
> entry:
> %tobool = icmp ne double* %a, null
> br i1 %tobool, label %cond.true, label %cond.false
> @@ -178,6 +252,29 @@ cond.end: ;
> preds = %cond.false, %cond.t
> }
>
> define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
> +; CHECK-LABEL: define {{[^@]+}}@scc_C
> +; CHECK-SAME: (i16* nofree readnone returned dereferenceable_or_null(4)
> "no-capture-maybe-returned" [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[BC:%.*]] = bitcast i16* [[A]] to i32*
> +; CHECK-NEXT: [[CALL:%.*]] = call dereferenceable_or_null(4) float*
> @scc_A(i32* noalias nofree nonnull readnone dereferenceable(4)
> "no-capture-maybe-returned" [[BC]])
> +; CHECK-NEXT: [[BC2:%.*]] = bitcast float* [[CALL]] to i8*
> +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[BC2]], null
> +; CHECK-NEXT: br i1 [[TOBOOL]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; CHECK: cond.true:
> +; CHECK-NEXT: [[TMP0:%.*]] = bitcast i16* [[A]] to double*
> +; CHECK-NEXT: [[CALL1:%.*]] = call dereferenceable_or_null(8) i64*
> @scc_B(double* noalias nofree nonnull readnone dereferenceable(8)
> "no-capture-maybe-returned" [[TMP0]])
> +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i64* [[CALL1]] to i8*
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.false:
> +; CHECK-NEXT: [[CALL2:%.*]] = call dereferenceable_or_null(4) i8*
> @scc_C(i16* noalias nofree nonnull readnone dereferenceable(4)
> "no-capture-maybe-returned" [[A]])
> +; CHECK-NEXT: br label [[COND_END]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: [[COND:%.*]] = phi i8* [ [[TMP1]], [[COND_TRUE]] ], [
> [[CALL2]], [[COND_FALSE]] ]
> +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i8* [[COND]] to i32*
> +; CHECK-NEXT: [[CALL3:%.*]] = call float* @scc_A(i32* noalias nofree
> nonnull readnone dereferenceable(4) "no-capture-maybe-returned" [[TMP2]])
> +; CHECK-NEXT: [[TMP3:%.*]] = bitcast float* [[CALL3]] to i8*
> +; CHECK-NEXT: ret i8* [[TMP3]]
> +;
> entry:
> %bc = bitcast i16* %a to i32*
> %call = call float* @scc_A(i32* %bc)
> @@ -211,10 +308,15 @@ cond.end: ;
> preds = %cond.false, %cond.t
> ; external_no_capture(p);
> ; }
> ;
> -; CHECK: define void @test_external_no_capture(i32* nocapture %p)
> declare void @external_no_capture(i32* nocapture)
>
> define void @test_external_no_capture(i32* %p) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@test_external_no_capture
> +; CHECK-SAME: (i32* nocapture [[P:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: call void @external_no_capture(i32* nocapture [[P]])
> +; CHECK-NEXT: ret void
> +;
> entry:
> call void @external_no_capture(i32* %p)
> ret void
> @@ -226,8 +328,13 @@ entry:
> ; printf(p, a);
> ; }
> ;
> -; CHECK: define void @test_var_arg_call(i8* nocapture %p, i32 %a)
> define void @test_var_arg_call(i8* %p, i32 %a) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@test_var_arg_call
> +; CHECK-SAME: (i8* nocapture [[P:%.*]], i32 [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, ...) @printf(i8* nocapture
> [[P]], i32 [[A]])
> +; CHECK-NEXT: ret void
> +;
> entry:
> %call = call i32 (i8*, ...) @printf(i8* %p, i32 %a)
> ret void
> @@ -244,9 +351,13 @@ declare i32 @printf(i8* nocapture, ...)
> ; }
> ;
> ; There should *not* be a no-capture attribute on %a
> -; CHECK: define nonnull align 8 dereferenceable(8) i64*
> @not_captured_but_returned_0(i64* nofree nonnull returned writeonly align 8
> dereferenceable(8) "no-capture-maybe-returned" %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]]
> +;
> entry:
> store i64 0, i64* %a, align 8
> ret i64* %a
> @@ -260,8 +371,14 @@ entry:
> ; }
> ;
> ; There should *not* be a no-capture attribute on %a
> -; CHECK: define nonnull align 8 dereferenceable(8) i64*
> @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8
> dereferenceable(16) "no-capture-maybe-returned" %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]]
> +;
> entry:
> %add.ptr = getelementptr inbounds i64, i64* %a, i64 1
> store i64 1, i64* %add.ptr, align 8
> @@ -275,8 +392,21 @@ entry:
> ; not_captured_but_returned_1(a);
> ; }
> ;
> -; CHECK: define void @test_not_captured_but_returned_calls(i64* nocapture
> nofree writeonly align 8 %a)
> define void @test_not_captured_but_returned_calls(i64* %a) #0 {
> +; IS__TUNIT____-LABEL: define
> {{[^@]+}}@test_not_captured_but_returned_calls
> +; IS__TUNIT____-SAME: (i64* nocapture nofree writeonly align 8 [[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: [[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____-LABEL: define
> {{[^@]+}}@test_not_captured_but_returned_calls
> +; IS__CGSCC____-SAME: (i64* nofree nonnull writeonly align 8
> dereferenceable(16) [[A:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64*
> @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8
> dereferenceable(16) [[A]])
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i64*
> @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8
> dereferenceable(16) [[A]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> entry:
> %call = call i64* @not_captured_but_returned_0(i64* %a)
> %call1 = call i64* @not_captured_but_returned_1(i64* %a)
> @@ -290,8 +420,19 @@ entry:
> ; }
> ;
> ; There should *not* be a no-capture attribute on %a
> -; CHECK: define align 8 i64*
> @negative_test_not_captured_but_returned_call_0a(i64* nofree returned
> writeonly align 8 "no-capture-maybe-returned" %a)
> define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 {
> +; 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____-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:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64*
> @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8
> dereferenceable(8) [[A]])
> +; IS__CGSCC____-NEXT: ret i64* [[CALL]]
> +;
> entry:
> %call = call i64* @not_captured_but_returned_0(i64* %a)
> ret i64* %call
> @@ -304,8 +445,23 @@ entry:
> ; }
> ;
> ; There should *not* be a no-capture attribute on %a
> -; CHECK: define void
> @negative_test_not_captured_but_returned_call_0b(i64* nofree writeonly
> align 8 %a)
> define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
> +; 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:
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i64*
> @not_captured_but_returned_0(i64* nofree writeonly align 8
> "no-capture-maybe-returned" [[A]])
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
> +; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i64*
> @not_captured_but_returned_0(i64* nofree nonnull writeonly align 8
> dereferenceable(8) [[A]])
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
> +; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[A]], align 8
> +; IS__CGSCC____-NEXT: ret void
> +;
> entry:
> %call = call i64* @not_captured_but_returned_0(i64* %a)
> %0 = ptrtoint i64* %call to i64
> @@ -320,8 +476,19 @@ entry:
> ; }
> ;
> ; There should *not* be a no-capture attribute on %a
> -; CHECK: define nonnull align 8 dereferenceable(8) i64*
> @negative_test_not_captured_but_returned_call_1a(i64* nofree writeonly
> align 8 "no-capture-maybe-returned" %a)
> define i64* @negative_test_not_captured_but_returned_call_1a(i64* %a) #0 {
> +; 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____-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:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call nonnull align 8
> dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree nonnull
> writeonly align 8 dereferenceable(16) [[A]])
> +; IS__CGSCC____-NEXT: ret i64* [[CALL]]
> +;
> entry:
> %call = call i64* @not_captured_but_returned_1(i64* %a)
> ret i64* %call
> @@ -334,8 +501,23 @@ entry:
> ; }
> ;
> ; There should *not* be a no-capture attribute on %a
> -; CHECK: define void
> @negative_test_not_captured_but_returned_call_1b(i64* nofree writeonly
> align 8 %a)
> define void @negative_test_not_captured_but_returned_call_1b(i64* %a) #0 {
> +; 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:
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call align 8 i64*
> @not_captured_but_returned_1(i64* nofree writeonly align 8
> "no-capture-maybe-returned" [[A]])
> +; IS__TUNIT____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
> +; IS__TUNIT____-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 8 i64*
> @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8
> dereferenceable(16) [[A]])
> +; IS__CGSCC____-NEXT: [[TMP0:%.*]] = ptrtoint i64* [[CALL]] to i64
> +; IS__CGSCC____-NEXT: store i64 [[TMP0]], i64* [[CALL]], align 8
> +; IS__CGSCC____-NEXT: ret void
> +;
> entry:
> %call = call i64* @not_captured_but_returned_1(i64* %a)
> %0 = ptrtoint i64* %call to i64
> @@ -353,12 +535,19 @@ entry:
> ;
> ; Verify we do *not* assume b is returned or not captured.
> ;
> -; CHECK: define i32* @ret_arg_or_unknown(i32* readnone %b)
> -; CHECK: define i32* @ret_arg_or_unknown_through_phi(i32* readnone %b)
> -
> -declare i32* @unknown()
>
> define i32* @ret_arg_or_unknown(i32* %b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown
> +; CHECK-SAME: (i32* [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
> +; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label
> [[RET_UNKNOWN:%.*]]
> +; CHECK: ret_arg:
> +; CHECK-NEXT: ret i32* [[B]]
> +; CHECK: ret_unknown:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown()
> +; CHECK-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %cmp = icmp eq i32* %b, null
> br i1 %cmp, label %ret_arg, label %ret_unknown
> @@ -372,6 +561,20 @@ ret_unknown:
> }
>
> define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
> +; CHECK-SAME: (i32* [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
> +; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label
> [[RET_UNKNOWN:%.*]]
> +; CHECK: ret_arg:
> +; CHECK-NEXT: br label [[R:%.*]]
> +; CHECK: ret_unknown:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown()
> +; CHECK-NEXT: br label [[R]]
> +; CHECK: r:
> +; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [
> [[CALL]], [[RET_UNKNOWN]] ]
> +; CHECK-NEXT: ret i32* [[PHI]]
> +;
> entry:
> %cmp = icmp eq i32* %b, null
> br i1 %cmp, label %ret_arg, label %ret_unknown
> @@ -391,10 +594,15 @@ r:
>
> ; TEST not captured by readonly external function
> ;
> -; CHECK: define void @not_captured_by_readonly_call(i32* nocapture
> readonly %b)
> declare i32* @readonly_unknown(i32*, i32*) readonly
>
> define void @not_captured_by_readonly_call(i32* %b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@not_captured_by_readonly_call
> +; CHECK-SAME: (i32* nocapture readonly [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly
> [[B]], i32* readonly [[B]])
> +; CHECK-NEXT: ret void
> +;
> entry:
> %call = call i32* @readonly_unknown(i32* %b, i32* %b)
> ret void
> @@ -405,13 +613,13 @@ entry:
> ;
> ; Make sure the returned flag on %r is strong enough to justify nocapture
> on %b but **not** on %r.
> ;
> -; CHECK: define i32*
> @not_captured_by_readonly_call_not_returned_either1(i32* nocapture readonly
> %b, i32* readonly returned %r)
> -;
> -; CHECK: define i32*
> @not_captured_by_readonly_call_not_returned_either2(i32* nocapture readonly
> %b, i32* readonly returned %r)
> -; CHECK: define i32*
> @not_captured_by_readonly_call_not_returned_either3(i32* nocapture readonly
> %b, i32* readonly returned %r)
> -;
> -; CHECK: define i32*
> @not_captured_by_readonly_call_not_returned_either4(i32* nocapture readonly
> %b, i32* readonly returned %r)
> define i32* @not_captured_by_readonly_call_not_returned_either1(i32* %b,
> i32* returned %r) {
> +; CHECK-LABEL: define
> {{[^@]+}}@not_captured_by_readonly_call_not_returned_either1
> +; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned
> [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown(i32* readonly
> [[B]], i32* readonly [[R]])
> +; CHECK-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %call = call i32* @readonly_unknown(i32* %b, i32* %r) nounwind
> ret i32* %call
> @@ -419,6 +627,12 @@ 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-LABEL: define
> {{[^@]+}}@not_captured_by_readonly_call_not_returned_either2
> +; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned
> [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32*
> readonly [[B]], i32* readonly [[R]])
> +; CHECK-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r) nounwind
> ret i32* %call
> @@ -426,12 +640,24 @@ 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-LABEL: define
> {{[^@]+}}@not_captured_by_readonly_call_not_returned_either3
> +; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned
> [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32*
> nocapture readonly [[B]], i32* readonly [[R]])
> +; CHECK-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %call = call i32* @readonly_unknown_r1b(i32* %b, i32* %r)
> ret i32* %call
> }
>
> define i32* @not_captured_by_readonly_call_not_returned_either4(i32* %b,
> i32* %r) nounwind {
> +; CHECK-LABEL: define
> {{[^@]+}}@not_captured_by_readonly_call_not_returned_either4
> +; CHECK-SAME: (i32* nocapture readonly [[B:%.*]], i32* readonly returned
> [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_unknown_r1a(i32*
> readonly [[B]], i32* readonly [[R]])
> +; CHECK-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r)
> ret i32* %call
> @@ -443,7 +669,7 @@ define void @nocapture_is_not_subsumed_1(i32*
> nocapture %b) {
> ; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_1
> ; CHECK-SAME: (i32* nocapture [[B:%.*]])
> ; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown_i32p(i32* [[B:%.*]])
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown_i32p(i32* [[B]])
> ; CHECK-NEXT: store i32 0, i32* [[CALL]]
> ; CHECK-NEXT: ret void
> ;
> @@ -456,9 +682,9 @@ entry:
> declare i32* @readonly_i32p(i32*) readonly
> define void @nocapture_is_not_subsumed_2(i32* nocapture %b) {
> ; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2
> -; CHECK-SAME: (i32* nocapture nofree [[B:%.*]])
> +; CHECK-SAME: (i32* nocapture [[B:%.*]])
> ; CHECK-NEXT: entry:
> -; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly
> [[B:%.*]])
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly
> [[B]])
> ; CHECK-NEXT: store i32 0, i32* [[CALL]]
> ; CHECK-NEXT: ret void
> ;
>
> diff --git a/llvm/test/Transforms/Attributor/nofree.ll
> b/llvm/test/Transforms/Attributor/nofree.ll
> index b72bfb6d3c75..538fee5fb875 100644
> --- a/llvm/test/Transforms/Attributor/nofree.ll
> +++ b/llvm/test/Transforms/Attributor/nofree.ll
> @@ -1,8 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=4 -S < %s | FileCheck %s
> --check-prefix=ATTRIBUTOR
> -; Copied from Transforms/FunctoinAttrs/nofree-attributor.ll
> -
> -; UTC_ARGS: --disable
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>
> @@ -16,10 +16,13 @@ declare void @_ZdaPv(i8*) local_unnamed_addr #2
>
>
> ; TEST 1 (positive case)
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define void @only_return()
> +; 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 {
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@only_return()
> +; CHECK-NEXT: ret void
> +;
> + ret void
> }
>
>
> @@ -29,12 +32,16 @@ define void @only_return() #0 {
> ; free(p);
> ; }
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: nofree
> -; ATTRIBUTOR-NEXT: define void @only_free(i8* nocapture %0)
> local_unnamed_addr #1
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: nofree
> define void @only_free(i8* nocapture %0) local_unnamed_addr #0 {
> - tail call void @free(i8* %0) #1
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@only_free
> +; CHECK-SAME: (i8* nocapture [[TMP0:%.*]]) local_unnamed_addr
> +; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP0]])
> +; CHECK-NEXT: ret void
> +;
> + tail call void @free(i8* %0) #1
> + ret void
> }
>
>
> @@ -49,19 +56,33 @@ define void @only_free(i8* nocapture %0)
> local_unnamed_addr #0 {
> ; }
>
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: nofree
> -; ATTRIBUTOR-NEXT: define void @free_in_scc1(i8* nocapture %0)
> local_unnamed_addr
> define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr #0 {
> +; 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]])
> +; CHECK-NEXT: ret void
> +;
> tail call void @free_in_scc2(i8* %0) #1
> ret void
> }
>
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: nofree
> -; ATTRIBUTOR: define void @free_in_scc2(i8* nocapture %0)
> local_unnamed_addr
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: nofree
> define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr #0 {
> +; CHECK-LABEL: define {{[^@]+}}@free_in_scc2
> +; CHECK-SAME: (i8* nocapture [[TMP0:%.*]]) local_unnamed_addr
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[TMP0]], null
> +; CHECK-NEXT: br i1 [[CMP]], label [[REC:%.*]], label [[CALL:%.*]]
> +; CHECK: call:
> +; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP0]])
> +; CHECK-NEXT: br label [[END:%.*]]
> +; CHECK: rec:
> +; CHECK-NEXT: tail call void @free_in_scc1(i8* nocapture [[TMP0]])
> +; CHECK-NEXT: br label [[END]]
> +; CHECK: end:
> +; CHECK-NEXT: ret void
> +;
> %cmp = icmp eq i8* %0, null
> br i1 %cmp, label %rec, label %call
> call:
> @@ -85,16 +106,22 @@ end:
> ; }
>
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; ATTRIBUTOR-NEXT: define void @mutual_recursion1()
> +; 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
> +;
> call void @mutual_recursion2()
> ret void
> }
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; ATTRIBUTOR-NEXT: define void @mutual_recursion2()
> +; 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
> +;
> call void @mutual_recursion1()
> ret void
> }
> @@ -106,10 +133,19 @@ define void @mutual_recursion2() #0 {
> ; delete [] p;
> ; }
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: nofree
> -; ATTRIBUTOR-NEXT: define void @_Z9delete_opPc(i8* %0) local_unnamed_addr
> #1
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: nofree
> define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #0 {
> +; CHECK-LABEL: define {{[^@]+}}@_Z9delete_opPc
> +; CHECK-SAME: (i8* [[TMP0:%.*]]) local_unnamed_addr
> +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
> +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP4:%.*]], label [[TMP3:%.*]]
> +; CHECK: 3:
> +; CHECK-NEXT: tail call void @_ZdaPv(i8* nonnull [[TMP0]])
> +; CHECK-NEXT: br label [[TMP4]]
> +; CHECK: 4:
> +; CHECK-NEXT: ret void
> +;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %4, label %3
>
> @@ -124,12 +160,16 @@ define void @_Z9delete_opPc(i8* %0)
> local_unnamed_addr #0 {
>
> ; TEST 6 (negative case)
> ; Call realloc
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: nofree
> -; ATTRIBUTOR-NEXT: define noalias i8* @call_realloc(i8* nocapture %0, i64
> %1) local_unnamed_addr
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: nofree
> define noalias i8* @call_realloc(i8* nocapture %0, i64 %1)
> local_unnamed_addr #0 {
> - %ret = tail call i8* @realloc(i8* %0, i64 %1) #2
> - ret i8* %ret
> +; 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]])
> +; CHECK-NEXT: ret i8* [[RET]]
> +;
> + %ret = tail call i8* @realloc(i8* %0, i64 %1) #2
> + ret i8* %ret
> }
>
>
> @@ -137,114 +177,152 @@ define noalias i8* @call_realloc(i8* nocapture %0,
> i64 %1) local_unnamed_addr #0
> ; Call function declaration with "nofree"
>
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline nounwind readnone uwtable
> -; ATTRIBUTOR-NEXT: declare void @nofree_function()
> +; CHECK: Function Attrs: nofree noinline nounwind readnone uwtable
> +; CHECK-NEXT: declare void @nofree_function()
> declare void @nofree_function() nofree readnone #0
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define void @call_nofree_function()
> +; 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 {
> - tail call void @nofree_function()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@call_nofree_function()
> +; CHECK-NEXT: ret void
> +;
> + tail call void @nofree_function()
> + ret void
> }
>
> ; TEST 8 (negative case)
> ; Call function declaration without "nofree"
>
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NEXT: declare void @maybe_free()
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NEXT: declare void @maybe_free()
> declare void @maybe_free() #0
>
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: nofree
> -; ATTRIBUTOR-NEXT: define void @call_maybe_free()
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: nofree
> define void @call_maybe_free() #0 {
> - tail call void @maybe_free()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@call_maybe_free()
> +; CHECK-NEXT: tail call void @maybe_free()
> +; CHECK-NEXT: ret void
> +;
> + tail call void @maybe_free()
> + ret void
> }
>
>
> ; TEST 9 (negative case)
> ; Call both of above functions
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: nofree
> -; ATTRIBUTOR-NEXT: define void @call_both()
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: nofree
> define void @call_both() #0 {
> - tail call void @maybe_free()
> - tail call void @nofree_function()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@call_both()
> +; CHECK-NEXT: tail call void @maybe_free()
> +; CHECK-NEXT: ret void
> +;
> + tail call void @maybe_free()
> + tail call void @nofree_function()
> + ret void
> }
>
>
> ; TEST 10 (positive case)
> ; Call intrinsic function
> -; ATTRIBUTOR: Function Attrs: nounwind readnone speculatable
> -; ATTRIBUTOR-NEXT: declare float @llvm.floor.f32(float)
> +; CHECK: Function Attrs: nounwind readnone speculatable
> +; CHECK-NEXT: declare float @llvm.floor.f32(float)
> declare float @llvm.floor.f32(float)
>
> -; FIXME: missing nofree
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable willreturn
> -; ATTRIBUTOR-NEXT: define void @call_floor(float %a)
> -
> +; 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 {
> - tail call float @llvm.floor.f32(float %a)
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@call_floor
> +; CHECK-SAME: (float [[A:%.*]])
> +; CHECK-NEXT: ret void
> +;
> + tail call float @llvm.floor.f32(float %a)
> + ret void
> }
>
> ; FIXME: missing nofree
> -; ATTRIBUTOR: Function Attrs: noinline nosync nounwind readnone uwtable
> -; ATTRIBUTOR-NEXT: define float @call_floor2(float %a)
> +; CHECK: Function Attrs: noinline nosync nounwind readnone uwtable
> define float @call_floor2(float %a) #0 {
> - %c = tail call float @llvm.floor.f32(float %a)
> - ret float %c
> +; CHECK-LABEL: define {{[^@]+}}@call_floor2
> +; CHECK-SAME: (float [[A:%.*]])
> +; CHECK-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]])
> +; CHECK-NEXT: ret float [[C]]
> +;
> + %c = tail call float @llvm.floor.f32(float %a)
> + ret float %c
> }
>
> ; TEST 11 (positive case)
> ; Check propagation.
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define void @f1()
> +; 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 {
> - tail call void @nofree_function()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@f1()
> +; CHECK-NEXT: ret void
> +;
> + tail call void @nofree_function()
> + ret void
> }
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define void @f2()
> +; 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 {
> - tail call void @f1()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@f2()
> +; CHECK-NEXT: ret void
> +;
> + tail call void @f1()
> + ret void
> }
>
> ; TEST 12 NoFree argument - positive.
> -; ATTRIBUTOR: define double @test12(double* nocapture nofree nonnull
> readonly align 8 dereferenceable(8) %a)
> define double @test12(double* nocapture readonly %a) {
> +; CHECK-LABEL: define {{[^@]+}}@test12
> +; CHECK-SAME: (double* nocapture nofree nonnull readonly align 8
> dereferenceable(8) [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[TMP0:%.*]] = load double, double* [[A]], align 8
> +; CHECK-NEXT: [[CALL:%.*]] = tail call double @cos(double [[TMP0]])
> +; CHECK-NEXT: ret double [[CALL]]
> +;
> entry:
> - %0 = load double, double* %a, align 8
> - %call = tail call double @cos(double %0) #2
> - ret double %call
> + %0 = load double, double* %a, align 8
> + %call = tail call double @cos(double %0) #2
> + ret double %call
> }
>
> declare double @cos(double) nobuiltin nounwind nofree
>
> ; FIXME: %a should be nofree.
> ; TEST 13 NoFree argument - positive.
> -; ATTRIBUTOR: define noalias i32* @test13(i64* nocapture nonnull readonly
> align 8 dereferenceable(8) %a)
> define noalias i32* @test13(i64* nocapture readonly %a) {
> +; CHECK-LABEL: define {{[^@]+}}@test13
> +; CHECK-SAME: (i64* nocapture nonnull readonly align 8 dereferenceable(8)
> [[A:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[TMP0:%.*]] = load i64, i64* [[A]], align 8
> +; CHECK-NEXT: [[CALL:%.*]] = tail call noalias i8* @malloc(i64
> [[TMP0]])
> +; CHECK-NEXT: [[TMP1:%.*]] = bitcast i8* [[CALL]] to i32*
> +; CHECK-NEXT: ret i32* [[TMP1]]
> +;
> entry:
> - %0 = load i64, i64* %a, align 8
> - %call = tail call noalias i8* @malloc(i64 %0) #2
> - %1 = bitcast i8* %call to i32*
> - ret i32* %1
> + %0 = load i64, i64* %a, align 8
> + %call = tail call noalias i8* @malloc(i64 %0) #2
> + %1 = bitcast i8* %call to i32*
> + ret i32* %1
> }
>
> -; ATTRIBUTOR: define void @test14(i8* nocapture %0, i8* nocapture nofree
> readnone %1)
> define void @test14(i8* nocapture %0, i8* nocapture %1) {
> - tail call void @free(i8* %0) #1
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@test14
> +; CHECK-SAME: (i8* nocapture [[TMP0:%.*]], i8* nocapture nofree readnone
> [[TMP1:%.*]])
> +; CHECK-NEXT: tail call void @free(i8* nocapture [[TMP0]])
> +; CHECK-NEXT: ret void
> +;
> + tail call void @free(i8* %0) #1
> + ret void
> }
>
> ; UTC_ARGS: --enable
> @@ -255,6 +333,12 @@ define void @nonnull_assume_pos(i8* %arg1, i8* %arg2,
> i8* %arg3, i8* %arg4) {
> ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) #11 [ "nofree"(i8*
> [[ARG1]]), "nofree"(i8* [[ARG3]]) ]
> ; ATTRIBUTOR-NEXT: call void @unknown(i8* nofree [[ARG1]], i8*
> [[ARG2]], i8* nofree [[ARG3]], i8* [[ARG4]])
> ; ATTRIBUTOR-NEXT: ret void
> +;
> +; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_pos
> +; CHECK-SAME: (i8* nofree [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* nofree
> [[ARG3:%.*]], i8* [[ARG4:%.*]])
> +; CHECK-NEXT: call void @llvm.assume(i1 true) #11 [ "nofree"(i8*
> [[ARG1]]), "nofree"(i8* [[ARG3]]) ]
> +; CHECK-NEXT: call void @unknown(i8* nofree [[ARG1]], i8* [[ARG2]],
> i8* nofree [[ARG3]], i8* [[ARG4]])
> +; CHECK-NEXT: ret void
> ;
> call void @llvm.assume(i1 true) ["nofree"(i8* %arg1), "nofree"(i8*
> %arg3)]
> call void @unknown(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4)
> @@ -266,6 +350,12 @@ define void @nonnull_assume_neg(i8* %arg1, i8* %arg2,
> i8* %arg3, i8* %arg4) {
> ; ATTRIBUTOR-NEXT: call void @unknown(i8* [[ARG1]], i8* [[ARG2]], i8*
> [[ARG3]], i8* [[ARG4]])
> ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) [ "nofree"(i8*
> [[ARG1]]), "nofree"(i8* [[ARG3]]) ]
> ; ATTRIBUTOR-NEXT: ret void
> +;
> +; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_neg
> +; CHECK-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8*
> [[ARG4:%.*]])
> +; CHECK-NEXT: call void @unknown(i8* [[ARG1]], i8* [[ARG2]], i8*
> [[ARG3]], i8* [[ARG4]])
> +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nofree"(i8*
> [[ARG1]]), "nofree"(i8* [[ARG3]]) ]
> +; CHECK-NEXT: ret void
> ;
> call void @unknown(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4)
> call void @llvm.assume(i1 true) ["nofree"(i8* %arg1), "nofree"(i8*
> %arg3)]
> @@ -286,6 +376,21 @@ define void @nonnull_assume_call(i8* %arg1, i8*
> %arg2, i8* %arg3, i8* %arg4) {
> ; ATTRIBUTOR-NEXT: call void @use_i8_ptr_ret(i8* noalias nofree
> readnone [[ARG3]])
> ; ATTRIBUTOR-NEXT: call void @use_i8_ptr_ret(i8* noalias nofree
> readnone [[ARG4]])
> ; ATTRIBUTOR-NEXT: ret void
> +;
> +; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_call
> +; CHECK-SAME: (i8* [[ARG1:%.*]], i8* [[ARG2:%.*]], i8* [[ARG3:%.*]], i8*
> [[ARG4:%.*]])
> +; CHECK-NEXT: call void @unknown(i8* [[ARG1]], i8* [[ARG2]], i8*
> [[ARG3]], i8* [[ARG4]])
> +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias readnone [[ARG1]])
> +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias readnone [[ARG2]])
> +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nofree"(i8*
> [[ARG1]]), "nofree"(i8* [[ARG3]]) ]
> +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nofree readnone
> [[ARG3]])
> +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias readnone [[ARG4]])
> +; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nofree readnone
> [[ARG1]])
> +; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias readnone [[ARG2]])
> +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nofree"(i8*
> [[ARG1]]), "nofree"(i8* [[ARG4]]) ]
> +; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nofree readnone
> [[ARG3]])
> +; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nofree readnone
> [[ARG4]])
> +; CHECK-NEXT: ret void
> ;
> call void @unknown(i8* %arg1, i8* %arg2, i8* %arg3, i8* %arg4)
> call void @use_i8_ptr(i8* %arg1)
>
> diff --git a/llvm/test/Transforms/Attributor/nonnull.ll
> b/llvm/test/Transforms/Attributor/nonnull.ll
> index 06ec6c2c585f..e0bdd5155ab1 100644
> --- a/llvm/test/Transforms/Attributor/nonnull.ll
> +++ b/llvm/test/Transforms/Attributor/nonnull.ll
> @@ -1,9 +1,9 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=5 -S < %s | FileCheck %s
> --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_OPM
> -; RUN: opt -passes=attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=5 -S < %s | FileCheck %s
> --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_NPM
> -; Copied from Transforms/FunctoinAttrs/nonnull.ll
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> -; UTC_ARGS: --disable
>
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>
> @@ -11,21 +11,35 @@ declare nonnull i8* @ret_nonnull()
>
> ; Return a pointer trivially nonnull (call return attribute)
> define i8* @test1() {
> -; ATTRIBUTOR: define nonnull i8* @test1
> +; CHECK-LABEL: define {{[^@]+}}@test1()
> +; CHECK-NEXT: [[RET:%.*]] = call nonnull i8* @ret_nonnull()
> +; CHECK-NEXT: ret i8* [[RET]]
> +;
> %ret = call i8* @ret_nonnull()
> ret i8* %ret
> }
>
> ; Return a pointer trivially nonnull (argument attribute)
> define i8* @test2(i8* nonnull %p) {
> -; ATTRIBUTOR: define nonnull i8* @test2
> +; CHECK-LABEL: define {{[^@]+}}@test2
> +; CHECK-SAME: (i8* nofree nonnull readnone returned
> "no-capture-maybe-returned" [[P:%.*]])
> +; CHECK-NEXT: ret i8* [[P]]
> +;
> ret i8* %p
> }
>
> ; Given an SCC where one of the functions can not be marked nonnull,
> ; can we still mark the other one which is trivially nonnull
> define i8* @scc_binder(i1 %c) {
> -; ATTRIBUTOR: define noalias align 536870912 i8* @scc_binder
> +; CHECK-LABEL: define {{[^@]+}}@scc_binder
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
> +; CHECK: rec:
> +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @test3(i1 [[C]])
> +; CHECK-NEXT: br label [[END]]
> +; CHECK: end:
> +; CHECK-NEXT: ret i8* null
> +;
> br i1 %c, label %rec, label %end
> rec:
> call i8* @test3(i1 %c)
> @@ -35,7 +49,12 @@ end:
> }
>
> define i8* @test3(i1 %c) {
> -; ATTRIBUTOR: define nonnull i8* @test3
> +; CHECK-LABEL: define {{[^@]+}}@test3
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @scc_binder(i1 [[C]])
> +; CHECK-NEXT: [[RET:%.*]] = call nonnull i8* @ret_nonnull()
> +; CHECK-NEXT: ret i8* [[RET]]
> +;
> call i8* @scc_binder(i1 %c)
> %ret = call i8* @ret_nonnull()
> ret i8* %ret
> @@ -45,13 +64,17 @@ define i8* @test3(i1 %c) {
> ; nonnull if neither can ever return null. (In this case, they
> ; just never return period.)
> define i8* @test4_helper() {
> -; ATTRIBUTOR: define noalias nonnull align 536870912
> dereferenceable(4294967295) i8* @test4_helper
> +; CHECK-LABEL: define {{[^@]+}}@test4_helper()
> +; CHECK-NEXT: unreachable
> +;
> %ret = call i8* @test4()
> ret i8* %ret
> }
>
> define i8* @test4() {
> -; ATTRIBUTOR: define noalias nonnull align 536870912
> dereferenceable(4294967295) i8* @test4
> +; CHECK-LABEL: define {{[^@]+}}@test4()
> +; CHECK-NEXT: unreachable
> +;
> %ret = call i8* @test4_helper()
> ret i8* %ret
> }
> @@ -59,7 +82,14 @@ 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) {
> -; ATTRIBUTOR: define noalias align 536870912 i8* @test5_helper
> +; 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
> +;
> br i1 %c, label %rec, label %end
> rec:
> %ret = call i8* @test5(i1 %c)
> @@ -69,15 +99,26 @@ end:
> }
>
> define i8* @test5(i1 %c) {
> -; ATTRIBUTOR: define noalias align 536870912 i8* @test5
> +; CHECK-LABEL: define {{[^@]+}}@test5
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: ret i8* null
> +;
> %ret = call i8* @test5_helper(i1 %c)
> ret i8* %ret
> }
>
> ; Local analysis, but going through a self recursive phi
> -; ATTRIBUTOR: Function Attrs: noreturn
> -; ATTRIBUTOR: define noalias nonnull align 536870912
> dereferenceable(4294967295) i8* @test6a()
> +; CHECK: Function Attrs: noreturn
> define i8* @test6a() {
> +; CHECK-LABEL: define {{[^@]+}}@test6a()
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[RET:%.*]] = call i8* @ret_nonnull()
> +; CHECK-NEXT: br label [[LOOP:%.*]]
> +; CHECK: loop:
> +; CHECK-NEXT: unreachable
> +; CHECK: exit:
> +; CHECK-NEXT: unreachable
> +;
> entry:
> %ret = call i8* @ret_nonnull()
> br label %loop
> @@ -88,8 +129,18 @@ exit:
> ret i8* %phi
> }
>
> -; ATTRIBUTOR: define nonnull i8* @test6b(i1 %c)
> define i8* @test6b(i1 %c) {
> +; CHECK-LABEL: define {{[^@]+}}@test6b
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[RET:%.*]] = call nonnull i8* @ret_nonnull()
> +; CHECK-NEXT: br label [[LOOP:%.*]]
> +; CHECK: loop:
> +; CHECK-NEXT: [[PHI:%.*]] = phi i8* [ [[RET]], [[ENTRY:%.*]] ], [
> [[PHI]], [[LOOP]] ]
> +; CHECK-NEXT: br i1 [[C]], label [[LOOP]], label [[EXIT:%.*]]
> +; CHECK: exit:
> +; CHECK-NEXT: ret i8* [[PHI]]
> +;
> entry:
> %ret = call i8* @ret_nonnull()
> br label %loop
> @@ -100,28 +151,44 @@ exit:
> ret i8* %phi
> }
>
> -; ATTRIBUTOR: define i8* @test7
> 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]]
> +;
> %b = getelementptr inbounds i8, i8* %a, i64 0
> ret i8* %b
> }
>
> -; ATTRIBUTOR: define nonnull i8* @test8
> 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]]
> +;
> %b = getelementptr inbounds i8, i8* %a, i64 1
> ret i8* %b
> }
>
> -; ATTRIBUTOR: define i8* @test9
> 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]]
> +;
> %b = getelementptr inbounds i8, i8* %a, i64 %n
> ret i8* %b
> }
>
> declare void @llvm.assume(i1)
> -; ATTRIBUTOR_OPM: define i8* @test10
> -; ATTRIBUTOR_NPM: define nonnull i8* @test10
> define i8* @test10(i8* %a, i64 %n) {
> +; CHECK-LABEL: define {{[^@]+}}@test10
> +; CHECK-SAME: (i8* nofree readnone "no-capture-maybe-returned" [[A:%.*]],
> i64 [[N:%.*]])
> +; CHECK-NEXT: call void @llvm.assume(i1 undef)
> +; CHECK-NEXT: [[B:%.*]] = getelementptr inbounds i8, i8* [[A]], i64
> [[N]]
> +; CHECK-NEXT: ret i8* [[B]]
> +;
> %cmp = icmp ne i64 %n, 0
> call void @llvm.assume(i1 %cmp)
> %b = getelementptr inbounds i8, i8* %a, i64 %n
> @@ -133,8 +200,18 @@ define i8* @test10(i8* %a, i64 %n) {
> ; return p? p: nonnull();
> ; }
> ; FIXME: missing nonnull
> -; ATTRIBUTOR: define i8* @test11
> define i8* @test11(i8*) local_unnamed_addr {
> +; CHECK-LABEL: define {{[^@]+}}@test11
> +; CHECK-SAME: (i8* [[TMP0:%.*]]) local_unnamed_addr
> +; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0]], null
> +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
> +; CHECK: 3:
> +; CHECK-NEXT: [[TMP4:%.*]] = tail call i8* @ret_nonnull()
> +; CHECK-NEXT: br label [[TMP5]]
> +; CHECK: 5:
> +; CHECK-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [
> [[TMP0]], [[TMP1:%.*]] ]
> +; CHECK-NEXT: ret i8* [[TMP6]]
> +;
> %2 = icmp eq i8* %0, null
> br i1 %2, label %3, label %5
>
> @@ -151,8 +228,11 @@ define i8* @test11(i8*) local_unnamed_addr {
> ; Simple CallSite Test
> declare void @test12_helper(i8*)
> define void @test12(i8* nonnull %a) {
> -; ATTRIBUTOR: define void @test12(i8* nonnull %a)
> -; ATTRIBUTOR-NEXT: tail call void @test12_helper(i8* nonnull %a)
> +; CHECK-LABEL: define {{[^@]+}}@test12
> +; CHECK-SAME: (i8* nonnull [[A:%.*]])
> +; CHECK-NEXT: tail call void @test12_helper(i8* nonnull [[A]])
> +; CHECK-NEXT: ret void
> +;
> tail call void @test12_helper(i8* %a)
> ret void
> }
> @@ -161,6 +241,13 @@ define void @test12(i8* nonnull %a) {
> ; Simple Argument Tests
> declare i8* @unknown()
> define void @test13_helper() {
> +; CHECK-LABEL: define {{[^@]+}}@test13_helper()
> +; CHECK-NEXT: [[NONNULLPTR:%.*]] = tail call nonnull i8* @ret_nonnull()
> +; CHECK-NEXT: [[MAYBENULLPTR:%.*]] = tail call i8* @unknown()
> +; CHECK-NEXT: tail call void @test13(i8* noalias nofree nonnull
> readnone [[NONNULLPTR]], i8* noalias nofree nonnull readnone
> [[NONNULLPTR]], i8* noalias nofree readnone [[MAYBENULLPTR]])
> +; CHECK-NEXT: tail call void @test13(i8* noalias nofree nonnull
> readnone [[NONNULLPTR]], i8* noalias nofree readnone [[MAYBENULLPTR]], i8*
> noalias nofree nonnull readnone [[NONNULLPTR]])
> +; CHECK-NEXT: ret void
> +;
> %nonnullptr = tail call i8* @ret_nonnull()
> %maybenullptr = tail call i8* @unknown()
> tail call void @test13(i8* %nonnullptr, i8* %nonnullptr, i8*
> %maybenullptr)
> @@ -168,7 +255,20 @@ define void @test13_helper() {
> ret void
> }
> define internal void @test13(i8* %a, i8* %b, i8* %c) {
> -; ATTRIBUTOR: define internal void @test13(i8* noalias nocapture nofree
> nonnull readnone %a, i8* noalias nocapture nofree readnone %b, i8* noalias
> nocapture nofree readnone %c)
> +; 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]])
> +; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture
> nofree readnone [[B]])
> +; IS__TUNIT____-NEXT: call void @use_i8_ptr(i8* noalias nocapture
> nofree readnone [[C]])
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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]])
> +; IS__CGSCC____-NEXT: call void @use_i8_ptr(i8* noalias nocapture
> nofree readnone [[B]])
> +; IS__CGSCC____-NEXT: call void @use_i8_ptr(i8* noalias nocapture
> nofree readnone [[C]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> call void @use_i8_ptr(i8* %a)
> call void @use_i8_ptr(i8* %b)
> call void @use_i8_ptr(i8* %c)
> @@ -191,7 +291,27 @@ declare nonnull i8* @nonnull()
>
> define internal i32* @f1(i32* %arg) {
> ; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull readonly
> %arg)
> -; ATTRIBUTOR: define internal nonnull i32* @f1(i32* nofree readonly %arg)
> +; CHECK-LABEL: define {{[^@]+}}@f1
> +; CHECK-SAME: (i32* nofree readonly [[ARG:%.*]])
> +; CHECK-NEXT: bb:
> +; CHECK-NEXT: [[TMP:%.*]] = icmp eq i32* [[ARG]], null
> +; CHECK-NEXT: br i1 [[TMP]], label [[BB9:%.*]], label [[BB1:%.*]]
> +; CHECK: bb1:
> +; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[ARG]], align 4
> +; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 0
> +; CHECK-NEXT: br i1 [[TMP3]], label [[BB6:%.*]], label [[BB4:%.*]]
> +; CHECK: bb4:
> +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, i32* [[ARG]],
> i64 1
> +; CHECK-NEXT: [[TMP5B:%.*]] = tail call nonnull i32* @f3(i32* nofree
> nonnull readonly [[TMP5]])
> +; CHECK-NEXT: [[TMP5C:%.*]] = getelementptr inbounds i32, i32*
> [[TMP5B]], i64 -1
> +; CHECK-NEXT: br label [[BB9]]
> +; CHECK: bb6:
> +; CHECK-NEXT: [[TMP7:%.*]] = tail call nonnull i32* @f2(i32* nofree
> nonnull readonly align 4 dereferenceable(4) [[ARG]])
> +; CHECK-NEXT: ret i32* [[TMP7]]
> +; CHECK: bb9:
> +; CHECK-NEXT: [[TMP10:%.*]] = phi i32* [ [[TMP5C]], [[BB4]] ], [
> inttoptr (i64 4 to i32*), [[BB:%.*]] ]
> +; CHECK-NEXT: ret i32* [[TMP10]]
> +;
>
> bb:
> %tmp = icmp eq i32* %arg, null
> @@ -204,13 +324,11 @@ bb1: ;
> preds = %bb
>
> bb4: ; preds = %bb1
> %tmp5 = getelementptr inbounds i32, i32* %arg, i64 1
> -; ATTRIBUTOR: %tmp5b = tail call nonnull i32* @f3(i32* nofree nonnull
> readonly %tmp5)
> %tmp5b = tail call i32* @f3(i32* %tmp5)
> %tmp5c = getelementptr inbounds i32, i32* %tmp5b, i64 -1
> br label %bb9
>
> bb6: ; preds = %bb1
> -; ATTRIBUTOR: %tmp7 = tail call nonnull i32* @f2(i32* nofree nonnull
> readonly align 4 dereferenceable(4) %arg)
> %tmp7 = tail call i32* @f2(i32* %arg)
> ret i32* %tmp7
>
> @@ -220,26 +338,38 @@ bb9: ;
> preds = %bb4, %bb
> }
>
> define internal i32* @f2(i32* %arg) {
> -; ATTRIBUTOR: define internal nonnull i32* @f2(i32* nofree nonnull
> readonly align 4 dereferenceable(4) %arg)
> +; CHECK-LABEL: define {{[^@]+}}@f2
> +; CHECK-SAME: (i32* nofree nonnull readonly align 4 dereferenceable(4)
> [[ARG:%.*]])
> +; CHECK-NEXT: bb:
> +; CHECK-NEXT: [[TMP:%.*]] = tail call nonnull i32* @f1(i32* nofree
> nonnull readonly align 4 dereferenceable(4) [[ARG]])
> +; CHECK-NEXT: ret i32* [[TMP]]
> +;
> bb:
> -; ATTRIBUTOR: %tmp = tail call nonnull i32* @f1(i32* nofree nonnull
> readonly align 4 dereferenceable(4) %arg)
> %tmp = tail call i32* @f1(i32* %arg)
> ret i32* %tmp
> }
>
> define dso_local noalias i32* @f3(i32* %arg) {
> ; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly
> %arg)
> -; ATTRIBUTOR: define dso_local noalias nonnull i32* @f3(i32* nofree
> readonly %arg)
> +; CHECK-LABEL: define {{[^@]+}}@f3
> +; CHECK-SAME: (i32* nofree readonly [[ARG:%.*]])
> +; CHECK-NEXT: bb:
> +; CHECK-NEXT: [[TMP:%.*]] = call nonnull i32* @f1(i32* nofree readonly
> [[ARG]])
> +; CHECK-NEXT: ret i32* [[TMP]]
> +;
> bb:
> ; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
> -; ATTRIBUTOR: %tmp = call nonnull i32* @f1(i32* nofree readonly %arg)
> %tmp = call i32* @f1(i32* %arg)
> ret i32* %tmp
> }
>
> ; TEST 15
> define void @f15(i8* %arg) {
> -; ATTRIBUTOR: tail call void @use1(i8* nonnull dereferenceable(4) %arg)
> +; CHECK-LABEL: define {{[^@]+}}@f15
> +; CHECK-SAME: (i8* nonnull dereferenceable(4) [[ARG:%.*]])
> +; CHECK-NEXT: tail call void @use1(i8* nonnull dereferenceable(4)
> [[ARG]])
> +; CHECK-NEXT: ret void
> +;
>
> tail call void @use1(i8* dereferenceable(4) %arg)
> ret void
> @@ -256,7 +386,17 @@ 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) {
> -; ATTRIBUTOR: define void @f16(i8* nonnull %a, i8* %b, i8 %c)
> +; CHECK-LABEL: define {{[^@]+}}@f16
> +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]])
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
> +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_ELSE:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* nonnull
> [[B]])
> +; CHECK-NEXT: ret void
> +; CHECK: if.else:
> +; CHECK-NEXT: tail call void @fun2(i8* nonnull [[A]], i8* [[B]])
> +; CHECK-NEXT: ret void
> +;
> %cmp = icmp eq i8 %c, 0
> br i1 %cmp, label %if.then, label %if.else
> if.then:
> @@ -274,7 +414,20 @@ if.else:
> ; fun1(nonnull %a)
> ; We can say that %a is nonnull
> define void @f17(i8* %a, i8 %c) {
> -; ATTRIBUTOR: define void @f17(i8* nonnull %a, i8 %c)
> +; CHECK-LABEL: define {{[^@]+}}@f17
> +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8 [[C:%.*]])
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[C]], 0
> +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_ELSE:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: tail call void @fun0()
> +; CHECK-NEXT: br label [[CONT:%.*]]
> +; CHECK: if.else:
> +; CHECK-NEXT: tail call void @fun0()
> +; CHECK-NEXT: br label [[CONT]]
> +; CHECK: cont:
> +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]])
> +; CHECK-NEXT: ret void
> +;
> %cmp = icmp eq i8 %c, 0
> br i1 %cmp, label %if.then, label %if.else
> if.then:
> @@ -299,7 +452,29 @@ cont:
> ; fun1(nonnull %a)
>
> define void @f18(i8* %a, i8* %b, i8 %c) {
> -; ATTRIBUTOR: define void @f18(i8* nonnull %a, i8* %b, i8 %c)
> +; CHECK-LABEL: define {{[^@]+}}@f18
> +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8 [[C:%.*]])
> +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[C]], 0
> +; CHECK-NEXT: br i1 [[CMP1]], label [[IF_THEN:%.*]], label
> [[IF_ELSE:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: tail call void @fun0()
> +; CHECK-NEXT: br label [[CONT:%.*]]
> +; CHECK: if.else:
> +; CHECK-NEXT: tail call void @fun0()
> +; CHECK-NEXT: br label [[CONT]]
> +; CHECK: cont:
> +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[C]], 1
> +; CHECK-NEXT: br i1 [[CMP2]], label [[CONT_THEN:%.*]], label
> [[CONT_ELSE:%.*]]
> +; CHECK: cont.then:
> +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]])
> +; CHECK-NEXT: br label [[CONT2:%.*]]
> +; CHECK: cont.else:
> +; CHECK-NEXT: tail call void @fun0()
> +; CHECK-NEXT: br label [[CONT2]]
> +; CHECK: cont2:
> +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]])
> +; CHECK-NEXT: ret void
> +;
> %cmp1 = icmp eq i8 %c, 0
> br i1 %cmp1, label %if.then, label %if.else
> if.then:
> @@ -325,7 +500,20 @@ cont2:
> ; TEST 19: Loop
>
> define void @f19(i8* %a, i8* %b, i8 %c) {
> -; ATTRIBUTOR: define void @f19(i8* %a, i8* nonnull %b, i8 %c)
> +; CHECK-LABEL: define {{[^@]+}}@f19
> +; CHECK-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8 [[C:%.*]])
> +; CHECK-NEXT: br label [[LOOP_HEADER:%.*]]
> +; CHECK: loop.header:
> +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[C]], 0
> +; CHECK-NEXT: br i1 [[CMP2]], label [[LOOP_BODY:%.*]], label
> [[LOOP_EXIT:%.*]]
> +; CHECK: loop.body:
> +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]])
> +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[A]])
> +; CHECK-NEXT: br label [[LOOP_HEADER]]
> +; CHECK: loop.exit:
> +; CHECK-NEXT: tail call void @fun1(i8* nonnull [[B]])
> +; CHECK-NEXT: ret void
> +;
> br label %loop.header
> loop.header:
> %cmp2 = icmp eq i8 %c, 0
> @@ -354,10 +542,12 @@ declare i8 @use1safecall(i8* %x) readonly nounwind ;
> readonly+nounwind guarantee
> ; Can't extend non-null to parent for any argument because the 2nd call
> is not guaranteed to execute.
>
> define void @parent1(i8* %a, i8* %b, i8* %c) {
> -; ATTRIBUTOR-LABEL: @parent1(i8* %a, i8* %b, i8* %c)
> -; ATTRIBUTOR-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
> -; ATTRIBUTOR-NEXT: call void @use3nonnull(i8* nonnull %b, i8* nonnull
> %c, i8* nonnull %a)
> -; ATTRIBUTOR-NEXT: ret void
> +; CHECK-LABEL: define {{[^@]+}}@parent1
> +; CHECK-SAME: (i8* [[A:%.*]], i8* [[B:%.*]], i8* [[C:%.*]])
> +; CHECK-NEXT: call void @use3(i8* [[C]], i8* [[A]], i8* [[B]])
> +; CHECK-NEXT: call void @use3nonnull(i8* nonnull [[B]], i8* nonnull
> [[C]], i8* nonnull [[A]])
> +; CHECK-NEXT: ret void
> +;
> call void @use3(i8* %c, i8* %a, i8* %b)
> call void @use3nonnull(i8* %b, i8* %c, i8* %a)
> ret void
> @@ -366,12 +556,13 @@ define void @parent1(i8* %a, i8* %b, i8* %c) {
> ; Extend non-null to parent for all arguments.
>
> define void @parent2(i8* %a, i8* %b, i8* %c) {
> +; CHECK-LABEL: define {{[^@]+}}@parent2
> +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* nonnull [[B:%.*]], i8* nonnull
> [[C:%.*]])
> +; CHECK-NEXT: call void @use3nonnull(i8* nonnull [[B]], i8* nonnull
> [[C]], i8* nonnull [[A]])
> +; CHECK-NEXT: call void @use3(i8* nonnull [[C]], i8* nonnull [[A]],
> i8* nonnull [[B]])
> +; CHECK-NEXT: ret void
> +;
>
> -; ATTRIBUTOR-LABEL: @parent2(i8* nonnull %a, i8* nonnull %b, i8* nonnull
> %c)
> -; ATTRIBUTOR-NEXT: call void @use3nonnull(i8* nonnull %b, i8* nonnull
> %c, i8* nonnull %a)
> -; ATTRIBUTOR-NEXT: call void @use3(i8* nonnull %c, i8* nonnull %a, i8*
> nonnull %b)
> -
> -; ATTRIBUTOR-NEXT: ret void
> call void @use3nonnull(i8* %b, i8* %c, i8* %a)
> call void @use3(i8* %c, i8* %a, i8* %b)
> ret void
> @@ -380,12 +571,13 @@ define void @parent2(i8* %a, i8* %b, i8* %c) {
> ; Extend non-null to parent for 1st argument.
>
> define void @parent3(i8* %a, i8* %b, i8* %c) {
> +; CHECK-LABEL: define {{[^@]+}}@parent3
> +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]], i8* [[C:%.*]])
> +; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]])
> +; CHECK-NEXT: call void @use3(i8* [[C]], i8* [[B]], i8* nonnull [[A]])
> +; CHECK-NEXT: ret void
> +;
>
> -; ATTRIBUTOR-LABEL: @parent3(i8* nonnull %a, i8* %b, i8* %c)
> -; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
> -; ATTRIBUTOR-NEXT: call void @use3(i8* %c, i8* %b, i8* nonnull %a)
> -
> -; ATTRIBUTOR-NEXT: ret void
>
> call void @use1nonnull(i8* %a)
> call void @use3(i8* %c, i8* %b, i8* %a)
> @@ -395,17 +587,15 @@ define void @parent3(i8* %a, i8* %b, i8* %c) {
> ; Extend non-null to parent for last 2 arguments.
>
> define void @parent4(i8* %a, i8* %b, i8* %c) {
> -; CHECK-LABEL: @parent4(i8* %a, i8* nonnull %b, i8* nonnull %c)
> -; CHECK-NEXT: call void @use2nonnull(i8* %c, i8* %b)
> -; CHECK-NEXT: call void @use2(i8* %a, i8* %c)
> -; CHECK-NEXT: call void @use1(i8* %b)
> +; CHECK-LABEL: define {{[^@]+}}@parent4
> +; CHECK-SAME: (i8* [[A:%.*]], i8* nonnull [[B:%.*]], i8* nonnull
> [[C:%.*]])
> +; CHECK-NEXT: call void @use2nonnull(i8* nonnull [[C]], i8* nonnull
> [[B]])
> +; CHECK-NEXT: call void @use2(i8* [[A]], i8* nonnull [[C]])
> +; CHECK-NEXT: call void @use1(i8* nonnull [[B]])
> +; CHECK-NEXT: ret void
> +;
>
> -; ATTRIBUTOR-LABEL: @parent4(i8* %a, i8* nonnull %b, i8* nonnull %c)
> -; ATTRIBUTOR-NEXT: call void @use2nonnull(i8* nonnull %c, i8* nonnull
> %b)
> -; ATTRIBUTOR-NEXT: call void @use2(i8* %a, i8* nonnull %c)
> -; ATTRIBUTOR-NEXT: call void @use1(i8* nonnull %b)
>
> -; ATTRIBUTOR: ret void
>
> call void @use2nonnull(i8* %c, i8* %b)
> call void @use2(i8* %a, i8* %c)
> @@ -418,13 +608,15 @@ define void @parent4(i8* %a, i8* %b, i8* %c) {
> ; because it would incorrectly propagate the wrong information to its
> callers.
>
> define void @parent5(i8* %a, i1 %a_is_notnull) {
> -; ATTRIBUTOR: @parent5(i8* %a, i1 %a_is_notnull)
> -; ATTRIBUTOR-NEXT: br i1 %a_is_notnull, label %t, label %f
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
> -; ATTRIBUTOR-NEXT: ret void
> -; ATTRIBUTOR: f:
> -; ATTRIBUTOR-NEXT: ret void
> +; CHECK-LABEL: define {{[^@]+}}@parent5
> +; CHECK-SAME: (i8* [[A:%.*]], i1 [[A_IS_NOTNULL:%.*]])
> +; CHECK-NEXT: br i1 [[A_IS_NOTNULL]], label [[T:%.*]], label [[F:%.*]]
> +; CHECK: t:
> +; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]])
> +; CHECK-NEXT: ret void
> +; CHECK: f:
> +; CHECK-NEXT: ret void
> +;
>
> br i1 %a_is_notnull, label %t, label %f
> t:
> @@ -438,10 +630,12 @@ f:
> ; The volatile load can't trap, so we can guarantee that we'll get to the
> call.
>
> define i8 @parent6(i8* %a, i8* %b) {
> -; ATTRIBUTOR-LABEL: @parent6(i8* nonnull %a, i8* %b)
> -; ATTRIBUTOR-NEXT: [[C:%.*]] = load volatile i8, i8* %b
> -; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
> -; ATTRIBUTOR-NEXT: ret i8 [[C]]
> +; CHECK-LABEL: define {{[^@]+}}@parent6
> +; CHECK-SAME: (i8* nonnull [[A:%.*]], i8* [[B:%.*]])
> +; CHECK-NEXT: [[C:%.*]] = load volatile i8, i8* [[B]]
> +; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]])
> +; CHECK-NEXT: ret i8 [[C]]
> +;
>
> %c = load volatile i8, i8* %b
> call void @use1nonnull(i8* %a)
> @@ -451,14 +645,14 @@ define i8 @parent6(i8* %a, i8* %b) {
> ; The nonnull callsite is guaranteed to execute, so the argument must be
> nonnull throughout the parent.
>
> define i8 @parent7(i8* %a) {
> +; CHECK-LABEL: define {{[^@]+}}@parent7
> +; CHECK-SAME: (i8* nonnull [[A:%.*]])
> +; CHECK-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull readonly
> [[A]])
> +; CHECK-NEXT: call void @use1nonnull(i8* nonnull [[A]])
> +; CHECK-NEXT: ret i8 [[RET]]
> +;
>
>
> -; ATTRIBUTOR-LABEL: @parent7(i8* nonnull %a)
> -; ATTRIBUTOR-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull
> readonly %a)
> -; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
> -
> -; ATTRIBUTOR-NEXT: ret i8 [[RET]]
> -
> %ret = call i8 @use1safecall(i8* %a)
> call void @use1nonnull(i8* %a)
> ret i8 %ret
> @@ -469,17 +663,32 @@ define i8 @parent7(i8* %a) {
> declare i32 @esfp(...)
>
> define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast
> (i32 (...)* @esfp to i8*){
> -; ATTRIBUTOR-LABEL: @parent8(i8* nonnull %a, i8* nocapture nofree
> readnone %bogus1, i8* nonnull %b)
> -; ATTRIBUTOR-NEXT: entry:
> -; ATTRIBUTOR-NEXT: invoke void @use2nonnull(i8* nonnull %a, i8*
> nonnull %b)
> -; ATTRIBUTOR-NEXT: to label %cont unwind label %exc
> -; ATTRIBUTOR: cont:
> -; ATTRIBUTOR-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %b, null
> -; ATTRIBUTOR-NEXT: ret i1 [[NULL_CHECK]]
> -; ATTRIBUTOR: exc:
> -; ATTRIBUTOR-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
> -; ATTRIBUTOR-NEXT: filter [0 x i8*] zeroinitializer
> -; ATTRIBUTOR-NEXT: unreachable
> +; 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:
> +; NOT_CGSCC_OPM-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8*
> nonnull [[B]])
> +; NOT_CGSCC_OPM-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
> +; NOT_CGSCC_OPM: cont:
> +; NOT_CGSCC_OPM-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[B]], null
> +; NOT_CGSCC_OPM-NEXT: ret i1 [[NULL_CHECK]]
> +; NOT_CGSCC_OPM: exc:
> +; NOT_CGSCC_OPM-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
> +; NOT_CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer
> +; NOT_CGSCC_OPM-NEXT: unreachable
> +;
> +; 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:
> +; IS__CGSCC_OPM-NEXT: invoke void @use2nonnull(i8* nonnull [[A]], i8*
> nonnull [[B]])
> +; IS__CGSCC_OPM-NEXT: to label [[CONT:%.*]] unwind label [[EXC:%.*]]
> +; IS__CGSCC_OPM: cont:
> +; IS__CGSCC_OPM-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* [[B]], null
> +; IS__CGSCC_OPM-NEXT: ret i1 [[NULL_CHECK]]
> +; IS__CGSCC_OPM: exc:
> +; IS__CGSCC_OPM-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
> +; IS__CGSCC_OPM-NEXT: filter [0 x i8*] zeroinitializer
> +; IS__CGSCC_OPM-NEXT: unreachable
> +;
>
> entry:
> invoke void @use2nonnull(i8* %a, i8* %b)
> @@ -495,83 +704,138 @@ exc:
> unreachable
> }
>
> -; ATTRIBUTOR: define nonnull i32* @gep1(
> 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]]
> +;
> %q = getelementptr inbounds i32, i32* %p, i32 1
> ret i32* %q
> }
>
> define i32* @gep1_no_null_opt(i32* %p) #0 {
> ; Should't be able to derive nonnull based on gep.
> -; ATTRIBUTOR: define i32* @gep1_no_null_opt(
> +; 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]]
> +;
> %q = getelementptr inbounds i32, i32* %p, i32 1
> ret i32* %q
> }
>
> -; ATTRIBUTOR: define i32 addrspace(3)* @gep2(
> 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]]
> +;
> %q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1
> ret i32 addrspace(3)* %q
> }
>
> ; FIXME: We should propagate dereferenceable here but *not* nonnull
> -; ATTRIBUTOR: define dereferenceable_or_null(4) i32 addrspace(3)* @as(i32
> addrspace(3)* nofree readnone returned dereferenceable(4)
> dereferenceable_or_null(4) %p)
> define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) {
> +; CHECK-LABEL: define {{[^@]+}}@as
> +; CHECK-SAME: (i32 addrspace(3)* nofree readnone returned
> dereferenceable(4) dereferenceable_or_null(4) "no-capture-maybe-returned"
> [[P:%.*]])
> +; CHECK-NEXT: ret i32 addrspace(3)* [[P]]
> +;
> ret i32 addrspace(3)* %p
> }
>
> -; ATTRIBUTOR-NOT: @g2()
> +; CHECK-NOT: @g2()
> define internal i32* @g2() {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@g2()
> +; IS__CGSCC____-NEXT: ret i32* inttoptr (i64 4 to i32*)
> +;
> ret i32* inttoptr (i64 4 to i32*)
> }
>
> -; ATTRIBUTOR: define nonnull align 4 i32* @g1()
> -; ATTRIBUTOR: ret i32* inttoptr (i64 4 to i32*)
> define i32* @g1() {
> - %c = call i32* @g2()
> +; CHECK-LABEL: define {{[^@]+}}@g1()
> +; CHECK-NEXT: ret i32* inttoptr (i64 4 to i32*)
> +;
> + %c = call i32* @g2()
> ret i32* %c
> }
>
> declare void @use_i32_ptr(i32* readnone nocapture) nounwind
> -; ATTRIBUTOR: define internal void @called_by_weak(i32* noalias nocapture
> nonnull readnone %a)
> define internal void @called_by_weak(i32* %a) {
> +; 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____-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]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> call void @use_i32_ptr(i32* %a)
> ret void
> }
>
> ; Check we do not annotate the function interface of this weak function.
> -; ATTRIBUTOR: define weak_odr void @weak_caller(i32* nonnull %a)
> define weak_odr void @weak_caller(i32* nonnull %a) {
> +; CHECK-LABEL: define {{[^@]+}}@weak_caller
> +; CHECK-SAME: (i32* nonnull [[A:%.*]])
> +; CHECK-NEXT: call void @called_by_weak(i32* noalias nonnull readnone
> [[A]])
> +; CHECK-NEXT: ret void
> +;
> call void @called_by_weak(i32* %a)
> ret void
> }
>
> ; Expect nonnull
> -; ATTRIBUTOR: define internal void @control(i32* noalias nocapture
> nonnull readnone align 16 dereferenceable(8) %a)
> define internal void @control(i32* dereferenceable(4) %a) {
> +; 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____-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]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> call void @use_i32_ptr(i32* %a)
> ret void
> }
> ; Avoid nonnull as we do not touch naked functions
> -; ATTRIBUTOR: define internal void @naked(i32* dereferenceable(4) %a)
> define internal void @naked(i32* dereferenceable(4) %a) naked {
> +; CHECK-LABEL: define {{[^@]+}}@naked
> +; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]])
> +; CHECK-NEXT: call void @use_i32_ptr(i32* [[A]])
> +; CHECK-NEXT: ret void
> +;
> call void @use_i32_ptr(i32* %a)
> ret void
> }
> ; Avoid nonnull as we do not touch optnone
> -; ATTRIBUTOR: define internal void @optnone(i32* dereferenceable(4) %a)
> define internal void @optnone(i32* dereferenceable(4) %a) optnone
> noinline {
> +; CHECK-LABEL: define {{[^@]+}}@optnone
> +; CHECK-SAME: (i32* dereferenceable(4) [[A:%.*]])
> +; CHECK-NEXT: call void @use_i32_ptr(i32* [[A]])
> +; CHECK-NEXT: ret void
> +;
> call void @use_i32_ptr(i32* %a)
> ret void
> }
> define void @make_live(i32* nonnull dereferenceable(8) %a) {
> +; CHECK-LABEL: define {{[^@]+}}@make_live
> +; CHECK-SAME: (i32* nonnull align 16 dereferenceable(8) [[A:%.*]])
> +; CHECK-NEXT: call void @naked(i32* nonnull align 16
> dereferenceable(8) [[A]])
> +; CHECK-NEXT: call void @control(i32* noalias nonnull readnone align
> 16 dereferenceable(8) [[A]])
> +; CHECK-NEXT: call void @optnone(i32* nonnull align 16
> dereferenceable(8) [[A]])
> +; CHECK-NEXT: ret void
> +;
> call void @naked(i32* nonnull dereferenceable(8) align 16 %a)
> call void @control(i32* nonnull dereferenceable(8) align 16 %a)
> call void @optnone(i32* nonnull dereferenceable(8) align 16 %a)
> ret void
> }
>
> -; UTC_ARGS: --enable
>
> ;int f(int *u, int n){
> ; for(int i = 0;i<n;i++){
> @@ -583,20 +847,20 @@ declare void @h(i32*) willreturn nounwind
> declare i32 @g(i32*) willreturn nounwind
> define i32 @nonnull_exec_ctx_1(i32* %a, i32 %b) {
> ;
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
> -; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
> -; ATTRIBUTOR-NEXT: en:
> -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
> -; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
> -; ATTRIBUTOR: ex:
> -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
> -; ATTRIBUTOR-NEXT: ret i32 [[TMP5]]
> -; ATTRIBUTOR: hd:
> -; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [
> 0, [[EN:%.*]] ]
> -; ATTRIBUTOR-NEXT: tail call void @h(i32* [[A]])
> -; ATTRIBUTOR-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
> -; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
> -; ATTRIBUTOR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
> +; 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]]
> ;
> en:
> %tmp3 = icmp eq i32 %b, 0
> @@ -616,22 +880,22 @@ hd:
>
> define i32 @nonnull_exec_ctx_1b(i32* %a, i32 %b) {
> ;
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
> -; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
> -; ATTRIBUTOR-NEXT: en:
> -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
> -; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
> -; ATTRIBUTOR: ex:
> -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
> -; ATTRIBUTOR-NEXT: ret i32 [[TMP5]]
> -; ATTRIBUTOR: hd:
> -; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]]
> ], [ 0, [[EN:%.*]] ]
> -; ATTRIBUTOR-NEXT: tail call void @h(i32* [[A]])
> -; ATTRIBUTOR-NEXT: br label [[HD2]]
> -; ATTRIBUTOR: hd2:
> -; ATTRIBUTOR-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
> -; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
> -; ATTRIBUTOR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
> +; 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]]
> ;
> en:
> %tmp3 = icmp eq i32 %b, 0
> @@ -654,20 +918,20 @@ hd2:
>
> define i32 @nonnull_exec_ctx_2(i32* %a, i32 %b) willreturn nounwind {
> ;
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
> -; ATTRIBUTOR-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]])
> -; ATTRIBUTOR-NEXT: en:
> -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
> -; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
> -; ATTRIBUTOR: ex:
> -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
> -; ATTRIBUTOR-NEXT: ret i32 [[TMP5]]
> -; ATTRIBUTOR: hd:
> -; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [
> 0, [[EN:%.*]] ]
> -; ATTRIBUTOR-NEXT: tail call void @h(i32* nonnull [[A]])
> -; ATTRIBUTOR-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
> -; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
> -; ATTRIBUTOR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
> +; CHECK-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
> +; CHECK-SAME: (i32* nonnull [[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* nonnull [[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]]
> ;
> en:
> %tmp3 = icmp eq i32 %b, 0
> @@ -687,22 +951,22 @@ hd:
>
> define i32 @nonnull_exec_ctx_2b(i32* %a, i32 %b) willreturn nounwind {
> ;
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
> -; ATTRIBUTOR-SAME: (i32* nonnull [[A:%.*]], i32 [[B:%.*]])
> -; ATTRIBUTOR-NEXT: en:
> -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B]], 0
> -; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
> -; ATTRIBUTOR: ex:
> -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A]])
> -; ATTRIBUTOR-NEXT: ret i32 [[TMP5]]
> -; ATTRIBUTOR: hd:
> -; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]]
> ], [ 0, [[EN:%.*]] ]
> -; ATTRIBUTOR-NEXT: tail call void @h(i32* nonnull [[A]])
> -; ATTRIBUTOR-NEXT: br label [[HD2]]
> -; ATTRIBUTOR: hd2:
> -; ATTRIBUTOR-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
> -; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
> -; ATTRIBUTOR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
> +; CHECK-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
> +; CHECK-SAME: (i32* nonnull [[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* nonnull [[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]]
> ;
> en:
> %tmp3 = icmp eq i32 %b, 0
> @@ -728,22 +992,22 @@ declare void @sink(i32*)
>
> ; FIXME: the sink argument should be marked nonnull as in @PR43833_simple.
> define void @PR43833(i32* %0, i32 %1) {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@PR43833
> -; ATTRIBUTOR-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]])
> -; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], 1
> -; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP7:%.*]]
> -; ATTRIBUTOR: 4:
> -; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
> -; ATTRIBUTOR-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP5]]
> -; ATTRIBUTOR-NEXT: br label [[TMP8:%.*]]
> -; ATTRIBUTOR: 7:
> -; ATTRIBUTOR-NEXT: ret void
> -; ATTRIBUTOR: 8:
> -; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [
> [[TMP10:%.*]], [[TMP8]] ]
> -; ATTRIBUTOR-NEXT: tail call void @sink(i32* [[TMP6]])
> -; ATTRIBUTOR-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
> -; ATTRIBUTOR-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
> -; ATTRIBUTOR-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
> +; CHECK-LABEL: define {{[^@]+}}@PR43833
> +; CHECK-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1]], 1
> +; CHECK-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
> +; CHECK: 4:
> +; CHECK-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
> +; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP5]]
> +; CHECK-NEXT: br label [[TMP8:%.*]]
> +; CHECK: 7:
> +; CHECK-NEXT: ret void
> +; CHECK: 8:
> +; CHECK-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]],
> [[TMP8]] ]
> +; CHECK-NEXT: tail call void @sink(i32* [[TMP6]])
> +; CHECK-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
> +; CHECK-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
> +; CHECK-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
> ;
> %3 = icmp sgt i32 %1, 1
> br i1 %3, label %4, label %7
> @@ -766,39 +1030,73 @@ define void @PR43833(i32* %0, i32 %1) {
>
> ; Adjusted from PR43833
> define void @PR43833_simple(i32* %0, i32 %1) {
> -; ATTRIBUTOR_OPM-LABEL: define {{[^@]+}}@PR43833_simple
> -; ATTRIBUTOR_OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]])
> -; ATTRIBUTOR_OPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
> -; ATTRIBUTOR_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP7:%.*]]
> -; ATTRIBUTOR_OPM: 4:
> -; ATTRIBUTOR_OPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
> -; ATTRIBUTOR_OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP5]]
> -; ATTRIBUTOR_OPM-NEXT: br label [[TMP8:%.*]]
> -; ATTRIBUTOR_OPM: 7:
> -; ATTRIBUTOR_OPM-NEXT: ret void
> -; ATTRIBUTOR_OPM: 8:
> -; ATTRIBUTOR_OPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [
> [[TMP10:%.*]], [[TMP8]] ]
> -; ATTRIBUTOR_OPM-NEXT: tail call void @sink(i32* [[TMP6]])
> -; ATTRIBUTOR_OPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
> -; ATTRIBUTOR_OPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
> -; ATTRIBUTOR_OPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
> -;
> -; ATTRIBUTOR_NPM-LABEL: define {{[^@]+}}@PR43833_simple
> -; ATTRIBUTOR_NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]])
> -; ATTRIBUTOR_NPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
> -; ATTRIBUTOR_NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP7:%.*]]
> -; ATTRIBUTOR_NPM: 4:
> -; ATTRIBUTOR_NPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
> -; ATTRIBUTOR_NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP5]]
> -; ATTRIBUTOR_NPM-NEXT: br label [[TMP8:%.*]]
> -; ATTRIBUTOR_NPM: 7:
> -; ATTRIBUTOR_NPM-NEXT: ret void
> -; ATTRIBUTOR_NPM: 8:
> -; ATTRIBUTOR_NPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [
> [[TMP10:%.*]], [[TMP8]] ]
> -; ATTRIBUTOR_NPM-NEXT: tail call void @sink(i32* nonnull [[TMP6]])
> -; ATTRIBUTOR_NPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
> -; ATTRIBUTOR_NPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
> -; ATTRIBUTOR_NPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
> +; CHECK_OPM-LABEL: define {{[^@]+}}@PR43833_simple
> +; CHECK_OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; CHECK_OPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
> +; CHECK_OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP7:%.*]]
> +; CHECK_OPM: 4:
> +; CHECK_OPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
> +; CHECK_OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP5]]
> +; CHECK_OPM-NEXT: br label [[TMP8:%.*]]
> +; CHECK_OPM: 7:
> +; CHECK_OPM-NEXT: ret void
> +; CHECK_OPM: 8:
> +; CHECK_OPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [
> [[TMP10:%.*]], [[TMP8]] ]
> +; CHECK_OPM-NEXT: tail call void @sink(i32* [[TMP6]])
> +; CHECK_OPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
> +; CHECK_OPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
> +; CHECK_OPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
> +;
> +; CHECK_NPM-LABEL: define {{[^@]+}}@PR43833_simple
> +; CHECK_NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; CHECK_NPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
> +; CHECK_NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP7:%.*]]
> +; CHECK_NPM: 4:
> +; CHECK_NPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
> +; CHECK_NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP5]]
> +; CHECK_NPM-NEXT: br label [[TMP8:%.*]]
> +; CHECK_NPM: 7:
> +; CHECK_NPM-NEXT: ret void
> +; CHECK_NPM: 8:
> +; CHECK_NPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [
> [[TMP10:%.*]], [[TMP8]] ]
> +; CHECK_NPM-NEXT: tail call void @sink(i32* nonnull [[TMP6]])
> +; CHECK_NPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
> +; CHECK_NPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
> +; CHECK_NPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
> +;
> +; IS________OPM-LABEL: define {{[^@]+}}@PR43833_simple
> +; IS________OPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; IS________OPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
> +; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP7:%.*]]
> +; IS________OPM: 4:
> +; IS________OPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
> +; IS________OPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP5]]
> +; IS________OPM-NEXT: br label [[TMP8:%.*]]
> +; IS________OPM: 7:
> +; IS________OPM-NEXT: ret void
> +; IS________OPM: 8:
> +; IS________OPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [
> [[TMP10:%.*]], [[TMP8]] ]
> +; IS________OPM-NEXT: tail call void @sink(i32* [[TMP6]])
> +; IS________OPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
> +; IS________OPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
> +; IS________OPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
> +;
> +; IS________NPM-LABEL: define {{[^@]+}}@PR43833_simple
> +; IS________NPM-SAME: (i32* [[TMP0:%.*]], i32 [[TMP1:%.*]])
> +; IS________NPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1]], 0
> +; IS________NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP7:%.*]]
> +; IS________NPM: 4:
> +; IS________NPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
> +; IS________NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP5]]
> +; IS________NPM-NEXT: br label [[TMP8:%.*]]
> +; IS________NPM: 7:
> +; IS________NPM-NEXT: ret void
> +; IS________NPM: 8:
> +; IS________NPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [
> [[TMP10:%.*]], [[TMP8]] ]
> +; IS________NPM-NEXT: tail call void @sink(i32* nonnull [[TMP6]])
> +; IS________NPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
> +; IS________NPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
> +; IS________NPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
> ;
> %3 = icmp ne i32 %1, 0
> br i1 %3, label %4, label %7
> @@ -823,13 +1121,13 @@ 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) {
> -; ATTRIBUTOR-LABEL: define {{[^@]+}}@mybasename
> -; ATTRIBUTOR-SAME: (i8* nofree readonly [[STR:%.*]])
> -; ATTRIBUTOR-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree
> readonly [[STR]], i32 47)
> -; ATTRIBUTOR-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null
> -; ATTRIBUTOR-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8*
> [[CALL]], i64 1
> -; ATTRIBUTOR-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8*
> [[ADD_PTR]], i8* [[STR]]
> -; ATTRIBUTOR-NEXT: ret i8* [[COND]]
> +; CHECK-LABEL: define {{[^@]+}}@mybasename
> +; CHECK-SAME: (i8* nofree readonly [[STR:%.*]])
> +; CHECK-NEXT: [[CALL:%.*]] = call i8* @strrchr(i8* nofree readonly
> [[STR]], i32 47)
> +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i8* [[CALL]], null
> +; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, i8*
> [[CALL]], i64 1
> +; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i8* [[ADD_PTR]],
> i8* [[STR]]
> +; CHECK-NEXT: ret i8* [[COND]]
> ;
> %call = call i8* @strrchr(i8* %str, i32 47)
> %tobool = icmp ne i8* %call, null
> @@ -845,6 +1143,20 @@ define void @nonnull_assume_pos(i8* %arg) {
> ; ATTRIBUTOR-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree
> nonnull readnone [[ARG]])
> ; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = call i8* @unknown()
> ; ATTRIBUTOR-NEXT: ret void
> +;
> +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
> +; NOT_CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]])
> +; NOT_CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #11 [
> "nonnull"(i8* [[ARG]]) ]
> +; NOT_CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture
> nofree nonnull readnone [[ARG]])
> +; NOT_CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown()
> +; NOT_CGSCC_OPM-NEXT: ret void
> +;
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@nonnull_assume_pos
> +; IS__CGSCC_OPM-SAME: (i8* nocapture nofree nonnull readnone [[ARG:%.*]])
> +; IS__CGSCC_OPM-NEXT: call void @llvm.assume(i1 true) #12 [
> "nonnull"(i8* [[ARG]]) ]
> +; IS__CGSCC_OPM-NEXT: call void @use_i8_ptr(i8* noalias nocapture
> nofree nonnull readnone [[ARG]])
> +; IS__CGSCC_OPM-NEXT: [[TMP1:%.*]] = call i8* @unknown()
> +; IS__CGSCC_OPM-NEXT: ret void
> ;
> call void @llvm.assume(i1 true) ["nonnull"(i8* %arg)]
> call void @use_i8_ptr(i8* %arg)
> @@ -863,6 +1175,18 @@ define void @nonnull_assume_neg(i8* %arg) {
> ; ATTRIBUTOR-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8*
> [[ARG]]) ]
> ; ATTRIBUTOR-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture
> nofree nonnull readnone [[ARG]])
> ; ATTRIBUTOR-NEXT: ret void
> +;
> +; CHECK-LABEL: define {{[^@]+}}@nonnull_assume_neg
> +; CHECK-SAME: (i8* nocapture nofree readnone [[ARG:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @unknown()
> +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree
> readnone [[ARG]])
> +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG]])
> ]
> +; CHECK-NEXT: call void @use_i8_ptr(i8* noalias nocapture nofree
> nonnull readnone [[ARG]])
> +; CHECK-NEXT: [[TMP2:%.*]] = call i8* @unknown()
> +; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree
> nonnull readnone [[ARG]])
> +; CHECK-NEXT: call void @llvm.assume(i1 true) [ "nonnull"(i8* [[ARG]])
> ]
> +; CHECK-NEXT: call void @use_i8_ptr_ret(i8* noalias nocapture nofree
> nonnull readnone [[ARG]])
> +; CHECK-NEXT: ret void
> ;
> call i8* @unknown()
> call void @use_i8_ptr(i8* %arg)
>
> diff --git a/llvm/test/Transforms/Attributor/norecurse.ll
> b/llvm/test/Transforms/Attributor/norecurse.ll
> index f7e29e2b27a8..3c60c08c8d8e 100644
> --- a/llvm/test/Transforms/Attributor/norecurse.ll
> +++ b/llvm/test/Transforms/Attributor/norecurse.ll
> @@ -1,100 +1,152 @@
> -; RUN: opt -attributor-cgscc --attributor-disable=false
> -attributor-annotate-decl-cs -S < %s | FileCheck %s
> --check-prefixes=ATTRIBUTOR
> -; RUN: opt -passes=attributor-cgscc --attributor-disable=false
> -attributor-annotate-decl-cs -S < %s | FileCheck %s
> --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_NPM
> -; Copied from Transforms/FunctoinAttrs/norecurse.ll
> -
> -; ATTRIBUTOR: Function Attrs: nofree norecurse nosync nounwind readnone
> willreturn
> -; ATTRIBUTOR-NEXT: define i32 @leaf()
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> +;
> ret i32 1
> }
>
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-SAME: readnone
> -; ATTRIBUTOR-NOT: norecurse
> -; ATTRIBUTOR-NEXT: define i32 @self_rec()
> +; CHECK: Function Attrs
> +; CHECK-SAME: readnone
> +; CHECK-NOT: norecurse
> define i32 @self_rec() {
> +; CHECK-LABEL: define {{[^@]+}}@self_rec()
> +; CHECK-NEXT: unreachable
> +;
> %a = call i32 @self_rec()
> ret i32 4
> }
>
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-SAME: readnone
> -; ATTRIBUTOR-NOT: norecurse
> -; ATTRIBUTOR-NEXT: define i32 @indirect_rec()
> +; CHECK: Function Attrs
> +; CHECK-SAME: readnone
> +; CHECK-NOT: norecurse
> define i32 @indirect_rec() {
> +; CHECK-LABEL: define {{[^@]+}}@indirect_rec()
> +; CHECK-NEXT: unreachable
> +;
> %a = call i32 @indirect_rec2()
> ret i32 %a
> }
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-SAME: readnone
> -; ATTRIBUTOR-NOT: norecurse
> -; ATTRIBUTOR-NEXT: define i32 @indirect_rec2()
> +; CHECK: Function Attrs
> +; CHECK-SAME: readnone
> +; CHECK-NOT: norecurse
> define i32 @indirect_rec2() {
> +; CHECK-LABEL: define {{[^@]+}}@indirect_rec2()
> +; CHECK-NEXT: unreachable
> +;
> %a = call i32 @indirect_rec()
> ret i32 %a
> }
>
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-SAME: readnone
> -; ATTRIBUTOR-NOT: norecurse
> -; ATTRIBUTOR-NEXT: define i32 @extern()
> +; CHECK: Function Attrs
> +; CHECK-SAME: readnone
> +; CHECK-NOT: norecurse
> define i32 @extern() {
> +; CHECK-LABEL: define {{[^@]+}}@extern()
> +; CHECK-NEXT: [[A:%.*]] = call i32 @k()
> +; CHECK-NEXT: ret i32 [[A]]
> +;
> %a = call i32 @k()
> ret i32 %a
> }
>
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-NEXT: declare i32 @k()
> +; CHECK: Function Attrs
> +; CHECK-NEXT: declare i32 @k()
> declare i32 @k() readnone
>
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-NOT: norecurse
> -; ATTRIBUTOR-NEXT: define void @intrinsic(i8* nocapture writeonly %dest,
> i8* nocapture readonly %src, i32 %len)
> +; CHECK: Function Attrs
> +; CHECK-NOT: norecurse
> define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
> +; 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)
> +; CHECK-NEXT: ret void
> +;
> call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1
> false)
> ret void
> }
>
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-NEXT: declare void @llvm.memcpy.p0i8.p0i8.i32
> +; CHECK: Function Attrs
> +; CHECK-NEXT: declare void @llvm.memcpy.p0i8.p0i8.i32
> declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
>
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-SAME: norecurse nosync readnone
> +; 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
> +;
> %a = call i32 @k()
> ret i32 %a
> }
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-NEXT: define void @m()
> +; CHECK: Function Attrs
> define void @m() norecurse {
> +; CHECK-LABEL: define {{[^@]+}}@m()
> +; CHECK-NEXT: [[A:%.*]] = call i32 @called_by_norecurse()
> +; CHECK-NEXT: ret void
> +;
> %a = call i32 @called_by_norecurse()
> ret void
> }
>
> -; ATTRIBUTOR: Function Attrs
> +; CHECK: Function Attrs
> ; FIXME: norecurse missing
> -; ATTRIBUTOR-SAME: nosync readnone
> -; ATTRIBUTOR-NEXT: @called_by_norecurse_indirectly
> +; CHECK-SAME: nosync readnone
> define internal i32 @called_by_norecurse_indirectly() {
> +; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly()
> +; CHECK-NEXT: [[A:%.*]] = call i32 @k()
> +; CHECK-NEXT: ret i32 [[A]]
> +;
> %a = call i32 @k()
> ret i32 %a
> }
> -; ATTRIBUTOR: Function Attrs
> -; ATTRIBUTOR-SAME: norecurse nosync readnone
> -; ATTRIBUTOR-NEXT: @o
> +; 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]]
> +;
> %a = call i32 @called_by_norecurse_indirectly()
> ret i32 %a
> }
> define i32 @p() norecurse {
> +; CHECK-LABEL: define {{[^@]+}}@p()
> +; CHECK-NEXT: [[A:%.*]] = call i32 @o()
> +; CHECK-NEXT: ret i32 [[A]]
> +;
> %a = call i32 @o()
> ret i32 %a
> }
>
> -; ATTRIBUTOR: Function Attrs: nofree nosync nounwind
> -; ATTRIBUTOR-NEXT: define void @f(i32 %x)
> +; CHECK: Function Attrs: nofree nosync nounwind
> define void @f(i32 %x) {
> +; CHECK-LABEL: define {{[^@]+}}@f
> +; CHECK-SAME: (i32 [[X:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[X_ADDR:%.*]] = alloca i32, align 4
> +; CHECK-NEXT: store i32 [[X]], i32* [[X_ADDR]], align 4
> +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
> +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
> +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: call void @g()
> +; CHECK-NEXT: br label [[IF_END]]
> +; CHECK: if.end:
> +; CHECK-NEXT: ret void
> +;
> entry:
> %x.addr = alloca i32, align 4
> store i32 %x, i32* %x.addr, align 4
> @@ -110,39 +162,57 @@ if.end:
> ret void
> }
>
> -; ATTRIBUTOR: define void @g()
> define void @g() norecurse {
> +; CHECK-LABEL: define {{[^@]+}}@g()
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: call void @f(i32 0)
> +; CHECK-NEXT: ret void
> +;
> entry:
> call void @f(i32 0)
> ret void
> }
>
> -; ATTRIBUTOR-NOT: Function Attrs
> -; ATTRIBUTOR: define linkonce_odr i32 @leaf_redefinable()
> +; CHECK-NOT: Function Attrs
> define linkonce_odr i32 @leaf_redefinable() {
> +; CHECK-LABEL: define {{[^@]+}}@leaf_redefinable()
> +; CHECK-NEXT: ret i32 1
> +;
> ret i32 1
> }
>
> ; Call through a function pointer
> -; ATTRIBUTOR-NOT: Function Attrs
> -; ATTRIBUTOR: define i32 @eval_func1(i32 (i32)* nocapture nofree nonnull
> %0, i32 %1)
> +; 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
> +; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]])
> +; CHECK-NEXT: ret i32 [[TMP3]]
> +;
> %3 = tail call i32 %0(i32 %1) #2
> ret i32 %3
> }
>
> -; ATTRIBUTOR-NOT: Function Attrs
> -; ATTRIBUTOR: define i32 @eval_func2(i32 (i32)* nocapture nofree %0, i32
> %1)
> +; CHECK-NOT: Function Attrs
> define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr
> "null-pointer-is-valid"="true"{
> +; 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]])
> +; CHECK-NEXT: ret i32 [[TMP3]]
> +;
> %3 = tail call i32 %0(i32 %1) #2
> ret i32 %3
> }
>
> -declare void @unknown()
> ; Call an unknown function in a dead block.
> -; ATTRIBUTOR_NPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
> -; ATTRIBUTOR_NPM: define i32 @call_unknown_in_dead_block()
> +; CHECK_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
> +;
> ret i32 0
> Dead:
> tail call void @unknown()
>
> diff --git a/llvm/test/Transforms/Attributor/noreturn.ll
> b/llvm/test/Transforms/Attributor/noreturn.ll
> index 06e2cc4570ad..864769dc3454 100644
> --- a/llvm/test/Transforms/Attributor/noreturn.ll
> +++ b/llvm/test/Transforms/Attributor/noreturn.ll
> @@ -1,4 +1,8 @@
> -; RUN: opt -functionattrs -attributor -attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=1 -S < %s | FileCheck %s
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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 cases specifically designed for the "no-return" function attribute.
> ; We use FIXME's to indicate problems and missing attributes.
> @@ -12,10 +16,13 @@ target datalayout =
> "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> ; return srec0();
> ; }
> ;
> -; CHECK: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; CHECK: define void @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
> +;
> entry:
> call void @srec0()
> ret void
> @@ -28,10 +35,16 @@ entry:
> ; return
> srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(a))))))))))))))));
> ; }
> ;
> -; CHECK: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; CHECK: define i32 @srec16(i32 %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
> +;
> entry:
> %call = call i32 @srec16(i32 %a)
> %call1 = call i32 @srec16(i32 %call)
> @@ -62,10 +75,16 @@ exit:
> ; while (1);
> ; }
> ;
> -; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync
> nounwind readnone uwtable
> -; CHECK: define i32 @endless_loop(i32 %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 @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]]
> +;
> entry:
> br label %while.body
>
> @@ -82,10 +101,18 @@ while.body: ;
> preds = %entry, %while.body
> ; }
> ;
> ; FIXME: no-return missing (D65243 should fix this)
> -; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync
> nounwind readnone uwtable
> -; CHECK: define i32 @dead_return(i32 returned %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 @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
> +;
> entry:
> br label %while.body
>
> @@ -103,10 +130,21 @@ return: ;
> No predecessors!
> ; return a == 0 ? endless_loop(a) : srec16(a);
> ; }
> ;
> -; CHECK: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; CHECK: define i32 @multiple_noreturn_calls(i32 %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
> +;
> entry:
> %cmp = icmp eq i32 %a, 0
> br i1 %cmp, label %cond.true, label %cond.false
> @@ -128,9 +166,15 @@ 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.
>
> -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind
> readnone willreturn
> -; CHECK-NEXT: define i32 @endless_loop_but_willreturn
> +; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone
> willreturn
> +; 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]]
> +;
> entry:
> br label %while.body
>
> @@ -139,9 +183,13 @@ while.body: ;
> preds = %entry, %while.body
> }
>
> ; TEST 6b: willreturn means *not* no-return or UB
> -; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind
> readnone willreturn
> -; CHECK-NEXT: define i32 @UB_and_willreturn
> +; IS__TUNIT____: Function Attrs: nofree noreturn nosync nounwind readnone
> willreturn
> +; 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
> +;
> entry:
> unreachable
> }
>
> diff --git a/llvm/test/Transforms/Attributor/nosync.ll
> b/llvm/test/Transforms/Attributor/nosync.ll
> index b23848e7ead0..7b7ba562544a 100644
> --- a/llvm/test/Transforms/Attributor/nosync.ll
> +++ b/llvm/test/Transforms/Attributor/nosync.ll
> @@ -1,4 +1,8 @@
> -; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s |
> FileCheck %s --check-prefix=ATTRIBUTOR
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>
> ; Test cases designed for the nosync function attribute.
> @@ -24,9 +28,15 @@ 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 }
>
> -; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp
> uwtable
> -; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* nofree readnone
> "no-capture-maybe-returned" %s)
> +; 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]]
> +;
> entry:
> %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1,
> i32 2, i32 1, i64 5, i64 13
> ret i32* %arrayidx
> @@ -39,9 +49,14 @@ entry:
> ; return n;
> ; }
>
> -; ATTRIBUTOR: Function Attrs: argmemonly nofree norecurse nosync nounwind
> uwtable
> -; ATTRIBUTOR-NEXT: define i32 @load_monotonic(i32* nocapture nofree
> nonnull readonly align 4 dereferenceable(4) %0)
> +; 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-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
> +; CHECK-NEXT: ret i32 [[TMP2]]
> +;
> %2 = load atomic i32, i32* %0 monotonic, align 4
> ret i32 %2
> }
> @@ -53,9 +68,14 @@ define i32 @load_monotonic(i32* nocapture readonly %0)
> norecurse nounwind uwtabl
> ; atomic_load_explicit(num, memory_order_relaxed);
> ; }
>
> -; ATTRIBUTOR: Function Attrs: argmemonly nofree norecurse nosync nounwind
> uwtable
> -; ATTRIBUTOR-NEXT: define void @store_monotonic(i32* nocapture nofree
> nonnull writeonly align 4 dereferenceable(4) %0)
> +; 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-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
> +; CHECK-NEXT: ret void
> +;
> store atomic i32 10, i32* %0 monotonic, align 4
> ret void
> }
> @@ -67,10 +87,15 @@ define void @store_monotonic(i32* nocapture %0)
> norecurse nounwind uwtable {
> ; return n;
> ; }
>
> -; ATTRIBUTOR: Function Attrs: argmemonly nofree norecurse nounwind uwtable
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR-NEXT: define i32 @load_acquire(i32* nocapture nofree nonnull
> readonly align 4 dereferenceable(4) %0)
> +; 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-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
> +; CHECK-NEXT: ret i32 [[TMP2]]
> +;
> %2 = load atomic i32, i32* %0 acquire, align 4
> ret i32 %2
> }
> @@ -81,20 +106,30 @@ define i32 @load_acquire(i32* nocapture readonly %0)
> norecurse nounwind uwtable
> ; atomic_store_explicit(num, 10, memory_order_release);
> ; }
>
> -; ATTRIBUTOR: Function Attrs: argmemonly nofree norecurse nounwind uwtable
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR-NEXT: define void @load_release(i32* nocapture nofree
> writeonly align 4 %0)
> +; 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-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
> +; CHECK-NEXT: ret void
> +;
> store atomic volatile i32 10, i32* %0 release, align 4
> ret void
> }
>
> ; TEST 6 - negative volatile, relaxed atomic
>
> -; ATTRIBUTOR: Function Attrs: argmemonly nofree norecurse nounwind uwtable
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR-NEXT: define void @load_volatile_release(i32* nocapture
> nofree writeonly align 4 %0)
> +; 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-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
> +; CHECK-NEXT: ret void
> +;
> store atomic volatile i32 10, i32* %0 release, align 4
> ret void
> }
> @@ -105,10 +140,15 @@ define void @load_volatile_release(i32* nocapture
> %0) norecurse nounwind uwtable
> ; *num = 14;
> ; }
>
> -; ATTRIBUTOR: Function Attrs: argmemonly nofree norecurse nounwind uwtable
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR-NEXT: define void @volatile_store(i32* nofree align 4 %0)
> +; 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-LABEL: define {{[^@]+}}@volatile_store
> +; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]])
> +; CHECK-NEXT: store volatile i32 14, i32* [[TMP0]], align 4
> +; CHECK-NEXT: ret void
> +;
> store volatile i32 14, i32* %0, align 4
> ret void
> }
> @@ -120,37 +160,50 @@ define void @volatile_store(i32* %0) norecurse
> nounwind uwtable {
> ; return n;
> ; }
>
> -; ATTRIBUTOR: Function Attrs: argmemonly nofree norecurse nounwind uwtable
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR-NEXT: define i32 @volatile_load(i32* nofree align 4 %0)
> +; 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-LABEL: define {{[^@]+}}@volatile_load
> +; CHECK-SAME: (i32* nofree align 4 [[TMP0:%.*]])
> +; CHECK-NEXT: [[TMP2:%.*]] = load volatile i32, i32* [[TMP0]], align 4
> +; CHECK-NEXT: ret i32 [[TMP2]]
> +;
> %2 = load volatile i32, i32* %0, align 4
> ret i32 %2
> }
>
> ; TEST 9
>
> -; ATTRIBUTOR: Function Attrs: noinline nosync nounwind uwtable
> -; ATTRIBUTOR-NEXT: declare void @nosync_function()
> +; CHECK: Function Attrs: noinline nosync nounwind uwtable
> +; CHECK-NEXT: declare void @nosync_function()
> declare void @nosync_function() noinline nounwind uwtable nosync
>
> -; ATTRIBUTOR: Function Attrs: noinline nosync nounwind uwtable
> -; ATTRIBUTOR-next: define void @call_nosync_function()
> +; 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-LABEL: define {{[^@]+}}@call_nosync_function()
> +; CHECK-NEXT: tail call void @nosync_function()
> +; CHECK-NEXT: ret void
> +;
> tail call void @nosync_function() noinline nounwind uwtable
> ret void
> }
>
> ; TEST 10 - negative, should not deduce nosync
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NEXT: declare void @might_sync()
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NEXT: declare void @might_sync()
> declare void @might_sync() noinline nounwind uwtable
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR-NEXT: define void @call_might_sync()
> +; 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-LABEL: define {{[^@]+}}@call_might_sync()
> +; CHECK-NEXT: tail call void @might_sync()
> +; CHECK-NEXT: ret void
> +;
> tail call void @might_sync() noinline nounwind uwtable
> ret void
> }
> @@ -158,17 +211,27 @@ 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.
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; ATTRIBUTOR-NEXT: define i32 @scc1(i32* nocapture nofree readnone %0)
> +; 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
> +;
> tail call void @scc2(i32* %0);
> %val = tail call i32 @volatile_load(i32* %0);
> ret i32 %val;
> }
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; ATTRIBUTOR-NEXT: define void @scc2(i32* nocapture nofree readnone %0)
> +; 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
> +;
> tail call i32 @scc1(i32* %0);
> ret void;
> }
> @@ -192,10 +255,16 @@ define void @scc2(i32* %0) noinline nounwind uwtable
> {
> %"struct.std::atomic" = type { %"struct.std::__atomic_base" }
> %"struct.std::__atomic_base" = type { i8 }
>
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR: define void @foo1(i32* nocapture nofree nonnull writeonly
> align 4 dereferenceable(4) %0, %"struct.std::atomic"* nocapture nofree
> nonnull writeonly dereferenceable(1) %1)
> -
> +; 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
> +;
> store i32 100, i32* %0, align 4
> fence release
> %3 = getelementptr inbounds %"struct.std::atomic",
> %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
> @@ -203,9 +272,21 @@ define void @foo1(i32* %0, %"struct.std::atomic"* %1)
> {
> ret void
> }
>
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR: define void @bar(i32* nocapture nofree readnone %0,
> %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1)
> %1)
> +; 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
> +;
> %3 = getelementptr inbounds %"struct.std::atomic",
> %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
> br label %4
>
> @@ -221,10 +302,17 @@ define void @bar(i32* %0, %"struct.std::atomic"* %1)
> {
> }
>
> ; TEST 13 - Fence syncscope("singlethread") seq_cst
> -; ATTRIBUTOR: Function Attrs: nofree nosync nounwind willreturn
> -; ATTRIBUTOR: define void @foo1_singlethread(i32* nocapture nofree
> nonnull writeonly align 4 dereferenceable(4) %0, %"struct.std::atomic"*
> nocapture nofree nonnull writeonly dereferenceable(1) %1)
> -
> +; IS__TUNIT____: Function Attrs: nofree nosync nounwind willreturn
> +; 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
> +;
> store i32 100, i32* %0, align 4
> fence syncscope("singlethread") release
> %3 = getelementptr inbounds %"struct.std::atomic",
> %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
> @@ -232,9 +320,22 @@ define void @foo1_singlethread(i32* %0,
> %"struct.std::atomic"* %1) {
> ret void
> }
>
> -; ATTRIBUTOR: Function Attrs: nofree nosync nounwind
> -; ATTRIBUTOR: define void @bar_singlethread(i32* nocapture nofree
> readnone %0, %"struct.std::atomic"* nocapture nofree nonnull readonly
> dereferenceable(1) %1)
> +; IS__TUNIT____: Function Attrs: nofree nosync nounwind
> +; 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
> +;
> %3 = getelementptr inbounds %"struct.std::atomic",
> %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
> br label %4
>
> @@ -256,10 +357,15 @@ 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.
> ;
> -; ATTRIBUTOR: Function Attrs: argmemonly nounwind
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR-NEXT: define i32 @memcpy_volatile(i8* nocapture writeonly
> %ptr1, i8* nocapture readonly %ptr2)
> +; IS__TUNIT____: Function Attrs: argmemonly nounwind
> +; IS__CGSCC____: Function Attrs: argmemonly nounwind
> +; CHECK-NOT: nosync
> define i32 @memcpy_volatile(i8* %ptr1, i8* %ptr2) {
> +; 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)
> +; CHECK-NEXT: ret i32 4
> +;
> call void @llvm.memcpy(i8* %ptr1, i8* %ptr2, i32 8, i1 1)
> ret i32 4
> }
> @@ -268,41 +374,57 @@ define i32 @memcpy_volatile(i8* %ptr1, i8* %ptr2) {
>
> ; It is odd to add nocapture but a result of the llvm.memset nocapture.
> ;
> -; ATTRIBUTOR: Function Attrs: argmemonly nosync
> -; ATTRIBUTOR-NEXT: define i32 @memset_non_volatile(i8* nocapture
> writeonly %ptr1, i8 %val)
> +; IS__TUNIT____: Function Attrs: argmemonly nosync
> +; IS__CGSCC____: Function Attrs: argmemonly nosync
> define i32 @memset_non_volatile(i8* %ptr1, i8 %val) {
> +; 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)
> +; CHECK-NEXT: ret i32 4
> +;
> call void @llvm.memset(i8* %ptr1, i8 %val, i32 8, i1 0)
> ret i32 4
> }
>
> ; TEST 16 - negative, inline assembly.
>
> -; ATTRIBUTOR: define i32 @inline_asm_test(i32 %x)
> define i32 @inline_asm_test(i32 %x) {
> +; CHECK-LABEL: define {{[^@]+}}@inline_asm_test
> +; CHECK-SAME: (i32 [[X:%.*]])
> +; CHECK-NEXT: [[TMP1:%.*]] = call i32 asm "bswap $0", "=r,r"(i32 [[X]])
> +; CHECK-NEXT: ret i32 4
> +;
> call i32 asm "bswap $0", "=r,r"(i32 %x)
> ret i32 4
> }
>
> declare void @readnone_test() convergent readnone
>
> -; ATTRIBUTOR: define void @convergent_readnone()
> ; TEST 17 - negative. Convergent
> define void @convergent_readnone(){
> - call void @readnone_test()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@convergent_readnone()
> +; CHECK-NEXT: call void @readnone_test()
> +; CHECK-NEXT: ret void
> +;
> + call void @readnone_test()
> + ret void
> }
>
> -; ATTRIBUTOR: Function Attrs: nounwind
> -; ATTRIBUTOR-NEXT: declare void @llvm.x86.sse2.clflush(i8*)
> +; CHECK: Function Attrs: nounwind
> +; CHECK-NEXT: declare void @llvm.x86.sse2.clflush(i8*)
> declare void @llvm.x86.sse2.clflush(i8*)
> @a = common global i32 0, align 4
>
> ; TEST 18 - negative. Synchronizing intrinsic
>
> -; ATTRIBUTOR: Function Attrs: nounwind
> -; ATTRIBUTOR-NOT: nosync
> -; ATTRIBUTOR-NEXT: define void @i_totally_sync()
> +; IS__TUNIT____: Function Attrs: nounwind
> +; IS__CGSCC____: Function Attrs: nounwind
> +; CHECK-NOT: nosync
> define void @i_totally_sync() {
> +; 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
> +;
> tail call void @llvm.x86.sse2.clflush(i8* bitcast (i32* @a to i8*))
> ret void
> }
> @@ -311,16 +433,25 @@ declare float @llvm.cos(float %val) readnone
>
> ; TEST 19 - positive, readnone & non-convergent intrinsic.
>
> -; ATTRIBUTOR: Function Attrs: nofree nosync nounwind readnone willreturn
> -; ATTRIBUTOR-NEXT: define i32 @cos_test(float %x)
> +; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
> willreturn
> +; 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
> +;
> call float @llvm.cos(float %x)
> ret i32 4
> }
>
> -; ATTRIBUTOR: Function Attrs: nosync nounwind
> -; ATTRIBUTOR-NEXT: define float @cos_test2(float %x)
> +; IS__TUNIT____: Function Attrs: nosync nounwind
> +; IS__CGSCC____: Function Attrs: nosync nounwind
> define float @cos_test2(float %x) {
> +; CHECK-LABEL: define {{[^@]+}}@cos_test2
> +; CHECK-SAME: (float [[X:%.*]])
> +; CHECK-NEXT: [[C:%.*]] = call float @llvm.cos.f32(float [[X]])
> +; CHECK-NEXT: ret float [[C]]
> +;
> %c = call float @llvm.cos(float %x)
> ret float %c
> }
>
> diff --git a/llvm/test/Transforms/Attributor/nounwind.ll
> b/llvm/test/Transforms/Attributor/nounwind.ll
> index e569095c8d41..a2f86d318e6c 100644
> --- a/llvm/test/Transforms/Attributor/nounwind.ll
> +++ b/llvm/test/Transforms/Attributor/nounwind.ll
> @@ -1,26 +1,40 @@
> -; RUN: opt < %s -attributor -attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=3 -S | FileCheck %s --check-prefix=ATTRIBUTOR
> -; Copied from Transforms/FunctoinAttrs/nounwind.ll
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> -; ATTRIBUTOR: Function Attrs: nofree nosync nounwind
> -; ATTRIBUTOR-NEXT: define i32 @foo1()
> +; 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
> +;
> ret i32 1
> }
>
> ; TEST 2
> -; ATTRIBUTOR: Function Attrs: nofree noreturn nosync nounwind
> -; ATTRIBUTOR-NEXT: define i32 @scc1_foo()
> +; 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
> +;
> %1 = call i32 @scc1_bar()
> ret i32 1
> }
>
>
> ; TEST 3
> -; ATTRIBUTOR: Function Attrs: nofree noreturn nosync nounwind
> -; ATTRIBUTOR-NEXT: define i32 @scc1_bar()
> +; 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
> +;
> %1 = call i32 @scc1_foo()
> ret i32 1
> }
> @@ -28,10 +42,13 @@ define i32 @scc1_bar() {
> declare i32 @non_nounwind()
>
> ; TEST 4
> -; ATTRIBUTOR: define void @call_non_nounwind() {
> define void @call_non_nounwind(){
> - tail call i32 @non_nounwind()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@call_non_nounwind()
> +; CHECK-NEXT: [[TMP1:%.*]] = tail call i32 @non_nounwind()
> +; CHECK-NEXT: ret void
> +;
> + tail call i32 @non_nounwind()
> + ret void
> }
>
> ; TEST 5 - throw
> @@ -42,8 +59,16 @@ define void @call_non_nounwind(){
> ; return -1;
> ; }
>
> -; ATTRIBUTOR: define i32 @maybe_throw(i1 zeroext %0)
> define i32 @maybe_throw(i1 zeroext %0) {
> +; CHECK-LABEL: define {{[^@]+}}@maybe_throw
> +; CHECK-SAME: (i1 zeroext [[TMP0:%.*]])
> +; CHECK-NEXT: br i1 [[TMP0]], label [[TMP2:%.*]], label [[TMP3:%.*]]
> +; CHECK: 2:
> +; CHECK-NEXT: tail call void @__cxa_rethrow()
> +; CHECK-NEXT: unreachable
> +; CHECK: 3:
> +; CHECK-NEXT: ret i32 -1
> +;
> br i1 %0, label %2, label %3
>
> 2: ; preds = %1
> @@ -65,17 +90,29 @@ declare void @__cxa_rethrow()
> ; return 1;
> ; }
>
> -; ATTRIBUTOR: define i32 @catch_thing()
> define i32 @catch_thing() personality i8* bitcast (i32 (...)*
> @__gxx_personality_v0 to i8*) {
> +; CHECK-LABEL: define {{[^@]+}}@catch_thing() personality i8* bitcast
> (i32 (...)* @__gxx_personality_v0 to i8*)
> +; CHECK-NEXT: invoke void @__cxa_rethrow()
> +; CHECK-NEXT: to label [[TMP1:%.*]] unwind label [[TMP2:%.*]]
> +; CHECK: 1:
> +; CHECK-NEXT: unreachable
> +; CHECK: 2:
> +; CHECK-NEXT: [[TMP3:%.*]] = landingpad { i8*, i32 }
> +; CHECK-NEXT: catch i8* null
> +; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i8*, i32 } [[TMP3]], 0
> +; CHECK-NEXT: [[TMP5:%.*]] = tail call i8* @__cxa_begin_catch(i8*
> [[TMP4]])
> +; CHECK-NEXT: tail call void @__cxa_end_catch()
> +; CHECK-NEXT: ret i32 -1
> +;
> invoke void @__cxa_rethrow() #1
> - to label %1 unwind label %2
> + to label %1 unwind label %2
>
> 1: ; preds = %0
> unreachable
>
> 2: ; preds = %0
> %3 = landingpad { i8*, i32 }
> - catch i8* null
> + catch i8* null
> %4 = extractvalue { i8*, i32 } %3, 0
> %5 = tail call i8* @__cxa_begin_catch(i8* %4) #2
> tail call void @__cxa_end_catch()
> @@ -83,9 +120,10 @@ define i32 @catch_thing() personality i8* bitcast (i32
> (...)* @__gxx_personality
> }
>
> define i32 @catch_thing_user() {
> -; ATTRIBUTOR: define i32 @catch_thing_user
> -; ATTRIBUTOR-NEXT: %catch_thing_call = call
> -; ATTRIBUTOR-NEXT: ret i32 -1
> +; CHECK-LABEL: define {{[^@]+}}@catch_thing_user()
> +; CHECK-NEXT: [[CATCH_THING_CALL:%.*]] = call i32 @catch_thing()
> +; CHECK-NEXT: ret i32 -1
> +;
> %catch_thing_call = call i32 @catch_thing()
> ret i32 %catch_thing_call
> }
>
> diff --git a/llvm/test/Transforms/Attributor/range.ll
> b/llvm/test/Transforms/Attributor/range.ll
> index efb2df556af6..e345b969d554 100644
> --- a/llvm/test/Transforms/Attributor/range.ll
> +++ b/llvm/test/Transforms/Attributor/range.ll
> @@ -1,8 +1,8 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -attributor -attributor-disable=false -S < %s | FileCheck %s
> --check-prefixes=CHECK,OLD_PM,MODULE_OLD_PM
> -; RUN: opt -passes=attributor -attributor-disable=false -S < %s |
> FileCheck %s --check-prefixes=CHECK,NEW_PM,MODULE_NEW_PM
> -; RUN: opt -attributor-cgscc -attributor-disable=false -S < %s |
> FileCheck %s --check-prefixes=CHECK,CGSCC_OLD_PM
> -; RUN: opt -passes=attributor-cgscc -attributor-disable=false -S < %s |
> FileCheck %s --check-prefixes=CHECK,CGSCC_NEW_PM
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> ; FIXME: CGSCC is not looking at callees and calleers even though it
> could be allowed.
>
> @@ -17,26 +17,15 @@ define i32 @test0(i32* %p) {
> }
>
> define i32 @test0-range-check(i32* %p) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test0-range-check
> +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> +; IS__TUNIT____-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture
> nofree readonly align 4 [[P]]) #4, !range !0
> +; IS__TUNIT____-NEXT: ret i32 [[A]]
> ;
> -; OLD_PM-LABEL: define {{[^@]+}}@test0-range-check
> -; OLD_PM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> -; OLD_PM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree
> readonly align 4 [[P]]) #{{[0-9]+}}, !range !0
> -; OLD_PM-NEXT: ret i32 [[A]]
> -;
> -; NEW_PM-LABEL: define {{[^@]+}}@test0-range-check
> -; NEW_PM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> -; NEW_PM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture nofree
> readonly align 4 [[P]]) #{{[0-9]+}}, !range !0
> -; NEW_PM-NEXT: ret i32 [[A]]
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@test0-range-check
> -; CGSCC_OLD_PM-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> -; CGSCC_OLD_PM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture
> nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> -; CGSCC_OLD_PM-NEXT: ret i32 [[A]]
> -;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@test0-range-check
> -; CGSCC_NEW_PM-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> -; CGSCC_NEW_PM-NEXT: [[A:%.*]] = tail call i32 @test0(i32* nocapture
> nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> -; CGSCC_NEW_PM-NEXT: ret i32 [[A]]
> +; 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]])
> +; IS__CGSCC____-NEXT: ret i32 [[A]]
> ;
> %a = tail call i32 @test0(i32* %p)
> ret i32 %a
> @@ -55,235 +44,121 @@ define void @use3(i1, i1, i1) {
>
> ; TEST0 icmp test
> define void @test0-icmp-check(i32* %p){
> -; OLD_PM-LABEL: define {{[^@]+}}@test0-icmp-check
> -; OLD_PM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> -; OLD_PM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture
> nofree readonly align 4 [[P]]) #{{[0-9]+}}, !range !0
> -; OLD_PM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
> -; OLD_PM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
> -; OLD_PM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
> -; OLD_PM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
> -; OLD_PM-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]], i1
> [[CMP_EQ_3]])
> -; OLD_PM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]],
> i1 false)
> -; OLD_PM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
> -; OLD_PM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
> -; OLD_PM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
> -; OLD_PM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
> -; OLD_PM-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]], i1
> [[CMP_NE_3]])
> -; OLD_PM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]],
> i1 true)
> -; OLD_PM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
> -; OLD_PM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
> -; OLD_PM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
> -; OLD_PM-NEXT: tail call void @use3(i1 false, i1 false, i1
> [[CMP_UGT_3]])
> -; OLD_PM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1
> [[CMP_UGT_5]], i1 false)
> -; OLD_PM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
> -; OLD_PM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
> -; OLD_PM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
> -; OLD_PM-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1
> [[CMP_UGE_3]])
> -; OLD_PM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1
> false)
> -; OLD_PM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
> -; OLD_PM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
> -; OLD_PM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
> -; OLD_PM-NEXT: tail call void @use3(i1 false, i1 false, i1
> [[CMP_SGT_3]])
> -; OLD_PM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1
> [[CMP_SGT_5]], i1 true)
> -; OLD_PM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
> -; OLD_PM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
> -; OLD_PM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
> -; OLD_PM-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1
> [[CMP_GTE_3]])
> -; OLD_PM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 true)
> -; OLD_PM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
> -; OLD_PM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
> -; OLD_PM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
> -; OLD_PM-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1
> [[CMP_SLT_3]])
> -; OLD_PM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1
> false)
> -; OLD_PM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
> -; OLD_PM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
> -; OLD_PM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
> -; OLD_PM-NEXT: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]])
> -; OLD_PM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1
> [[CMP_LTE_5]], i1 false)
> -; OLD_PM-NEXT: ret void
> -;
> -; NEW_PM-LABEL: define {{[^@]+}}@test0-icmp-check
> -; NEW_PM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> -; NEW_PM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture
> nofree readonly align 4 [[P]]) #{{[0-9]+}}, !range !0
> -; NEW_PM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
> -; NEW_PM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
> -; NEW_PM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
> -; NEW_PM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
> -; NEW_PM-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]], i1
> [[CMP_EQ_3]])
> -; NEW_PM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1 [[CMP_EQ_5]],
> i1 false)
> -; NEW_PM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
> -; NEW_PM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
> -; NEW_PM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
> -; NEW_PM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
> -; NEW_PM-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]], i1
> [[CMP_NE_3]])
> -; NEW_PM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1 [[CMP_NE_5]],
> i1 true)
> -; NEW_PM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
> -; NEW_PM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
> -; NEW_PM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
> -; NEW_PM-NEXT: tail call void @use3(i1 false, i1 false, i1
> [[CMP_UGT_3]])
> -; NEW_PM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1
> [[CMP_UGT_5]], i1 false)
> -; NEW_PM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
> -; NEW_PM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
> -; NEW_PM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
> -; NEW_PM-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]], i1
> [[CMP_UGE_3]])
> -; NEW_PM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true, i1
> false)
> -; NEW_PM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
> -; NEW_PM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
> -; NEW_PM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
> -; NEW_PM-NEXT: tail call void @use3(i1 false, i1 false, i1
> [[CMP_SGT_3]])
> -; NEW_PM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1
> [[CMP_SGT_5]], i1 true)
> -; NEW_PM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
> -; NEW_PM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
> -; NEW_PM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
> -; NEW_PM-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]], i1
> [[CMP_GTE_3]])
> -; NEW_PM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true, i1 true)
> -; NEW_PM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
> -; NEW_PM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
> -; NEW_PM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
> -; NEW_PM-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]], i1
> [[CMP_SLT_3]])
> -; NEW_PM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false, i1
> false)
> -; NEW_PM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
> -; NEW_PM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
> -; NEW_PM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
> -; NEW_PM-NEXT: tail call void @use3(i1 true, i1 true, i1 [[CMP_LTE_3]])
> -; NEW_PM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1
> [[CMP_LTE_5]], i1 false)
> -; NEW_PM-NEXT: ret void
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@test0-icmp-check
> -; CGSCC_OLD_PM-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> -; CGSCC_OLD_PM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture
> nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> -; CGSCC_OLD_PM-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
> -; CGSCC_OLD_PM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
> -; CGSCC_OLD_PM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
> -; CGSCC_OLD_PM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
> -; CGSCC_OLD_PM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
> -; CGSCC_OLD_PM-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1
> [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1
> [[CMP_EQ_5]], i1 [[CMP_EQ_6]])
> -; CGSCC_OLD_PM-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10
> -; CGSCC_OLD_PM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
> -; CGSCC_OLD_PM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
> -; CGSCC_OLD_PM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
> -; CGSCC_OLD_PM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
> -; CGSCC_OLD_PM-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1
> [[CMP_NE_2]], i1 [[CMP_NE_3]])
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1
> [[CMP_NE_5]], i1 [[CMP_NE_6]])
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1
> [[CMP_UGT_2]], i1 [[CMP_UGT_3]])
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1
> [[CMP_UGT_5]], i1 false)
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
> -; CGSCC_OLD_PM-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1
> [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true,
> i1 [[CMP_UGE_6]])
> -; CGSCC_OLD_PM-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10
> -; CGSCC_OLD_PM-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9
> -; CGSCC_OLD_PM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
> -; CGSCC_OLD_PM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
> -; CGSCC_OLD_PM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
> -; CGSCC_OLD_PM-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1
> [[CMP_SGT_2]], i1 [[CMP_SGT_3]])
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1
> [[CMP_SGT_5]], i1 [[CMP_SGT_6]])
> -; CGSCC_OLD_PM-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10
> -; CGSCC_OLD_PM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
> -; CGSCC_OLD_PM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
> -; CGSCC_OLD_PM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
> -; CGSCC_OLD_PM-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0
> -; CGSCC_OLD_PM-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1
> [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1
> [[CMP_GTE_5]], i1 [[CMP_GTE_6]])
> -; CGSCC_OLD_PM-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10
> -; CGSCC_OLD_PM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
> -; CGSCC_OLD_PM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
> -; CGSCC_OLD_PM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
> -; CGSCC_OLD_PM-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0
> -; CGSCC_OLD_PM-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1
> [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1
> [[CMP_SLT_5]], i1 [[CMP_SLT_6]])
> -; CGSCC_OLD_PM-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10
> -; CGSCC_OLD_PM-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9
> -; CGSCC_OLD_PM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
> -; CGSCC_OLD_PM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
> -; CGSCC_OLD_PM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
> -; CGSCC_OLD_PM-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1
> [[CMP_LTE_2]], i1 [[CMP_LTE_3]])
> -; CGSCC_OLD_PM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1
> [[CMP_LTE_5]], i1 [[CMP_LTE_6]])
> -; CGSCC_OLD_PM-NEXT: ret void
> -;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@test0-icmp-check
> -; CGSCC_NEW_PM-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> -; CGSCC_NEW_PM-NEXT: [[RET:%.*]] = tail call i32 @test0(i32* nocapture
> nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> -; CGSCC_NEW_PM-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
> -; CGSCC_NEW_PM-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
> -; CGSCC_NEW_PM-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
> -; CGSCC_NEW_PM-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
> -; CGSCC_NEW_PM-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
> -; CGSCC_NEW_PM-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1
> [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1
> [[CMP_EQ_5]], i1 [[CMP_EQ_6]])
> -; CGSCC_NEW_PM-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10
> -; CGSCC_NEW_PM-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
> -; CGSCC_NEW_PM-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
> -; CGSCC_NEW_PM-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
> -; CGSCC_NEW_PM-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
> -; CGSCC_NEW_PM-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1
> [[CMP_NE_2]], i1 [[CMP_NE_3]])
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1
> [[CMP_NE_5]], i1 [[CMP_NE_6]])
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1
> [[CMP_UGT_2]], i1 [[CMP_UGT_3]])
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1
> [[CMP_UGT_5]], i1 false)
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
> -; CGSCC_NEW_PM-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1
> [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true,
> i1 [[CMP_UGE_6]])
> -; CGSCC_NEW_PM-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10
> -; CGSCC_NEW_PM-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9
> -; CGSCC_NEW_PM-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
> -; CGSCC_NEW_PM-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
> -; CGSCC_NEW_PM-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
> -; CGSCC_NEW_PM-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1
> [[CMP_SGT_2]], i1 [[CMP_SGT_3]])
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1
> [[CMP_SGT_5]], i1 [[CMP_SGT_6]])
> -; CGSCC_NEW_PM-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10
> -; CGSCC_NEW_PM-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
> -; CGSCC_NEW_PM-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
> -; CGSCC_NEW_PM-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
> -; CGSCC_NEW_PM-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0
> -; CGSCC_NEW_PM-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1
> [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1
> [[CMP_GTE_5]], i1 [[CMP_GTE_6]])
> -; CGSCC_NEW_PM-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10
> -; CGSCC_NEW_PM-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
> -; CGSCC_NEW_PM-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
> -; CGSCC_NEW_PM-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
> -; CGSCC_NEW_PM-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0
> -; CGSCC_NEW_PM-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1
> [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1
> [[CMP_SLT_5]], i1 [[CMP_SLT_6]])
> -; CGSCC_NEW_PM-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10
> -; CGSCC_NEW_PM-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9
> -; CGSCC_NEW_PM-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
> -; CGSCC_NEW_PM-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
> -; CGSCC_NEW_PM-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
> -; CGSCC_NEW_PM-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1
> [[CMP_LTE_2]], i1 [[CMP_LTE_3]])
> -; CGSCC_NEW_PM-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1
> [[CMP_LTE_5]], i1 [[CMP_LTE_6]])
> -; CGSCC_NEW_PM-NEXT: ret void
> -;
> ; ret = [0, 10)
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test0-icmp-check
> +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> +; IS__TUNIT____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32*
> nocapture nofree readonly align 4 [[P]]) #4, !range !0
> +; IS__TUNIT____-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
> +; IS__TUNIT____-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
> +; IS__TUNIT____-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
> +; IS__TUNIT____-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 [[CMP_EQ_2]],
> i1 [[CMP_EQ_3]])
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1
> [[CMP_EQ_5]], i1 false)
> +; IS__TUNIT____-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
> +; IS__TUNIT____-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
> +; IS__TUNIT____-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
> +; IS__TUNIT____-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 true, i1 [[CMP_NE_2]],
> i1 [[CMP_NE_3]])
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1
> [[CMP_NE_5]], i1 true)
> +; IS__TUNIT____-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
> +; IS__TUNIT____-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
> +; IS__TUNIT____-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 false, i1
> [[CMP_UGT_3]])
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1
> [[CMP_UGT_5]], i1 false)
> +; IS__TUNIT____-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
> +; IS__TUNIT____-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
> +; IS__TUNIT____-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 [[CMP_UGE_2]],
> i1 [[CMP_UGE_3]])
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true,
> i1 false)
> +; IS__TUNIT____-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
> +; IS__TUNIT____-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
> +; IS__TUNIT____-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 false, i1
> [[CMP_SGT_3]])
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1
> [[CMP_SGT_5]], i1 true)
> +; IS__TUNIT____-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
> +; IS__TUNIT____-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
> +; IS__TUNIT____-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 false, i1 [[CMP_GTE_2]],
> i1 [[CMP_GTE_3]])
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1 true,
> i1 true)
> +; IS__TUNIT____-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
> +; IS__TUNIT____-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
> +; IS__TUNIT____-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 true, i1 [[CMP_SLT_2]],
> i1 [[CMP_SLT_3]])
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1 false,
> i1 false)
> +; IS__TUNIT____-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
> +; IS__TUNIT____-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
> +; IS__TUNIT____-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 true, i1 true, i1
> [[CMP_LTE_3]])
> +; IS__TUNIT____-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1
> [[CMP_LTE_5]], i1 false)
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test0-icmp-check
> +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> +; IS__CGSCC____-NEXT: [[RET:%.*]] = tail call i32 @test0(i32*
> nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> +; IS__CGSCC____-NEXT: [[CMP_EQ_1:%.*]] = icmp eq i32 [[RET]], 10
> +; IS__CGSCC____-NEXT: [[CMP_EQ_2:%.*]] = icmp eq i32 [[RET]], 9
> +; IS__CGSCC____-NEXT: [[CMP_EQ_3:%.*]] = icmp eq i32 [[RET]], 8
> +; IS__CGSCC____-NEXT: [[CMP_EQ_4:%.*]] = icmp eq i32 [[RET]], 1
> +; IS__CGSCC____-NEXT: [[CMP_EQ_5:%.*]] = icmp eq i32 [[RET]], 0
> +; IS__CGSCC____-NEXT: [[CMP_EQ_6:%.*]] = icmp eq i32 [[RET]], -1
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_EQ_1]], i1
> [[CMP_EQ_2]], i1 [[CMP_EQ_3]])
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_EQ_4]], i1
> [[CMP_EQ_5]], i1 [[CMP_EQ_6]])
> +; IS__CGSCC____-NEXT: [[CMP_NE_1:%.*]] = icmp ne i32 [[RET]], 10
> +; IS__CGSCC____-NEXT: [[CMP_NE_2:%.*]] = icmp ne i32 [[RET]], 9
> +; IS__CGSCC____-NEXT: [[CMP_NE_3:%.*]] = icmp ne i32 [[RET]], 8
> +; IS__CGSCC____-NEXT: [[CMP_NE_4:%.*]] = icmp ne i32 [[RET]], 1
> +; IS__CGSCC____-NEXT: [[CMP_NE_5:%.*]] = icmp ne i32 [[RET]], 0
> +; IS__CGSCC____-NEXT: [[CMP_NE_6:%.*]] = icmp ne i32 [[RET]], -1
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_NE_1]], i1
> [[CMP_NE_2]], i1 [[CMP_NE_3]])
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_NE_4]], i1
> [[CMP_NE_5]], i1 [[CMP_NE_6]])
> +; IS__CGSCC____-NEXT: [[CMP_UGT_1:%.*]] = icmp ugt i32 [[RET]], 10
> +; IS__CGSCC____-NEXT: [[CMP_UGT_2:%.*]] = icmp ugt i32 [[RET]], 9
> +; IS__CGSCC____-NEXT: [[CMP_UGT_3:%.*]] = icmp ugt i32 [[RET]], 8
> +; IS__CGSCC____-NEXT: [[CMP_UGT_4:%.*]] = icmp ugt i32 [[RET]], 1
> +; IS__CGSCC____-NEXT: [[CMP_UGT_5:%.*]] = icmp ugt i32 [[RET]], 0
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGT_1]], i1
> [[CMP_UGT_2]], i1 [[CMP_UGT_3]])
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGT_4]], i1
> [[CMP_UGT_5]], i1 false)
> +; IS__CGSCC____-NEXT: [[CMP_UGE_1:%.*]] = icmp uge i32 [[RET]], 10
> +; IS__CGSCC____-NEXT: [[CMP_UGE_2:%.*]] = icmp uge i32 [[RET]], 9
> +; IS__CGSCC____-NEXT: [[CMP_UGE_3:%.*]] = icmp uge i32 [[RET]], 8
> +; IS__CGSCC____-NEXT: [[CMP_UGE_4:%.*]] = icmp uge i32 [[RET]], 1
> +; IS__CGSCC____-NEXT: [[CMP_UGE_6:%.*]] = icmp uge i32 [[RET]], -1
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGE_1]], i1
> [[CMP_UGE_2]], i1 [[CMP_UGE_3]])
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_UGE_4]], i1 true,
> i1 [[CMP_UGE_6]])
> +; IS__CGSCC____-NEXT: [[CMP_SGT_1:%.*]] = icmp sgt i32 [[RET]], 10
> +; IS__CGSCC____-NEXT: [[CMP_SGT_2:%.*]] = icmp sgt i32 [[RET]], 9
> +; IS__CGSCC____-NEXT: [[CMP_SGT_3:%.*]] = icmp sgt i32 [[RET]], 8
> +; IS__CGSCC____-NEXT: [[CMP_SGT_4:%.*]] = icmp sgt i32 [[RET]], 1
> +; IS__CGSCC____-NEXT: [[CMP_SGT_5:%.*]] = icmp sgt i32 [[RET]], 0
> +; IS__CGSCC____-NEXT: [[CMP_SGT_6:%.*]] = icmp sgt i32 [[RET]], -1
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SGT_1]], i1
> [[CMP_SGT_2]], i1 [[CMP_SGT_3]])
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SGT_4]], i1
> [[CMP_SGT_5]], i1 [[CMP_SGT_6]])
> +; IS__CGSCC____-NEXT: [[CMP_GTE_1:%.*]] = icmp sge i32 [[RET]], 10
> +; IS__CGSCC____-NEXT: [[CMP_GTE_2:%.*]] = icmp sge i32 [[RET]], 9
> +; IS__CGSCC____-NEXT: [[CMP_GTE_3:%.*]] = icmp sge i32 [[RET]], 8
> +; IS__CGSCC____-NEXT: [[CMP_GTE_4:%.*]] = icmp sge i32 [[RET]], 1
> +; IS__CGSCC____-NEXT: [[CMP_GTE_5:%.*]] = icmp sge i32 [[RET]], 0
> +; IS__CGSCC____-NEXT: [[CMP_GTE_6:%.*]] = icmp sge i32 [[RET]], -1
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_GTE_1]], i1
> [[CMP_GTE_2]], i1 [[CMP_GTE_3]])
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_GTE_4]], i1
> [[CMP_GTE_5]], i1 [[CMP_GTE_6]])
> +; IS__CGSCC____-NEXT: [[CMP_SLT_1:%.*]] = icmp slt i32 [[RET]], 10
> +; IS__CGSCC____-NEXT: [[CMP_SLT_2:%.*]] = icmp slt i32 [[RET]], 9
> +; IS__CGSCC____-NEXT: [[CMP_SLT_3:%.*]] = icmp slt i32 [[RET]], 8
> +; IS__CGSCC____-NEXT: [[CMP_SLT_4:%.*]] = icmp slt i32 [[RET]], 1
> +; IS__CGSCC____-NEXT: [[CMP_SLT_5:%.*]] = icmp slt i32 [[RET]], 0
> +; IS__CGSCC____-NEXT: [[CMP_SLT_6:%.*]] = icmp slt i32 [[RET]], -1
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SLT_1]], i1
> [[CMP_SLT_2]], i1 [[CMP_SLT_3]])
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_SLT_4]], i1
> [[CMP_SLT_5]], i1 [[CMP_SLT_6]])
> +; IS__CGSCC____-NEXT: [[CMP_LTE_1:%.*]] = icmp sle i32 [[RET]], 10
> +; IS__CGSCC____-NEXT: [[CMP_LTE_2:%.*]] = icmp sle i32 [[RET]], 9
> +; IS__CGSCC____-NEXT: [[CMP_LTE_3:%.*]] = icmp sle i32 [[RET]], 8
> +; IS__CGSCC____-NEXT: [[CMP_LTE_4:%.*]] = icmp sle i32 [[RET]], 1
> +; IS__CGSCC____-NEXT: [[CMP_LTE_5:%.*]] = icmp sle i32 [[RET]], 0
> +; IS__CGSCC____-NEXT: [[CMP_LTE_6:%.*]] = icmp sle i32 [[RET]], -1
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_LTE_1]], i1
> [[CMP_LTE_2]], i1 [[CMP_LTE_3]])
> +; IS__CGSCC____-NEXT: tail call void @use3(i1 [[CMP_LTE_4]], i1
> [[CMP_LTE_5]], i1 [[CMP_LTE_6]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> %ret = tail call i32 @test0(i32 *%p)
>
> ; ret = [0, 10), eq
> @@ -383,29 +258,18 @@ define i32 @test1(i32* %p) {
> }
>
> define i1 @test1-check(i32* %p) {
> -; OLD_PM-LABEL: define {{[^@]+}}@test1-check
> -; OLD_PM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> -; OLD_PM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture
> nofree readonly align 4 [[P]]) #{{[0-9]+}}, !range !2
> -; OLD_PM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
> -; OLD_PM-NEXT: ret i1 [[CMP]]
> ;
> -; NEW_PM-LABEL: define {{[^@]+}}@test1-check
> -; NEW_PM-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> -; NEW_PM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture
> nofree readonly align 4 [[P]]) #{{[0-9]+}}, !range !2
> -; NEW_PM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
> -; NEW_PM-NEXT: ret i1 [[CMP]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test1-check
> +; IS__TUNIT____-SAME: (i32* nocapture nofree readonly align 4 [[P:%.*]])
> +; IS__TUNIT____-NEXT: [[RES:%.*]] = tail call i32 @test1(i32*
> nocapture nofree readonly align 4 [[P]]) #4, !range !2
> +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
> +; IS__TUNIT____-NEXT: ret i1 [[CMP]]
> ;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@test1-check
> -; CGSCC_OLD_PM-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> -; CGSCC_OLD_PM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture
> nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> -; CGSCC_OLD_PM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
> -; CGSCC_OLD_PM-NEXT: ret i1 [[CMP]]
> -;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@test1-check
> -; CGSCC_NEW_PM-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> -; CGSCC_NEW_PM-NEXT: [[RES:%.*]] = tail call i32 @test1(i32* nocapture
> nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> -; CGSCC_NEW_PM-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
> -; CGSCC_NEW_PM-NEXT: ret i1 [[CMP]]
> +; 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]])
> +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp eq i32 [[RES]], 500
> +; IS__CGSCC____-NEXT: ret i1 [[CMP]]
> ;
> %res = tail call i32 @test1(i32* %p)
> %cmp = icmp eq i32 %res, 500
> @@ -441,55 +305,30 @@ entry:
> }
>
> define i32 @test2_check(i32* %p) {
> -; OLD_PM-LABEL: define {{[^@]+}}@test2_check
> -; OLD_PM-SAME: (i32* nocapture nofree readnone align 4 [[P:%.*]])
> -; OLD_PM-NEXT: entry:
> -; OLD_PM-NEXT: br label [[IF_THEN:%.*]]
> -; OLD_PM: if.then:
> -; OLD_PM-NEXT: br label [[RETURN:%.*]]
> -; OLD_PM: if.end:
> -; OLD_PM-NEXT: unreachable
> -; OLD_PM: return:
> -; OLD_PM-NEXT: ret i32 2
> -;
> -; NEW_PM-LABEL: define {{[^@]+}}@test2_check
> -; NEW_PM-SAME: (i32* nocapture nofree readnone align 4 [[P:%.*]])
> -; NEW_PM-NEXT: entry:
> -; NEW_PM-NEXT: br label [[IF_THEN:%.*]]
> -; NEW_PM: if.then:
> -; NEW_PM-NEXT: br label [[RETURN:%.*]]
> -; NEW_PM: if.end:
> -; NEW_PM-NEXT: unreachable
> -; NEW_PM: return:
> -; NEW_PM-NEXT: ret i32 2
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@test2_check
> -; CGSCC_OLD_PM-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> -; CGSCC_OLD_PM-NEXT: entry:
> -; CGSCC_OLD_PM-NEXT: [[CALL:%.*]] = tail call i32 @test2(i32*
> nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> -; CGSCC_OLD_PM-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5
> -; CGSCC_OLD_PM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> -; CGSCC_OLD_PM: if.then:
> -; CGSCC_OLD_PM-NEXT: br label [[RETURN:%.*]]
> -; CGSCC_OLD_PM: if.end:
> -; CGSCC_OLD_PM-NEXT: br label [[RETURN]]
> -; CGSCC_OLD_PM: return:
> -; CGSCC_OLD_PM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [
> 3, [[IF_END]] ]
> -; CGSCC_OLD_PM-NEXT: ret i32 [[RETVAL_0]]
> -;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@test2_check
> -; CGSCC_NEW_PM-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> -; CGSCC_NEW_PM-NEXT: entry:
> -; CGSCC_NEW_PM-NEXT: [[CALL:%.*]] = tail call i32 @test2(i32*
> nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> -; CGSCC_NEW_PM-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5
> -; CGSCC_NEW_PM-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> -; CGSCC_NEW_PM: if.then:
> -; CGSCC_NEW_PM-NEXT: br label [[RETURN:%.*]]
> -; CGSCC_NEW_PM: if.end:
> -; CGSCC_NEW_PM-NEXT: br label [[RETURN]]
> -; CGSCC_NEW_PM: return:
> -; CGSCC_NEW_PM-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [
> 3, [[IF_END]] ]
> -; CGSCC_NEW_PM-NEXT: ret i32 [[RETVAL_0]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test2_check
> +; IS__TUNIT____-SAME: (i32* nocapture nofree readnone align 4 [[P:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: br label [[IF_THEN:%.*]]
> +; IS__TUNIT____: if.then:
> +; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
> +; IS__TUNIT____: if.end:
> +; IS__TUNIT____-NEXT: unreachable
> +; IS__TUNIT____: return:
> +; IS__TUNIT____-NEXT: ret i32 2
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test2_check
> +; IS__CGSCC____-SAME: (i32* nocapture nofree nonnull readonly align 4
> dereferenceable(4) [[P:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = tail call i32 @test2(i32*
> nocapture nofree nonnull readonly align 4 dereferenceable(4) [[P]])
> +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 5
> +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; IS__CGSCC____: if.then:
> +; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
> +; IS__CGSCC____: if.end:
> +; IS__CGSCC____-NEXT: br label [[RETURN]]
> +; IS__CGSCC____: return:
> +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ 2, [[IF_THEN]] ], [
> 3, [[IF_END]] ]
> +; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
> ;
> entry:
> %call = tail call i32 @test2(i32* %p)
> @@ -535,55 +374,38 @@ return: ;
> preds = %if.end, %if.then
> declare dso_local void @unkown()
>
> define internal i32 @r1(i32) local_unnamed_addr {
> -; OLD_PM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
> -; OLD_PM-NEXT: br label [[TMP4:%.*]]
> -; OLD_PM: 1:
> -; OLD_PM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
> -; OLD_PM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[F:%.*]]
> -; OLD_PM: 3:
> -; OLD_PM-NEXT: ret i32 20
> -; OLD_PM: f:
> -; OLD_PM-NEXT: ret i32 10
> -; OLD_PM: 4:
> -; OLD_PM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [
> [[TMP8:%.*]], [[TMP4]] ]
> -; OLD_PM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [ [[TMP7]],
> [[TMP4]] ]
> -; OLD_PM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
> -; OLD_PM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
> -; OLD_PM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
> -; OLD_PM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
> -; CGSCC_OLD_PM-NEXT: br label [[TMP4:%.*]]
> -; CGSCC_OLD_PM: 1:
> -; CGSCC_OLD_PM-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP7:%.*]], 10000
> -; CGSCC_OLD_PM-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label
> [[F:%.*]]
> -; CGSCC_OLD_PM: 3:
> -; CGSCC_OLD_PM-NEXT: ret i32 20
> -; CGSCC_OLD_PM: f:
> -; CGSCC_OLD_PM-NEXT: ret i32 10
> -; CGSCC_OLD_PM: 4:
> -; CGSCC_OLD_PM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [
> [[TMP8:%.*]], [[TMP4]] ]
> -; CGSCC_OLD_PM-NEXT: [[TMP6:%.*]] = phi i32 [ 0, [[TMP0]] ], [
> [[TMP7]], [[TMP4]] ]
> -; CGSCC_OLD_PM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP5]], [[TMP6]]
> -; CGSCC_OLD_PM-NEXT: [[TMP8]] = add nuw nsw i32 [[TMP5]], 1
> -; CGSCC_OLD_PM-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], 100
> -; CGSCC_OLD_PM-NEXT: br i1 [[TMP9]], label [[TMP1:%.*]], label [[TMP4]]
> -;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
> -; CGSCC_NEW_PM-NEXT: br label [[TMP3:%.*]]
> -; CGSCC_NEW_PM: 1:
> -; CGSCC_NEW_PM-NEXT: br label [[F:%.*]]
> -; CGSCC_NEW_PM: 2:
> -; CGSCC_NEW_PM-NEXT: unreachable
> -; CGSCC_NEW_PM: f:
> -; CGSCC_NEW_PM-NEXT: ret i32 10
> -; CGSCC_NEW_PM: 3:
> -; CGSCC_NEW_PM-NEXT: [[TMP4:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [
> [[TMP7:%.*]], [[TMP3]] ]
> -; CGSCC_NEW_PM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0]] ], [
> [[TMP6:%.*]], [[TMP3]] ]
> -; CGSCC_NEW_PM-NEXT: [[TMP6]] = add nuw nsw i32 [[TMP4]], [[TMP5]]
> -; CGSCC_NEW_PM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP4]], 1
> -; CGSCC_NEW_PM-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 100
> -; CGSCC_NEW_PM-NEXT: br i1 [[TMP8]], label [[TMP1:%.*]], label [[TMP3]]
> +; 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__CGSCC_NPM-LABEL: define {{[^@]+}}@r1() local_unnamed_addr
> +; IS__CGSCC_NPM-NEXT: br label [[TMP3:%.*]]
> +; IS__CGSCC_NPM: 1:
> +; IS__CGSCC_NPM-NEXT: br label [[F:%.*]]
> +; IS__CGSCC_NPM: 2:
> +; IS__CGSCC_NPM-NEXT: unreachable
> +; IS__CGSCC_NPM: f:
> +; IS__CGSCC_NPM-NEXT: ret i32 10
> +; IS__CGSCC_NPM: 3:
> +; IS__CGSCC_NPM-NEXT: [[TMP4:%.*]] = phi i32 [ 0, [[TMP0:%.*]] ], [
> [[TMP7:%.*]], [[TMP3]] ]
> +; IS__CGSCC_NPM-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP0]] ], [
> [[TMP6:%.*]], [[TMP3]] ]
> +; IS__CGSCC_NPM-NEXT: [[TMP6]] = add nuw nsw i32 [[TMP4]], [[TMP5]]
> +; IS__CGSCC_NPM-NEXT: [[TMP7]] = add nuw nsw i32 [[TMP4]], 1
> +; IS__CGSCC_NPM-NEXT: [[TMP8:%.*]] = icmp eq i32 [[TMP7]], 100
> +; IS__CGSCC_NPM-NEXT: br i1 [[TMP8]], label [[TMP1:%.*]], label
> [[TMP3]]
> ;
> br label %5
>
> @@ -604,43 +426,24 @@ f:
> }
>
> define void @f1(i32){
> -; OLD_PM-LABEL: define {{[^@]+}}@f1
> -; OLD_PM-SAME: (i32 [[TMP0:%.*]])
> -; OLD_PM-NEXT: [[TMP2:%.*]] = tail call i32 @r1()
> -; OLD_PM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
> -; OLD_PM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP5:%.*]]
> -; OLD_PM: 4:
> -; OLD_PM-NEXT: tail call void @unkown()
> -; OLD_PM-NEXT: br label [[TMP5]]
> -; OLD_PM: 5:
> -; OLD_PM-NEXT: ret void
> -;
> -; NEW_PM-LABEL: define {{[^@]+}}@f1
> -; NEW_PM-SAME: (i32 [[TMP0:%.*]])
> -; NEW_PM-NEXT: br label [[TMP3:%.*]]
> -; NEW_PM: 2:
> -; NEW_PM-NEXT: unreachable
> -; NEW_PM: 3:
> -; NEW_PM-NEXT: ret void
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@f1
> -; CGSCC_OLD_PM-SAME: (i32 [[TMP0:%.*]])
> -; CGSCC_OLD_PM-NEXT: [[TMP2:%.*]] = tail call i32 @r1()
> -; CGSCC_OLD_PM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
> -; CGSCC_OLD_PM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP5:%.*]]
> -; CGSCC_OLD_PM: 4:
> -; CGSCC_OLD_PM-NEXT: tail call void @unkown()
> -; CGSCC_OLD_PM-NEXT: br label [[TMP5]]
> -; CGSCC_OLD_PM: 5:
> -; CGSCC_OLD_PM-NEXT: ret void
> -;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@f1
> -; CGSCC_NEW_PM-SAME: (i32 [[TMP0:%.*]])
> -; CGSCC_NEW_PM-NEXT: br label [[TMP3:%.*]]
> -; CGSCC_NEW_PM: 2:
> -; CGSCC_NEW_PM-NEXT: unreachable
> -; CGSCC_NEW_PM: 3:
> -; CGSCC_NEW_PM-NEXT: ret void
> +; IS________OPM-LABEL: define {{[^@]+}}@f1
> +; IS________OPM-SAME: (i32 [[TMP0:%.*]])
> +; IS________OPM-NEXT: [[TMP2:%.*]] = tail call i32 @r1()
> +; IS________OPM-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
> +; IS________OPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP5:%.*]]
> +; IS________OPM: 4:
> +; IS________OPM-NEXT: tail call void @unkown()
> +; IS________OPM-NEXT: br label [[TMP5]]
> +; 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
> ;
> %2 = tail call i32 @r1(i32 %0)
> %3 = icmp sgt i32 %2, 15
> @@ -745,65 +548,39 @@ return: ;
> preds = %if.else, %if.then
>
>
> define dso_local i32 @test4-g2(i32 %u) {
> -; OLD_PM-LABEL: define {{[^@]+}}@test4-g2
> -; OLD_PM-SAME: (i32 [[U:%.*]])
> -; OLD_PM-NEXT: entry:
> -; OLD_PM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
> -; OLD_PM-NEXT: ret i32 [[CALL]]
> -;
> -; NEW_PM-LABEL: define {{[^@]+}}@test4-g2
> -; NEW_PM-SAME: (i32 [[U:%.*]])
> -; NEW_PM-NEXT: entry:
> -; NEW_PM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]]) #2,
> !range !3
> -; NEW_PM-NEXT: ret i32 [[CALL]]
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@test4-g2
> -; CGSCC_OLD_PM-SAME: (i32 [[U:%.*]])
> -; CGSCC_OLD_PM-NEXT: entry:
> -; CGSCC_OLD_PM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
> -; CGSCC_OLD_PM-NEXT: ret i32 [[CALL]]
> +; 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_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]]) #2, !range !3
> +; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
> ;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@test4-g2
> -; CGSCC_NEW_PM-SAME: (i32 [[U:%.*]])
> -; CGSCC_NEW_PM-NEXT: entry:
> -; CGSCC_NEW_PM-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
> -; CGSCC_NEW_PM-NEXT: ret i32 [[CALL]]
> -;
> -; CGSCC-LABEL: define {{[^@]+}}@test4-g2
> -; CGSCC-SAME: (i32 [[U:%.*]])
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: [[CALL:%.*]] = tail call i32 @test4-f2(i32 [[U]])
> -; CGSCC-NEXT: ret i32 [[CALL]]
> entry:
> %call = tail call i32 @test4-f2(i32 %u)
> ret i32 %call
> }
>
> define dso_local i32 @test-5() {
> -; OLD_PM-LABEL: define {{[^@]+}}@test-5()
> -; OLD_PM-NEXT: entry:
> -; OLD_PM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !3
> -; OLD_PM-NEXT: ret i32 [[CALL]]
> -;
> -; NEW_PM-LABEL: define {{[^@]+}}@test-5()
> -; NEW_PM-NEXT: entry:
> -; NEW_PM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !4
> -; NEW_PM-NEXT: ret i32 [[CALL]]
> +; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@test-5()
> +; IS__TUNIT_OPM-NEXT: entry:
> +; IS__TUNIT_OPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !3
> +; IS__TUNIT_OPM-NEXT: ret i32 [[CALL]]
> ;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@test-5()
> -; CGSCC_OLD_PM-NEXT: entry:
> -; CGSCC_OLD_PM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0)
> -; CGSCC_OLD_PM-NEXT: ret i32 [[CALL]]
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@test-5()
> +; IS__TUNIT_NPM-NEXT: entry:
> +; IS__TUNIT_NPM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0), !range !4
> +; IS__TUNIT_NPM-NEXT: ret i32 [[CALL]]
> ;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@test-5()
> -; CGSCC_NEW_PM-NEXT: entry:
> -; CGSCC_NEW_PM-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0)
> -; CGSCC_NEW_PM-NEXT: ret i32 [[CALL]]
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test-5()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0)
> +; IS__CGSCC____-NEXT: ret i32 [[CALL]]
> ;
> -; CGSCC-LABEL: define {{[^@]+}}@test-5()
> -; CGSCC-NEXT: entry:
> -; CGSCC-NEXT: [[CALL:%.*]] = call i32 @rec(i32 0)
> -; CGSCC-NEXT: ret i32 [[CALL]]
> entry:
> %call = call i32 @rec(i32 0)
> ret i32 %call
> @@ -1087,23 +864,15 @@ define i8 @undef_collapse_2() {
> }
>
> define i8 @undef_collapse_caller() {
> -; OLD_PM-LABEL: define {{[^@]+}}@undef_collapse_caller()
> -; OLD_PM-NEXT: ret i8 0
> -;
> -; NEW_PM-LABEL: define {{[^@]+}}@undef_collapse_caller()
> -; NEW_PM-NEXT: ret i8 0
> ;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@undef_collapse_caller()
> -; CGSCC_OLD_PM-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1()
> -; CGSCC_OLD_PM-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2()
> -; CGSCC_OLD_PM-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]]
> -; CGSCC_OLD_PM-NEXT: ret i8 [[A]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@undef_collapse_caller()
> +; IS__TUNIT____-NEXT: ret i8 0
> ;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@undef_collapse_caller()
> -; CGSCC_NEW_PM-NEXT: [[C1:%.*]] = call i8 @undef_collapse_1()
> -; CGSCC_NEW_PM-NEXT: [[C2:%.*]] = call i8 @undef_collapse_2()
> -; CGSCC_NEW_PM-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]]
> -; CGSCC_NEW_PM-NEXT: ret i8 [[A]]
> +; 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()
> +; IS__CGSCC____-NEXT: [[A:%.*]] = add i8 [[C1]], [[C2]]
> +; IS__CGSCC____-NEXT: ret i8 [[A]]
> ;
> %c1 = call i8 @undef_collapse_1()
> %c2 = call i8 @undef_collapse_2()
> @@ -1121,35 +890,21 @@ define i32 @ret1or2(i1 %c) {
> ret i32 %s
> }
> define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
> -; OLD_PM-LABEL: define {{[^@]+}}@callee_range_1
> -; OLD_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
> -; OLD_PM-NEXT: ret i1 true
> ;
> -; NEW_PM-LABEL: define {{[^@]+}}@callee_range_1
> -; NEW_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
> -; NEW_PM-NEXT: ret i1 true
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@callee_range_1
> -; CGSCC_OLD_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
> -; CGSCC_OLD_PM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
> -; CGSCC_OLD_PM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
> -; CGSCC_OLD_PM-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32
> [[R1]], i32 [[R2]]
> -; CGSCC_OLD_PM-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
> -; CGSCC_OLD_PM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4
> -; CGSCC_OLD_PM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> -; CGSCC_OLD_PM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> -; CGSCC_OLD_PM-NEXT: ret i1 [[F]]
> -;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@callee_range_1
> -; CGSCC_NEW_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
> -; CGSCC_NEW_PM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
> -; CGSCC_NEW_PM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
> -; CGSCC_NEW_PM-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32
> [[R1]], i32 [[R2]]
> -; CGSCC_NEW_PM-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
> -; CGSCC_NEW_PM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4
> -; CGSCC_NEW_PM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> -; CGSCC_NEW_PM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> -; CGSCC_NEW_PM-NEXT: ret i1 [[F]]
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@callee_range_1
> +; IS__TUNIT____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]], i1 [[C3:%.*]])
> +; IS__TUNIT____-NEXT: ret i1 true
> +;
> +; 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]])
> +; IS__CGSCC____-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
> +; IS__CGSCC____-NEXT: [[INDIRECTION:%.*]] = select i1 [[C3]], i32
> [[R1]], i32 [[R2]]
> +; IS__CGSCC____-NEXT: [[A:%.*]] = add i32 [[R1]], [[INDIRECTION]]
> +; IS__CGSCC____-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 4
> +; IS__CGSCC____-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> +; IS__CGSCC____-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> +; IS__CGSCC____-NEXT: ret i1 [[F]]
> ;
> %r1 = call i32 @ret1or2(i1 %c1)
> %r2 = call i32 @ret1or2(i1 %c2)
> @@ -1162,45 +917,36 @@ define i1 @callee_range_1(i1 %c1, i1 %c2, i1 %c3) {
> }
>
> define i1 @callee_range_2(i1 %c1, i1 %c2) {
> -; OLD_PM-LABEL: define {{[^@]+}}@callee_range_2
> -; OLD_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
> -; OLD_PM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #2, !range !4
> -; OLD_PM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #3, !range !4
> -; OLD_PM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
> -; OLD_PM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
> -; OLD_PM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> -; OLD_PM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> -; OLD_PM-NEXT: ret i1 [[F]]
> -;
> -; NEW_PM-LABEL: define {{[^@]+}}@callee_range_2
> -; NEW_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
> -; NEW_PM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]]) #2, !range !5
> -; NEW_PM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #3, !range !5
> -; NEW_PM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
> -; NEW_PM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
> -; NEW_PM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> -; NEW_PM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> -; NEW_PM-NEXT: ret i1 [[F]]
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@callee_range_2
> -; CGSCC_OLD_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
> -; CGSCC_OLD_PM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
> -; CGSCC_OLD_PM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
> -; CGSCC_OLD_PM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
> -; CGSCC_OLD_PM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
> -; CGSCC_OLD_PM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> -; CGSCC_OLD_PM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> -; CGSCC_OLD_PM-NEXT: ret i1 [[F]]
> ;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@callee_range_2
> -; CGSCC_NEW_PM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
> -; CGSCC_NEW_PM-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
> -; CGSCC_NEW_PM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
> -; CGSCC_NEW_PM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
> -; CGSCC_NEW_PM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
> -; CGSCC_NEW_PM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> -; CGSCC_NEW_PM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> -; CGSCC_NEW_PM-NEXT: ret i1 [[F]]
> +; 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
> +; IS__TUNIT_OPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #3,
> !range !4
> +; IS__TUNIT_OPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
> +; IS__TUNIT_OPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
> +; IS__TUNIT_OPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> +; IS__TUNIT_OPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> +; IS__TUNIT_OPM-NEXT: ret i1 [[F]]
> +;
> +; 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]]) #2,
> !range !5
> +; IS__TUNIT_NPM-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]]) #3,
> !range !5
> +; IS__TUNIT_NPM-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
> +; IS__TUNIT_NPM-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
> +; IS__TUNIT_NPM-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> +; IS__TUNIT_NPM-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> +; IS__TUNIT_NPM-NEXT: ret i1 [[F]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@callee_range_2
> +; IS__CGSCC____-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]])
> +; IS__CGSCC____-NEXT: [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
> +; IS__CGSCC____-NEXT: [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
> +; IS__CGSCC____-NEXT: [[A:%.*]] = add i32 [[R1]], [[R2]]
> +; IS__CGSCC____-NEXT: [[I1:%.*]] = icmp sle i32 [[A]], 3
> +; IS__CGSCC____-NEXT: [[I2:%.*]] = icmp sge i32 [[A]], 2
> +; IS__CGSCC____-NEXT: [[F:%.*]] = and i1 [[I1]], [[I2]]
> +; IS__CGSCC____-NEXT: ret i1 [[F]]
> ;
> %r1 = call i32 @ret1or2(i1 %c1)
> %r2 = call i32 @ret1or2(i1 %c2)
> @@ -1220,53 +966,30 @@ define i32 @ret100() {
> }
>
> define i1 @ctx_adjustment(i32 %V) {
> -; OLD_PM-LABEL: define {{[^@]+}}@ctx_adjustment
> -; OLD_PM-SAME: (i32 [[V:%.*]])
> -; OLD_PM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
> -; OLD_PM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label
> [[IF_FALSE:%.*]]
> -; OLD_PM: if.true:
> -; OLD_PM-NEXT: br label [[END:%.*]]
> -; OLD_PM: if.false:
> -; OLD_PM-NEXT: br label [[END]]
> -; OLD_PM: end:
> -; OLD_PM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [ 100,
> [[IF_FALSE]] ]
> -; OLD_PM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100
> -; OLD_PM-NEXT: ret i1 [[C2]]
> ;
> -; NEW_PM-LABEL: define {{[^@]+}}@ctx_adjustment
> -; NEW_PM-SAME: (i32 [[V:%.*]])
> -; NEW_PM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
> -; NEW_PM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label
> [[IF_FALSE:%.*]]
> -; NEW_PM: if.true:
> -; NEW_PM-NEXT: br label [[END:%.*]]
> -; NEW_PM: if.false:
> -; NEW_PM-NEXT: br label [[END]]
> -; NEW_PM: end:
> -; NEW_PM-NEXT: ret i1 true
> -;
> -; CGSCC_OLD_PM-LABEL: define {{[^@]+}}@ctx_adjustment
> -; CGSCC_OLD_PM-SAME: (i32 [[V:%.*]])
> -; CGSCC_OLD_PM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
> -; CGSCC_OLD_PM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label
> [[IF_FALSE:%.*]]
> -; CGSCC_OLD_PM: if.true:
> -; CGSCC_OLD_PM-NEXT: br label [[END:%.*]]
> -; CGSCC_OLD_PM: if.false:
> -; CGSCC_OLD_PM-NEXT: br label [[END]]
> -; CGSCC_OLD_PM: end:
> -; CGSCC_OLD_PM-NEXT: [[PHI:%.*]] = phi i32 [ [[V]], [[IF_TRUE]] ], [
> 100, [[IF_FALSE]] ]
> -; CGSCC_OLD_PM-NEXT: [[C2:%.*]] = icmp sge i32 [[PHI]], 100
> -; CGSCC_OLD_PM-NEXT: ret i1 [[C2]]
> -;
> -; CGSCC_NEW_PM-LABEL: define {{[^@]+}}@ctx_adjustment
> -; CGSCC_NEW_PM-SAME: (i32 [[V:%.*]])
> -; CGSCC_NEW_PM-NEXT: [[C1:%.*]] = icmp sge i32 [[V]], 100
> -; CGSCC_NEW_PM-NEXT: br i1 [[C1]], label [[IF_TRUE:%.*]], label
> [[IF_FALSE:%.*]]
> -; CGSCC_NEW_PM: if.true:
> -; CGSCC_NEW_PM-NEXT: br label [[END:%.*]]
> -; CGSCC_NEW_PM: if.false:
> -; CGSCC_NEW_PM-NEXT: br label [[END]]
> -; CGSCC_NEW_PM: end:
> -; CGSCC_NEW_PM-NEXT: ret i1 true
> +; 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
> ;
> %c1 = icmp sge i32 %V, 100
> br i1 %c1, label %if.true, label %if.false
> @@ -1284,9 +1007,22 @@ end:
>
> !0 = !{i32 0, i32 10}
> !1 = !{i32 10, i32 100}
> -; CHECK: !0 = !{i32 0, i32 10}
> -; CHECK-NEXT: !1 = !{i32 10, i32 100}
> -; NEW_PM: !2 = !{i32 200, i32 1091}
> -; OLD_PM: !3 = !{i32 0, i32 2}
> -; NEW_PM: !3 = !{i32 1, i32 -2147483648}
> -; NEW_PM: !4 = !{i32 0, i32 2}
> +
> +; NOT_TUNIT____: !0 = !{i32 0, i32 10}
> +; NOT_TUNIT____: !1 = !{i32 10, i32 100}
> +; NOT_TUNIT____-NOT: !2
> +
> +; IS__TUNIT_OPM: !0 = !{i32 0, i32 10}
> +; IS__TUNIT_OPM: !1 = !{i32 10, i32 100}
> +; IS__TUNIT_OPM: !2 = !{i32 200, i32 1091}
> +; IS__TUNIT_OPM: !3 = !{i32 0, i32 2}
> +; IS__TUNIT_OPM: !4 = !{i32 1, i32 3}
> +; IS__TUNIT_OPM-NOT: !5
> +
> +; IS__TUNIT_NPM: !0 = !{i32 0, i32 10}
> +; IS__TUNIT_NPM: !1 = !{i32 10, i32 100}
> +; IS__TUNIT_NPM: !2 = !{i32 200, i32 1091}
> +; IS__TUNIT_NPM: !3 = !{i32 1, i32 -2147483648}
> +; IS__TUNIT_NPM: !4 = !{i32 0, i32 2}
> +; IS__TUNIT_NPM: !5 = !{i32 1, i32 3}
> +; IS__TUNIT_NPM-NOT: !6
>
> 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 1ddde3a9bcb4..673f17f66437 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,9 @@
> -; RUN: opt -functionattrs -enable-nonnull-arg-prop -attributor
> -attributor-manifest-internal -attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=6 -S < %s | FileCheck %s
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> +
> ;
> ; This is an evolved example to stress test SCC parameter attribute
> propagation.
> ; The SCC in this test is made up of the following six function, three of
> which
> @@ -30,8 +35,16 @@
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>
> ; CHECK: Function Attrs: argmemonly nofree nosync nounwind
> -; CHECK-NEXT: define i32* @external_ret2_nrw(i32* nofree %n0, i32* nofree
> %r0, i32* nofree returned %w0)
> define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
> +; CHECK-LABEL: define {{[^@]+}}@external_ret2_nrw
> +; CHECK-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]], i32*
> nofree returned [[W0:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @internal_ret0_nw(i32* nofree
> [[N0]], i32* nofree [[W0]])
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rrw(i32* nofree
> align 4 [[R0]], i32* nofree [[R0]], i32* nofree [[W0]])
> +; CHECK-NEXT: [[CALL2:%.*]] = call i32* @external_sink_ret2_nrw(i32*
> nofree [[N0]], i32* nofree readonly align 4 [[R0]], i32* nofree writeonly
> [[W0]])
> +; CHECK-NEXT: [[CALL3:%.*]] = call i32* @internal_ret1_rw(i32* nofree
> align 4 [[R0]], i32* nofree [[W0]])
> +; CHECK-NEXT: ret i32* [[CALL3]]
> +;
> entry:
> %call = call i32* @internal_ret0_nw(i32* %n0, i32* %w0)
> %call1 = call i32* @internal_ret1_rrw(i32* %r0, i32* %r0, i32* %w0)
> @@ -41,8 +54,55 @@ entry:
> }
>
> ; CHECK: Function Attrs: argmemonly nofree nosync nounwind
> -; CHECK-NEXT: define internal i32* @internal_ret0_nw(i32* nofree returned
> %n0, i32* nofree %w0)
> define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@internal_ret0_nw
> +; IS__TUNIT____-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree
> [[W0:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[R0:%.*]] = alloca i32, align 4
> +; IS__TUNIT____-NEXT: [[R1:%.*]] = alloca i32, align 4
> +; 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: store i32 3, i32* [[R0]], align 4
> +; IS__TUNIT____-NEXT: store i32 5, i32* [[R1]], align 4
> +; IS__TUNIT____-NEXT: store i32 1, i32* [[W0]], align 4
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rrw(i32*
> nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align
> 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32*
> @external_ret2_nrw(i32* nofree [[N0]], i32* nofree nonnull align 4
> dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; IS__TUNIT____-NEXT: [[CALL2:%.*]] = call i32*
> @external_ret2_nrw(i32* nofree [[N0]], i32* nofree nonnull align 4
> dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; IS__TUNIT____-NEXT: [[CALL3:%.*]] = call i32*
> @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nofree nonnull readonly
> align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4
> dereferenceable(4) "no-capture-maybe-returned" [[W0]])
> +; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32*
> @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nofree nonnull readonly
> align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4
> dereferenceable(4) "no-capture-maybe-returned" [[W0]])
> +; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32*
> nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]])
> +; IS__TUNIT____-NEXT: br label [[RETURN]]
> +; IS__TUNIT____: return:
> +; IS__TUNIT____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]],
> [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
> +; IS__TUNIT____-NEXT: ret i32* [[RETVAL_0]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@internal_ret0_nw
> +; IS__CGSCC____-SAME: (i32* nofree returned [[N0:%.*]], i32* nofree
> [[W0:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[R0:%.*]] = alloca i32, align 4
> +; IS__CGSCC____-NEXT: [[R1:%.*]] = alloca i32, align 4
> +; 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: store i32 3, i32* [[R0]], align 4
> +; IS__CGSCC____-NEXT: store i32 5, i32* [[R1]], align 4
> +; IS__CGSCC____-NEXT: store i32 1, i32* [[W0]], align 4
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rrw(i32*
> nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align
> 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32*
> @external_ret2_nrw(i32* nofree [[N0]], i32* nofree nonnull align 4
> dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; IS__CGSCC____-NEXT: [[CALL2:%.*]] = call i32*
> @external_ret2_nrw(i32* nofree [[N0]], i32* nofree nonnull align 4
> dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; IS__CGSCC____-NEXT: [[CALL3:%.*]] = call i32*
> @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nofree nonnull readonly
> align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly align 4
> dereferenceable(4) [[W0]])
> +; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32*
> @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nofree nonnull readonly
> align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly align 4
> dereferenceable(4) [[W0]])
> +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32* @internal_ret0_nw(i32*
> nofree [[N0]], i32* nofree nonnull align 4 dereferenceable(4) [[W0]])
> +; IS__CGSCC____-NEXT: br label [[RETURN]]
> +; IS__CGSCC____: return:
> +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL5]],
> [[IF_END]] ], [ [[N0]], [[IF_THEN]] ]
> +; IS__CGSCC____-NEXT: ret i32* [[RETVAL_0]]
> +;
> entry:
> %r0 = alloca i32, align 4
> %r1 = alloca i32, align 4
> @@ -70,8 +130,34 @@ return: ;
> preds = %if.end, %if.then
> }
>
> ; CHECK: Function Attrs: argmemonly nofree nosync nounwind
> -; CHECK-NEXT: define internal i32* @internal_ret1_rrw(i32* nofree nonnull
> align 4 dereferenceable(4) %r0, i32* nofree returned %r1, i32* nofree %w0)
> define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
> +; CHECK-LABEL: define {{[^@]+}}@internal_ret1_rrw
> +; CHECK-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]],
> i32* nofree returned [[R1:%.*]], i32* nofree [[W0:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
> +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
> +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label
> [[IF_THEN:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: br label [[RETURN:%.*]]
> +; CHECK: if.end:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R0]], i32* nofree [[W0]])
> +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[R0]], align 4
> +; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[R1]], align 4
> +; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP1]], [[TMP2]]
> +; CHECK-NEXT: store i32 [[ADD]], i32* [[W0]], align 4
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32* @internal_ret1_rw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4
> dereferenceable(4) [[W0]])
> +; CHECK-NEXT: [[CALL2:%.*]] = call i32* @internal_ret0_nw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4
> dereferenceable(4) [[W0]])
> +; CHECK-NEXT: [[CALL3:%.*]] = call i32* @internal_ret0_nw(i32* nofree
> nonnull align 4 dereferenceable(4) [[W0]], i32* nofree nonnull align 4
> dereferenceable(4) [[W0]])
> +; CHECK-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4
> dereferenceable(4) [[R1]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; CHECK-NEXT: [[CALL5:%.*]] = call i32* @external_ret2_nrw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4
> dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; CHECK-NEXT: [[CALL6:%.*]] = call i32* @external_sink_ret2_nrw(i32*
> nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull
> readonly align 4 dereferenceable(4) [[R1]], i32* nofree nonnull writeonly
> align 4 dereferenceable(4) [[W0]])
> +; CHECK-NEXT: [[CALL7:%.*]] = call i32* @external_sink_ret2_nrw(i32*
> nofree nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull
> readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly
> align 4 dereferenceable(4) [[W0]])
> +; CHECK-NEXT: [[CALL8:%.*]] = call i32* @internal_ret0_nw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R1]], i32* nofree nonnull align 4
> dereferenceable(4) [[W0]])
> +; CHECK-NEXT: br label [[RETURN]]
> +; CHECK: return:
> +; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL8]], [[IF_END]] ], [
> [[R1]], [[IF_THEN]] ]
> +; CHECK-NEXT: ret i32* undef
> +;
> entry:
> %0 = load i32, i32* %r0, align 4
> %tobool = icmp ne i32 %0, 0
> @@ -101,9 +187,23 @@ return: ;
> preds = %if.end, %if.then
> ret i32* %retval.0
> }
>
> -; CHECK: Function Attrs: argmemonly nofree norecurse nosync nounwind
> willreturn
> -; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* nofree readnone
> %n0, i32* nocapture nofree readonly %r0, i32* nofree returned writeonly
> "no-capture-maybe-returned" %w0)
> +; IS__TUNIT____: Function Attrs: argmemonly nofree nosync nounwind
> willreturn
> +; 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]]
> +;
> entry:
> %tobool = icmp ne i32* %n0, null
> br i1 %tobool, label %if.end, label %if.then
> @@ -121,8 +221,28 @@ return: ;
> preds = %if.end, %if.then
> }
>
> ; CHECK: Function Attrs: argmemonly nofree nosync nounwind
> -; CHECK-NEXT: define internal i32* @internal_ret1_rw(i32* nofree nonnull
> align 4 dereferenceable(4) %r0, i32* nofree returned %w0)
> define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
> +; CHECK-LABEL: define {{[^@]+}}@internal_ret1_rw
> +; CHECK-SAME: (i32* nofree nonnull align 4 dereferenceable(4) [[R0:%.*]],
> i32* nofree returned [[W0:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[R0]], align 4
> +; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
> +; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label
> [[IF_THEN:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: br label [[RETURN:%.*]]
> +; CHECK: if.end:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @internal_ret1_rrw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4
> dereferenceable(4) [[R0]], i32* nofree [[W0]])
> +; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[R0]], align 4
> +; CHECK-NEXT: store i32 [[TMP1]], i32* [[W0]], align 4
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32* @internal_ret0_nw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4
> dereferenceable(4) [[W0]])
> +; CHECK-NEXT: [[CALL2:%.*]] = call i32* @internal_ret0_nw(i32* nofree
> nonnull align 4 dereferenceable(4) [[W0]], i32* nofree nonnull align 4
> dereferenceable(4) [[W0]])
> +; CHECK-NEXT: [[CALL3:%.*]] = call i32* @external_sink_ret2_nrw(i32*
> nofree nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull
> readonly align 4 dereferenceable(4) [[R0]], i32* nofree nonnull writeonly
> align 4 dereferenceable(4) [[W0]])
> +; CHECK-NEXT: [[CALL4:%.*]] = call i32* @external_ret2_nrw(i32* nofree
> nonnull align 4 dereferenceable(4) [[R0]], i32* nofree nonnull align 4
> dereferenceable(4) [[R0]], i32* nofree nonnull align 4 dereferenceable(4)
> [[W0]])
> +; CHECK-NEXT: br label [[RETURN]]
> +; CHECK: return:
> +; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32* [ [[CALL4]], [[IF_END]] ], [
> [[W0]], [[IF_THEN]] ]
> +; CHECK-NEXT: ret i32* [[RETVAL_0]]
> +;
> entry:
> %0 = load i32, i32* %r0, align 4
> %tobool = icmp ne i32 %0, 0
> @@ -147,8 +267,21 @@ return: ;
> preds = %if.end, %if.then
> }
>
> ; CHECK: Function Attrs: argmemonly nofree nosync nounwind
> -; CHECK-NEXT: define i32* @external_source_ret2_nrw(i32* nofree %n0, i32*
> nofree %r0, i32* nofree returned %w0)
> define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
> +; 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:
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32*
> @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nocapture nofree readonly
> [[R0]], i32* nofree writeonly "no-capture-maybe-returned" [[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____-LABEL: define {{[^@]+}}@external_source_ret2_nrw
> +; IS__CGSCC____-SAME: (i32* nofree [[N0:%.*]], i32* nofree [[R0:%.*]],
> i32* nofree returned [[W0:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32*
> @external_sink_ret2_nrw(i32* nofree [[N0]], i32* nofree readonly [[R0]],
> i32* nofree writeonly [[W0]])
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32*
> @external_ret2_nrw(i32* nofree [[N0]], i32* nofree [[R0]], i32* nofree
> [[W0]])
> +; IS__CGSCC____-NEXT: ret i32* [[CALL1]]
> +;
> entry:
> %call = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
> %call1 = call i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
> @@ -158,9 +291,17 @@ entry:
> ; Verify that we see only expected attribute sets, the above lines only
> check
> ; for a subset relation.
> ;
> -; CHECK-NOT: attributes #
> -; CHECK: attributes #{{.*}} = { argmemonly nofree nosync nounwind }
> -; CHECK: attributes #{{.*}} = { argmemonly nofree norecurse nosync
> nounwind willreturn }
> -; CHECK: attributes #{{.*}} = { nosync nounwind }
> -; CHECK: attributes #{{.*}} = { norecurse nosync nounwind willreturn }
> -; CHECK-NOT: attributes #
> +; IS__CGSCC____-NOT: attributes #
> +; IS__CGSCC____: attributes #{{.*}} = { argmemonly nofree nosync nounwind
> }
> +; IS__CGSCC____: attributes #{{.*}} = { argmemonly nofree norecurse
> nosync nounwind willreturn }
> +; IS__CGSCC____: attributes #{{.*}} = { nofree nosync nounwind }
> +; IS__CGSCC____: attributes #{{.*}} = { nounwind }
> +; IS__CGSCC____: attributes #{{.*}} = { nounwind willreturn }
> +; IS__CGSCC____-NOT: attributes #
> +
> +; IS__TUNIT____-NOT: attributes #
> +; IS__TUNIT____: attributes #{{.*}} = { argmemonly nofree nosync nounwind
> }
> +; IS__TUNIT____: attributes #{{.*}} = { argmemonly nofree nosync nounwind
> willreturn }
> +; IS__TUNIT____: attributes #{{.*}} = { nofree nosync nounwind }
> +; IS__TUNIT____: attributes #{{.*}} = { nofree nosync nounwind willreturn
> }
> +; IS__TUNIT____-NOT: attributes #
>
> diff --git a/llvm/test/Transforms/Attributor/readattrs.ll
> b/llvm/test/Transforms/Attributor/readattrs.ll
> index 08c13d92b01c..cadb79e3bc21 100644
> --- a/llvm/test/Transforms/Attributor/readattrs.ll
> +++ b/llvm/test/Transforms/Attributor/readattrs.ll
> @@ -1,6 +1,9 @@
> -; RUN: opt < %s -attributor -attributor-disable=false -S
> -attributor-annotate-decl-cs | FileCheck %s --check-prefixes=ATTRIBUTOR
> -; RUN: opt < %s -aa-pipeline=basic-aa -passes='attributor'
> -attributor-disable=false -S -attributor-annotate-decl-cs | FileCheck %s
> --check-prefixes=ATTRIBUTOR
> -; Copied from Transforms/FunctionAttrs/readattrs.ll
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> +
>
> @x = global i32 0
>
> @@ -8,111 +11,175 @@ declare void @test1_1(i8* %x1_1, i8* readonly %y1_1,
> ...)
>
> ; NOTE: readonly for %y1_2 would be OK here but not for the similar
> situation in test13.
> ;
> -; ATTRIBUTOR: define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2)
> define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2) {
> +; CHECK-LABEL: define {{[^@]+}}@test1_2
> +; CHECK-SAME: (i8* [[X1_2:%.*]], i8* [[Y1_2:%.*]], i8* [[Z1_2:%.*]])
> +; CHECK-NEXT: call void (i8*, i8*, ...) @test1_1(i8* [[X1_2]], i8*
> readonly [[Y1_2]], i8* [[Z1_2]])
> +; CHECK-NEXT: store i32 0, i32* @x, align 4
> +; CHECK-NEXT: ret void
> +;
> call void (i8*, i8*, ...) @test1_1(i8* %x1_2, i8* %y1_2, i8* %z1_2)
> store i32 0, i32* @x
> ret void
> }
>
> -; ATTRIBUTOR: define i8* @test2(i8* nofree readnone returned %p)
> 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]]
> +;
> store i32 0, i32* @x
> ret i8* %p
> }
>
> -; ATTRIBUTOR: define i1 @test3(i8* nofree readnone %p, i8* nofree
> readnone %q)
> 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]]
> +;
> %A = icmp ult i8* %p, %q
> ret i1 %A
> }
>
> declare void @test4_1(i8* nocapture) readonly
>
> -; ATTRIBUTOR: define void @test4_2(i8* nocapture readonly %p)
> define void @test4_2(i8* %p) {
> +; CHECK-LABEL: define {{[^@]+}}@test4_2
> +; CHECK-SAME: (i8* nocapture readonly [[P:%.*]])
> +; CHECK-NEXT: call void @test4_1(i8* nocapture readonly [[P]])
> +; CHECK-NEXT: ret void
> +;
> call void @test4_1(i8* %p)
> ret void
> }
>
> -; ATTRIBUTOR: define void @test5(i8** nocapture nofree nonnull writeonly
> align 8 dereferenceable(8) %p, i8* nofree writeonly %q)
> ; 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
> +;
> store i8* %q, i8** %p
> ret void
> }
>
> declare void @test6_1()
> -; ATTRIBUTOR: define void @test6_2(i8** nocapture nonnull writeonly align
> 8 dereferenceable(8) %p, i8* %q)
> ; This is not a missed optz'n.
> define void @test6_2(i8** %p, i8* %q) {
> +; CHECK-LABEL: define {{[^@]+}}@test6_2
> +; CHECK-SAME: (i8** nocapture nonnull writeonly align 8
> dereferenceable(8) [[P:%.*]], i8* [[Q:%.*]])
> +; CHECK-NEXT: store i8* [[Q]], i8** [[P]], align 8
> +; CHECK-NEXT: call void @test6_1()
> +; CHECK-NEXT: ret void
> +;
> store i8* %q, i8** %p
> call void @test6_1()
> ret void
> }
>
> -; ATTRIBUTOR: define void @test7_1(i32* inalloca nocapture nofree
> writeonly %a)
> ; 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
> +;
> ret void
> }
>
> -; ATTRIBUTOR: define i32* @test8_1(i32* nofree readnone returned %p)
> 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]]
> +;
> entry:
> ret i32* %p
> }
>
> -; ATTRIBUTOR: define void @test8_2(i32* nocapture nofree writeonly %p)
> define void @test8_2(i32* %p) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@test8_2
> +; IS__TUNIT____-SAME: (i32* nocapture nofree writeonly [[P:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @test8_1(i32* noalias
> nofree readnone "no-capture-maybe-returned" [[P]])
> +; IS__TUNIT____-NEXT: store i32 10, i32* [[CALL]], align 4
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@test8_2
> +; IS__CGSCC____-SAME: (i32* nofree writeonly [[P:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call align 4 i32* @test8_1(i32*
> noalias nofree readnone [[P]])
> +; IS__CGSCC____-NEXT: store i32 10, i32* [[CALL]], align 4
> +; IS__CGSCC____-NEXT: ret void
> +;
> entry:
> %call = call i32* @test8_1(i32* %p)
> store i32 10, i32* %call, align 4
> ret void
> }
>
> -; ATTRIBUTOR: declare void @llvm.masked.scatter
> +; CHECK: declare void @llvm.masked.scatter
> declare void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32>%val, <4 x
> i32*>, i32, <4 x i1>)
>
> -; ATTRIBUTOR-NOT: readnone
> -; ATTRIBUTOR-NOT: readonly
> -; ATTRIBUTOR: define void @test9
> +; CHECK-NOT: readnone
> +; CHECK-NOT: readonly
> define void @test9(<4 x i32*> %ptrs, <4 x i32>%val) {
> +; 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>)
> +; CHECK-NEXT: ret void
> +;
> 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>)
> ret void
> }
>
> -; ATTRIBUTOR: declare <4 x i32> @llvm.masked.gather
> +; 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>)
> -; ATTRIBUTOR: readonly
> -; ATTRIBUTOR: define <4 x i32> @test10
> +; CHECK: readonly
> define <4 x i32> @test10(<4 x i32*> %ptrs) {
> +; 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)
> +; CHECK-NEXT: ret <4 x i32> [[RES]]
> +;
> %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)
> ret <4 x i32> %res
> }
>
> -; ATTRIBUTOR: declare <4 x i32> @test11_1
> +; CHECK: declare <4 x i32> @test11_1
> declare <4 x i32> @test11_1(<4 x i32*>) argmemonly nounwind readonly
> -; ATTRIBUTOR: readonly
> -; ATTRIBUTOR-NOT: readnone
> -; ATTRIBUTOR: define <4 x i32> @test11_2
> +; CHECK: readonly
> +; CHECK-NOT: readnone
> define <4 x i32> @test11_2(<4 x i32*> %ptrs) {
> +; CHECK-LABEL: define {{[^@]+}}@test11_2
> +; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]])
> +; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*>
> [[PTRS]])
> +; CHECK-NEXT: ret <4 x i32> [[RES]]
> +;
> %res = call <4 x i32> @test11_1(<4 x i32*> %ptrs)
> ret <4 x i32> %res
> }
>
> declare <4 x i32> @test12_1(<4 x i32*>) argmemonly nounwind
> -; ATTRIBUTOR-NOT: readnone
> -; ATTRIBUTOR: define <4 x i32> @test12_2
> +; CHECK-NOT: readnone
> define <4 x i32> @test12_2(<4 x i32*> %ptrs) {
> +; CHECK-LABEL: define {{[^@]+}}@test12_2
> +; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]])
> +; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @test12_1(<4 x i32*>
> [[PTRS]])
> +; CHECK-NEXT: ret <4 x i32> [[RES]]
> +;
> %res = call <4 x i32> @test12_1(<4 x i32*> %ptrs)
> ret <4 x i32> %res
> }
>
> -; ATTRIBUTOR: define i32 @volatile_load(
> -; ATTRIBUTOR-NOT: readonly
> -; ATTRIBUTOR: ret
> 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]]
> +;
> %load = load volatile i32, i32* %p
> ret i32 %load
> }
> @@ -125,10 +192,15 @@ declare void @escape_readonly_ptr(i8** %addr, i8*
> readonly %ptr)
> ; is marked as readnone/only. However, the functions can write the
> pointer into
> ; %addr, causing the store to write to %escaped_then_written.
> ;
> -;
> -; ATTRIBUTOR: define void @unsound_readnone(i8* nocapture nofree readnone
> %ignored, i8* %escaped_then_written)
> -; ATTRIBUTOR: define void @unsound_readonly(i8* nocapture nofree readnone
> %ignored, i8* %escaped_then_written)
> define void @unsound_readnone(i8* %ignored, i8* %escaped_then_written) {
> +; CHECK-LABEL: define {{[^@]+}}@unsound_readnone
> +; CHECK-SAME: (i8* nocapture nofree readnone [[IGNORED:%.*]], i8*
> [[ESCAPED_THEN_WRITTEN:%.*]])
> +; CHECK-NEXT: [[ADDR:%.*]] = alloca i8*
> +; CHECK-NEXT: call void @escape_readnone_ptr(i8** nonnull align 8
> dereferenceable(8) [[ADDR]], i8* noalias readnone [[ESCAPED_THEN_WRITTEN]])
> +; CHECK-NEXT: [[ADDR_LD:%.*]] = load i8*, i8** [[ADDR]], align 8
> +; CHECK-NEXT: store i8 0, i8* [[ADDR_LD]]
> +; CHECK-NEXT: ret void
> +;
> %addr = alloca i8*
> call void @escape_readnone_ptr(i8** %addr, i8* %escaped_then_written)
> %addr.ld = load i8*, i8** %addr
> @@ -137,6 +209,14 @@ define void @unsound_readnone(i8* %ignored, i8*
> %escaped_then_written) {
> }
>
> define void @unsound_readonly(i8* %ignored, i8* %escaped_then_written) {
> +; CHECK-LABEL: define {{[^@]+}}@unsound_readonly
> +; CHECK-SAME: (i8* nocapture nofree readnone [[IGNORED:%.*]], i8*
> [[ESCAPED_THEN_WRITTEN:%.*]])
> +; CHECK-NEXT: [[ADDR:%.*]] = alloca i8*
> +; CHECK-NEXT: call void @escape_readonly_ptr(i8** nonnull align 8
> dereferenceable(8) [[ADDR]], i8* readonly [[ESCAPED_THEN_WRITTEN]])
> +; CHECK-NEXT: [[ADDR_LD:%.*]] = load i8*, i8** [[ADDR]], align 8
> +; CHECK-NEXT: store i8 0, i8* [[ADDR_LD]]
> +; CHECK-NEXT: ret void
> +;
> %addr = alloca i8*
> call void @escape_readonly_ptr(i8** %addr, i8* %escaped_then_written)
> %addr.ld = load i8*, i8** %addr
> @@ -149,44 +229,69 @@ define void @unsound_readonly(i8* %ignored, i8*
> %escaped_then_written) {
> ;{
> declare void @escape_i8(i8* %ptr)
>
> -; ATTRIBUTOR: @byval_not_readonly_1
> -; ATTRIBUTOR-SAME: i8* noalias byval %written
> define void @byval_not_readonly_1(i8* byval %written) readonly {
> +; CHECK-LABEL: define {{[^@]+}}@byval_not_readonly_1
> +; CHECK-SAME: (i8* noalias byval [[WRITTEN:%.*]])
> +; CHECK-NEXT: call void @escape_i8(i8* [[WRITTEN]])
> +; CHECK-NEXT: ret void
> +;
> call void @escape_i8(i8* %written)
> ret void
> }
>
> -; ATTRIBUTOR: @byval_not_readonly_2
> -; ATTRIBUTOR-SAME: i8* noalias nocapture nofree nonnull writeonly byval
> dereferenceable(1) %written
> 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]]
> +; CHECK-NEXT: ret void
> +;
> store i8 0, i8* %written
> ret void
> }
>
> -; ATTRIBUTOR: @byval_not_readnone_1
> -; ATTRIBUTOR-SAME: i8* noalias byval %written
> define void @byval_not_readnone_1(i8* byval %written) readnone {
> +; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_1
> +; CHECK-SAME: (i8* noalias byval [[WRITTEN:%.*]])
> +; CHECK-NEXT: call void @escape_i8(i8* [[WRITTEN]])
> +; CHECK-NEXT: ret void
> +;
> call void @escape_i8(i8* %written)
> ret void
> }
>
> -; ATTRIBUTOR: @byval_not_readnone_2
> -; ATTRIBUTOR-SAME: i8* noalias nocapture nofree nonnull writeonly byval
> dereferenceable(1) %written
> 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]]
> +; CHECK-NEXT: ret void
> +;
> store i8 0, i8* %written
> ret void
> }
>
> -; ATTRIBUTOR: @byval_no_fnarg
> -; ATTRIBUTOR-SAME: i8* noalias nocapture nofree nonnull writeonly byval
> dereferenceable(1) %written
> 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]]
> +; CHECK-NEXT: ret void
> +;
> store i8 0, i8* %written
> ret void
> }
>
> -; ATTRIBUTOR: @testbyval
> -; ATTRIBUTOR-SAME: i8* nocapture readonly %read_only
> define void @testbyval(i8* %read_only) {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@testbyval
> +; IS__TUNIT____-SAME: (i8* nocapture readonly [[READ_ONLY:%.*]])
> +; IS__TUNIT____-NEXT: call void @byval_not_readonly_1(i8* nocapture
> readonly [[READ_ONLY]])
> +; IS__TUNIT____-NEXT: call void @byval_not_readnone_1(i8* noalias
> nocapture readnone [[READ_ONLY]])
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@testbyval
> +; IS__CGSCC____-SAME: (i8* nocapture readonly [[READ_ONLY:%.*]])
> +; IS__CGSCC____-NEXT: call void @byval_not_readonly_1(i8* noalias
> nocapture readonly [[READ_ONLY]])
> +; IS__CGSCC____-NEXT: call void @byval_not_readnone_1(i8* noalias
> nocapture nonnull readnone dereferenceable(1) [[READ_ONLY]])
> +; IS__CGSCC____-NEXT: ret void
> +;
> call void @byval_not_readonly_1(i8* %read_only)
> call void @byval_not_readonly_2(i8* %read_only)
> call void @byval_not_readnone_1(i8* %read_only)
> @@ -201,7 +306,10 @@ declare i8 @maybe_returned_val(i8* %ptr) readonly
> nounwind
> declare void @val_use(i8 %ptr) readonly nounwind
>
> define void @ptr_uses(i8* %ptr) {
> -; ATTRIBUTOR: define void @ptr_uses(i8* nocapture readonly %ptr)
> +; CHECK-LABEL: define {{[^@]+}}@ptr_uses
> +; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]])
> +; CHECK-NEXT: ret void
> +;
> %call_ptr = call i8* @maybe_returned_ptr(i8* %ptr)
> %call_val = call i8 @maybe_returned_val(i8* %call_ptr)
> call void @val_use(i8 %call_val)
>
> diff --git a/llvm/test/Transforms/Attributor/returned.ll
> b/llvm/test/Transforms/Attributor/returned.ll
> index 98399fe2f9cc..4e4448ead796 100644
> --- a/llvm/test/Transforms/Attributor/returned.ll
> +++ b/llvm/test/Transforms/Attributor/returned.ll
> @@ -1,29 +1,15 @@
> -; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -attributor-max-iterations-verify
> -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s |
> FileCheck %s --check-prefix=ATTRIBUTOR
> -; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -attributor-annotate-decl-cs -functionattrs -S <
> %s | FileCheck %s --check-prefix=BOTH
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
> ;
> -; Copied from
> Transforms/FunctoinAttrs/read_write_returned_arguments_scc.ll
> -;
> ; Test cases specifically designed for the "returned" argument attribute.
> ; We use FIXME's to indicate problems and missing attributes.
> ;
>
> ; TEST SCC test returning an integer value argument
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable
> -; BOTH-NEXT: define i32 @sink_r0(i32 returned %r)
> -; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
> -; BOTH-NEXT: define i32 @scc_r1(i32 %a, i32 returned %r, i32 %b)
> -; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
> -; BOTH-NEXT: define i32 @scc_r2(i32 %a, i32 %b, i32 returned %r)
> -; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
> -; BOTH-NEXT: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
> -;
> -;
> -; ATTRIBUTOR: define i32 @sink_r0(i32 returned %r)
> -; ATTRIBUTOR: define i32 @scc_r1(i32 %a, i32 returned %r, i32 %b)
> -; ATTRIBUTOR: define i32 @scc_r2(i32 %a, i32 %b, i32 returned %r)
> -; ATTRIBUTOR: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
> -;
> ; int scc_r1(int a, int b, int r);
> ; int scc_r2(int a, int b, int r);
> ;
> @@ -52,11 +38,23 @@
> 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]]
> +;
> entry:
> ret i32 %r
> }
>
> define i32 @scc_r1(i32 %a, i32 %r, i32 %b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@scc_r1
> +; CHECK-SAME: (i32 [[A:%.*]], i32 returned [[R:%.*]], i32 [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]])
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[A]],
> i32 [[CALL]])
> +; CHECK-NEXT: ret i32 [[CALL1]]
> +;
> entry:
> %call = call i32 @sink_r0(i32 %r)
> %call1 = call i32 @scc_r2(i32 %r, i32 %a, i32 %call)
> @@ -64,6 +62,42 @@ entry:
> }
>
> define i32 @scc_r2(i32 %a, i32 %b, i32 %r) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@scc_r2
> +; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 returned [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
> +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]])
> +; CHECK-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32 [[A]],
> i32 [[CALL]])
> +; CHECK-NEXT: br label [[RETURN:%.*]]
> +; CHECK: if.end:
> +; CHECK-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
> +; CHECK-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label
> [[IF_END12:%.*]]
> +; CHECK: if.then3:
> +; CHECK-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]])
> +; CHECK-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32 [[B]],
> i32 undef)
> +; CHECK-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32 [[R]],
> i32 [[R]])
> +; CHECK-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32
> [[CALL6]], i32 undef)
> +; CHECK-NEXT: [[CALL8:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]],
> i32 [[R]])
> +; CHECK-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]], i32
> [[CALL7]], i32 [[CALL8]])
> +; CHECK-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]], i32
> [[CALL9]], i32 undef)
> +; CHECK-NEXT: br label [[RETURN]]
> +; CHECK: if.end12:
> +; CHECK-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
> +; CHECK-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; CHECK: cond.true:
> +; CHECK-NEXT: br label [[COND_END:%.*]]
> +; CHECK: cond.false:
> +; CHECK-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32 [[B]],
> i32 [[R]])
> +; CHECK-NEXT: br label [[COND_END]]
> +; CHECK: cond.end:
> +; CHECK-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ], [
> [[CALL14]], [[COND_FALSE]] ]
> +; CHECK-NEXT: br label [[RETURN]]
> +; CHECK: return:
> +; CHECK-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]], [[IF_THEN]] ], [
> [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
> +; CHECK-NEXT: ret i32 [[RETVAL_0]]
> +;
> entry:
> %cmp = icmp sgt i32 %a, %b
> br i1 %cmp, label %if.then, label %if.end
> @@ -109,6 +143,79 @@ return: ;
> preds = %cond.end, %if.then3
> }
>
> define i32 @scc_rX(i32 %a, i32 %b, i32 %r) #0 {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@scc_rX
> +; IS__TUNIT____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
> +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; IS__TUNIT____: if.then:
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]])
> +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32
> [[A]], i32 [[CALL]])
> +; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
> +; IS__TUNIT____: if.end:
> +; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
> +; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label
> [[IF_END12:%.*]]
> +; IS__TUNIT____: if.then3:
> +; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]])
> +; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32
> [[B]], i32 undef)
> +; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32
> [[R]], i32 [[R]])
> +; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32
> [[CALL6]], i32 undef)
> +; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32
> [[B]], i32 undef)
> +; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]],
> i32 [[CALL7]], i32 [[CALL8]])
> +; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]],
> i32 [[CALL9]], i32 undef)
> +; IS__TUNIT____-NEXT: br label [[RETURN]]
> +; IS__TUNIT____: if.end12:
> +; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
> +; IS__TUNIT____-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; IS__TUNIT____: cond.true:
> +; IS__TUNIT____-NEXT: br label [[COND_END:%.*]]
> +; IS__TUNIT____: cond.false:
> +; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32
> [[B]], i32 [[R]])
> +; IS__TUNIT____-NEXT: br label [[COND_END]]
> +; IS__TUNIT____: cond.end:
> +; IS__TUNIT____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ],
> [ [[CALL14]], [[COND_FALSE]] ]
> +; IS__TUNIT____-NEXT: br label [[RETURN]]
> +; IS__TUNIT____: return:
> +; 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____-LABEL: define {{[^@]+}}@scc_rX
> +; IS__CGSCC____-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[R:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], [[B]]
> +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; IS__CGSCC____: if.then:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32 @sink_r0(i32 [[R]])
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call i32 @scc_r2(i32 [[B]], i32
> [[A]], i32 [[CALL]])
> +; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
> +; IS__CGSCC____: if.end:
> +; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp slt i32 [[A]], [[B]]
> +; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label
> [[IF_END12:%.*]]
> +; IS__CGSCC____: if.then3:
> +; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call i32 @sink_r0(i32 [[B]])
> +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call i32 @scc_r1(i32 [[A]], i32
> [[B]], i32 [[R]])
> +; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call i32 @scc_r2(i32 [[R]], i32
> [[R]], i32 [[R]])
> +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call i32 @scc_r1(i32 [[A]], i32
> [[CALL6]], i32 [[R]])
> +; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call i32 @scc_r1(i32 [[A]], i32
> [[B]], i32 [[R]])
> +; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call i32 @scc_r2(i32 [[CALL5]],
> i32 [[CALL7]], i32 [[CALL8]])
> +; IS__CGSCC____-NEXT: [[CALL10:%.*]] = call i32 @scc_r1(i32 [[A]], i32
> [[B]], i32 [[R]])
> +; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call i32 @scc_r1(i32 [[CALL4]],
> i32 [[CALL9]], i32 [[CALL10]])
> +; IS__CGSCC____-NEXT: br label [[RETURN]]
> +; IS__CGSCC____: if.end12:
> +; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq i32 [[A]], [[B]]
> +; IS__CGSCC____-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; IS__CGSCC____: cond.true:
> +; IS__CGSCC____-NEXT: br label [[COND_END:%.*]]
> +; IS__CGSCC____: cond.false:
> +; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call i32 @scc_r2(i32 [[A]], i32
> [[B]], i32 [[R]])
> +; IS__CGSCC____-NEXT: br label [[COND_END]]
> +; IS__CGSCC____: cond.end:
> +; IS__CGSCC____-NEXT: [[COND:%.*]] = phi i32 [ [[R]], [[COND_TRUE]] ],
> [ [[CALL14]], [[COND_FALSE]] ]
> +; IS__CGSCC____-NEXT: br label [[RETURN]]
> +; IS__CGSCC____: return:
> +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi i32 [ [[CALL1]],
> [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
> +; IS__CGSCC____-NEXT: ret i32 [[RETVAL_0]]
> +;
> entry:
> %cmp = icmp sgt i32 %a, %b
> br i1 %cmp, label %if.then, label %if.end
> @@ -156,14 +263,6 @@ return: ;
> preds = %cond.end, %if.then3
>
> ; TEST SCC test returning a pointer value argument
> ;
> -;
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double* @ptr_sink_r0(double* nofree readnone
> returned "no-capture-maybe-returned" %r)
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double* @ptr_scc_r1(double* nofree readnone %a,
> double* nofree readnone returned %r, double* nocapture nofree readnone %b)
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double* @ptr_scc_r2(double* nofree readnone %a,
> double* nofree readnone %b, double* nofree readnone returned %r)
> -;
> ; double* ptr_scc_r1(double* a, double* b, double* r);
> ; double* ptr_scc_r2(double* a, double* b, double* r);
> ;
> @@ -183,11 +282,30 @@ 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]]
> +;
> entry:
> ret double* %r
> }
>
> define double* @ptr_scc_r1(double* %a, double* %r, double* %b) #0 {
> +; 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:
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double*
> noalias nofree readnone "no-capture-maybe-returned" [[R]])
> +; 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____-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:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double*
> noalias nofree readnone [[R]])
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[R]], double* noalias nofree readnone [[A]],
> double* noalias nofree readnone [[CALL]])
> +; IS__CGSCC____-NEXT: ret double* [[CALL1]]
> +;
> entry:
> %call = call double* @ptr_sink_r0(double* %r)
> %call1 = call double* @ptr_scc_r2(double* %r, double* %a, double* %call)
> @@ -195,6 +313,78 @@ entry:
> }
>
> define double* @ptr_scc_r2(double* %a, double* %b, double* %r) #0 {
> +; 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:
> +; IS__TUNIT____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
> +; IS__TUNIT____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; IS__TUNIT____: if.then:
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double*
> noalias nofree readnone "no-capture-maybe-returned" [[R]])
> +; IS__TUNIT____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[B]], double* noalias nofree readnone [[A]],
> double* noalias nofree readnone [[CALL]])
> +; IS__TUNIT____-NEXT: br label [[RETURN:%.*]]
> +; IS__TUNIT____: if.end:
> +; IS__TUNIT____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
> +; IS__TUNIT____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label
> [[IF_END12:%.*]]
> +; IS__TUNIT____: if.then3:
> +; IS__TUNIT____-NEXT: [[CALL4:%.*]] = call double*
> @ptr_sink_r0(double* noalias nofree readnone [[B]])
> +; IS__TUNIT____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double*
> noalias nofree readnone [[A]], double* noalias nofree readnone [[B]],
> double* noalias nofree readnone undef)
> +; IS__TUNIT____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[R]], double* noalias nofree readnone [[R]],
> double* noalias nofree readnone [[R]])
> +; IS__TUNIT____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double*
> noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL6]],
> double* noalias nofree readnone undef)
> +; IS__TUNIT____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[A]], double* noalias nofree readnone [[B]],
> double* noalias nofree readnone [[R]])
> +; IS__TUNIT____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[CALL5]], double* noalias nofree readnone
> [[CALL7]], double* noalias nofree readnone [[CALL8]])
> +; IS__TUNIT____-NEXT: [[CALL11:%.*]] = call double*
> @ptr_scc_r1(double* noalias nofree readnone [[CALL4]], double* noalias
> nofree readnone [[CALL9]], double* noalias nofree readnone undef)
> +; IS__TUNIT____-NEXT: br label [[RETURN]]
> +; IS__TUNIT____: if.end12:
> +; IS__TUNIT____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
> +; IS__TUNIT____-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; IS__TUNIT____: cond.true:
> +; IS__TUNIT____-NEXT: br label [[COND_END:%.*]]
> +; IS__TUNIT____: cond.false:
> +; IS__TUNIT____-NEXT: [[CALL14:%.*]] = call double*
> @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree
> readnone [[B]], double* noalias nofree readnone [[R]])
> +; IS__TUNIT____-NEXT: br label [[COND_END]]
> +; IS__TUNIT____: cond.end:
> +; IS__TUNIT____-NEXT: [[COND:%.*]] = phi double* [ [[R]],
> [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
> +; IS__TUNIT____-NEXT: br label [[RETURN]]
> +; IS__TUNIT____: return:
> +; 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____-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:
> +; IS__CGSCC____-NEXT: [[CMP:%.*]] = icmp ugt double* [[A]], [[B]]
> +; IS__CGSCC____-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; IS__CGSCC____: if.then:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call double* @ptr_sink_r0(double*
> noalias nofree readnone [[R]])
> +; IS__CGSCC____-NEXT: [[CALL1:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[B]], double* noalias nofree readnone [[A]],
> double* noalias nofree readnone [[CALL]])
> +; IS__CGSCC____-NEXT: br label [[RETURN:%.*]]
> +; IS__CGSCC____: if.end:
> +; IS__CGSCC____-NEXT: [[CMP2:%.*]] = icmp ult double* [[A]], [[B]]
> +; IS__CGSCC____-NEXT: br i1 [[CMP2]], label [[IF_THEN3:%.*]], label
> [[IF_END12:%.*]]
> +; IS__CGSCC____: if.then3:
> +; IS__CGSCC____-NEXT: [[CALL4:%.*]] = call double*
> @ptr_sink_r0(double* noalias nofree readnone [[B]])
> +; IS__CGSCC____-NEXT: [[CALL5:%.*]] = call double* @ptr_scc_r1(double*
> noalias nofree readnone [[A]], double* noalias nofree readnone [[B]],
> double* noalias nofree readnone undef)
> +; IS__CGSCC____-NEXT: [[CALL6:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[R]], double* noalias nofree readnone [[R]],
> double* noalias nofree readnone [[R]])
> +; IS__CGSCC____-NEXT: [[CALL7:%.*]] = call double* @ptr_scc_r1(double*
> noalias nofree readnone [[A]], double* noalias nofree readnone [[CALL6]],
> double* noalias nofree readnone undef)
> +; IS__CGSCC____-NEXT: [[CALL8:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[A]], double* noalias nofree readnone [[B]],
> double* noalias nofree readnone [[R]])
> +; IS__CGSCC____-NEXT: [[CALL9:%.*]] = call double* @ptr_scc_r2(double*
> noalias nofree readnone [[CALL5]], double* noalias nofree readnone
> [[CALL7]], double* noalias nofree readnone [[CALL8]])
> +; IS__CGSCC____-NEXT: [[CALL11:%.*]] = call double*
> @ptr_scc_r1(double* noalias nofree readnone [[CALL4]], double* noalias
> nofree readnone [[CALL9]], double* noalias nofree readnone undef)
> +; IS__CGSCC____-NEXT: br label [[RETURN]]
> +; IS__CGSCC____: if.end12:
> +; IS__CGSCC____-NEXT: [[CMP13:%.*]] = icmp eq double* [[A]], [[B]]
> +; IS__CGSCC____-NEXT: br i1 [[CMP13]], label [[COND_TRUE:%.*]], label
> [[COND_FALSE:%.*]]
> +; IS__CGSCC____: cond.true:
> +; IS__CGSCC____-NEXT: br label [[COND_END:%.*]]
> +; IS__CGSCC____: cond.false:
> +; IS__CGSCC____-NEXT: [[CALL14:%.*]] = call double*
> @ptr_scc_r2(double* noalias nofree readnone [[A]], double* noalias nofree
> readnone [[B]], double* noalias nofree readnone [[R]])
> +; IS__CGSCC____-NEXT: br label [[COND_END]]
> +; IS__CGSCC____: cond.end:
> +; IS__CGSCC____-NEXT: [[COND:%.*]] = phi double* [ [[R]],
> [[COND_TRUE]] ], [ [[CALL14]], [[COND_FALSE]] ]
> +; IS__CGSCC____-NEXT: br label [[RETURN]]
> +; IS__CGSCC____: return:
> +; IS__CGSCC____-NEXT: [[RETVAL_0:%.*]] = phi double* [ [[CALL1]],
> [[IF_THEN]] ], [ [[CALL11]], [[IF_THEN3]] ], [ [[COND]], [[COND_END]] ]
> +; IS__CGSCC____-NEXT: ret double* [[RETVAL_0]]
> +;
> entry:
> %cmp = icmp ugt double* %a, %b
> br i1 %cmp, label %if.then, label %if.end
> @@ -246,9 +436,12 @@ return: ;
> preds = %cond.end, %if.then3
> ; return *a ? a : rt0(a);
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse noreturn nosync
> nounwind readnone uwtable willreturn
> -; BOTH-NEXT: define noalias nonnull align 536870912
> dereferenceable(4294967295) i32* @rt0(i32* nocapture nofree nonnull
> readnone align 4 dereferenceable(4) %a)
> 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
> +;
> entry:
> %v = load i32, i32* %a, align 4
> %tobool = icmp ne i32 %v, 0
> @@ -263,9 +456,12 @@ entry:
> ; return *a ? undef : rt1(a);
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse noreturn nosync
> nounwind readnone uwtable willreturn
> -; BOTH-NEXT: define noalias nonnull align 536870912
> dereferenceable(4294967295) i32* @rt1(i32* nocapture nofree nonnull
> readnone align 4 dereferenceable(4) %a)
> 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
> +;
> entry:
> %v = load i32, i32* %a, align 4
> %tobool = icmp ne i32 %v, 0
> @@ -276,15 +472,37 @@ entry:
>
> ; TEST another SCC test
> ;
> -; BOTH: define i32* @rt2_helper(i32* nofree readnone returned %a)
> -; BOTH: define i32* @rt2(i32* nofree readnone %a, i32* nofree readnone
> "no-capture-maybe-returned" %b)
> define i32* @rt2_helper(i32* %a) #0 {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@rt2_helper
> +; IS__TUNIT____-SAME: (i32* nofree readnone returned [[A:%.*]])
> +; IS__TUNIT____-NEXT: entry:
> +; IS__TUNIT____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias
> nofree readnone [[A]], i32* noalias nofree readnone
> "no-capture-maybe-returned" [[A]])
> +; IS__TUNIT____-NEXT: ret i32* [[CALL]]
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@rt2_helper
> +; IS__CGSCC____-SAME: (i32* nofree readnone returned [[A:%.*]])
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: [[CALL:%.*]] = call i32* @rt2(i32* noalias
> nofree readnone [[A]], i32* noalias nofree readnone [[A]])
> +; IS__CGSCC____-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %call = call i32* @rt2(i32* %a, i32* %a)
> ret i32* %call
> }
>
> define i32* @rt2(i32* %a, i32 *%b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@rt2
> +; CHECK-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone
> "no-capture-maybe-returned" [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
> +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @rt2_helper(i32* noalias nofree
> readnone [[A]])
> +; CHECK-NEXT: br label [[IF_END]]
> +; CHECK: if.end:
> +; CHECK-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [
> [[CALL]], [[IF_THEN]] ]
> +; CHECK-NEXT: ret i32* [[SEL]]
> +;
> entry:
> %cmp = icmp eq i32* %a, null
> br i1 %cmp, label %if.then, label %if.end
> @@ -300,15 +518,31 @@ if.end:
>
> ; TEST another SCC test
> ;
> -; BOTH: define i32* @rt3_helper(i32* nofree readnone %a, i32* nofree
> readnone returned "no-capture-maybe-returned" %b)
> -; BOTH: define i32* @rt3(i32* nofree readnone %a, i32* nofree readnone
> returned "no-capture-maybe-returned" %b)
> define i32* @rt3_helper(i32* %a, i32* %b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@rt3_helper
> +; CHECK-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone
> returned "no-capture-maybe-returned" [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @rt3(i32* noalias nofree
> readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned"
> [[B]])
> +; CHECK-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %call = call i32* @rt3(i32* %a, i32* %b)
> ret i32* %call
> }
>
> define i32* @rt3(i32* %a, i32 *%b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@rt3
> +; CHECK-SAME: (i32* nofree readnone [[A:%.*]], i32* nofree readnone
> returned "no-capture-maybe-returned" [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[A]], null
> +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @rt3_helper(i32* noalias nofree
> readnone [[A]], i32* noalias nofree readnone "no-capture-maybe-returned"
> [[B]])
> +; CHECK-NEXT: br label [[IF_END]]
> +; CHECK: if.end:
> +; CHECK-NEXT: [[SEL:%.*]] = phi i32* [ [[B]], [[ENTRY:%.*]] ], [
> [[CALL]], [[IF_THEN]] ]
> +; CHECK-NEXT: ret i32* [[SEL]]
> +;
> entry:
> %cmp = icmp eq i32* %a, null
> br i1 %cmp, label %if.then, label %if.end
> @@ -331,14 +565,14 @@ if.end:
> ; return r;
> ; }
> ;
> -; BOTH: declare void @unknown_fn(i32* (i32*)*)
> -;
> -; BOTH: Function Attrs: noinline nounwind uwtable
> -; BOTH-NEXT: define i32* @calls_unknown_fn(i32* nofree readnone returned
> "no-capture-maybe-returned" %r)
> -; ATTRIBUTOR: define i32* @calls_unknown_fn(i32* nofree readnone returned
> "no-capture-maybe-returned" %r)
> declare void @unknown_fn(i32* (i32*)*) #0
>
> define i32* @calls_unknown_fn(i32* %r) #0 {
> +; 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)
> +; CHECK-NEXT: ret i32* [[R]]
> +;
> tail call void @unknown_fn(i32* (i32*)* nonnull @calls_unknown_fn)
> ret i32* %r
> }
> @@ -357,23 +591,23 @@ define i32* @calls_unknown_fn(i32* %r) #0 {
> ;
> ; Verify the maybe-redefined function is not annotated:
> ;
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR: define linkonce_odr i32* @maybe_redefined_fn(i32* %r)
> -;
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR: define i32* @calls_maybe_redefined_fn(i32* returned %r)
> -;
> -; BOTH: Function Attrs: noinline nounwind uwtable
> -; BOTH-NEXT: define linkonce_odr i32* @maybe_redefined_fn(i32* %r)
> -;
> -; BOTH: Function Attrs: noinline nounwind uwtable
> -; BOTH-NEXT: define i32* @calls_maybe_redefined_fn(i32* returned %r)
> define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn
> +; CHECK-SAME: (i32* [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: ret i32* [[R]]
> +;
> entry:
> ret i32* %r
> }
>
> define i32* @calls_maybe_redefined_fn(i32* %r) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn
> +; CHECK-SAME: (i32* returned [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn(i32* [[R]])
> +; CHECK-NEXT: ret i32* [[R]]
> +;
> entry:
> %call = call i32* @maybe_redefined_fn(i32* %r)
> ret i32* %r
> @@ -391,18 +625,23 @@ entry:
> ;
> ; Verify the maybe-redefined function is not annotated:
> ;
> -; BOTH: Function Attrs: noinline nounwind uwtable
> -; BOTH-NEXT: define linkonce_odr i32* @maybe_redefined_fn2(i32* %r)
> -; BOTH: Function Attrs: noinline nounwind uwtable
> -; BOTH-NEXT: define i32* @calls_maybe_redefined_fn2(i32* %r)
> -;
> -; ATTRIBUTOR: define i32* @calls_maybe_redefined_fn2(i32* %r)
> define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@maybe_redefined_fn2
> +; CHECK-SAME: (i32* [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: ret i32* [[R]]
> +;
> entry:
> ret i32* %r
> }
>
> define i32* @calls_maybe_redefined_fn2(i32* %r) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@calls_maybe_redefined_fn2
> +; CHECK-SAME: (i32* [[R:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @maybe_redefined_fn2(i32* [[R]])
> +; CHECK-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %call = call i32* @maybe_redefined_fn2(i32* %r)
> ret i32* %call
> @@ -418,12 +657,20 @@ entry:
> ; return b == 0? b : x;
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable
> -; BOTH-NEXT: define double @select_and_phi(double returned %b)
> -;
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double @select_and_phi(double returned %b)
> 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]]
> +;
> entry:
> %cmp = fcmp ogt double %b, 0.000000e+00
> br i1 %cmp, label %if.then, label %if.end
> @@ -448,13 +695,22 @@ if.end: ;
> preds = %if.then, %entry
> ; return b == 0? b : x;
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
> -; BOTH-NEXT: define double @recursion_select_and_phi(i32 %a, double
> returned %b)
> -;
> -;
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double @recursion_select_and_phi(i32 %a, double
> returned %b)
> define double @recursion_select_and_phi(i32 %a, double %b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@recursion_select_and_phi
> +; CHECK-SAME: (i32 [[A:%.*]], double returned [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[DEC:%.*]] = add nsw i32 [[A]], -1
> +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[A]], 0
> +; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> +; CHECK: if.then:
> +; CHECK-NEXT: [[CALL:%.*]] = call double @recursion_select_and_phi(i32
> [[DEC]], double [[B]])
> +; CHECK-NEXT: br label [[IF_END]]
> +; CHECK: if.end:
> +; CHECK-NEXT: [[PHI:%.*]] = phi double [ [[CALL]], [[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]]
> +;
> entry:
> %dec = add nsw i32 %a, -1
> %cmp = icmp sgt i32 %a, 0
> @@ -478,13 +734,13 @@ if.end: ;
> preds = %if.then, %entry
> ; return (double*)b;
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable
> -; BOTH-NEXT: define double* @bitcast(i32* nofree readnone returned
> "no-capture-maybe-returned" %b)
> -;
> -;
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double* @bitcast(i32* nofree readnone returned
> "no-capture-maybe-returned" %b)
> 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]]
> +;
> entry:
> %bc0 = bitcast i32* %b to double*
> ret double* %bc0
> @@ -500,13 +756,25 @@ entry:
> ; return b != 0 ? b : x;
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable
> -; BOTH-NEXT: define double* @bitcasts_select_and_phi(i32* nofree readnone
> returned %b)
> -;
> -;
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double* @bitcasts_select_and_phi(i32* nofree
> readnone returned %b)
> 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]]
> +;
> entry:
> %bc0 = bitcast i32* %b to double*
> %cmp = icmp eq double* %bc0, null
> @@ -537,13 +805,23 @@ if.end: ;
> preds = %if.then, %entry
> ; /* return undef */
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable
> -; BOTH-NEXT: define double* @ret_arg_arg_undef(i32* nofree readnone
> returned %b)
> -;
> -;
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double* @ret_arg_arg_undef(i32* nofree readnone
> returned %b)
> 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
> +;
> entry:
> %bc0 = bitcast i32* %b to double*
> %cmp = icmp eq double* %bc0, null
> @@ -574,13 +852,23 @@ ret_undef:
> ; /* return undef */
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable
> -; BOTH-NEXT: define double* @ret_undef_arg_arg(i32* nofree readnone
> returned %b)
> -;
> -;
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define double* @ret_undef_arg_arg(i32* nofree readnone
> returned %b)
> 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]]
> +;
> entry:
> %bc0 = bitcast i32* %b to double*
> %cmp = icmp eq double* %bc0, null
> @@ -611,11 +899,22 @@ ret_arg1:
> ; /* return undef */
> ; }
> ;
> -; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable
> -; BOTH-NEXT: define double* @ret_undef_arg_undef(i32* nofree readnone
> returned %b)
> -;
> -; ATTRIBUTOR: define double* @ret_undef_arg_undef(i32* nofree readnone
> returned %b)
> 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
> +;
> entry:
> %bc0 = bitcast i32* %b to double*
> %cmp = icmp eq double* %bc0, null
> @@ -644,13 +943,20 @@ ret_undef1:
> ;
> ; Verify we do not assume b is returned
> ;
> -; ATTRIBUTOR: define i32* @ret_arg_or_unknown(i32* %b)
> -; ATTRIBUTOR: define i32* @ret_arg_or_unknown_through_phi(i32* %b)
> -; BOTH: define i32* @ret_arg_or_unknown(i32* %b)
> -; BOTH: define i32* @ret_arg_or_unknown_through_phi(i32* %b)
> declare i32* @unknown(i32*)
>
> define i32* @ret_arg_or_unknown(i32* %b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown
> +; CHECK-SAME: (i32* [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
> +; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label
> [[RET_UNKNOWN:%.*]]
> +; CHECK: ret_arg:
> +; CHECK-NEXT: ret i32* [[B]]
> +; CHECK: ret_unknown:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
> +; CHECK-NEXT: ret i32* [[CALL]]
> +;
> entry:
> %cmp = icmp eq i32* %b, null
> br i1 %cmp, label %ret_arg, label %ret_unknown
> @@ -664,6 +970,20 @@ ret_unknown:
> }
>
> define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@ret_arg_or_unknown_through_phi
> +; CHECK-SAME: (i32* [[B:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32* [[B]], null
> +; CHECK-NEXT: br i1 [[CMP]], label [[RET_ARG:%.*]], label
> [[RET_UNKNOWN:%.*]]
> +; CHECK: ret_arg:
> +; CHECK-NEXT: br label [[R:%.*]]
> +; CHECK: ret_unknown:
> +; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown(i32* [[B]])
> +; CHECK-NEXT: br label [[R]]
> +; CHECK: r:
> +; CHECK-NEXT: [[PHI:%.*]] = phi i32* [ [[B]], [[RET_ARG]] ], [
> [[CALL]], [[RET_UNKNOWN]] ]
> +; CHECK-NEXT: ret i32* [[PHI]]
> +;
> entry:
> %cmp = icmp eq i32* %b, null
> br i1 %cmp, label %ret_arg, label %ret_unknown
> @@ -682,15 +1002,14 @@ r:
>
> ; TEST inconsistent IR in dead code.
> ;
> -; ATTRIBUTOR: define i32 @deadblockcall1(i32 returned %A)
> -; ATTRIBUTOR: define i32 @deadblockcall2(i32 returned %A)
> -; ATTRIBUTOR: define i32 @deadblockphi1(i32 returned %A)
> -; ATTRIBUTOR: define i32 @deadblockphi2(i32 returned %A)
> -; BOTH: define i32 @deadblockcall1(i32 returned %A)
> -; BOTH: define i32 @deadblockcall2(i32 returned %A)
> -; BOTH: define i32 @deadblockphi1(i32 returned %A)
> -; BOTH: define i32 @deadblockphi2(i32 returned %A)
> 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
> +;
> entry:
> ret i32 %A
> unreachableblock:
> @@ -701,6 +1020,15 @@ 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
> +;
> entry:
> ret i32 %A
> unreachableblock1:
> @@ -712,6 +1040,17 @@ 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]]
> +;
> entry:
> br label %r
> unreachableblock1:
> @@ -726,6 +1065,19 @@ 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]]
> +;
> entry:
> br label %r
> unreachableblock1:
> @@ -745,6 +1097,20 @@ r:
> declare void @noreturn() noreturn;
>
> define i32 @deadblockphi3(i32 %A, i1 %c) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@deadblockphi3
> +; CHECK-SAME: (i32 returned [[A:%.*]], i1 [[C:%.*]])
> +; CHECK-NEXT: entry:
> +; CHECK-NEXT: br i1 [[C]], label [[R:%.*]], label
> [[UNREACHABLECALL:%.*]]
> +; CHECK: unreachablecall:
> +; CHECK-NEXT: call void @noreturn()
> +; CHECK-NEXT: unreachable
> +; CHECK: unreachableblock2:
> +; CHECK-NEXT: unreachable
> +; CHECK: unreachableblock3:
> +; CHECK-NEXT: unreachable
> +; CHECK: r:
> +; CHECK-NEXT: ret i32 [[A]]
> +;
> entry:
> br i1 %c, label %r, label %unreachablecall
> unreachablecall:
> @@ -763,38 +1129,109 @@ r:
> }
>
> define weak_odr i32 @non_exact_0() {
> +; CHECK-LABEL: define {{[^@]+}}@non_exact_0()
> +; CHECK-NEXT: ret i32 0
> +;
> ret i32 0
> }
> define weak_odr i32 @non_exact_1(i32 %a) {
> +; CHECK-LABEL: define {{[^@]+}}@non_exact_1
> +; CHECK-SAME: (i32 [[A:%.*]])
> +; CHECK-NEXT: ret i32 [[A]]
> +;
> ret i32 %a
> }
> define weak_odr i32 @non_exact_2(i32 returned %a) {
> +; CHECK-LABEL: define {{[^@]+}}@non_exact_2
> +; CHECK-SAME: (i32 returned [[A:%.*]])
> +; CHECK-NEXT: ret i32 [[A]]
> +;
> ret i32 %a
> }
> define weak_odr align 16 i32* @non_exact_3(i32* align 32 returned %a) {
> +; CHECK-LABEL: define {{[^@]+}}@non_exact_3
> +; CHECK-SAME: (i32* returned align 32 [[A:%.*]])
> +; CHECK-NEXT: ret i32* [[A]]
> +;
> ret i32* %a
> }
> define weak_odr align 16 i32* @non_exact_4(i32* align 32 %a) {
> +; CHECK-LABEL: define {{[^@]+}}@non_exact_4
> +; CHECK-SAME: (i32* align 32 [[A:%.*]])
> +; CHECK-NEXT: ret i32* [[A]]
> +;
> ret i32* %a
> }
> +; We can use the alignment information of the weak function non_exact_3
> argument
> +; because it was given to us and not derived.
> +; We can use the return information of the weak function non_exact_4.
> +; FIXME: %c2 and %c3 should be replaced but not %c0 or %c1!
> define i32 @exact(i32* align 8 %a, i32* align 8 %b) {
> +; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@exact
> +; NOT_CGSCC_NPM-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]])
> +; NOT_CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @non_exact_0()
> +; NOT_CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 1)
> +; NOT_CGSCC_NPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 2)
> +; NOT_CGSCC_NPM-NEXT: [[C3:%.*]] = call align 32 i32*
> @non_exact_3(i32* align 32 [[A]])
> +; NOT_CGSCC_NPM-NEXT: [[C4:%.*]] = call align 16 i32*
> @non_exact_4(i32* align 32 [[B]])
> +; NOT_CGSCC_NPM-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32
> +; NOT_CGSCC_NPM-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16
> +; NOT_CGSCC_NPM-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]]
> +; NOT_CGSCC_NPM-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], [[C2]]
> +; NOT_CGSCC_NPM-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]]
> +; NOT_CGSCC_NPM-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]]
> +; NOT_CGSCC_NPM-NEXT: ret i32 [[ADD4]]
> +;
> +; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@exact
> +; IS__CGSCC_NPM-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]])
> +; IS__CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @non_exact_0()
> +; IS__CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 1)
> +; IS__CGSCC_NPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 2)
> +; IS__CGSCC_NPM-NEXT: [[C3:%.*]] = call align 32 i32*
> @non_exact_3(i32* align 32 [[A]])
> +; IS__CGSCC_NPM-NEXT: [[C4:%.*]] = call align 16 i32*
> @non_exact_4(i32* align 32 [[B]])
> +; IS__CGSCC_NPM-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32
> +; IS__CGSCC_NPM-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16
> +; IS__CGSCC_NPM-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]]
> +; IS__CGSCC_NPM-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2
> +; IS__CGSCC_NPM-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]]
> +; IS__CGSCC_NPM-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]]
> +; IS__CGSCC_NPM-NEXT: ret i32 [[ADD4]]
> +;
> +; ____CGSCC_NPM-LABEL: define {{[^@]+}}@exact
> +; ____CGSCC_NPM-SAME: (i32* align 8 [[A:%.*]], i32* align 8 [[B:%.*]])
> +; ____CGSCC_NPM-NEXT: [[C0:%.*]] = call i32 @non_exact_0()
> +; ____CGSCC_NPM-NEXT: [[C1:%.*]] = call i32 @non_exact_1(i32 1)
> +; ____CGSCC_NPM-NEXT: [[C2:%.*]] = call i32 @non_exact_2(i32 2)
> +; ____CGSCC_NPM-NEXT: [[C3:%.*]] = call align 32 i32*
> @non_exact_3(i32* align 32 [[A]])
> +; ____CGSCC_NPM-NEXT: [[C4:%.*]] = call align 16 i32*
> @non_exact_4(i32* align 32 [[B]])
> +; ____CGSCC_NPM-NEXT: [[C3L:%.*]] = load i32, i32* [[C3]], align 32
> +; ____CGSCC_NPM-NEXT: [[C4L:%.*]] = load i32, i32* [[C4]], align 16
> +; ____CGSCC_NPM-NEXT: [[ADD1:%.*]] = add i32 [[C0]], [[C1]]
> +; ____CGSCC_NPM-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 2
> +; ____CGSCC_NPM-NEXT: [[ADD3:%.*]] = add i32 [[ADD2]], [[C3L]]
> +; ____CGSCC_NPM-NEXT: [[ADD4:%.*]] = add i32 [[ADD3]], [[C4L]]
> +; ____CGSCC_NPM-NEXT: ret i32 [[ADD4]]
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-LABEL: define {{[^@]+}}@exact
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-SAME: (i32* align 8 [[A:%.*]], i32*
> align 8 [[B:%.*]])
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[C0:%.*]] = call i32
> @non_exact_0()
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[C1:%.*]] = call i32
> @non_exact_1(i32 1)
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[C2:%.*]] = call i32
> @non_exact_2(i32 2)
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[C3:%.*]] = call align 32
> i32* @non_exact_3(i32* align 32 [[A]])
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[C4:%.*]] = call align 16
> i32* @non_exact_4(i32* align 32 [[B]])
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[C3L:%.*]] = load i32,
> i32* [[C3]], align 32
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[C4L:%.*]] = load i32,
> i32* [[C4]], align 16
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[ADD1:%.*]] = add i32
> [[C0]], [[C1]]
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[ADD2:%.*]] = add i32
> [[ADD1]], 2
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[ADD3:%.*]] = add i32
> [[ADD2]], [[C3L]]
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: [[ADD4:%.*]] = add i32
> [[ADD3]], [[C4L]]
> +; CGSCC_NPM,CHECK_MODULE,CHECK_CGSCC-NEXT: ret i32 [[ADD4]]
> %c0 = call i32 @non_exact_0()
> %c1 = call i32 @non_exact_1(i32 1)
> %c2 = call i32 @non_exact_2(i32 2)
> %c3 = call i32* @non_exact_3(i32* %a)
> %c4 = call i32* @non_exact_4(i32* %b)
> -; We can use the alignment information of the weak function non_exact_3
> argument
> -; because it was given to us and not derived.
> -; ATTRIBUTOR: %c3l = load i32, i32* %c3, align 32
> %c3l = load i32, i32* %c3
> -; We can use the return information of the weak function non_exact_4.
> -; ATTRIBUTOR: %c4l = load i32, i32* %c4, align 16
> %c4l = load i32, i32* %c4
> -; FIXME: %c2 and %c3 should be replaced but not %c0 or %c1!
> -; ATTRIBUTOR: %add1 = add i32 %c0, %c1
> -; ATTRIBUTOR: %add2 = add i32 %add1, %c2
> -; ATTRIBUTOR: %add3 = add i32 %add2, %c3l
> -; ATTRIBUTOR: %add4 = add i32 %add3, %c4l
> %add1 = add i32 %c0, %c1
> %add2 = add i32 %add1, %c2
> %add3 = add i32 %add2, %c3l
> @@ -804,17 +1241,30 @@ 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]]
> +;
> %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*)
> +;
> %c = call i32* @ret_const()
> - ; ATTRIBUTOR: ret i32* bitcast (i8* @G to i32*)
> ret i32* %c
> }
> define i32* @dont_use_const() #0 {
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@dont_use_const()
> +; IS__TUNIT____-NEXT: [[C:%.*]] = musttail call i32* @ret_const()
> +; IS__TUNIT____-NEXT: ret i32* [[C]]
> +;
> +; 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]]
> +;
> %c = musttail call i32* @ret_const()
> - ; ATTRIBUTOR: ret i32* %c
> ret i32* %c
> }
>
>
> diff --git a/llvm/test/Transforms/Attributor/undefined_behavior.ll
> b/llvm/test/Transforms/Attributor/undefined_behavior.ll
> index 4265de525e73..4aa9cef4a64f 100644
> --- a/llvm/test/Transforms/Attributor/undefined_behavior.ll
> +++ b/llvm/test/Transforms/Attributor/undefined_behavior.ll
> @@ -1,4 +1,8 @@
> -; RUN: opt --attributor --attributor-disable=false -S < %s | FileCheck %s
> --check-prefix=ATTRIBUTOR
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
>
> @@ -9,16 +13,16 @@ target datalayout =
> "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> ; -- Load tests --
>
> define void @load_wholly_unreachable() {
> -; ATTRIBUTOR-LABEL: @load_wholly_unreachable(
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@load_wholly_unreachable()
> +; CHECK-NEXT: unreachable
> ;
> %a = load i32, i32* null
> ret void
> }
>
> define void @loads_wholly_unreachable() {
> -; ATTRIBUTOR-LABEL: @loads_wholly_unreachable(
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@loads_wholly_unreachable()
> +; CHECK-NEXT: unreachable
> ;
> %a = load i32, i32* null
> %b = load i32, i32* null
> @@ -27,12 +31,13 @@ define void @loads_wholly_unreachable() {
>
>
> define void @load_single_bb_unreachable(i1 %cond) {
> -; ATTRIBUTOR-LABEL: @load_single_bb_unreachable(
> -; ATTRIBUTOR-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[E:%.*]]
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> br i1 %cond, label %t, label %e
> t:
> @@ -45,20 +50,23 @@ 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"="true" {
> -; ATTRIBUTOR-LABEL: @load_null_pointer_is_defined(
> -; ATTRIBUTOR-NEXT: ret void
> +; CHECK-LABEL: define {{[^@]+}}@load_null_pointer_is_defined()
> +; CHECK-NEXT: ret void
> ;
> %a = load i32, i32* null
> ret void
> }
>
> define internal i32* @ret_null() {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@ret_null()
> +; IS__CGSCC____-NEXT: ret i32* null
> +;
> ret i32* null
> }
>
> define void @load_null_propagated() {
> -; ATTRIBUTOR-LABEL: @load_null_propagated(
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@load_null_propagated()
> +; CHECK-NEXT: unreachable
> ;
> %ptr = call i32* @ret_null()
> %a = load i32, i32* %ptr
> @@ -68,20 +76,21 @@ define void @load_null_propagated() {
> ; -- Store tests --
>
> define void @store_wholly_unreachable() {
> -; ATTRIBUTOR-LABEL: @store_wholly_unreachable(
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@store_wholly_unreachable()
> +; CHECK-NEXT: unreachable
> ;
> store i32 5, i32* null
> ret void
> }
>
> define void @store_single_bb_unreachable(i1 %cond) {
> -; ATTRIBUTOR-LABEL: @store_single_bb_unreachable(
> -; ATTRIBUTOR-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[E:%.*]]
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> br i1 %cond, label %t, label %e
> t:
> @@ -92,9 +101,9 @@ e:
> }
>
> define void @store_null_pointer_is_defined()
> "null-pointer-is-valid"="true" {
> -; ATTRIBUTOR-LABEL: @store_null_pointer_is_defined(
> -; ATTRIBUTOR-NEXT: store i32 5, i32* null
> -; ATTRIBUTOR-NEXT: ret void
> +; CHECK-LABEL: define {{[^@]+}}@store_null_pointer_is_defined()
> +; CHECK-NEXT: store i32 5, i32* null, align 536870912
> +; CHECK-NEXT: ret void
> ;
> store i32 5, i32* null
> ret void
> @@ -103,6 +112,9 @@ define void @store_null_pointer_is_defined()
> "null-pointer-is-valid"="true" {
> define void @store_null_propagated() {
> ; ATTRIBUTOR-LABEL: @store_null_propagated(
> ; ATTRIBUTOR-NEXT: unreachable
> +;
> +; CHECK-LABEL: define {{[^@]+}}@store_null_propagated()
> +; CHECK-NEXT: unreachable
> ;
> %ptr = call i32* @ret_null()
> store i32 5, i32* %ptr
> @@ -112,20 +124,21 @@ define void @store_null_propagated() {
> ; -- AtomicRMW tests --
>
> define void @atomicrmw_wholly_unreachable() {
> -; ATTRIBUTOR-LABEL: @atomicrmw_wholly_unreachable(
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@atomicrmw_wholly_unreachable()
> +; CHECK-NEXT: unreachable
> ;
> %a = atomicrmw add i32* null, i32 1 acquire
> ret void
> }
>
> define void @atomicrmw_single_bb_unreachable(i1 %cond) {
> -; ATTRIBUTOR-LABEL: @atomicrmw_single_bb_unreachable(
> -; ATTRIBUTOR-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[E:%.*]]
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> br i1 %cond, label %t, label %e
> t:
> @@ -136,9 +149,9 @@ e:
> }
>
> define void @atomicrmw_null_pointer_is_defined()
> "null-pointer-is-valid"="true" {
> -; ATTRIBUTOR-LABEL: @atomicrmw_null_pointer_is_defined(
> -; ATTRIBUTOR-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire
> -; ATTRIBUTOR-NEXT: ret void
> +; CHECK-LABEL: define {{[^@]+}}@atomicrmw_null_pointer_is_defined()
> +; CHECK-NEXT: [[A:%.*]] = atomicrmw add i32* null, i32 1 acquire
> +; CHECK-NEXT: ret void
> ;
> %a = atomicrmw add i32* null, i32 1 acquire
> ret void
> @@ -147,6 +160,9 @@ define void @atomicrmw_null_pointer_is_defined()
> "null-pointer-is-valid"="true"
> define void @atomicrmw_null_propagated() {
> ; ATTRIBUTOR-LABEL: @atomicrmw_null_propagated(
> ; ATTRIBUTOR-NEXT: unreachable
> +;
> +; CHECK-LABEL: define {{[^@]+}}@atomicrmw_null_propagated()
> +; CHECK-NEXT: unreachable
> ;
> %ptr = call i32* @ret_null()
> %a = atomicrmw add i32* %ptr, i32 1 acquire
> @@ -156,20 +172,21 @@ define void @atomicrmw_null_propagated() {
> ; -- AtomicCmpXchg tests --
>
> define void @atomiccmpxchg_wholly_unreachable() {
> -; ATTRIBUTOR-LABEL: @atomiccmpxchg_wholly_unreachable(
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_wholly_unreachable()
> +; CHECK-NEXT: unreachable
> ;
> %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic
> ret void
> }
>
> define void @atomiccmpxchg_single_bb_unreachable(i1 %cond) {
> -; ATTRIBUTOR-LABEL: @atomiccmpxchg_single_bb_unreachable(
> -; ATTRIBUTOR-NEXT: br i1 [[COND:%.*]], label [[T:%.*]], label [[E:%.*]]
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> br i1 %cond, label %t, label %e
> t:
> @@ -180,9 +197,9 @@ e:
> }
>
> define void @atomiccmpxchg_null_pointer_is_defined()
> "null-pointer-is-valid"="true" {
> -; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_pointer_is_defined(
> -; ATTRIBUTOR-NEXT: [[A:%.*]] = cmpxchg i32* null, i32 2, i32 3 acq_rel
> monotonic
> -; ATTRIBUTOR-NEXT: ret void
> +; 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
> ;
> %a = cmpxchg i32* null, i32 2, i32 3 acq_rel monotonic
> ret void
> @@ -191,6 +208,9 @@ define void @atomiccmpxchg_null_pointer_is_defined()
> "null-pointer-is-valid"="tr
> define void @atomiccmpxchg_null_propagated() {
> ; ATTRIBUTOR-LABEL: @atomiccmpxchg_null_propagated(
> ; ATTRIBUTOR-NEXT: unreachable
> +;
> +; CHECK-LABEL: define {{[^@]+}}@atomiccmpxchg_null_propagated()
> +; CHECK-NEXT: unreachable
> ;
> %ptr = call i32* @ret_null()
> %a = cmpxchg i32* %ptr, i32 2, i32 3 acq_rel monotonic
> @@ -202,14 +222,13 @@ define void @atomiccmpxchg_null_propagated() {
> ; Note: The unreachable on %t and %e is _not_ from AAUndefinedBehavior
>
> define i32 @cond_br_on_undef() {
> -; ATTRIBUTOR-LABEL: @cond_br_on_undef(
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef()
> +; CHECK-NEXT: unreachable
> +; CHECK: t:
> +; CHECK-NEXT: unreachable
> +; CHECK: e:
> +; CHECK-NEXT: unreachable
> ;
> -
> br i1 undef, label %t, label %e
> t:
> ret i32 1
> @@ -218,21 +237,21 @@ e:
> }
>
> ; More complicated branching
> -define void @cond_br_on_undef2(i1 %cond) {
> -; ATTRIBUTOR-LABEL: @cond_br_on_undef2(
> -; ATTRIBUTOR-NEXT: br i1 [[COND:%.*]], label [[T1:%.*]], label
> [[E1:%.*]]
> -; ATTRIBUTOR: t1:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: t2:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e2:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e1:
> -; ATTRIBUTOR-NEXT: ret void
> -;
> -
> ; 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
> +;
> br i1 %cond, label %t1, label %e1
> t1:
> br i1 undef, label %t2, label %e2
> @@ -245,17 +264,20 @@ e1:
> }
>
> define i1 @ret_undef() {
> +; CHECK-LABEL: define {{[^@]+}}@ret_undef()
> +; CHECK-NEXT: ret i1 undef
> +;
> ret i1 undef
> }
>
> define void @cond_br_on_undef_interproc() {
> -; ATTRIBUTOR-LABEL: @cond_br_on_undef_interproc(
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: unreachable
> -
> +; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc()
> +; CHECK-NEXT: unreachable
> +; CHECK: t:
> +; CHECK-NEXT: unreachable
> +; CHECK: e:
> +; CHECK-NEXT: unreachable
> +;
> %cond = call i1 @ret_undef()
> br i1 %cond, label %t, label %e
> t:
> @@ -265,6 +287,13 @@ 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
> +;
> br i1 true, label %t, label %e
> t:
> ret i1 undef
> @@ -274,12 +303,13 @@ e:
>
> ; More complicated interproc deduction of undef
> define void @cond_br_on_undef_interproc2() {
> -; ATTRIBUTOR-LABEL: @cond_br_on_undef_interproc2(
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: unreachable
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: unreachable
> +; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_interproc2()
> +; CHECK-NEXT: unreachable
> +; CHECK: t:
> +; CHECK-NEXT: unreachable
> +; CHECK: e:
> +; CHECK-NEXT: unreachable
> +;
> %cond = call i1 @ret_undef2()
> br i1 %cond, label %t, label %e
> t:
> @@ -291,13 +321,13 @@ e:
> ; Branch on undef that depends on propagation of
> ; undef of a previous instruction.
> define i32 @cond_br_on_undef3() {
> -; ATTRIBUTOR-LABEL: @cond_br_on_undef3(
> -; ATTRIBUTOR-NEXT: br label %t
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: ret i32 1
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: unreachable
> -
> +; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef3()
> +; CHECK-NEXT: br label [[T:%.*]]
> +; CHECK: t:
> +; CHECK-NEXT: ret i32 1
> +; CHECK: e:
> +; CHECK-NEXT: unreachable
> +;
> %cond = icmp ne i32 1, undef
> br i1 %cond, label %t, label %e
> t:
> @@ -309,15 +339,15 @@ e:
> ; Branch on undef because of uninitialized value.
> ; FIXME: Currently it doesn't propagate the undef.
> define i32 @cond_br_on_undef_uninit() {
> -; ATTRIBUTOR-LABEL: @cond_br_on_undef_uninit(
> -; ATTRIBUTOR-NEXT: %alloc = alloca i1
> -; ATTRIBUTOR-NEXT: %cond = load i1, i1* %alloc
> -; ATTRIBUTOR-NEXT: br i1 %cond, label %t, label %e
> -; ATTRIBUTOR: t:
> -; ATTRIBUTOR-NEXT: ret i32 1
> -; ATTRIBUTOR: e:
> -; ATTRIBUTOR-NEXT: ret i32 2
> -
> +; CHECK-LABEL: define {{[^@]+}}@cond_br_on_undef_uninit()
> +; CHECK-NEXT: [[ALLOC:%.*]] = alloca i1
> +; 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
> +;
> %alloc = alloca i1
> %cond = load i1, i1* %alloc
> br i1 %cond, label %t, label %e
> @@ -330,8 +360,16 @@ e:
> ; Note that the `load` has UB (so it will be changed to unreachable)
> ; and the branch is a terminator that can be constant-folded.
> ; We want to test that doing both won't cause a segfault.
> +; MODULE-NOT: @callee(
> define internal i32 @callee(i1 %C, i32* %A) {
> -; ATTRIBUTOR-NOT: @callee(
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@callee()
> +; IS__CGSCC____-NEXT: entry:
> +; IS__CGSCC____-NEXT: unreachable
> +; IS__CGSCC____: T:
> +; IS__CGSCC____-NEXT: unreachable
> +; IS__CGSCC____: F:
> +; IS__CGSCC____-NEXT: ret i32 1
> ;
> entry:
> %A.0 = load i32, i32* null
> @@ -345,8 +383,9 @@ F:
> }
>
> define i32 @foo() {
> -; ATTRIBUTOR-LABEL: @foo()
> -; ATTRIBUTOR-NEXT: ret i32 1
> +; CHECK-LABEL: define {{[^@]+}}@foo()
> +; CHECK-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 5a131c6f0b8c..931212f53967 100644
> --- a/llvm/test/Transforms/Attributor/value-simplify.ll
> +++ b/llvm/test/Transforms/Attributor/value-simplify.ll
> @@ -1,38 +1,59 @@
> ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> -; RUN: opt -attributor --attributor-disable=false
> -attributor-annotate-decl-cs -S < %s | FileCheck %s
> -; TODO: Add max-iteration check
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> -; Disable update test checks and enable it where required.
> -; UTC_ARGS: --disable
> -
> -; ModuleID = 'value-simplify.ll'
> -source_filename = "value-simplify.ll"
> target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
> declare void @f(i32)
>
> ; Test1: Replace argument with constant
> define internal void @test1(i32 %a) {
> -; CHECK: tail call void @f(i32 1)
> +; CHECK-LABEL: define {{[^@]+}}@test1()
> +; CHECK-NEXT: tail call void @f(i32 1)
> +; CHECK-NEXT: ret void
> +;
> tail call void @f(i32 %a)
> ret void
> }
>
> define void @test1_helper() {
> +; CHECK-LABEL: define {{[^@]+}}@test1_helper()
> +; CHECK-NEXT: tail call void @test1()
> +; CHECK-NEXT: ret void
> +;
> tail call void @test1(i32 1)
> ret void
> }
>
> ; TEST 2 : Simplify return value
> define i32 @return0() {
> +; CHECK-LABEL: define {{[^@]+}}@return0()
> +; CHECK-NEXT: ret i32 0
> +;
> ret i32 0
> }
>
> define i32 @return1() {
> +; CHECK-LABEL: define {{[^@]+}}@return1()
> +; CHECK-NEXT: ret i32 1
> +;
> ret i32 1
> }
>
> -; CHECK: define i32 @test2_1(i1 %c)
> 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
> +;
> br i1 %c, label %if.true, label %if.false
> if.true:
> %call = tail call i32 @return0()
> @@ -43,25 +64,36 @@ if.false:
> br label %end
> end:
>
> -; CHECK: %ret = phi i32 [ %ret0, %if.true ], [ 1, %if.false ]
> %ret = phi i32 [ %ret0, %if.true ], [ %ret1, %if.false ]
>
> -; CHECK: ret i32 1
> ret i32 1
> }
>
>
>
> -; CHECK: define i32 @test2_2(i1 %c)
> define i32 @test2_2(i1 %c) {
> +; CHECK-LABEL: define {{[^@]+}}@test2_2
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: ret i32 1
> +;
> %ret = tail call i32 @test2_1(i1 %c)
> -; CHECK: ret i32 1
> ret i32 %ret
> }
>
> declare void @use(i32)
> -; CHECK: define void @test3(i1 %c)
> define void @test3(i1 %c) {
> +; CHECK-LABEL: define {{[^@]+}}@test3
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label
> [[IF_FALSE:%.*]]
> +; CHECK: if.true:
> +; CHECK-NEXT: br label [[END:%.*]]
> +; CHECK: if.false:
> +; CHECK-NEXT: br label [[END]]
> +; CHECK: end:
> +; CHECK-NEXT: [[R:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1,
> [[IF_FALSE]] ]
> +; CHECK-NEXT: tail call void @use(i32 1)
> +; CHECK-NEXT: ret void
> +;
> br i1 %c, label %if.true, label %if.false
> if.true:
> br label %end
> @@ -70,21 +102,40 @@ if.false:
> br label %end
> end:
>
> -; CHECK: %r = phi i32 [ 1, %if.true ], [ 1, %if.false ]
> %r = phi i32 [ 1, %if.true ], [ %ret1, %if.false ]
>
> -; CHECK: tail call void @use(i32 1)
> tail call void @use(i32 %r)
> ret void
> }
>
> define void @test-select-phi(i1 %c) {
> +; CHECK-LABEL: define {{[^@]+}}@test-select-phi
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: tail call void @use(i32 1)
> +; CHECK-NEXT: [[SELECT_NOT_SAME:%.*]] = select i1 [[C]], i32 1, i32 0
> +; CHECK-NEXT: tail call void @use(i32 [[SELECT_NOT_SAME]])
> +; CHECK-NEXT: br i1 [[C]], label [[IF_TRUE:%.*]], label
> [[IF_FALSE:%.*]]
> +; CHECK: if-true:
> +; CHECK-NEXT: br label [[END:%.*]]
> +; CHECK: if-false:
> +; CHECK-NEXT: br label [[END]]
> +; CHECK: end:
> +; CHECK-NEXT: [[PHI_SAME:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1,
> [[IF_FALSE]] ]
> +; CHECK-NEXT: [[PHI_NOT_SAME:%.*]] = phi i32 [ 0, [[IF_TRUE]] ], [ 1,
> [[IF_FALSE]] ]
> +; CHECK-NEXT: [[PHI_SAME_PROP:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [ 1,
> [[IF_FALSE]] ]
> +; CHECK-NEXT: [[PHI_SAME_UNDEF:%.*]] = phi i32 [ 1, [[IF_TRUE]] ], [
> undef, [[IF_FALSE]] ]
> +; CHECK-NEXT: [[SELECT_NOT_SAME_UNDEF:%.*]] = select i1 [[C]], i32
> [[PHI_NOT_SAME]], i32 undef
> +; CHECK-NEXT: tail call void @use(i32 1)
> +; CHECK-NEXT: tail call void @use(i32 [[PHI_NOT_SAME]])
> +; CHECK-NEXT: tail call void @use(i32 1)
> +; CHECK-NEXT: tail call void @use(i32 1)
> +; CHECK-NEXT: tail call void @use(i32 [[SELECT_NOT_SAME_UNDEF]])
> +; CHECK-NEXT: ret void
> +;
> %select-same = select i1 %c, i32 1, i32 1
> - ; CHECK: tail call void @use(i32 1)
> tail call void @use(i32 %select-same)
>
> %select-not-same = select i1 %c, i32 1, i32 0
> - ; CHECK: tail call void @use(i32 %select-not-same)
> tail call void @use(i32 %select-not-same)
> br i1 %c, label %if-true, label %if-false
> if-true:
> @@ -99,19 +150,14 @@ end:
> %select-not-same-undef = select i1 %c, i32 %phi-not-same, i32 undef
>
>
> - ; CHECK: tail call void @use(i32 1)
> tail call void @use(i32 %phi-same)
>
> - ; CHECK: tail call void @use(i32 %phi-not-same)
> tail call void @use(i32 %phi-not-same)
>
> - ; CHECK: tail call void @use(i32 1)
> tail call void @use(i32 %phi-same-prop)
>
> - ; CHECK: tail call void @use(i32 1)
> tail call void @use(i32 %phi-same-undef)
>
> - ; CHECK: tail call void @use(i32 %select-not-same-undef)
> tail call void @use(i32 %select-not-same-undef)
>
> ret void
> @@ -123,7 +169,7 @@ define i32 @ipccp1(i32 %a) {
> ; CHECK-SAME: (i32 returned [[A:%.*]])
> ; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]]
> ; CHECK: t:
> -; CHECK-NEXT: ret i32 [[A:%.*]]
> +; CHECK-NEXT: ret i32 [[A]]
> ; CHECK: f:
> ; CHECK-NEXT: unreachable
> ;
> @@ -136,6 +182,13 @@ f:
> }
>
> define internal i1 @ipccp2i(i1 %a) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2i()
> +; IS__CGSCC____-NEXT: br label [[T:%.*]]
> +; IS__CGSCC____: t:
> +; IS__CGSCC____-NEXT: ret i1 true
> +; IS__CGSCC____: f:
> +; IS__CGSCC____-NEXT: unreachable
> +;
> br i1 %a, label %t, label %f
> t:
> ret i1 %a
> @@ -145,14 +198,25 @@ f:
> }
>
> define i1 @ipccp2() {
> -; CHECK-LABEL: define {{[^@]+}}@ipccp2()
> -; CHECK-NEXT: ret i1 true
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp2()
> +; IS__TUNIT____-NEXT: ret i1 true
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2()
> +; IS__CGSCC____-NEXT: [[R:%.*]] = call i1 @ipccp2i()
> +; IS__CGSCC____-NEXT: ret i1 [[R]]
> ;
> %r = call i1 @ipccp2i(i1 true)
> ret i1 %r
> }
>
> define internal i1 @ipccp2ib(i1 %a) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp2ib()
> +; IS__CGSCC____-NEXT: br label [[T:%.*]]
> +; IS__CGSCC____: t:
> +; IS__CGSCC____-NEXT: ret i1 true
> +; IS__CGSCC____: f:
> +; IS__CGSCC____-NEXT: unreachable
> +;
> br i1 %a, label %t, label %f
> t:
> ret i1 true
> @@ -170,6 +234,13 @@ define i1 @ipccp2b() {
> }
>
> define internal i32 @ipccp3i(i32 %a) {
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp3i()
> +; IS__CGSCC____-NEXT: br label [[T:%.*]]
> +; IS__CGSCC____: t:
> +; IS__CGSCC____-NEXT: ret i32 7
> +; IS__CGSCC____: f:
> +; IS__CGSCC____-NEXT: unreachable
> +;
> %c = icmp eq i32 %a, 7
> br i1 %c, label %t, label %f
> t:
> @@ -180,20 +251,27 @@ f:
> }
>
> define i32 @ipccp3() {
> -; CHECK-LABEL: define {{[^@]+}}@ipccp3()
> -; CHECK-NEXT: ret i32 7
> +; IS__TUNIT____-LABEL: define {{[^@]+}}@ipccp3()
> +; IS__TUNIT____-NEXT: ret i32 7
> +;
> +; IS__CGSCC____-LABEL: define {{[^@]+}}@ipccp3()
> +; IS__CGSCC____-NEXT: [[R:%.*]] = call i32 @ipccp3i()
> +; IS__CGSCC____-NEXT: ret i32 [[R]]
> +;
> %r = call i32 @ipccp3i(i32 7)
> ret i32 %r
> }
>
> -; UTC_ARGS: --enable
> -
> ; 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 [[A:%.*]])
> -; CHECK-NEXT: ret i32* [[A]]
> +; 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____-LABEL: define {{[^@]+}}@test_inalloca
> +; IS__CGSCC____-SAME: (i32* inalloca noalias nofree returned writeonly
> "no-capture-maybe-returned" [[A:%.*]])
> +; IS__CGSCC____-NEXT: ret i32* [[A]]
> ;
> ret i32* %a
> }
> @@ -207,29 +285,45 @@ define i32* @complicated_args_inalloca() {
> }
>
> define internal void @test_sret(%struct.X* sret %a, %struct.X** %b) {
> -; CHECK-LABEL: define {{[^@]+}}@test_sret
> -; CHECK-SAME: (%struct.X* noalias nofree sret writeonly align 536870912
> [[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____-LABEL: define {{[^@]+}}@test_sret
> +; IS__TUNIT____-SAME: (%struct.X* noalias nofree sret writeonly align
> 536870912 [[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____-LABEL: define {{[^@]+}}@test_sret
> +; IS__CGSCC____-SAME: (%struct.X* noalias nofree sret writeonly
> [[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
> }
> ; FIXME: Alignment and dereferenceability are not propagated to the
> argument
> define void @complicated_args_sret(%struct.X** %b) {
> -; CHECK-LABEL: define {{[^@]+}}@complicated_args_sret
> -; CHECK-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]])
> -; CHECK-NEXT: call void @test_sret(%struct.X* noalias nofree writeonly
> align 536870912 null, %struct.X** nocapture nofree writeonly align 8 [[B]])
> -; CHECK-NEXT: ret void
> +;
> +; 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 nofree
> writeonly align 536870912 null, %struct.X** nocapture nofree writeonly
> align 8 [[B]])
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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 nofree
> writeonly align 536870912 null, %struct.X** nocapture nofree nonnull
> writeonly align 8 dereferenceable(8) [[B]])
> +; IS__CGSCC____-NEXT: ret void
> ;
> call void @test_sret(%struct.X* null, %struct.X** %b)
> ret void
> }
>
> 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 [[A:%.*]])
> -; CHECK-NEXT: ret %struct.X* [[A]]
> +; 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____-LABEL: define {{[^@]+}}@test_nest
> +; IS__CGSCC____-SAME: (%struct.X* nest noalias nofree readnone returned
> "no-capture-maybe-returned" [[A:%.*]])
> +; IS__CGSCC____-NEXT: ret %struct.X* [[A]]
> ;
> ret %struct.X* %a
> }
> @@ -244,6 +338,21 @@ define %struct.X* @complicated_args_nest() {
>
> @S = external global %struct.X
> define internal void @test_byval(%struct.X* byval %a) {
> +; 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-LABEL: define {{[^@]+}}@test_byval
> +; IS__CGSCC_NPM-SAME: (i8* nocapture nofree readnone [[TMP0:%.*]])
> +; IS__CGSCC_NPM-NEXT: [[A_PRIV:%.*]] = alloca [[STRUCT_X:%.*]]
> +; IS__CGSCC_NPM-NEXT: [[A_PRIV_CAST:%.*]] = bitcast %struct.X*
> [[A_PRIV]] to i8**
> +; IS__CGSCC_NPM-NEXT: store i8* [[TMP0]], i8** [[A_PRIV_CAST]]
> +; IS__CGSCC_NPM-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X]],
> %struct.X* [[A_PRIV]], i32 0, i32 0
> +; IS__CGSCC_NPM-NEXT: store i8* null, i8** [[G0]], align 8
> +; IS__CGSCC_NPM-NEXT: ret void
> +;
> %g0 = getelementptr %struct.X, %struct.X* %a, i32 0, i32 0
> store i8* null, i8** %g0
> ret void
> @@ -383,4 +492,3 @@ define internal i8 @callee(i8 %a) {
> ret i8 %c
> }
>
> -; UTC_ARGS: --disable
>
> diff --git a/llvm/test/Transforms/Attributor/willreturn.ll
> b/llvm/test/Transforms/Attributor/willreturn.ll
> index f521293e5a97..f168aa7864df 100644
> --- a/llvm/test/Transforms/Attributor/willreturn.ll
> +++ b/llvm/test/Transforms/Attributor/willreturn.ll
> @@ -1,19 +1,23 @@
> -; RUN: opt -passes=attributor --attributor-disable=false
> -attributor-max-iterations-verify -attributor-annotate-decl-cs
> -attributor-max-iterations=6 -S < %s | FileCheck %s
> --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_MODULE
> -; RUN: opt -passes=attributor-cgscc --attributor-disable=false
> -attributor-annotate-decl-cs -S < %s | FileCheck %s
> --check-prefixes=ATTRIBUTOR,ATTRIBUTOR_CGSCC
> +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
> UTC_ARGS: --function-signature --scrub-attributes
> +; RUN: opt -attributor -attributor-manifest-internal
> -attributor-disable=false -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-disable=false
> -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-disable=false -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-disable=false
> -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
>
> -
> -target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
> +target datalayout = "e-m:e-i54:64-f80:128-n8:16:32:64-S128"
>
> ; Test cases specifically designed for the "willreturn" function
> attribute.
> ; We use FIXME's to indicate problems and missing attributes.
>
>
> ; TEST 1 (positive case)
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree noinline nosync nounwind
> readnone uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree noinline norecurse nosync
> nounwind readnone uwtable willreturn
> -; ATTRIBUTOR-NEXT: define void @only_return()
> +; CHECK_MODULE: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable willreturn
> +; CHECK_CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable willreturn
> define void @only_return() #0 {
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@only_return()
> +; CHECK-NEXT: ret void
> +;
> + ret void
> }
>
>
> @@ -25,9 +29,22 @@ define void @only_return() #0 {
> ; }
>
> ; FIXME: missing willreturn
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> -; ATTRIBUTOR-NEXT: define i32 @fib(i32 %0) local_unnamed_addr
> +; CHECK: Function Attrs: nofree noinline nosync nounwind readnone uwtable
> define i32 @fib(i32 %0) local_unnamed_addr #0 {
> +; CHECK-LABEL: define {{[^@]+}}@fib
> +; CHECK-SAME: (i32 [[TMP0:%.*]]) local_unnamed_addr
> +; CHECK-NEXT: [[TMP2:%.*]] = icmp slt i32 [[TMP0]], 2
> +; CHECK-NEXT: br i1 [[TMP2]], label [[TMP9:%.*]], label [[TMP3:%.*]]
> +; CHECK: 3:
> +; CHECK-NEXT: [[TMP4:%.*]] = add nsw i32 [[TMP0]], -1
> +; CHECK-NEXT: [[TMP5:%.*]] = tail call i32 @fib(i32 [[TMP4]])
> +; CHECK-NEXT: [[TMP6:%.*]] = add nsw i32 [[TMP0]], -2
> +; CHECK-NEXT: [[TMP7:%.*]] = tail call i32 @fib(i32 [[TMP6]])
> +; CHECK-NEXT: [[TMP8:%.*]] = add nsw i32 [[TMP7]], [[TMP5]]
> +; CHECK-NEXT: ret i32 [[TMP8]]
> +; CHECK: 9:
> +; CHECK-NEXT: ret i32 [[TMP0]]
> +;
> %2 = icmp slt i32 %0, 2
> br i1 %2, label %9, label %3
>
> @@ -53,11 +70,27 @@ define i32 @fib(i32 %0) local_unnamed_addr #0 {
> ; }
> ; fact_maybe_not(-1) doesn't stop.
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree noinline nosync nounwind
> readnone uwtable
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree noinline norecurse nosync
> nounwind readnone uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define i32 @fact_maybe_not_halt(i32 %0)
> local_unnamed_addr
> +; CHECK_MODULE: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable
> +; CHECK_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]]
> +;
> %2 = icmp eq i32 %0, 0
> br i1 %2, label %11, label %3
>
> @@ -87,10 +120,24 @@ define i32 @fact_maybe_not_halt(i32 %0)
> local_unnamed_addr #0 {
> ; return ans;
> ; }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree noinline nosync nounwind
> readnone uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree noinline norecurse nosync
> nounwind readnone uwtable willreturn
> -; ATTRIBUTOR-NEXT: define i32 @fact_loop(i32 %0) local_unnamed_addr
> +; CHECK_MODULE: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable willreturn
> +; CHECK_CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable willreturn
> 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]]
> +;
> %2 = icmp slt i32 %0, 1
> br i1 %2, label %3, label %5
>
> @@ -118,10 +165,19 @@ define i32 @fact_loop(i32 %0) local_unnamed_addr #0 {
>
> declare void @sink() nounwind willreturn nosync nofree
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @mutual_recursion1(i1 %c)
> +; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable
> +; CHECK-NOT: willreturn
> define void @mutual_recursion1(i1 %c) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@mutual_recursion1
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: br i1 [[C]], label [[REC:%.*]], label [[END:%.*]]
> +; CHECK: rec:
> +; CHECK-NEXT: call void @sink()
> +; CHECK-NEXT: call void @mutual_recursion2(i1 [[C]])
> +; CHECK-NEXT: br label [[END]]
> +; CHECK: end:
> +; CHECK-NEXT: ret void
> +;
> br i1 %c, label %rec, label %end
> rec:
> call void @sink()
> @@ -132,10 +188,14 @@ end:
> }
>
>
> -; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @mutual_recursion2(i1 %c)
> +; CHECK: Function Attrs: nofree noinline nosync nounwind uwtable
> +; CHECK-NOT: willreturn
> define void @mutual_recursion2(i1 %c) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@mutual_recursion2
> +; CHECK-SAME: (i1 [[C:%.*]])
> +; CHECK-NEXT: call void @mutual_recursion1(i1 [[C]])
> +; CHECK-NEXT: ret void
> +;
> call void @mutual_recursion1(i1 %c)
> ret void
> }
> @@ -143,14 +203,17 @@ define void @mutual_recursion2(i1 %c) #0 {
>
> ; TEST 5 (negative case)
> ; call exit/abort (has noreturn attribute)
> -; ATTRIBUTOR: Function Attrs: noreturn
> -; ATTRIBUTOR-NEXT: declare void @exit(i32) local_unnamed_add
> +; CHECK: Function Attrs: noreturn
> +; CHECK-NEXT: declare void @exit(i32) local_unnamed_add
> declare void @exit(i32 %0) local_unnamed_addr noreturn
>
> -; ATTRIBUTOR: Function Attrs: noinline noreturn nounwind uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @only_exit() local_unnamed_addr
> +; CHECK: Function Attrs: noinline noreturn nounwind uwtable
> +; CHECK-NOT: willreturn
> define void @only_exit() local_unnamed_addr #0 {
> +; CHECK-LABEL: define {{[^@]+}}@only_exit() local_unnamed_addr
> +; CHECK-NEXT: tail call void @exit(i32 0)
> +; CHECK-NEXT: unreachable
> +;
> tail call void @exit(i32 0)
> unreachable
> }
> @@ -165,10 +228,26 @@ define void @only_exit() local_unnamed_addr #0 {
> ; }
> ; return;
> ; }
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @conditional_exit(i32 %0, i32* nocapture
> readonly %1) local_unnamed_addr
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: willreturn
> define void @conditional_exit(i32 %0, i32* nocapture readonly %1)
> local_unnamed_addr #0 {
> +; CHECK-LABEL: define {{[^@]+}}@conditional_exit
> +; CHECK-SAME: (i32 [[TMP0:%.*]], i32* nocapture readonly [[TMP1:%.*]])
> local_unnamed_addr
> +; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP0]], 0
> +; CHECK-NEXT: br i1 [[TMP3]], label [[TMP5:%.*]], label [[TMP4:%.*]]
> +; CHECK: 4:
> +; CHECK-NEXT: tail call void @exit(i32 0)
> +; CHECK-NEXT: unreachable
> +; CHECK: 5:
> +; CHECK-NEXT: [[TMP6:%.*]] = load i32, i32* [[TMP1]], align 4
> +; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i32 [[TMP6]], 0
> +; CHECK-NEXT: br i1 [[TMP7]], label [[TMP9:%.*]], label [[TMP8:%.*]]
> +; CHECK: 8:
> +; CHECK-NEXT: tail call void @exit(i32 1)
> +; CHECK-NEXT: unreachable
> +; CHECK: 9:
> +; CHECK-NEXT: ret void
> +;
> %3 = icmp eq i32 %0, 0
> br i1 %3, label %5, label %4
>
> @@ -191,77 +270,100 @@ define void @conditional_exit(i32 %0, i32*
> nocapture readonly %1) local_unnamed_
>
> ; TEST 6 (positive case)
> ; Call intrinsic function
> -; ATTRIBUTOR: Function Attrs: nounwind readnone speculatable willreturn
> -; ATTRIBUTOR-NEXT: declare float @llvm.floor.f32(float)
> +; CHECK: Function Attrs: nounwind readnone speculatable willreturn
> +; CHECK-NEXT: declare float @llvm.floor.f32(float)
> declare float @llvm.floor.f32(float)
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree noinline nosync nounwind
> readnone uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree noinline norecurse nosync
> nounwind readnone uwtable willreturn
> -; ATTRIBUTOR-NEXT: define void @call_floor(float %a)
> +; CHECK_MODULE: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable willreturn
> +; CHECK_CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable willreturn
> define void @call_floor(float %a) #0 {
> - tail call float @llvm.floor.f32(float %a)
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@call_floor
> +; CHECK-SAME: (float [[A:%.*]])
> +; CHECK-NEXT: ret void
> +;
> + tail call float @llvm.floor.f32(float %a)
> + ret void
> }
>
> -; ATTRIBUTOR: Function Attrs: noinline nosync nounwind readnone uwtable
> willreturn
> -; ATTRIBUTOR-NEXT: define float @call_floor2(float %a)
> +; CHECK: Function Attrs: noinline nosync nounwind readnone uwtable
> willreturn
> define float @call_floor2(float %a) #0 {
> - %c = tail call float @llvm.floor.f32(float %a)
> - ret float %c
> +; CHECK-LABEL: define {{[^@]+}}@call_floor2
> +; CHECK-SAME: (float [[A:%.*]])
> +; CHECK-NEXT: [[C:%.*]] = tail call float @llvm.floor.f32(float [[A]])
> +; CHECK-NEXT: ret float [[C]]
> +;
> + %c = tail call float @llvm.floor.f32(float %a)
> + ret float %c
> }
>
>
> ; TEST 7 (negative case)
> ; Call function declaration without willreturn
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: declare void @maybe_noreturn()
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: willreturn
> +; CHECK-NEXT: declare void @maybe_noreturn()
> declare void @maybe_noreturn() #0
>
> -; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @call_maybe_noreturn()
> +; CHECK: Function Attrs: noinline nounwind uwtable
> +; CHECK-NOT: willreturn
> define void @call_maybe_noreturn() #0 {
> - tail call void @maybe_noreturn()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@call_maybe_noreturn()
> +; CHECK-NEXT: tail call void @maybe_noreturn()
> +; CHECK-NEXT: ret void
> +;
> + tail call void @maybe_noreturn()
> + ret void
> }
>
>
> ; TEST 8 (positive case)
> ; Check propagation.
>
> -; ATTRIBUTOR: Function Attrs: norecurse willreturn
> -; ATTRIBUTOR-NEXT: declare void @will_return()
> +; CHECK: Function Attrs: norecurse willreturn
> +; CHECK-NEXT: declare void @will_return()
> declare void @will_return() willreturn norecurse
>
> -; ATTRIBUTOR_MODULE: Function Attrs: noinline nounwind uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: noinline norecurse nounwind uwtable
> willreturn
> -; ATTRIBUTOR-NEXT: define void @f1()
> +; CHECK_MODULE: Function Attrs: noinline nounwind uwtable willreturn
> +; CHECK_CGSCC: Function Attrs: noinline norecurse nounwind uwtable
> willreturn
> define void @f1() #0 {
> - tail call void @will_return()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@f1()
> +; CHECK-NEXT: tail call void @will_return()
> +; CHECK-NEXT: ret void
> +;
> + tail call void @will_return()
> + ret void
> }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: noinline nounwind uwtable
> +; CHECK_MODULE: Function Attrs: noinline nounwind uwtable
> ; FIXME: Because we do not derive norecurse in the module run anymore,
> willreturn is missing as well.
> -; ATTRIBUTOR_MODULE-NOT: willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: noinline norecurse nounwind uwtable
> willreturn
> -; ATTRIBUTOR-NEXT: define void @f2()
> +; CHECK_MODULE-NOT: willreturn
> +; CHECK_CGSCC: Function Attrs: noinline norecurse nounwind uwtable
> willreturn
> define void @f2() #0 {
> - tail call void @f1()
> - ret void
> +; CHECK-LABEL: define {{[^@]+}}@f2()
> +; CHECK-NEXT: tail call void @f1()
> +; CHECK-NEXT: ret void
> +;
> + tail call void @f1()
> + ret void
> }
>
>
> ; TEST 9 (negative case)
> ; call willreturn function in endless loop.
>
> -; ATTRIBUTOR_MODULE: Function Attrs: noinline noreturn nounwind uwtable
> -; ATTRIBUTOR_CGSCC: Function Attrs: noinline norecurse noreturn nounwind
> uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @call_will_return_but_has_loop()
> +; CHECK_MODULE: Function Attrs: noinline noreturn nounwind uwtable
> +; CHECK_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]]
> +;
> br label %label1
> label1:
> tail call void @will_return()
> @@ -274,21 +376,40 @@ label2:
> ; TEST 10 (positive case)
> ; invoke a function with willreturn
>
> -; ATTRIBUTOR: Function Attrs: noinline uwtable willreturn
> -; ATTRIBUTOR-NEXT: declare i1 @maybe_raise_exception()
> +; CHECK: Function Attrs: noinline uwtable willreturn
> +; CHECK-NEXT: declare i1 @maybe_raise_exception()
> declare i1 @maybe_raise_exception() #1 willreturn
>
> -; ATTRIBUTOR: Function Attrs: nounwind willreturn
> -; ATTRIBUTOR-NEXT: define void @invoke_test()
> +; CHECK: Function Attrs: nounwind willreturn
> define void @invoke_test() personality i32 (...)* @__gxx_personality_v0 {
> +; 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:%.*]]
> +; IS__TUNIT____: N:
> +; IS__TUNIT____-NEXT: ret void
> +; IS__TUNIT____: F:
> +; IS__TUNIT____-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 }
> +; IS__TUNIT____-NEXT: catch i8* null
> +; IS__TUNIT____-NEXT: ret void
> +;
> +; 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:%.*]]
> +; IS__CGSCC____: N:
> +; IS__CGSCC____-NEXT: ret void
> +; IS__CGSCC____: F:
> +; IS__CGSCC____-NEXT: [[VAL:%.*]] = landingpad { i8*, i32 }
> +; IS__CGSCC____-NEXT: catch i8* null
> +; IS__CGSCC____-NEXT: ret void
> +;
> invoke i1 @maybe_raise_exception()
> - to label %N unwind label %F
> + to label %N unwind label %F
> N:
> - ret void
> + ret void
> F:
> - %val = landingpad { i8*, i32 }
> - catch i8* null
> - ret void
> + %val = landingpad { i8*, i32 }
> + catch i8* null
> + ret void
> }
>
> declare i32 @__gxx_personality_v0(...)
> @@ -304,10 +425,24 @@ declare i32 @__gxx_personality_v0(...)
> ; return ans;
> ; }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: argmemonly nofree noinline nosync
> nounwind readonly uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: argmemonly nofree noinline norecurse
> nosync nounwind readonly uwtable willreturn
> -; ATTRIBUTOR-NEXT: define i32 @loop_constant_trip_count(i32* nocapture
> nofree readonly %0)
> +; CHECK_MODULE: Function Attrs: argmemonly nofree noinline nosync
> nounwind readonly uwtable willreturn
> +; CHECK_CGSCC: Function Attrs: argmemonly nofree noinline norecurse
> nosync nounwind readonly uwtable willreturn
> define i32 @loop_constant_trip_count(i32* nocapture readonly %0) #0 {
> +; CHECK-LABEL: define {{[^@]+}}@loop_constant_trip_count
> +; CHECK-SAME: (i32* nocapture nofree readonly [[TMP0:%.*]])
> +; CHECK-NEXT: br label [[TMP3:%.*]]
> +; CHECK: 2:
> +; CHECK-NEXT: ret i32 [[TMP8:%.*]]
> +; CHECK: 3:
> +; CHECK-NEXT: [[TMP4:%.*]] = phi i64 [ 0, [[TMP1:%.*]] ], [
> [[TMP9:%.*]], [[TMP3]] ]
> +; CHECK-NEXT: [[TMP5:%.*]] = phi i32 [ 0, [[TMP1]] ], [ [[TMP8]],
> [[TMP3]] ]
> +; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32*
> [[TMP0]], i64 [[TMP4]]
> +; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4
> +; CHECK-NEXT: [[TMP8]] = add nsw i32 [[TMP7]], [[TMP5]]
> +; CHECK-NEXT: [[TMP9]] = add nuw nsw i64 [[TMP4]], 1
> +; CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 10
> +; CHECK-NEXT: br i1 [[TMP10]], label [[TMP2:%.*]], label [[TMP3]]
> +;
> br label %3
>
> ; <label>:2: ; preds = %3
> @@ -335,12 +470,28 @@ define i32 @loop_constant_trip_count(i32* nocapture
> readonly %0) #0 {
> ; }
> ; return ans;
> ; }
> -; FNATTR-NEXT: define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32*
> nocapture readonly %2, i32 %3) local_unnamed_addr
> -; ATTRIBUTOR_MODULE: Function Attrs: argmemonly nofree noinline nosync
> nounwind readonly uwtable
> -; ATTRIBUTOR_CGSCC: Function Attrs: argmemonly nofree noinline norecurse
> nosync nounwind readonly uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define i32 @loop_trip_count_unbound(i32 %0, i32 %1,
> i32* nocapture nofree readonly %2, i32 %3) local_unnamed_addr
> +; CHECK_MODULE: Function Attrs: argmemonly nofree noinline nosync
> nounwind readonly uwtable
> +; CHECK_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]]
> +;
> %5 = icmp eq i32 %0, %1
> br i1 %5, label %6, label %8
>
> @@ -372,11 +523,30 @@ define i32 @loop_trip_count_unbound(i32 %0, i32 %1,
> i32* nocapture readonly %2,
> ; }
>
>
> -; ATTRIBUTOR_MODULE: Function Attrs: argmemonly nofree noinline nosync
> nounwind readonly uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: argmemonly nofree noinline norecurse
> nosync nounwind readonly uwtable willreturn
> -; ATTRIBUTOR-NEXT: define i32 @loop_trip_dec(i32 %0, i32* nocapture
> nofree readonly %1) local_unnamed_addr
> +; CHECK_MODULE: Function Attrs: argmemonly nofree noinline nosync
> nounwind readonly uwtable willreturn
> +; CHECK_CGSCC: Function Attrs: argmemonly nofree noinline norecurse
> nosync nounwind readonly uwtable willreturn
>
> 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]]
> +;
> %3 = icmp sgt i32 %0, -1
> br i1 %3, label %4, label %14
>
> @@ -402,10 +572,18 @@ define i32 @loop_trip_dec(i32 %0, i32* nocapture
> readonly %1) local_unnamed_addr
> ; TEST 14 (positive case)
> ; multiple return
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree noinline nosync nounwind
> readnone uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree noinline norecurse nosync
> nounwind readnone uwtable willreturn
> -; ATTRIBUTOR-NEXT: define i32 @multiple_return(i32 %a)
> +; CHECK_MODULE: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable willreturn
> +; CHECK_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
> +;
> %b = icmp eq i32 %a, 0
> br i1 %b, label %t, label %f
>
> @@ -419,10 +597,15 @@ f:
> ; unreachable exit
>
> ; 15.1 (positive case)
> -; ATTRIBUTOR_MODULE: Function Attrs: noinline nounwind uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: noinline norecurse nounwind uwtable
> willreturn
> -; ATTRIBUTOR-NEXT: define void @unreachable_exit_positive1()
> +; CHECK_MODULE: Function Attrs: noinline nounwind uwtable willreturn
> +; CHECK_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
> +;
> tail call void @will_return()
> ret void
>
> @@ -431,10 +614,26 @@ unreachable_label:
> unreachable
> }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree noinline nosync nounwind
> readnone uwtable willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree noinline norecurse nosync
> nounwind readnone uwtable willreturn
> -; ATTRIBUTOR-NEXT: define i32 @unreachable_exit_positive2(i32 %0)
> +; CHECK_MODULE: Function Attrs: nofree noinline nosync nounwind readnone
> uwtable willreturn
> +; CHECK_CGSCC: Function Attrs: nofree noinline norecurse nosync nounwind
> readnone uwtable willreturn
> 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
> +;
> %2 = icmp slt i32 %0, 1
> br i1 %2, label %3, label %5
>
> @@ -458,10 +657,15 @@ unreachable_label:
>
> ;15.2
>
> -; ATTRIBUTOR: Function Attrs: noinline noreturn nounwind uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @unreachable_exit_negative1()
> +; CHECK: Function Attrs: noinline noreturn nounwind uwtable
> +; CHECK-NOT: willreturn
> define void @unreachable_exit_negative1() #0 {
> +; CHECK-LABEL: define {{[^@]+}}@unreachable_exit_negative1()
> +; CHECK-NEXT: tail call void @exit(i32 0)
> +; CHECK-NEXT: unreachable
> +; CHECK: unreachable_label:
> +; CHECK-NEXT: unreachable
> +;
> tail call void @exit(i32 0)
> ret void
>
> @@ -470,12 +674,19 @@ unreachable_label:
> unreachable
> }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree noinline noreturn nosync
> nounwind readnone uwtable
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree noinline norecurse noreturn
> nosync nounwind readnone uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @unreachable_exit_negative2()
> +; CHECK_MODULE: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> +; CHECK_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
> +;
> br label %L1
> L1:
> br label %L2
> @@ -487,20 +698,24 @@ unreachable_label:
> unreachable
> }
>
> -; ATTRIBUTOR: Function Attrs: noreturn nounwind
> -; ATTRIBUTOR-NEXT: declare void @llvm.eh.sjlj.longjmp(i8*)
> +; CHECK: Function Attrs: noreturn nounwind
> +; CHECK-NEXT: declare void @llvm.eh.sjlj.longjmp(i8*)
> declare void @llvm.eh.sjlj.longjmp(i8*)
>
> -; ATTRIBUTOR: Function Attrs: noinline noreturn nounwind uwtable
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @call_longjmp(i8* nocapture readnone %0)
> local_unnamed_addr
> +; CHECK: Function Attrs: noinline noreturn nounwind uwtable
> +; CHECK-NOT: willreturn
> define void @call_longjmp(i8* nocapture readnone %0) local_unnamed_addr
> #0 {
> +; 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]])
> +; CHECK-NEXT: unreachable
> +;
> tail call void @llvm.eh.sjlj.longjmp(i8* %0)
> ret void
> }
>
>
> -; TEST 16 (negative case)
> +; TEST 16 (negative case)
> ; int infinite_loop_inside_bounded_loop(int n) {
> ; int ans = 0;
> ; for (int i = 0; i < n; i++) {
> @@ -510,11 +725,30 @@ define void @call_longjmp(i8* nocapture readnone %0)
> local_unnamed_addr #0 {
> ; return ans;
> ; }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree nosync nounwind readnone
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree norecurse nosync nounwind
> readnone
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define i32 @infinite_loop_inside_bounded_loop(i32 %n)
> +; CHECK_MODULE: Function Attrs: nofree nosync nounwind readnone
> +; CHECK_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
> +;
> entry:
> br label %for.cond
>
> @@ -554,10 +788,37 @@ for.end: ;
> preds = %for.cond.cleanup
> ; return ans;
> ; }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree nosync nounwind readnone
> willreturn
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
> -; ATTRIBUTOR-NEXT: define i32 @bounded_nested_loops(i32 %n)
> +; CHECK_MODULE: Function Attrs: nofree nosync nounwind readnone
> willreturn
> +; CHECK_CGSCC: Function Attrs: nofree norecurse nosync nounwind readnone
> willreturn
> 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]]
> +;
> entry:
> br label %for.cond
>
> @@ -605,11 +866,40 @@ for.end: ;
> preds = %for.cond.cleanup
> ; return ans;
> ; }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree nosync nounwind readnone
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree norecurse nosync nounwind
> readnone
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define i32 @bounded_loop_inside_unbounded_loop(i32 %n)
> +; CHECK_MODULE: Function Attrs: nofree nosync nounwind readnone
> +; CHECK_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]]
> +;
> entry:
> br label %while.cond
>
> @@ -662,11 +952,39 @@ while.end: ;
> preds = %while.cond
> ; return ans;
> ; }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree nosync nounwind readnone
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree norecurse nosync nounwind
> readnone
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define i32 @nested_unbounded_loops(i32 %n)
> +; CHECK_MODULE: Function Attrs: nofree nosync nounwind readnone
> +; CHECK_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]]
> +;
> entry:
> br label %while.cond
>
> @@ -726,11 +1044,39 @@ while.end11: ;
> preds = %while.cond
> ; return;
> ; }
>
> -; ATTRIBUTOR_MODULE: Function Attrs: nofree nosync nounwind readnone
> -; ATTRIBUTOR_CGSCC: Function Attrs: nofree norecurse nosync nounwind
> readnone
> -; ATTRIBUTOR-NOT: willreturn
> -; ATTRIBUTOR-NEXT: define void @non_loop_cycle(i32 %n)
> +; CHECK_MODULE: Function Attrs: nofree nosync nounwind readnone
> +; CHECK_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
> +;
> entry:
> %call = call i32 @fact_loop(i32 %n)
> %cmp = icmp sgt i32 %call, 5
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200420/b778cc2e/attachment-0001.html>
More information about the llvm-commits
mailing list