[llvm] 2920770 - [Local] Treat calls that may not return as being alive.

Florian Hahn via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 7 13:16:57 PST 2021


Hi,

thanks for letting me know. I'll take a look ASAP.

Cheers,
Florian

On Fri, Feb 5, 2021 at 9:23 AM <douglas.yung at sony.com> wrote:

> Hi Florian,
>
> One of our internal tests started to fail and I bisected it to your change
> and put the details in PR49022. Can you take a look?
>
> Douglas Yung
>
> -----Original Message-----
> From: llvm-commits <llvm-commits-bounces at lists.llvm.org> On Behalf Of
> Florian Hahn via llvm-commits
> Sent: Saturday, January 23, 2021 8:07
> To: llvm-commits at lists.llvm.org
> Subject: [llvm] 2920770 - [Local] Treat calls that may not return as being
> alive.
>
>
> Author: Florian Hahn
> Date: 2021-01-23T16:05:14Z
> New Revision: 292077072ec1279d89d21873fe900061e55ef936
>
> URL:
> https://github.com/llvm/llvm-project/commit/292077072ec1279d89d21873fe900061e55ef936
> DIFF:
> https://github.com/llvm/llvm-project/commit/292077072ec1279d89d21873fe900061e55ef936.diff
>
> LOG: [Local] Treat calls that may not return as being alive.
>
> With the addition of the `willreturn` attribute, functions that may
> not return (e.g. due to an infinite loop) are well defined, if they are
> not marked as `willreturn`.
>
> This patch updates `wouldInstructionBeTriviallyDead` to not consider
> calls that may not return as dead.
>
> This patch still provides an escape hatch for intrinsics, which are
> still assumed as willreturn unconditionally. It will be removed once
> all intrinsics definitions have been reviewed and updated.
>
> Reviewed By: jdoerfert
>
> Differential Revision: https://reviews.llvm.org/D94106
>
> Added:
>
>
> Modified:
>     llvm/include/llvm/IR/InstrTypes.h
>     llvm/lib/Transforms/Utils/Local.cpp
>     llvm/test/Feature/OperandBundles/early-cse.ll
>     llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
>     llvm/test/Transforms/Attributor/align.ll
>     llvm/test/Transforms/Attributor/nocapture-1.ll
>     llvm/test/Transforms/Attributor/nocapture-2.ll
>     llvm/test/Transforms/Attributor/nonnull.ll
>     llvm/test/Transforms/Attributor/norecurse.ll
>     llvm/test/Transforms/Attributor/range.ll
>     llvm/test/Transforms/Attributor/readattrs.ll
>     llvm/test/Transforms/BDCE/basic.ll
>     llvm/test/Transforms/CodeGenPrepare/X86/delete-assume-dead-code.ll
>     llvm/test/Transforms/Coroutines/coro-split-00.ll
>     llvm/test/Transforms/Coroutines/coro-split-hidden.ll
>     llvm/test/Transforms/Coroutines/no-suspend.ll
>     llvm/test/Transforms/DeadStoreElimination/MSSA/simple.ll
>
> llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/DeleteThrowableInst.ll
>     llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/simple.ll
>     llvm/test/Transforms/Inline/dead-calls-willreturn.ll
>     llvm/test/Transforms/InstCombine/constant-fold-libfunc.ll
>     llvm/test/Transforms/InstCombine/nothrow.ll
>     llvm/test/Transforms/InstSimplify/ConstProp/rint.ll
>     llvm/test/Transforms/InstSimplify/remove-dead-call.ll
>     llvm/test/Transforms/InstSimplify/returned.ll
>     llvm/test/Transforms/MemCpyOpt/memcpy.ll
>     llvm/test/Transforms/NewGVN/eliminate-callsite-inline.ll
>     llvm/test/Transforms/OpenMP/parallel_deletion.ll
>     llvm/test/Transforms/Reassociate/erase_inst_made_change.ll
>
> Removed:
>
>
>
>
> ################################################################################
> diff  --git a/llvm/include/llvm/IR/InstrTypes.h
> b/llvm/include/llvm/IR/InstrTypes.h
> index 7b99cc96b149..f42ef48de6b3 100644
> --- a/llvm/include/llvm/IR/InstrTypes.h
> +++ b/llvm/include/llvm/IR/InstrTypes.h
> @@ -1756,6 +1756,10 @@ class CallBase : public Instruction {
>    bool onlyReadsMemory() const {
>      return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
>    }
> +
> +  /// Returns true if this function is guaranteed to return.
> +  bool willReturn() const { return hasFnAttr(Attribute::WillReturn); }
> +
>    void setOnlyReadsMemory() {
>      addAttribute(AttributeList::FunctionIndex, Attribute::ReadOnly);
>    }
>
> diff  --git a/llvm/lib/Transforms/Utils/Local.cpp
> b/llvm/lib/Transforms/Utils/Local.cpp
> index 1f94c6191554..477ea458c763 100644
> --- a/llvm/lib/Transforms/Utils/Local.cpp
> +++ b/llvm/lib/Transforms/Utils/Local.cpp
> @@ -420,6 +420,14 @@ bool
> llvm::wouldInstructionBeTriviallyDead(Instruction *I,
>      return true;
>    }
>
> +  if (auto *CB = dyn_cast<CallBase>(I)) {
> +    // Treat calls that may not return as alive.
> +    // TODO: Remove the intrinsic escape hatch once all intrinsics set
> +    // willreturn properly.
> +    if (!CB->willReturn() && !isa<IntrinsicInst>(I))
> +      return false;
> +  }
> +
>    if (!I->mayHaveSideEffects())
>      return true;
>
>
> diff  --git a/llvm/test/Feature/OperandBundles/early-cse.ll
> b/llvm/test/Feature/OperandBundles/early-cse.ll
> index cf06cd1e1f1d..1b93fe7312bf 100644
> --- a/llvm/test/Feature/OperandBundles/early-cse.ll
> +++ b/llvm/test/Feature/OperandBundles/early-cse.ll
> @@ -5,8 +5,8 @@
>  ; they're carrying unknown operand bundles since the presence of
>  ; unknown operand bundles implies arbitrary memory effects.
>
> -declare void @readonly_function() readonly nounwind
> -declare void @readnone_function() readnone nounwind
> +declare void @readonly_function() readonly nounwind willreturn
> +declare void @readnone_function() readnone nounwind willreturn
>
>  define i32 @test0(i32* %x) {
>  ; CHECK-LABEL: @test0(
>
> diff  --git a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
> b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
> index 47c5eba84b77..cafdba142cac 100644
> --- a/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
> +++ b/llvm/test/Transforms/Attributor/ArgumentPromotion/fp80.ll
> @@ -17,16 +17,32 @@ target triple = "x86_64-unknown-linux-gnu"
>  @a = internal global %struct.Foo { i32 1, i64 2 }, align 8
>
>  define void @run() {
> -; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
> -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@run
> -; NOT_CGSCC_NPM-SAME: () [[ATTR0:#.*]] {
> -; NOT_CGSCC_NPM-NEXT:  entry:
> -; NOT_CGSCC_NPM-NEXT:    unreachable
> +; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone
> +; IS________OPM-LABEL: define {{[^@]+}}@run
> +; IS________OPM-SAME: () [[ATTR0:#.*]] {
> +; IS________OPM-NEXT:  entry:
> +; IS________OPM-NEXT:    [[TMP0:%.*]] = call i64
> @CaptureAStruct(%struct.Foo* nocapture nofree noundef nonnull readonly
> align 8 dereferenceable(16) @a) [[ATTR0]]
> +; IS________OPM-NEXT:    unreachable
> +;
> +; IS__TUNIT_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@run
> +; IS__TUNIT_NPM-SAME: () [[ATTR0:#.*]] {
> +; IS__TUNIT_NPM-NEXT:  entry:
> +; IS__TUNIT_NPM-NEXT:    [[A_CAST:%.*]] = bitcast %struct.Foo* @a to i32*
> +; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = load i32, i32* [[A_CAST]], align 8
> +; IS__TUNIT_NPM-NEXT:    [[A_0_1:%.*]] = getelementptr
> [[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT:    [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
> +; IS__TUNIT_NPM-NEXT:    [[TMP2:%.*]] = call i64 @CaptureAStruct(i32
> [[TMP0]], i64 [[TMP1]]) [[ATTR0]]
> +; IS__TUNIT_NPM-NEXT:    unreachable
>  ;
>  ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync
> nounwind readonly willreturn
>  ; IS__CGSCC____-LABEL: define {{[^@]+}}@run
>  ; IS__CGSCC____-SAME: () [[ATTR0:#.*]] {
>  ; IS__CGSCC____-NEXT:  entry:
> +; IS__CGSCC____-NEXT:    [[A_CAST:%.*]] = bitcast %struct.Foo* @a to i32*
> +; IS__CGSCC____-NEXT:    [[TMP0:%.*]] = load i32, i32* [[A_CAST]], align 8
> +; IS__CGSCC____-NEXT:    [[A_0_1:%.*]] = getelementptr
> [[STRUCT_FOO:%.*]], %struct.Foo* @a, i32 0, i32 1
> +; IS__CGSCC____-NEXT:    [[TMP1:%.*]] = load i64, i64* [[A_0_1]], align 8
>  ; IS__CGSCC____-NEXT:    unreachable
>  ;
>  entry:
> @@ -86,6 +102,37 @@ define internal i64 @CaptureAStruct(%struct.Foo*
> byval(%struct.Foo) %a) {
>  ; IS__CGSCC_OPM-NEXT:    [[GEP]] = getelementptr [[STRUCT_FOO:%.*]],
> %struct.Foo* [[A]], i64 0
>  ; IS__CGSCC_OPM-NEXT:    br label [[LOOP]]
>  ;
> +; IS________OPM: Function Attrs: nofree noreturn nosync nounwind readnone
> +; IS________OPM-LABEL: define {{[^@]+}}@CaptureAStruct
> +; IS________OPM-SAME: (%struct.Foo* noalias nofree noundef nonnull
> byval(%struct.Foo) align 8 dereferenceable(16) [[A:%.*]]) [[ATTR0]] {
> +; IS________OPM-NEXT:  entry:
> +; IS________OPM-NEXT:    [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
> +; IS________OPM-NEXT:    br label [[LOOP:%.*]]
> +; IS________OPM:       loop:
> +; IS________OPM-NEXT:    [[PHI:%.*]] = phi %struct.Foo* [ null,
> [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
> +; IS________OPM-NEXT:    [[TMP0:%.*]] = phi %struct.Foo* [ [[A]],
> [[ENTRY]] ], [ [[TMP0]], [[LOOP]] ]
> +; IS________OPM-NEXT:    store %struct.Foo* [[PHI]], %struct.Foo**
> [[A_PTR]], align 8
> +; IS________OPM-NEXT:    [[GEP]] = getelementptr [[STRUCT_FOO:%.*]],
> %struct.Foo* [[A]], i64 0
> +; IS________OPM-NEXT:    br label [[LOOP]]
> +;
> +; IS__TUNIT_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
> +; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@CaptureAStruct
> +; IS__TUNIT_NPM-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) [[ATTR0]] {
> +; IS__TUNIT_NPM-NEXT:  entry:
> +; IS__TUNIT_NPM-NEXT:    [[A_PRIV:%.*]] = alloca [[STRUCT_FOO:%.*]],
> align 8
> +; IS__TUNIT_NPM-NEXT:    [[A_PRIV_CAST:%.*]] = bitcast %struct.Foo*
> [[A_PRIV]] to i32*
> +; IS__TUNIT_NPM-NEXT:    store i32 [[TMP0]], i32* [[A_PRIV_CAST]], align 4
> +; IS__TUNIT_NPM-NEXT:    [[A_PRIV_0_1:%.*]] = getelementptr
> [[STRUCT_FOO]], %struct.Foo* [[A_PRIV]], i32 0, i32 1
> +; IS__TUNIT_NPM-NEXT:    store i64 [[TMP1]], i64* [[A_PRIV_0_1]], align 8
> +; IS__TUNIT_NPM-NEXT:    [[A_PTR:%.*]] = alloca %struct.Foo*, align 8
> +; IS__TUNIT_NPM-NEXT:    br label [[LOOP:%.*]]
> +; IS__TUNIT_NPM:       loop:
> +; IS__TUNIT_NPM-NEXT:    [[PHI:%.*]] = phi %struct.Foo* [ null,
> [[ENTRY:%.*]] ], [ [[GEP:%.*]], [[LOOP]] ]
> +; IS__TUNIT_NPM-NEXT:    [[TMP2:%.*]] = phi %struct.Foo* [ [[A_PRIV]],
> [[ENTRY]] ], [ [[TMP2]], [[LOOP]] ]
> +; IS__TUNIT_NPM-NEXT:    store %struct.Foo* [[PHI]], %struct.Foo**
> [[A_PTR]], align 8
> +; IS__TUNIT_NPM-NEXT:    [[GEP]] = getelementptr [[STRUCT_FOO]],
> %struct.Foo* [[A_PRIV]], i64 0
> +; IS__TUNIT_NPM-NEXT:    br label [[LOOP]]
> +;
>  ; IS__CGSCC____: Function Attrs: nofree norecurse noreturn nosync
> nounwind readnone
>  ; IS__CGSCC____-LABEL: define {{[^@]+}}@CaptureAStruct
>  ; IS__CGSCC____-SAME: (i32 [[TMP0:%.*]], i64 [[TMP1:%.*]]) [[ATTR2:#.*]] {
>
> diff  --git a/llvm/test/Transforms/Attributor/align.ll
> b/llvm/test/Transforms/Attributor/align.ll
> index 5318a829a762..c210763ce3dd 100644
> --- a/llvm/test/Transforms/Attributor/align.ll
> +++ b/llvm/test/Transforms/Attributor/align.ll
> @@ -102,30 +102,34 @@ define i32* @test5_2() {
>  ; TEST 6
>  ; SCC
>  define i32* @test6_1() #0 {
> -; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
> -; NOT_CGSCC_NPM-SAME: () [[ATTR1:#.*]] {
> -; NOT_CGSCC_NPM-NEXT:    unreachable
> -;
> -; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn
> nosync nounwind readnone uwtable willreturn
> -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_1
> -; IS__CGSCC_NPM-SAME: () [[ATTR1:#.*]] {
> -; IS__CGSCC_NPM-NEXT:    unreachable
> +; NOT_CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6_1
> +; NOT_CGSCC_OPM-SAME: () [[ATTR1:#.*]] {
> +; NOT_CGSCC_OPM-NEXT:    [[RET:%.*]] = tail call i32* @test6_2()
> [[ATTR11:#.*]]
> +; NOT_CGSCC_OPM-NEXT:    unreachable
> +;
> +; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6_1
> +; IS__CGSCC_OPM-SAME: () [[ATTR1:#.*]] {
> +; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = tail call i32* @test6_2()
> [[ATTR12:#.*]]
> +; IS__CGSCC_OPM-NEXT:    unreachable
>  ;
>    %ret = tail call i32* @test6_2()
>    ret i32* %ret
>  }
>
>  define i32* @test6_2() #0 {
> -; NOT_CGSCC_NPM: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
> -; NOT_CGSCC_NPM-SAME: () [[ATTR1]] {
> -; NOT_CGSCC_NPM-NEXT:    unreachable
> -;
> -; IS__CGSCC_NPM: Function Attrs: nofree noinline norecurse noreturn
> nosync nounwind readnone uwtable willreturn
> -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test6_2
> -; IS__CGSCC_NPM-SAME: () [[ATTR1]] {
> -; IS__CGSCC_NPM-NEXT:    unreachable
> +; NOT_CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> +; NOT_CGSCC_OPM-LABEL: define {{[^@]+}}@test6_2
> +; NOT_CGSCC_OPM-SAME: () [[ATTR1]] {
> +; NOT_CGSCC_OPM-NEXT:    [[RET:%.*]] = tail call i32* @test6_1()
> [[ATTR11]]
> +; NOT_CGSCC_OPM-NEXT:    unreachable
> +;
> +; IS__CGSCC_OPM: Function Attrs: nofree noinline noreturn nosync nounwind
> readnone uwtable
> +; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test6_2
> +; IS__CGSCC_OPM-SAME: () [[ATTR1]] {
> +; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = tail call i32* @test6_1()
> [[ATTR12]]
> +; IS__CGSCC_OPM-NEXT:    unreachable
>  ;
>    %ret = tail call i32* @test6_1()
>    ret i32* %ret
> @@ -967,7 +971,7 @@ define i32 @musttail_caller_1(i32* %p) {
>  ; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
>  ; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
>  ; IS__CGSCC_OPM:       mt:
> -; IS__CGSCC_OPM-NEXT:    [[V:%.*]] = musttail call i32
> @musttail_callee_1(i32* nocapture nofree nonnull readonly
> dereferenceable(4) [[P]]) [[ATTR12:#.*]]
> +; IS__CGSCC_OPM-NEXT:    [[V:%.*]] = musttail call i32
> @musttail_callee_1(i32* nocapture nofree nonnull readonly
> dereferenceable(4) [[P]]) [[ATTR13:#.*]]
>  ; IS__CGSCC_OPM-NEXT:    ret i32 [[V]]
>  ; IS__CGSCC_OPM:       exit:
>  ; IS__CGSCC_OPM-NEXT:    ret i32 0
> @@ -978,7 +982,7 @@ define i32 @musttail_caller_1(i32* %p) {
>  ; IS__CGSCC_NPM-NEXT:    [[C:%.*]] = load i1, i1* @cnd, align 1
>  ; IS__CGSCC_NPM-NEXT:    br i1 [[C]], label [[MT:%.*]], label [[EXIT:%.*]]
>  ; IS__CGSCC_NPM:       mt:
> -; IS__CGSCC_NPM-NEXT:    [[V:%.*]] = musttail call i32
> @musttail_callee_1(i32* nocapture nofree nonnull readonly
> dereferenceable(4) [[P]]) [[ATTR11:#.*]]
> +; IS__CGSCC_NPM-NEXT:    [[V:%.*]] = musttail call i32
> @musttail_callee_1(i32* nocapture nofree nonnull readonly
> dereferenceable(4) [[P]]) [[ATTR12:#.*]]
>  ; IS__CGSCC_NPM-NEXT:    ret i32 [[V]]
>  ; IS__CGSCC_NPM:       exit:
>  ; IS__CGSCC_NPM-NEXT:    ret i32 0
>
> diff  --git a/llvm/test/Transforms/Attributor/nocapture-1.ll
> b/llvm/test/Transforms/Attributor/nocapture-1.ll
> index d99f9a879a28..74b39d718501 100644
> --- a/llvm/test/Transforms/Attributor/nocapture-1.ll
> +++ b/llvm/test/Transforms/Attributor/nocapture-1.ll
> @@ -849,6 +849,8 @@ define void @ptr_uses(i8* %ptr, i8* %wptr) {
>  ; CHECK: Function Attrs: nounwind
>  ; CHECK-LABEL: define {{[^@]+}}@ptr_uses
>  ; CHECK-SAME: (i8* [[PTR:%.*]], i8* nocapture nonnull writeonly
> dereferenceable(1) [[WPTR:%.*]]) [[ATTR13:#.*]] {
> +; CHECK-NEXT:    [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8*
> readonly [[PTR]]) [[ATTR4]]
> +; CHECK-NEXT:    [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8*
> readonly [[CALL_PTR]]) [[ATTR4]]
>  ; CHECK-NEXT:    store i8 0, i8* [[WPTR]], align 1
>  ; CHECK-NEXT:    ret void
>  ;
>
> diff  --git a/llvm/test/Transforms/Attributor/nocapture-2.ll
> b/llvm/test/Transforms/Attributor/nocapture-2.ll
> index bb5ace7cce1c..c176a1c1ce0f 100644
> --- a/llvm/test/Transforms/Attributor/nocapture-2.ll
> +++ b/llvm/test/Transforms/Attributor/nocapture-2.ll
> @@ -728,7 +728,7 @@ 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:%.*]]) [[ATTR8]] {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32*
> nocapture readonly [[B]], i32* readonly [[R]]) [[ATTR6]]
> +; CHECK-NEXT:    [[CALL:%.*]] = call i32* @readonly_unknown_r1b(i32*
> nocapture readonly [[B]], i32* readonly [[R]]) [[ATTR8]]
>  ; CHECK-NEXT:    ret i32* [[CALL]]
>  ;
>  entry:
>
> diff  --git a/llvm/test/Transforms/Attributor/nonnull.ll
> b/llvm/test/Transforms/Attributor/nonnull.ll
> index 3c836e4e5c28..b54ab775d53a 100644
> --- a/llvm/test/Transforms/Attributor/nonnull.ll
> +++ b/llvm/test/Transforms/Attributor/nonnull.ll
> @@ -149,11 +149,13 @@ define i8* @test4_helper() {
>  ; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
>  ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
>  ; NOT_CGSCC_NPM-SAME: () [[ATTR2:#.*]] {
> +; NOT_CGSCC_NPM-NEXT:    [[RET:%.*]] = call i8* @test4()
>  ; NOT_CGSCC_NPM-NEXT:    unreachable
>  ;
> -; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync
> nounwind readnone willreturn
> +; IS__CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
>  ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4_helper
>  ; IS__CGSCC_NPM-SAME: () [[ATTR2:#.*]] {
> +; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i8* @test4()
>  ; IS__CGSCC_NPM-NEXT:    unreachable
>  ;
>    %ret = call i8* @test4()
> @@ -164,11 +166,13 @@ define i8* @test4() {
>  ; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
>  ; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@test4
>  ; NOT_CGSCC_NPM-SAME: () [[ATTR2]] {
> +; NOT_CGSCC_NPM-NEXT:    [[RET:%.*]] = call i8* @test4_helper()
>  ; NOT_CGSCC_NPM-NEXT:    unreachable
>  ;
> -; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync
> nounwind readnone willreturn
> +; IS__CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
>  ; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@test4
>  ; IS__CGSCC_NPM-SAME: () [[ATTR2]] {
> +; IS__CGSCC_NPM-NEXT:    [[RET:%.*]] = call i8* @test4_helper()
>  ; IS__CGSCC_NPM-NEXT:    unreachable
>  ;
>    %ret = call i8* @test4_helper()
>
> diff  --git a/llvm/test/Transforms/Attributor/norecurse.ll
> b/llvm/test/Transforms/Attributor/norecurse.ll
> index f5560abbfb35..0df8f9d6973a 100644
> --- a/llvm/test/Transforms/Attributor/norecurse.ll
> +++ b/llvm/test/Transforms/Attributor/norecurse.ll
> @@ -34,29 +34,21 @@ define i32 @self_rec() {
>  }
>
>  define i32 @indirect_rec() {
> -; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
> -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec
> -; NOT_CGSCC_NPM-SAME: () [[ATTR2:#.*]] {
> -; NOT_CGSCC_NPM-NEXT:    unreachable
> -;
> -; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync
> nounwind readnone willreturn
> -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec
> -; IS__CGSCC_NPM-SAME: () [[ATTR1:#.*]] {
> -; IS__CGSCC_NPM-NEXT:    unreachable
> +; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
> +; CHECK-LABEL: define {{[^@]+}}@indirect_rec
> +; CHECK-SAME: () [[ATTR2:#.*]] {
> +; CHECK-NEXT:    [[A:%.*]] = call i32 @indirect_rec2() [[ATTR2]]
> +; CHECK-NEXT:    unreachable
>  ;
>    %a = call i32 @indirect_rec2()
>    ret i32 %a
>  }
>  define i32 @indirect_rec2() {
> -; NOT_CGSCC_NPM: Function Attrs: nofree noreturn nosync nounwind readnone
> -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2
> -; NOT_CGSCC_NPM-SAME: () [[ATTR2]] {
> -; NOT_CGSCC_NPM-NEXT:    unreachable
> -;
> -; IS__CGSCC_NPM: Function Attrs: nofree norecurse noreturn nosync
> nounwind readnone willreturn
> -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@indirect_rec2
> -; IS__CGSCC_NPM-SAME: () [[ATTR1]] {
> -; IS__CGSCC_NPM-NEXT:    unreachable
> +; CHECK: Function Attrs: nofree noreturn nosync nounwind readnone
> +; CHECK-LABEL: define {{[^@]+}}@indirect_rec2
> +; CHECK-SAME: () [[ATTR2]] {
> +; CHECK-NEXT:    [[A:%.*]] = call i32 @indirect_rec() [[ATTR2]]
> +; CHECK-NEXT:    unreachable
>  ;
>    %a = call i32 @indirect_rec()
>    ret i32 %a
> @@ -65,7 +57,7 @@ define i32 @indirect_rec2() {
>  define i32 @extern() {
>  ; CHECK: Function Attrs: nosync readnone
>  ; CHECK-LABEL: define {{[^@]+}}@extern
> -; CHECK-SAME: () [[ATTR2:#.*]] {
> +; CHECK-SAME: () [[ATTR3:#.*]] {
>  ; CHECK-NEXT:    [[A:%.*]] = call i32 @k()
>  ; CHECK-NEXT:    ret i32 [[A]]
>  ;
> @@ -78,17 +70,11 @@ define i32 @extern() {
>  declare i32 @k() readnone
>
>  define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
> -; NOT_CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind
> willreturn
> -; NOT_CGSCC_NPM-LABEL: define {{[^@]+}}@intrinsic
> -; NOT_CGSCC_NPM-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8*
> nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR5:#.*]] {
> -; NOT_CGSCC_NPM-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias
> nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly
> [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR10:#.*]]
> -; NOT_CGSCC_NPM-NEXT:    ret void
> -;
> -; IS__CGSCC_NPM: Function Attrs: argmemonly nofree nosync nounwind
> willreturn
> -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@intrinsic
> -; IS__CGSCC_NPM-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8*
> nocapture nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR4:#.*]] {
> -; IS__CGSCC_NPM-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias
> nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly
> [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR7:#.*]]
> -; IS__CGSCC_NPM-NEXT:    ret void
> +; CHECK: Function Attrs: argmemonly nofree nosync nounwind willreturn
> +; CHECK-LABEL: define {{[^@]+}}@intrinsic
> +; CHECK-SAME: (i8* nocapture nofree writeonly [[DEST:%.*]], i8* nocapture
> nofree readonly [[SRC:%.*]], i32 [[LEN:%.*]]) [[ATTR5:#.*]] {
> +; CHECK-NEXT:    call void @llvm.memcpy.p0i8.p0i8.i32(i8* noalias
> nocapture nofree writeonly [[DEST]], i8* noalias nocapture nofree readonly
> [[SRC]], i32 [[LEN]], i1 noundef false) [[ATTR10:#.*]]
> +; CHECK-NEXT:    ret void
>  ;
>    call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1
> false)
>    ret void
> @@ -107,7 +93,7 @@ define internal i32 @called_by_norecurse() {
>  ;
>  ; IS__CGSCC____: Function Attrs: norecurse nosync readnone
>  ; IS__CGSCC____-LABEL: define {{[^@]+}}@called_by_norecurse
> -; IS__CGSCC____-SAME: () [[ATTR5:#.*]] {
> +; IS__CGSCC____-SAME: () [[ATTR6:#.*]] {
>  ; IS__CGSCC____-NEXT:    [[A:%.*]] = call i32 @k()
>  ; IS__CGSCC____-NEXT:    ret i32 undef
>  ;
> @@ -123,7 +109,7 @@ define void @m() norecurse {
>  ;
>  ; IS__CGSCC____: Function Attrs: norecurse nosync readnone
>  ; IS__CGSCC____-LABEL: define {{[^@]+}}@m
> -; IS__CGSCC____-SAME: () [[ATTR5]] {
> +; IS__CGSCC____-SAME: () [[ATTR6]] {
>  ; IS__CGSCC____-NEXT:    [[A:%.*]] = call i32 @called_by_norecurse()
>  ; IS__CGSCC____-NEXT:    ret void
>  ;
> @@ -134,7 +120,7 @@ define void @m() norecurse {
>  define internal i32 @called_by_norecurse_indirectly() {
>  ; CHECK: Function Attrs: nosync readnone
>  ; CHECK-LABEL: define {{[^@]+}}@called_by_norecurse_indirectly
> -; CHECK-SAME: () [[ATTR2]] {
> +; CHECK-SAME: () [[ATTR3]] {
>  ; CHECK-NEXT:    [[A:%.*]] = call i32 @k()
>  ; CHECK-NEXT:    ret i32 [[A]]
>  ;
> @@ -150,7 +136,7 @@ define internal i32 @o() {
>  ;
>  ; IS__CGSCC____: Function Attrs: norecurse nosync readnone
>  ; IS__CGSCC____-LABEL: define {{[^@]+}}@o
> -; IS__CGSCC____-SAME: () [[ATTR5]] {
> +; IS__CGSCC____-SAME: () [[ATTR6]] {
>  ; IS__CGSCC____-NEXT:    [[A:%.*]] = call i32
> @called_by_norecurse_indirectly()
>  ; IS__CGSCC____-NEXT:    ret i32 [[A]]
>  ;
> @@ -166,7 +152,7 @@ define i32 @p() norecurse {
>  ;
>  ; IS__CGSCC____: Function Attrs: norecurse nosync readnone
>  ; IS__CGSCC____-LABEL: define {{[^@]+}}@p
> -; IS__CGSCC____-SAME: () [[ATTR5]] {
> +; IS__CGSCC____-SAME: () [[ATTR6]] {
>  ; IS__CGSCC____-NEXT:    [[A:%.*]] = call i32 @o()
>  ; IS__CGSCC____-NEXT:    ret i32 [[A]]
>  ;
> @@ -175,48 +161,20 @@ define i32 @p() norecurse {
>  }
>
>  define void @f(i32 %x)  {
> -; IS__TUNIT____: Function Attrs: nofree nosync nounwind readnone
> -; IS__TUNIT____-LABEL: define {{[^@]+}}@f
> -; IS__TUNIT____-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] {
> -; IS__TUNIT____-NEXT:  entry:
> -; IS__TUNIT____-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
> -; IS__TUNIT____-NEXT:    store i32 [[X]], i32* [[X_ADDR]], align 4
> -; IS__TUNIT____-NEXT:    [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
> -; IS__TUNIT____-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
> -; IS__TUNIT____-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> -; IS__TUNIT____:       if.then:
> -; IS__TUNIT____-NEXT:    call void @g() [[ATTR8:#.*]]
> -; IS__TUNIT____-NEXT:    br label [[IF_END]]
> -; IS__TUNIT____:       if.end:
> -; IS__TUNIT____-NEXT:    ret void
> -;
> -; IS__CGSCC_OPM: Function Attrs: nofree nosync nounwind readnone
> -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f
> -; IS__CGSCC_OPM-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] {
> -; IS__CGSCC_OPM-NEXT:  entry:
> -; IS__CGSCC_OPM-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
> -; IS__CGSCC_OPM-NEXT:    store i32 [[X]], i32* [[X_ADDR]], align 4
> -; IS__CGSCC_OPM-NEXT:    [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
> -; IS__CGSCC_OPM-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
> -; IS__CGSCC_OPM-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> -; IS__CGSCC_OPM:       if.then:
> -; IS__CGSCC_OPM-NEXT:    br label [[IF_END]]
> -; IS__CGSCC_OPM:       if.end:
> -; IS__CGSCC_OPM-NEXT:    ret void
> -;
> -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
> -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@f
> -; IS__CGSCC_NPM-SAME: (i32 [[X:%.*]]) [[ATTR0:#.*]] {
> -; IS__CGSCC_NPM-NEXT:  entry:
> -; IS__CGSCC_NPM-NEXT:    [[X_ADDR:%.*]] = alloca i32, align 4
> -; IS__CGSCC_NPM-NEXT:    store i32 [[X]], i32* [[X_ADDR]], align 4
> -; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = load i32, i32* [[X_ADDR]], align 4
> -; IS__CGSCC_NPM-NEXT:    [[TOBOOL:%.*]] = icmp ne i32 [[TMP0]], 0
> -; IS__CGSCC_NPM-NEXT:    br i1 [[TOBOOL]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
> -; IS__CGSCC_NPM:       if.then:
> -; IS__CGSCC_NPM-NEXT:    br label [[IF_END]]
> -; IS__CGSCC_NPM:       if.end:
> -; IS__CGSCC_NPM-NEXT:    ret void
> +; CHECK: Function Attrs: nofree nosync nounwind readnone
> +; CHECK-LABEL: define {{[^@]+}}@f
> +; CHECK-SAME: (i32 [[X:%.*]]) [[ATTR7:#.*]] {
> +; 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() [[ATTR8:#.*]]
> +; CHECK-NEXT:    br label [[IF_END]]
> +; CHECK:       if.end:
> +; CHECK-NEXT:    ret void
>  ;
>  entry:
>    %x.addr = alloca i32, align 4
> @@ -234,24 +192,12 @@ if.end:
>  }
>
>  define void @g() norecurse {
> -; IS__TUNIT____: Function Attrs: nofree norecurse nosync nounwind readnone
> -; IS__TUNIT____-LABEL: define {{[^@]+}}@g
> -; IS__TUNIT____-SAME: () [[ATTR8]] {
> -; IS__TUNIT____-NEXT:  entry:
> -; IS__TUNIT____-NEXT:    ret void
> -;
> -; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind readnone
> -; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@g
> -; IS__CGSCC_OPM-SAME: () [[ATTR8:#.*]] {
> -; IS__CGSCC_OPM-NEXT:  entry:
> -; IS__CGSCC_OPM-NEXT:    call void @f(i32 noundef 0) [[ATTR7]]
> -; IS__CGSCC_OPM-NEXT:    ret void
> -;
> -; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
> -; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@g
> -; IS__CGSCC_NPM-SAME: () [[ATTR0]] {
> -; IS__CGSCC_NPM-NEXT:  entry:
> -; IS__CGSCC_NPM-NEXT:    ret void
> +; CHECK: Function Attrs: nofree norecurse nosync nounwind readnone
> +; CHECK-LABEL: define {{[^@]+}}@g
> +; CHECK-SAME: () [[ATTR8]] {
> +; CHECK-NEXT:  entry:
> +; CHECK-NEXT:    call void @f(i32 noundef 0) [[ATTR7]]
> +; CHECK-NEXT:    ret void
>  ;
>  entry:
>    call void @f(i32 0)
> @@ -279,7 +225,7 @@ define i32 @eval_func1(i32 (i32)* , i32)
> local_unnamed_addr {
>  define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr
> null_pointer_is_valid{
>  ; CHECK: Function Attrs: null_pointer_is_valid
>  ; CHECK-LABEL: define {{[^@]+}}@eval_func2
> -; CHECK-SAME: (i32 (i32)* nocapture nofree [[TMP0:%.*]], i32
> [[TMP1:%.*]]) local_unnamed_addr [[ATTR6:#.*]] {
> +; CHECK-SAME: (i32 (i32)* nocapture nofree [[TMP0:%.*]], i32
> [[TMP1:%.*]]) local_unnamed_addr [[ATTR9:#.*]] {
>  ; CHECK-NEXT:    [[TMP3:%.*]] = tail call i32 [[TMP0]](i32 [[TMP1]])
>  ; CHECK-NEXT:    ret i32 [[TMP3]]
>  ;
>
> diff  --git a/llvm/test/Transforms/Attributor/range.ll
> b/llvm/test/Transforms/Attributor/range.ll
> index a1ca947954f9..3d1bcfeb6f53 100644
> --- a/llvm/test/Transforms/Attributor/range.ll
> +++ b/llvm/test/Transforms/Attributor/range.ll
> @@ -600,7 +600,7 @@ define void @f1(i32){
>  ;
>  ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@f1
>  ; IS__CGSCC_OPM-SAME: (i32 [[TMP0:%.*]]) {
> -; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = tail call i32 @r1(),
> [[RNG3:!range !.*]]
> +; IS__CGSCC_OPM-NEXT:    [[TMP2:%.*]] = tail call i32 @r1()
> [[ATTR4:#.*]], [[RNG3:!range !.*]]
>  ; IS__CGSCC_OPM-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP2]], 15
>  ; IS__CGSCC_OPM-NEXT:    br i1 [[TMP3]], label [[TMP4:%.*]], label
> [[TMP5:%.*]]
>  ; IS__CGSCC_OPM:       4:
> @@ -698,7 +698,7 @@ define dso_local i32 @test4-g1(i32 %u) {
>  ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g1
>  ; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) [[ATTR2:#.*]] {
>  ; IS__CGSCC_OPM-NEXT:  entry:
> -; IS__CGSCC_OPM-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f1(i32
> [[U]]) [[ATTR4:#.*]]
> +; IS__CGSCC_OPM-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f1(i32
> [[U]]) [[ATTR5:#.*]]
>  ; IS__CGSCC_OPM-NEXT:    ret i32 [[CALL]]
>  ;
>  ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
> @@ -790,7 +790,7 @@ define dso_local i32 @test4-g2(i32 %u) {
>  ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@test4-g2
>  ; IS__CGSCC_OPM-SAME: (i32 [[U:%.*]]) [[ATTR2]] {
>  ; IS__CGSCC_OPM-NEXT:  entry:
> -; IS__CGSCC_OPM-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f2(i32
> [[U]]) [[ATTR4]]
> +; IS__CGSCC_OPM-NEXT:    [[CALL:%.*]] = tail call i32 @test4-f2(i32
> [[U]]) [[ATTR5]]
>  ; IS__CGSCC_OPM-NEXT:    ret i32 [[CALL]]
>  ;
>  ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
> @@ -1154,10 +1154,10 @@ define i1 @fcmp_caller(float %fa, float %fb,
> double %da, double %db, double* %dp
>  ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
>  ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@fcmp_caller
>  ; IS__CGSCC_OPM-SAME: (float [[FA:%.*]], float [[FB:%.*]], double
> [[DA:%.*]], double [[DB:%.*]], double* nofree readnone [[DPA:%.*]], double*
> nofree readnone [[DPB:%.*]], i8* nofree readnone [[IPA:%.*]], i8* nofree
> readnone [[IPB:%.*]]) [[ATTR2]] {
> -; IS__CGSCC_OPM-NEXT:    [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float
> [[FB]]) [[ATTR4]]
> -; IS__CGSCC_OPM-NEXT:    [[R2:%.*]] = call i1 @d_fcmp(double [[DA]],
> double [[DB]]) [[ATTR4]]
> -; IS__CGSCC_OPM-NEXT:    [[R3:%.*]] = call i1 @dp_icmp(double* noalias
> nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) [[ATTR4]]
> -; IS__CGSCC_OPM-NEXT:    [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree
> readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) [[ATTR4]]
> +; IS__CGSCC_OPM-NEXT:    [[R1:%.*]] = call i1 @f_fcmp(float [[FA]], float
> [[FB]]) [[ATTR5]]
> +; IS__CGSCC_OPM-NEXT:    [[R2:%.*]] = call i1 @d_fcmp(double [[DA]],
> double [[DB]]) [[ATTR5]]
> +; IS__CGSCC_OPM-NEXT:    [[R3:%.*]] = call i1 @dp_icmp(double* noalias
> nofree readnone [[DPA]], double* noalias nofree readnone [[DPB]]) [[ATTR5]]
> +; IS__CGSCC_OPM-NEXT:    [[R4:%.*]] = call i1 @ip_icmp(i8* noalias nofree
> readnone [[IPA]], i8* noalias nofree readnone [[IPB]]) [[ATTR5]]
>  ; IS__CGSCC_OPM-NEXT:    [[O1:%.*]] = or i1 [[R1]], [[R2]]
>  ; IS__CGSCC_OPM-NEXT:    [[O2:%.*]] = or i1 [[R3]], [[R4]]
>  ; IS__CGSCC_OPM-NEXT:    [[O3:%.*]] = or i1 [[O1]], [[O2]]
> @@ -1329,8 +1329,8 @@ define i1 @callee_range_2(i1 %c1, i1 %c2) {
>  ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
>  ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@callee_range_2
>  ; IS__CGSCC_OPM-SAME: (i1 [[C1:%.*]], i1 [[C2:%.*]]) [[ATTR2]] {
> -; IS__CGSCC_OPM-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
> [[ATTR4]], [[RNG5:!range !.*]]
> -; IS__CGSCC_OPM-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
> [[ATTR4]], [[RNG5]]
> +; IS__CGSCC_OPM-NEXT:    [[R1:%.*]] = call i32 @ret1or2(i1 [[C1]])
> [[ATTR5]], [[RNG5:!range !.*]]
> +; IS__CGSCC_OPM-NEXT:    [[R2:%.*]] = call i32 @ret1or2(i1 [[C2]])
> [[ATTR5]], [[RNG5]]
>  ; IS__CGSCC_OPM-NEXT:    [[A:%.*]] = add i32 [[R1]], [[R2]]
>  ; IS__CGSCC_OPM-NEXT:    [[I1:%.*]] = icmp sle i32 [[A]], 3
>  ; IS__CGSCC_OPM-NEXT:    [[I2:%.*]] = icmp sge i32 [[A]], 2
> @@ -1488,10 +1488,10 @@ define i32 @simplify_callsite_argument(i1 %d) {
>  ; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = select i1 [[D]], i1 true, i1 false
>  ; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
>  ; IS__CGSCC_OPM:       t:
> -; IS__CGSCC_OPM-NEXT:    [[RET1:%.*]] = call i32 @func(i1 noundef [[C]])
> [[ATTR4]], [[RNG4:!range !.*]]
> +; IS__CGSCC_OPM-NEXT:    [[RET1:%.*]] = call i32 @func(i1 noundef [[C]])
> [[ATTR5]], [[RNG4:!range !.*]]
>  ; IS__CGSCC_OPM-NEXT:    ret i32 [[RET1]]
>  ; IS__CGSCC_OPM:       f:
> -; IS__CGSCC_OPM-NEXT:    [[RET2:%.*]] = call i32 @func(i1 noundef false)
> [[ATTR4]], [[RNG4]]
> +; IS__CGSCC_OPM-NEXT:    [[RET2:%.*]] = call i32 @func(i1 noundef false)
> [[ATTR5]], [[RNG4]]
>  ; IS__CGSCC_OPM-NEXT:    ret i32 [[RET2]]
>  ;
>  ; IS__CGSCC_NPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
> @@ -1575,10 +1575,10 @@ define i1 @check_divided_range(i32 %arg) {
>  ; IS__CGSCC_OPM: Function Attrs: nofree norecurse nosync nounwind
> readnone willreturn
>  ; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@check_divided_range
>  ; IS__CGSCC_OPM-SAME: (i32 [[ARG:%.*]]) [[ATTR2]] {
> -; IS__CGSCC_OPM-NEXT:    [[CSRET1:%.*]] = call i32 @less_than_65536(i32
> noundef 0) [[ATTR4]]
> -; IS__CGSCC_OPM-NEXT:    [[CSRET2:%.*]] = call i32 @less_than_65536(i32
> [[ARG]]) [[ATTR4]]
> -; IS__CGSCC_OPM-NEXT:    [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32
> [[CSRET1]]) [[ATTR4]]
> -; IS__CGSCC_OPM-NEXT:    [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32
> [[CSRET2]]) [[ATTR4]]
> +; IS__CGSCC_OPM-NEXT:    [[CSRET1:%.*]] = call i32 @less_than_65536(i32
> noundef 0) [[ATTR5]]
> +; IS__CGSCC_OPM-NEXT:    [[CSRET2:%.*]] = call i32 @less_than_65536(i32
> [[ARG]]) [[ATTR5]]
> +; IS__CGSCC_OPM-NEXT:    [[TRUE1:%.*]] = call i1 @is_less_than_65536(i32
> [[CSRET1]]) [[ATTR5]]
> +; IS__CGSCC_OPM-NEXT:    [[TRUE2:%.*]] = call i1 @is_less_than_65536(i32
> [[CSRET2]]) [[ATTR5]]
>  ; IS__CGSCC_OPM-NEXT:    [[RET:%.*]] = and i1 [[TRUE1]], [[TRUE2]]
>  ; IS__CGSCC_OPM-NEXT:    ret i1 [[RET]]
>  ;
> @@ -1930,7 +1930,7 @@ define i1 @context(i8* %p) {
>  ; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = icmp slt i8 0, [[L]]
>  ; IS__CGSCC_OPM-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
>  ; IS__CGSCC_OPM:       t:
> -; IS__CGSCC_OPM-NEXT:    [[R:%.*]] = call i1 @non_zero(i8 [[L]]) [[ATTR4]]
> +; IS__CGSCC_OPM-NEXT:    [[R:%.*]] = call i1 @non_zero(i8 [[L]]) [[ATTR5]]
>  ; IS__CGSCC_OPM-NEXT:    ret i1 [[R]]
>  ; IS__CGSCC_OPM:       f:
>  ; IS__CGSCC_OPM-NEXT:    ret i1 false
>
> diff  --git a/llvm/test/Transforms/Attributor/readattrs.ll
> b/llvm/test/Transforms/Attributor/readattrs.ll
> index e7e02c791b7e..829cb5d3b3dd 100644
> --- a/llvm/test/Transforms/Attributor/readattrs.ll
> +++ b/llvm/test/Transforms/Attributor/readattrs.ll
> @@ -204,7 +204,7 @@ define <4 x i32> @test11_2(<4 x i32*> %ptrs) {
>  ; CHECK: Function Attrs: argmemonly nounwind readonly
>  ; CHECK-LABEL: define {{[^@]+}}@test11_2
>  ; CHECK-SAME: (<4 x i32*> [[PTRS:%.*]]) [[ATTR6:#.*]] {
> -; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*>
> [[PTRS]]) [[ATTR2]]
> +; CHECK-NEXT:    [[RES:%.*]] = call <4 x i32> @test11_1(<4 x i32*>
> [[PTRS]]) [[ATTR9:#.*]]
>  ; CHECK-NEXT:    ret <4 x i32> [[RES]]
>  ;
>    %res = call <4 x i32> @test11_1(<4 x i32*> %ptrs)
> @@ -323,7 +323,7 @@ define void @byval_not_readonly_2(i8* byval(i8)
> %written) readonly {
>  define void @byval_not_readnone_1(i8* byval(i8) %written) readnone {
>  ; CHECK: Function Attrs: readnone
>  ; CHECK-LABEL: define {{[^@]+}}@byval_not_readnone_1
> -; CHECK-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1)
> [[WRITTEN:%.*]]) [[ATTR9:#.*]] {
> +; CHECK-SAME: (i8* noalias nonnull byval(i8) dereferenceable(1)
> [[WRITTEN:%.*]]) [[ATTR8:#.*]] {
>  ; CHECK-NEXT:    call void @escape_i8(i8* nonnull dereferenceable(1)
> [[WRITTEN]])
>  ; CHECK-NEXT:    ret void
>  ;
> @@ -395,7 +395,9 @@ declare void @val_use(i8 %ptr) readonly nounwind
>  define void @ptr_uses(i8* %ptr) {
>  ; CHECK: Function Attrs: nounwind readonly
>  ; CHECK-LABEL: define {{[^@]+}}@ptr_uses
> -; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]]) [[ATTR10:#.*]] {
> +; CHECK-SAME: (i8* nocapture readonly [[PTR:%.*]]) [[ATTR9:#.*]] {
> +; CHECK-NEXT:    [[CALL_PTR:%.*]] = call i8* @maybe_returned_ptr(i8*
> readonly [[PTR]])
> +; CHECK-NEXT:    [[CALL_VAL:%.*]] = call i8 @maybe_returned_val(i8*
> readonly [[CALL_PTR]])
>  ; CHECK-NEXT:    ret void
>  ;
>    %call_ptr = call i8* @maybe_returned_ptr(i8* %ptr)
>
> diff  --git a/llvm/test/Transforms/BDCE/basic.ll
> b/llvm/test/Transforms/BDCE/basic.ll
> index 1e4002541802..f724f89225fc 100644
> --- a/llvm/test/Transforms/BDCE/basic.ll
> +++ b/llvm/test/Transforms/BDCE/basic.ll
> @@ -392,6 +392,6 @@ entry:
>    ret i16 %cast
>  }
>
> -attributes #0 = { nounwind readnone }
> +attributes #0 = { nounwind readnone willreturn }
>  attributes #1 = { nounwind }
>
>
> diff  --git
> a/llvm/test/Transforms/CodeGenPrepare/X86/delete-assume-dead-code.ll
> b/llvm/test/Transforms/CodeGenPrepare/X86/delete-assume-dead-code.ll
> index 17e46b614609..54463d0d73a8 100644
> --- a/llvm/test/Transforms/CodeGenPrepare/X86/delete-assume-dead-code.ll
> +++ b/llvm/test/Transforms/CodeGenPrepare/X86/delete-assume-dead-code.ll
> @@ -21,7 +21,7 @@ entry:
>
>  if.end:
>    %gep = getelementptr i8, i8* %d, i32 42
> -  %call = call i64 @foo(i8* %gep) nounwind readonly
> +  %call = call i64 @foo(i8* %gep) nounwind readonly willreturn
>    %cmp2 = icmp ne i64 %call, 0
>    call void @llvm.assume(i1 %cmp2)
>    br label %exit
> @@ -31,5 +31,5 @@ exit:
>    ret i32 %conv
>  }
>
> -declare i64 @foo(i8*) nounwind readonly
> +declare i64 @foo(i8*) nounwind readonly willreturn
>  declare void @llvm.assume(i1 noundef) nounwind willreturn
>
> diff  --git a/llvm/test/Transforms/Coroutines/coro-split-00.ll
> b/llvm/test/Transforms/Coroutines/coro-split-00.ll
> index 539d515cf5e1..8671a3c07136 100644
> --- a/llvm/test/Transforms/Coroutines/coro-split-00.ll
> +++ b/llvm/test/Transforms/Coroutines/coro-split-00.ll
> @@ -77,4 +77,4 @@ declare i1 @llvm.coro.end(i8*, i1)
>
>  declare noalias i8* @malloc(i32)
>  declare void @print(i32)
> -declare void @free(i8*)
> +declare void @free(i8*) willreturn
>
> diff  --git a/llvm/test/Transforms/Coroutines/coro-split-hidden.ll
> b/llvm/test/Transforms/Coroutines/coro-split-hidden.ll
> index 9a306cbc2688..939f57462eda 100644
> --- a/llvm/test/Transforms/Coroutines/coro-split-hidden.ll
> +++ b/llvm/test/Transforms/Coroutines/coro-split-hidden.ll
> @@ -79,4 +79,4 @@ declare i1 @llvm.coro.end(i8*, i1)
>
>  declare noalias i8* @malloc(i32)
>  declare void @print(i32)
> -declare void @free(i8*)
> +declare void @free(i8*) willreturn
>
> diff  --git a/llvm/test/Transforms/Coroutines/no-suspend.ll
> b/llvm/test/Transforms/Coroutines/no-suspend.ll
> index 211e16c6ccdb..a9e2fe142556 100644
> --- a/llvm/test/Transforms/Coroutines/no-suspend.ll
> +++ b/llvm/test/Transforms/Coroutines/no-suspend.ll
> @@ -415,7 +415,7 @@ lpad:
>  }
>
>  declare i8* @malloc(i32)
> -declare void @free(i8*)
> +declare void @free(i8*) willreturn
>  declare void @print(i32)
>  declare void @foo()
>
>
> diff  --git a/llvm/test/Transforms/DeadStoreElimination/MSSA/simple.ll
> b/llvm/test/Transforms/DeadStoreElimination/MSSA/simple.ll
> index 8fe4155d487c..48a939c1228f 100644
> --- a/llvm/test/Transforms/DeadStoreElimination/MSSA/simple.ll
> +++ b/llvm/test/Transforms/DeadStoreElimination/MSSA/simple.ll
> @@ -234,8 +234,8 @@ define i32 addrspace(1)* @test13_addrspacecast() {
>  }
>
>
> -declare noalias i8* @malloc(i32)
> -declare noalias i8* @calloc(i32, i32)
> +declare noalias i8* @malloc(i32) willreturn
> +declare noalias i8* @calloc(i32, i32) willreturn
>
>  define void @test14(i32* %Q) {
>  ; CHECK-LABEL: @test14(
>
> diff  --git
> a/llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/DeleteThrowableInst.ll
> b/llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/DeleteThrowableInst.ll
> index 7e8c9ca3bd8a..768b3bb91daf 100644
> ---
> a/llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/DeleteThrowableInst.ll
> +++
> b/llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/DeleteThrowableInst.ll
> @@ -1,8 +1,8 @@
>  ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
>  ; RUN: opt < %s -basic-aa -dse -enable-dse-memoryssa=false -S | FileCheck
> %s
>
> -declare i8* @_Znwj(i32) local_unnamed_addr
> -declare void @foo() readnone
> +declare i8* @_Znwj(i32) willreturn
> +declare void @foo() readnone willreturn
>
>  define void @test1(i8** %ptr) {
>  ; CHECK-LABEL: @test1(
>
> diff  --git
> a/llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/simple.ll
> b/llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/simple.ll
> index 15caa6c898dc..1d6a9c691fc8 100644
> --- a/llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/simple.ll
> +++ b/llvm/test/Transforms/DeadStoreElimination/MemDepAnalysis/simple.ll
> @@ -267,8 +267,8 @@ define i32 addrspace(1)* @test13_addrspacecast() {
>    ret i32 addrspace(1)* %P
>  }
>
> -declare noalias i8* @malloc(i32)
> -declare noalias i8* @calloc(i32, i32)
> +declare noalias i8* @malloc(i32) willreturn
> +declare noalias i8* @calloc(i32, i32) willreturn
>  declare noalias i8* @aligned_alloc(i32, i32)
>  declare void @free(i8*)
>
>
> diff  --git a/llvm/test/Transforms/Inline/dead-calls-willreturn.ll
> b/llvm/test/Transforms/Inline/dead-calls-willreturn.ll
> index 463cc5894bb5..c36d044b1ac3 100644
> --- a/llvm/test/Transforms/Inline/dead-calls-willreturn.ll
> +++ b/llvm/test/Transforms/Inline/dead-calls-willreturn.ll
> @@ -31,6 +31,10 @@ entry:
>  define void @caller_may_not_return() ssp {
>  ; CHECK-LABEL: @caller_may_not_return(
>  ; CHECK-NEXT:  entry:
> +; CHECK-NEXT:    br label [[WHILE_BODY_I:%.*]]
> +; CHECK:       while.body.i:
> +; CHECK-NEXT:    br label [[WHILE_BODY_I]]
> +; CHECK:       readnone_may_not_return.exit:
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> @@ -41,13 +45,13 @@ entry:
>
>  ; @caller_willreturn is marked as willreturn, so all called functions
> also must
>  ; return. All calls are dead.
> -define void @caller_willreturn() ssp willreturn {
> +define void @caller_willreturn() ssp {
>  ; CHECK-LABEL: @caller_willreturn(
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> -  call void @readnone_may_not_return()
> +  call void @readnone_may_not_return() willreturn
>    call void @readnone_willreturn()
>    ret void
>  }
>
> diff  --git a/llvm/test/Transforms/InstCombine/constant-fold-libfunc.ll
> b/llvm/test/Transforms/InstCombine/constant-fold-libfunc.ll
> index af33d9895447..6af77f17f934 100644
> --- a/llvm/test/Transforms/InstCombine/constant-fold-libfunc.ll
> +++ b/llvm/test/Transforms/InstCombine/constant-fold-libfunc.ll
> @@ -1,6 +1,6 @@
>  ; RUN: opt < %s -instcombine -S | FileCheck %s
>
> -declare double @acos(double)
> +declare double @acos(double) willreturn
>
>  ; Check that functions without any function attributes are simplified.
>
>
> diff  --git a/llvm/test/Transforms/InstCombine/nothrow.ll
> b/llvm/test/Transforms/InstCombine/nothrow.ll
> index 08d90bfbd7d4..476b63a6b27f 100644
> --- a/llvm/test/Transforms/InstCombine/nothrow.ll
> +++ b/llvm/test/Transforms/InstCombine/nothrow.ll
> @@ -1,6 +1,6 @@
>  ; RUN: opt < %s -instcombine -S | not grep call
>  ; rdar://6880732
> -declare double @t1(i32) readonly
> +declare double @t1(i32) readonly willreturn
>
>  define void @t2() nounwind {
>    call double @t1(i32 42)  ;; dead call even though callee is not nothrow.
>
> diff  --git a/llvm/test/Transforms/InstSimplify/ConstProp/rint.ll
> b/llvm/test/Transforms/InstSimplify/ConstProp/rint.ll
> index 72a2abdbcf91..3b7b0ea57278 100644
> --- a/llvm/test/Transforms/InstSimplify/ConstProp/rint.ll
> +++ b/llvm/test/Transforms/InstSimplify/ConstProp/rint.ll
> @@ -2,13 +2,13 @@
>  ; RUN: opt -S -early-cse -earlycse-debug-hash < %s | FileCheck %s
>
>  declare float @nearbyintf(float) #0
> -declare float @llvm.nearbyint.f32(float) #0
> +declare float @llvm.nearbyint.f32(float)
>  declare double @nearbyint(double) #0
> -declare double @llvm.nearbyint.f64(double) #0
> +declare double @llvm.nearbyint.f64(double)
>  declare float @rintf(float) #0
> -declare float @llvm.rint.f32(float) #0
> +declare float @llvm.rint.f32(float)
>  declare double @rint(double) #0
> -declare double @llvm.rint.f64(double) #0
> +declare double @llvm.rint.f64(double)
>
>  define float @constant_fold_rint_f32_01() #0 {
>  ; CHECK-LABEL: @constant_fold_rint_f32_01(
> @@ -106,4 +106,4 @@ define double @constant_fold_rint_f64_06() #0 {
>    ret double %x
>  }
>
> -attributes #0 = { nounwind readnone }
> +attributes #0 = { nounwind readnone willreturn }
>
> diff  --git a/llvm/test/Transforms/InstSimplify/remove-dead-call.ll
> b/llvm/test/Transforms/InstSimplify/remove-dead-call.ll
> index 2b149f51c456..724d3573002d 100755
> --- a/llvm/test/Transforms/InstSimplify/remove-dead-call.ll
> +++ b/llvm/test/Transforms/InstSimplify/remove-dead-call.ll
> @@ -9,9 +9,9 @@
>
>  define internal void @func_1(i64* nocapture readnone %0) #0 {
>  ; CHECK-LABEL: @func_1(
> -; CHECK-NEXT:    unreachable
> +; CHECK-NEXT:    ret void
>  ;
> -  unreachable
> +  ret void
>  }
>
>  define i16 @main(i16 %0, i16** nocapture readnone %1) #1 {
> @@ -24,5 +24,5 @@ bb1:
>    unreachable
>  }
>
> -attributes #0 = { noinline norecurse nounwind readnone }
> +attributes #0 = { noinline norecurse nounwind readnone willreturn }
>  attributes #1 = { norecurse nounwind readnone }
>
> diff  --git a/llvm/test/Transforms/InstSimplify/returned.ll
> b/llvm/test/Transforms/InstSimplify/returned.ll
> index 0e89e91085dc..a34f52b0910e 100644
> --- a/llvm/test/Transforms/InstSimplify/returned.ll
> +++ b/llvm/test/Transforms/InstSimplify/returned.ll
> @@ -25,6 +25,6 @@ define i1 @gep3() {
>  ; CHECK-NEXT: ret i1 false
>  }
>
> -declare i8* @func1(i8* returned) nounwind readnone
> -declare %gept* @func2(%gept* returned) nounwind readnone
> +declare i8* @func1(i8* returned) nounwind readnone willreturn
> +declare %gept* @func2(%gept* returned) nounwind readnone willreturn
>
>
> diff  --git a/llvm/test/Transforms/MemCpyOpt/memcpy.ll
> b/llvm/test/Transforms/MemCpyOpt/memcpy.ll
> index 97be3e2fa9ed..096d5d9ea7f8 100644
> --- a/llvm/test/Transforms/MemCpyOpt/memcpy.ll
> +++ b/llvm/test/Transforms/MemCpyOpt/memcpy.ll
> @@ -285,7 +285,7 @@ define void @test8() {
>    ret void
>  }
>
> -declare noalias i8* @malloc(i32)
> +declare noalias i8* @malloc(i32) willreturn
>
>  ; rdar://11341081
>  %struct.big = type { [50 x i32] }
> @@ -384,5 +384,6 @@ declare void @f2(%struct.big*)
>  ; CHECK: attributes [[ATTR0]] = { nounwind }
>  ; CHECK: attributes #1 = { argmemonly nofree nosync nounwind willreturn }
>  ; CHECK: attributes #2 = { nounwind ssp }
> -; CHECK: attributes #3 = { nounwind ssp uwtable }
> -; CHECK: attributes #4 = { argmemonly nofree nosync nounwind willreturn
> writeonly }
> +; CHECK: attributes #3 = { willreturn }
> +; CHECK: attributes #4 = { nounwind ssp uwtable }
> +; CHECK: attributes #5 = { argmemonly nofree nosync nounwind willreturn
> writeonly }
>
> diff  --git a/llvm/test/Transforms/NewGVN/eliminate-callsite-inline.ll
> b/llvm/test/Transforms/NewGVN/eliminate-callsite-inline.ll
> index 4cbeef19711b..5d863ccdd6a0 100644
> --- a/llvm/test/Transforms/NewGVN/eliminate-callsite-inline.ll
> +++ b/llvm/test/Transforms/NewGVN/eliminate-callsite-inline.ll
> @@ -14,4 +14,4 @@ entry:
>    ret void
>  }
>
> -attributes #1 = { noinline nounwind readnone }
> +attributes #1 = { noinline nounwind readnone willreturn }
>
> diff  --git a/llvm/test/Transforms/OpenMP/parallel_deletion.ll
> b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
> index 627026d8da70..1a6d1587a8c8 100644
> --- a/llvm/test/Transforms/OpenMP/parallel_deletion.ll
> +++ b/llvm/test/Transforms/OpenMP/parallel_deletion.ll
> @@ -25,9 +25,9 @@ target datalayout =
> "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16
>  ;
>  ; We delete all but the first of the parallel regions in this test.
>  define void @delete_parallel_0() {
> -; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0()
> +; CHECK-LABEL: define {{[^@]+}}@delete_parallel_0() {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef
> bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void (i32*, i32*,
> ...)*))
> +; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) [[GLOB0:@.*]], i32 noundef 0, void (i32*, i32*, ...)*
> noundef bitcast (void (i32*, i32*)* @.omp_outlined.willreturn to void
> (i32*, i32*, ...)*))
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> @@ -40,9 +40,9 @@ entry:
>
>  define internal void @.omp_outlined.willreturn(i32* noalias
> %.global_tid., i32* noalias %.bound_tid.) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) #0
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) [[ATTR0:#.*]] {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    call void @unknown() #0
> +; CHECK-NEXT:    call void @unknown() [[ATTR0]]
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> @@ -52,9 +52,9 @@ entry:
>
>  define internal void @.omp_outlined.willreturn.0(i32* noalias
> %.global_tid., i32* noalias %.bound_tid.) willreturn {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.0
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) #1
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) [[ATTR1:#.*]] {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    call void @readonly() #4
> +; CHECK-NEXT:    call void @readonly() [[ATTR4:#.*]]
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> @@ -64,9 +64,9 @@ entry:
>
>  define internal void @.omp_outlined.willreturn.1(i32* noalias
> %.global_tid., i32* noalias %.bound_tid.) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.1
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) #2
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) [[ATTR2:#.*]] {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    call void @readnone() #0
> +; CHECK-NEXT:    call void @readnone() [[ATTR0]]
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> @@ -76,7 +76,7 @@ entry:
>
>  define internal void @.omp_outlined.willreturn.2(i32* noalias
> %.global_tid., i32* noalias %.bound_tid.) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.willreturn.2
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) #3
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) [[ATTR3:#.*]] {
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    ret void
>  ;
> @@ -97,11 +97,11 @@ entry:
>  ;
>  ; We delete only the last parallel regions in this test because the
> others might not return.
>  define void @delete_parallel_1() {
> -; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1()
> +; CHECK-LABEL: define {{[^@]+}}@delete_parallel_1() {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef
> bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*, ...)*))
> -; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef
> bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*, ...)*))
> -; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) @0, i32 noundef 0, void (i32*, i32*, ...)* noundef
> bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*, ...)*))
> +; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)*
> noundef bitcast (void (i32*, i32*)* @.omp_outlined. to void (i32*, i32*,
> ...)*))
> +; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)*
> noundef bitcast (void (i32*, i32*)* @.omp_outlined..0 to void (i32*, i32*,
> ...)*))
> +; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) [[GLOB0]], i32 noundef 0, void (i32*, i32*, ...)*
> noundef bitcast (void (i32*, i32*)* @.omp_outlined..1 to void (i32*, i32*,
> ...)*))
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> @@ -114,7 +114,7 @@ entry:
>
>  define internal void @.omp_outlined.(i32* noalias %.global_tid., i32*
> noalias %.bound_tid.) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined.
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]])
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) {
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    call void @unknown()
>  ; CHECK-NEXT:    ret void
> @@ -126,9 +126,9 @@ entry:
>
>  define internal void @.omp_outlined..0(i32* noalias %.global_tid., i32*
> noalias %.bound_tid.) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..0
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) #4
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) [[ATTR4]] {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    call void @readonly() #4
> +; CHECK-NEXT:    call void @readonly() [[ATTR4]]
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> @@ -138,7 +138,7 @@ entry:
>
>  define internal void @.omp_outlined..1(i32* noalias %.global_tid., i32*
> noalias %.bound_tid.) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..1
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) #5
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) [[ATTR5:#.*]] {
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    call void @readnone()
>  ; CHECK-NEXT:    ret void
> @@ -150,7 +150,7 @@ entry:
>
>  define internal void @.omp_outlined..2(i32* noalias %.global_tid., i32*
> noalias %.bound_tid.) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..2
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) #3
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]]) [[ATTR3]] {
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    ret void
>  ;
> @@ -184,16 +184,16 @@ entry:
>  ; FIXME: We do not realize that `a` is dead and all accesses to it can be
> removed
>  ;        making the parallel regions readonly and deletable.
>  define void @delete_parallel_2() {
> -; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2()
> +; CHECK-LABEL: define {{[^@]+}}@delete_parallel_2() {
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
>  ; CHECK-NEXT:    [[TMP:%.*]] = bitcast i32* [[A]] to i8*
> -; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8*
> noundef nonnull align 4 dereferenceable(4) [[TMP]]) #0
> +; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8*
> noundef nonnull align 4 dereferenceable(4) [[TMP]]) [[ATTR0]]
>  ; CHECK-NEXT:    store i32 0, i32* [[A]], align 4
> -; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef
> bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*, i32*,
> ...)*), i32* nocapture nofree noundef nonnull align 4 dereferenceable(4)
> [[A]])
> -; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef
> bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*, i32*,
> ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
> -; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef
> bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*, i32*,
> ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
> -; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) @0, i32 noundef 1, void (i32*, i32*, ...)* noundef
> bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*, i32*,
> ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4) [[A]])
> +; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)*
> noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..3 to void (i32*,
> i32*, ...)*), i32* nocapture nofree noundef nonnull align 4
> dereferenceable(4) [[A]])
> +; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)*
> noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..4 to void (i32*,
> i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4)
> [[A]])
> +; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)*
> noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..5 to void (i32*,
> i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4)
> [[A]])
> +; CHECK-NEXT:    call void (%struct.ident_t*, i32, void (i32*, i32*,
> ...)*, ...) @__kmpc_fork_call(%struct.ident_t* noundef nonnull align 8
> dereferenceable(24) [[GLOB0]], i32 noundef 1, void (i32*, i32*, ...)*
> noundef bitcast (void (i32*, i32*, i32*)* @.omp_outlined..6 to void (i32*,
> i32*, ...)*), i32* nocapture noundef nonnull align 4 dereferenceable(4)
> [[A]])
>  ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
>  ; CHECK-NEXT:    call void @llvm.lifetime.end.p0i8(i64 noundef 4, i8*
> noundef nonnull [[TMP1]])
>  ; CHECK-NEXT:    ret void
> @@ -214,9 +214,9 @@ entry:
>
>  define internal void @.omp_outlined..3(i32* noalias %.global_tid., i32*
> noalias %.bound_tid., i32* dereferenceable(4) %a) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..3
> -; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4
> dereferenceable(4) [[A:%.*]]) #6
> +; CHECK-SAME: (i32* noalias nocapture nofree readnone
> [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree readnone
> [[DOTBOUND_TID_:%.*]], i32* nocapture nofree noundef nonnull align 4
> dereferenceable(4) [[A:%.*]]) [[ATTR6:#.*]] {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    [[CALL:%.*]] = call i32 @omp_get_thread_num() #4
> +; CHECK-NEXT:    [[CALL:%.*]] = call i32 @omp_get_thread_num()
> [[ATTR12:#.*]]
>  ; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[CALL]], 0
>  ; CHECK-NEXT:    br i1 [[CMP]], label [[IF_THEN:%.*]], label
> [[IF_END:%.*]]
>  ; CHECK:       if.then:
> @@ -244,17 +244,17 @@ if.end:                                           ;
> preds = %if.then, %entry
>
>  define internal void @.omp_outlined..4(i32* noalias %.global_tid., i32*
> noalias %.bound_tid., i32* dereferenceable(4) %a) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..4
> -; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree
> readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4
> dereferenceable(4) [[A:%.*]])
> +; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree
> readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4
> dereferenceable(4) [[A:%.*]]) {
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
> -; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t*
> noundef nonnull @0, i32 [[TMP]])
> +; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_master(%struct.ident_t*
> noundef nonnull [[GLOB0]], i32 [[TMP]])
>  ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
>  ; CHECK-NEXT:    br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label
> [[OMP_IF_THEN:%.*]]
>  ; CHECK:       omp_if.then:
>  ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[A]], align 4
>  ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
>  ; CHECK-NEXT:    store i32 [[INC]], i32* [[A]], align 4
> -; CHECK-NEXT:    call void @__kmpc_end_master(%struct.ident_t* noundef
> nonnull @0, i32 [[TMP]])
> +; CHECK-NEXT:    call void @__kmpc_end_master(%struct.ident_t* noundef
> nonnull [[GLOB0]], i32 [[TMP]])
>  ; CHECK-NEXT:    br label [[OMP_IF_END]]
>  ; CHECK:       omp_if.end:
>  ; CHECK-NEXT:    ret void
> @@ -286,21 +286,21 @@ declare void @__kmpc_end_master(%struct.ident_t*,
> i32)
>
>  define internal void @.omp_outlined..5(i32* noalias %.global_tid., i32*
> noalias %.bound_tid., i32* dereferenceable(4) %a) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..5
> -; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree
> readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4
> dereferenceable(4) [[A:%.*]])
> +; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree
> readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4
> dereferenceable(4) [[A:%.*]]) {
>  ; CHECK-NEXT:  entry:
> -; CHECK-NEXT:    [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32
> @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull @0)
> +; CHECK-NEXT:    [[OMP_GLOBAL_THREAD_NUM:%.*]] = call i32
> @__kmpc_global_thread_num(%struct.ident_t* noundef nonnull [[GLOB0]])
> [[ATTR12]]
>  ; CHECK-NEXT:    [[TMP:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
> -; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t*
> noundef nonnull @0, i32 [[TMP]])
> +; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @__kmpc_single(%struct.ident_t*
> noundef nonnull [[GLOB0]], i32 [[TMP]])
>  ; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0
>  ; CHECK-NEXT:    br i1 [[TMP2]], label [[OMP_IF_END:%.*]], label
> [[OMP_IF_THEN:%.*]]
>  ; CHECK:       omp_if.then:
>  ; CHECK-NEXT:    [[TMP3:%.*]] = load i32, i32* [[A]], align 4
>  ; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 [[TMP3]], 1
>  ; CHECK-NEXT:    store i32 [[INC]], i32* [[A]], align 4
> -; CHECK-NEXT:    call void @__kmpc_end_single(%struct.ident_t* noundef
> nonnull @0, i32 [[TMP]])
> +; CHECK-NEXT:    call void @__kmpc_end_single(%struct.ident_t* noundef
> nonnull [[GLOB0]], i32 [[TMP]])
>  ; CHECK-NEXT:    br label [[OMP_IF_END]]
>  ; CHECK:       omp_if.end:
> -; CHECK-NEXT:    call void @__kmpc_barrier(%struct.ident_t* noundef
> nonnull @1, i32 [[OMP_GLOBAL_THREAD_NUM]])
> +; CHECK-NEXT:    call void @__kmpc_barrier(%struct.ident_t* noundef
> nonnull [[GLOB1:@.*]], i32 [[OMP_GLOBAL_THREAD_NUM]])
>  ; CHECK-NEXT:    ret void
>  ;
>  entry:
> @@ -324,18 +324,18 @@ omp_if.end:                                       ;
> preds = %entry, %omp_if.then
>
>  define internal void @.omp_outlined..6(i32* noalias %.global_tid., i32*
> noalias %.bound_tid., i32* dereferenceable(4) %a) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp_outlined..6
> -; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree
> readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4
> dereferenceable(4) [[A:%.*]])
> +; CHECK-SAME: (i32* noalias nocapture nonnull readonly align 4
> dereferenceable(4) [[DOTGLOBAL_TID_:%.*]], i32* noalias nocapture nofree
> readnone [[DOTBOUND_TID_:%.*]], i32* nocapture noundef nonnull align 4
> dereferenceable(4) [[A:%.*]]) {
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    [[A1:%.*]] = alloca i32, align 4
>  ; CHECK-NEXT:    [[DOTOMP_REDUCTION_RED_LIST:%.*]] = alloca [1 x i8*],
> align 8
>  ; CHECK-NEXT:    [[TMP:%.*]] = bitcast i32* [[A1]] to i8*
> -; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8*
> noundef nonnull align 4 [[TMP]]) #0
> +; CHECK-NEXT:    call void @llvm.lifetime.start.p0i8(i64 noundef 4, i8*
> noundef nonnull align 4 [[TMP]]) [[ATTR0]]
>  ; CHECK-NEXT:    store i32 1, i32* [[A1]], align 4
>  ; CHECK-NEXT:    [[TMP1:%.*]] = bitcast [1 x i8*]*
> [[DOTOMP_REDUCTION_RED_LIST]] to i32**
>  ; CHECK-NEXT:    store i32* [[A1]], i32** [[TMP1]], align 8
>  ; CHECK-NEXT:    [[TMP2:%.*]] = load i32, i32* [[DOTGLOBAL_TID_]], align 4
>  ; CHECK-NEXT:    [[TMP3:%.*]] = bitcast [1 x i8*]*
> [[DOTOMP_REDUCTION_RED_LIST]] to i8*
> -; CHECK-NEXT:    [[TMP4:%.*]] = call i32
> @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull @2, i32 [[TMP2]],
> i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8 [[TMP3]], void
> (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func, [8 x i32]*
> noundef nonnull @.gomp_critical_user_.reduction.var)
> +; CHECK-NEXT:    [[TMP4:%.*]] = call i32
> @__kmpc_reduce_nowait(%struct.ident_t* noundef nonnull [[GLOB2:@.*]], i32
> [[TMP2]], i32 noundef 1, i64 noundef 8, i8* noundef nonnull align 8
> [[TMP3]], void (i8*, i8*)* noundef nonnull @.omp.reduction.reduction_func,
> [8 x i32]* noundef nonnull @.gomp_critical_user_.reduction.var)
>  ; CHECK-NEXT:    switch i32 [[TMP4]], label
> [[DOTOMP_REDUCTION_DEFAULT:%.*]] [
>  ; CHECK-NEXT:    i32 1, label [[DOTOMP_REDUCTION_CASE1:%.*]]
>  ; CHECK-NEXT:    i32 2, label [[DOTOMP_REDUCTION_CASE2:%.*]]
> @@ -345,7 +345,7 @@ define internal void @.omp_outlined..6(i32* noalias
> %.global_tid., i32* noalias
>  ; CHECK-NEXT:    [[TMP6:%.*]] = load i32, i32* [[A1]], align 4
>  ; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP5]], [[TMP6]]
>  ; CHECK-NEXT:    store i32 [[ADD]], i32* [[A]], align 4
> -; CHECK-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t*
> noundef nonnull @2, i32 [[TMP2]], [8 x i32]* noundef nonnull
> @.gomp_critical_user_.reduction.var)
> +; CHECK-NEXT:    call void @__kmpc_end_reduce_nowait(%struct.ident_t*
> noundef nonnull [[GLOB2]], i32 [[TMP2]], [8 x i32]* noundef nonnull
> @.gomp_critical_user_.reduction.var)
>  ; CHECK-NEXT:    br label [[DOTOMP_REDUCTION_DEFAULT]]
>  ; CHECK:       .omp.reduction.case2:
>  ; CHECK-NEXT:    [[TMP7:%.*]] = load i32, i32* [[A1]], align 4
> @@ -393,7 +393,7 @@ entry:
>
>  define internal void @.omp.reduction.reduction_func(i8* %arg, i8* %arg1) {
>  ; CHECK-LABEL: define {{[^@]+}}@.omp.reduction.reduction_func
> -; CHECK-SAME: (i8* nocapture nofree nonnull readonly align 8
> dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align
> 8 dereferenceable(8) [[ARG1:%.*]]) #{{[0-9]+}}
> +; CHECK-SAME: (i8* nocapture nofree nonnull readonly align 8
> dereferenceable(8) [[ARG:%.*]], i8* nocapture nofree nonnull readonly align
> 8 dereferenceable(8) [[ARG1:%.*]]) [[ATTR9:#.*]] {
>  ; CHECK-NEXT:  entry:
>  ; CHECK-NEXT:    [[TMP:%.*]] = bitcast i8* [[ARG1]] to i32**
>  ; CHECK-NEXT:    [[TMP2:%.*]] = load i32*, i32** [[TMP]], align 8
>
> diff  --git a/llvm/test/Transforms/Reassociate/erase_inst_made_change.ll
> b/llvm/test/Transforms/Reassociate/erase_inst_made_change.ll
> index 0bb926f207ae..5c743b291126 100644
> --- a/llvm/test/Transforms/Reassociate/erase_inst_made_change.ll
> +++ b/llvm/test/Transforms/Reassociate/erase_inst_made_change.ll
> @@ -20,7 +20,7 @@ entry:
>    ret void
>  }
>
> -define internal void @bar() noinline nounwind readnone {
> +define internal void @bar() noinline nounwind readnone willreturn {
>  entry:
>    ret void
>  }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>


-- 

http://www.fhahn.com/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210207/c87f11c1/attachment.html>


More information about the llvm-commits mailing list