[llvm] 2920770 - [Local] Treat calls that may not return as being alive.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 23 08:06:54 PST 2021
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
}
More information about the llvm-commits
mailing list