summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/FunctionAttrs
diff options
context:
space:
mode:
authorHideto Ueno <uenoku.tokotoko@gmail.com>2019-12-02 13:40:09 +0000
committerHideto Ueno <uenoku.tokotoko@gmail.com>2019-12-02 15:36:29 +0000
commit96552036e307f7b0dd6477583c3fdb7de17e8aac (patch)
treeaddd48e33e8f9ff13d2d86e6840b538deec7d35e /llvm/test/Transforms/FunctionAttrs
parentec7436f299f8b2c2e9ad0e2ca66f3cdeb830cf2a (diff)
downloadbcm5719-llvm-96552036e307f7b0dd6477583c3fdb7de17e8aac.tar.gz
bcm5719-llvm-96552036e307f7b0dd6477583c3fdb7de17e8aac.zip
[Attributor] Copy or port test cases related to Attributor to` Attributor` test folder
Summary: This patch moves the test cases related to Attributor to `Transforms/Attributor` folder. We have used `Transforms/FunctionAttrs` as the primary folder for Attributor test but we need to change testing way now. For the test cases which I think functionattrs doesn't infer anything something like (willreturn, nosync, value-simplify, h2s ..etc), I moved them with the command `git mv`. For the test cases in which functoinattrs and attributor are tested, I copied the test to the folder and remove the check only used by functoinattrs. Reviewers: jdoerfert, sstefan1 Reviewed By: jdoerfert Subscribers: jfb, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D70843
Diffstat (limited to 'llvm/test/Transforms/FunctionAttrs')
-rw-r--r--llvm/test/Transforms/FunctionAttrs/align.ll400
-rw-r--r--llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll471
-rw-r--r--llvm/test/Transforms/FunctionAttrs/arg_returned.ll158
-rw-r--r--llvm/test/Transforms/FunctionAttrs/callbacks.ll65
-rw-r--r--llvm/test/Transforms/FunctionAttrs/dereferenceable.ll209
-rw-r--r--llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll149
-rw-r--r--llvm/test/Transforms/FunctionAttrs/heap_to_stack.ll376
-rw-r--r--llvm/test/Transforms/FunctionAttrs/internal-noalias.ll48
-rw-r--r--llvm/test/Transforms/FunctionAttrs/liveness.ll857
-rw-r--r--llvm/test/Transforms/FunctionAttrs/misc.ll105
-rw-r--r--llvm/test/Transforms/FunctionAttrs/new_attributes.ll43
-rw-r--r--llvm/test/Transforms/FunctionAttrs/noalias_returned.ll270
-rw-r--r--llvm/test/Transforms/FunctionAttrs/nocapture.ll72
-rw-r--r--llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll69
-rw-r--r--llvm/test/Transforms/FunctionAttrs/nonnull.ll259
-rw-r--r--llvm/test/Transforms/FunctionAttrs/norecurse.ll121
-rw-r--r--llvm/test/Transforms/FunctionAttrs/noreturn_async.ll142
-rw-r--r--llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll138
-rw-r--r--llvm/test/Transforms/FunctionAttrs/nosync.ll356
-rw-r--r--llvm/test/Transforms/FunctionAttrs/nounwind.ll13
-rw-r--r--llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll165
-rw-r--r--llvm/test/Transforms/FunctionAttrs/readattrs.ll36
-rw-r--r--llvm/test/Transforms/FunctionAttrs/value-simplify.ll276
-rw-r--r--llvm/test/Transforms/FunctionAttrs/willreturn.ll553
24 files changed, 115 insertions, 5236 deletions
diff --git a/llvm/test/Transforms/FunctionAttrs/align.ll b/llvm/test/Transforms/FunctionAttrs/align.ll
deleted file mode 100644
index a5bf91915ba..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/align.ll
+++ /dev/null
@@ -1,400 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-; Test cases specifically designed for "align" attribute.
-; We use FIXME's to indicate problems and missing attributes.
-
-
-; TEST 1
-; ATTRIBUTOR: define align 8 i32* @test1(i32* nofree readnone returned align 8 "no-capture-maybe-returned" %0)
-define i32* @test1(i32* align 8 %0) #0 {
- ret i32* %0
-}
-
-; TEST 2
-; ATTRIBUTOR: define i32* @test2(i32* nofree readnone returned "no-capture-maybe-returned" %0)
-define i32* @test2(i32* %0) #0 {
- ret i32* %0
-}
-
-; TEST 3
-; ATTRIBUTOR: define align 4 i32* @test3(i32* nofree readnone align 8 "no-capture-maybe-returned" %0, i32* nofree readnone align 4 "no-capture-maybe-returned" %1, i1 %2)
-define i32* @test3(i32* align 8 %0, i32* align 4 %1, i1 %2) #0 {
- %ret = select i1 %2, i32* %0, i32* %1
- ret i32* %ret
-}
-
-; TEST 4
-; ATTRIBUTOR: define align 32 i32* @test4(i32* nofree readnone align 32 "no-capture-maybe-returned" %0, i32* nofree readnone align 32 "no-capture-maybe-returned" %1, i1 %2)
-define i32* @test4(i32* align 32 %0, i32* align 32 %1, i1 %2) #0 {
- %ret = select i1 %2, i32* %0, i32* %1
- ret i32* %ret
-}
-
-; TEST 5
-declare i32* @unknown()
-declare align 8 i32* @align8()
-
-
-; ATTRIBUTOR: define align 8 i32* @test5_1()
-define i32* @test5_1() {
- %ret = tail call align 8 i32* @unknown()
- ret i32* %ret
-}
-
-; ATTRIBUTOR: define align 8 i32* @test5_2()
-define i32* @test5_2() {
- %ret = tail call i32* @align8()
- ret i32* %ret
-}
-
-; TEST 6
-; SCC
-; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @test6_1()
-define i32* @test6_1() #0 {
- %ret = tail call i32* @test6_2()
- ret i32* %ret
-}
-
-; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @test6_2()
-define i32* @test6_2() #0 {
- %ret = tail call i32* @test6_1()
- ret i32* %ret
-}
-
-
-; char a1 __attribute__((aligned(8)));
-; char a2 __attribute__((aligned(16)));
-;
-; char* f1(char* a ){
-; return a?a:f2(&a1);
-; }
-; char* f2(char* a){
-; return a?f1(a):f3(&a2);
-; }
-;
-; char* f3(char* a){
-; return a?&a1: f1(&a2);
-; }
-
-@a1 = common global i8 0, align 8
-@a2 = common global i8 0, align 16
-
-; Function Attrs: nounwind readnone ssp uwtable
-define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
- %2 = icmp eq i8* %0, null
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %1
- %4 = tail call i8* @f2(i8* nonnull @a1)
- %l = load i8, i8* %4
- br label %5
-
-; <label>:5: ; preds = %1, %3
- %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
- ret i8* %6
-}
-
-; Function Attrs: nounwind readnone ssp uwtable
-define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
- %2 = icmp eq i8* %0, null
- br i1 %2, label %5, label %3
-
-; <label>:3: ; preds = %1
-
- %4 = tail call i8* @f1(i8* nonnull %0)
- br label %7
-
-; <label>:5: ; preds = %1
- %6 = tail call i8* @f3(i8* nonnull @a2)
- br label %7
-
-; <label>:7: ; preds = %5, %3
- %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
- ret i8* %8
-}
-
-; Function Attrs: nounwind readnone ssp uwtable
-define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
- %2 = icmp eq i8* %0, null
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %1
- %4 = tail call i8* @f1(i8* nonnull @a2)
- br label %5
-
-; <label>:5: ; preds = %1, %3
- %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
- ret i8* %6
-}
-
-; TEST 7
-; Better than IR information
-define align 4 i32* @test7(i32* align 32 %p) #0 {
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7
-; ATTRIBUTOR-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]])
-; ATTRIBUTOR-NEXT: ret i32* [[P:%.*]]
-;
- tail call i8* @f1(i8* align 8 dereferenceable(1) @a1)
- ret i32* %p
-}
-
-; TEST 7b
-; Function Attrs: nounwind readnone ssp uwtable
-define internal i8* @f1b(i8* readnone %0) local_unnamed_addr #0 {
-;
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@f1b
-; ATTRIBUTOR-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
-; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = icmp eq i8* [[TMP0:%.*]], null
-; ATTRIBUTOR-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
-; ATTRIBUTOR: 3:
-; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call align 8 i8* @f2b(i8* nofree nonnull align 8 dereferenceable(1) @a1)
-; ATTRIBUTOR-NEXT: [[L:%.*]] = load i8, i8* [[TMP4]], align 8
-; ATTRIBUTOR-NEXT: store i8 [[L]], i8* @a1, align 8
-; ATTRIBUTOR-NEXT: br label [[TMP5]]
-; ATTRIBUTOR: 5:
-; ATTRIBUTOR-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP0]], [[TMP1:%.*]] ]
-; ATTRIBUTOR-NEXT: ret i8* [[TMP6]]
-;
- %2 = icmp eq i8* %0, null
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %1
- %4 = tail call i8* @f2b(i8* nonnull @a1)
- %l = load i8, i8* %4
- store i8 %l, i8* @a1
- br label %5
-
-; <label>:5: ; preds = %1, %3
- %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
- ret i8* %6
-}
-
-; Function Attrs: nounwind readnone ssp uwtable
-define internal i8* @f2b(i8* readnone %0) local_unnamed_addr #0 {
-;
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@f2b
-; ATTRIBUTOR-SAME: (i8* nofree nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[TMP0:%.*]]) local_unnamed_addr
-; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = icmp eq i8* @a1, null
-; ATTRIBUTOR-NEXT: br i1 [[TMP2]], label [[TMP5:%.*]], label [[TMP3:%.*]]
-; ATTRIBUTOR: 3:
-; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call i8* @f1b(i8* nofree nonnull align 8 dereferenceable(1) "no-capture-maybe-returned" @a1)
-; ATTRIBUTOR-NEXT: br label [[TMP7:%.*]]
-; ATTRIBUTOR: 5:
-; ATTRIBUTOR-NEXT: [[TMP6:%.*]] = tail call i8* @f3b(i8* nofree nonnull align 16 dereferenceable(1) @a2)
-; ATTRIBUTOR-NEXT: br label [[TMP7]]
-; ATTRIBUTOR: 7:
-; ATTRIBUTOR-NEXT: [[TMP8:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ [[TMP6]], [[TMP5]] ]
-; ATTRIBUTOR-NEXT: ret i8* [[TMP8]]
-;
- %2 = icmp eq i8* %0, null
- br i1 %2, label %5, label %3
-
-; <label>:3: ; preds = %1
-
- %4 = tail call i8* @f1b(i8* nonnull %0)
- br label %7
-
-; <label>:5: ; preds = %1
- %6 = tail call i8* @f3b(i8* nonnull @a2)
- br label %7
-
-; <label>:7: ; preds = %5, %3
- %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
- ret i8* %8
-}
-
-; Function Attrs: nounwind readnone ssp uwtable
-define internal i8* @f3b(i8* readnone %0) local_unnamed_addr #0 {
-;
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@f3b
-; ATTRIBUTOR-SAME: (i8* nocapture nofree nonnull readnone align 16 dereferenceable(1) [[TMP0:%.*]]) local_unnamed_addr
-; ATTRIBUTOR-NEXT: [[TMP2:%.*]] = icmp eq i8* @a2, null
-; ATTRIBUTOR-NEXT: br i1 [[TMP2]], label [[TMP3:%.*]], label [[TMP5:%.*]]
-; ATTRIBUTOR: 3:
-; ATTRIBUTOR-NEXT: [[TMP4:%.*]] = tail call i8* @f1b(i8* nofree nonnull align 16 dereferenceable(1) @a2)
-; ATTRIBUTOR-NEXT: br label [[TMP5]]
-; ATTRIBUTOR: 5:
-; ATTRIBUTOR-NEXT: [[TMP6:%.*]] = phi i8* [ [[TMP4]], [[TMP3]] ], [ @a1, [[TMP1:%.*]] ]
-; ATTRIBUTOR-NEXT: ret i8* [[TMP6]]
-;
- %2 = icmp eq i8* %0, null
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %1
- %4 = tail call i8* @f1b(i8* nonnull @a2)
- br label %5
-
-; <label>:5: ; preds = %1, %3
- %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
- ret i8* %6
-}
-
-define align 4 i32* @test7b(i32* align 32 %p) #0 {
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@test7b
-; ATTRIBUTOR-SAME: (i32* nofree readnone returned align 32 "no-capture-maybe-returned" [[P:%.*]])
-; ATTRIBUTOR-NEXT: [[TMP1:%.*]] = tail call i8* @f1b(i8* nofree nonnull align 8 dereferenceable(1) @a1)
-; ATTRIBUTOR-NEXT: ret i32* [[P:%.*]]
-;
- tail call i8* @f1b(i8* align 8 dereferenceable(1) @a1)
- ret i32* %p
-}
-
-
-; TEST 8
-define void @test8_helper() {
- %ptr0 = tail call i32* @unknown()
- %ptr1 = tail call align 4 i32* @unknown()
- %ptr2 = tail call align 8 i32* @unknown()
-
- tail call void @test8(i32* %ptr1, i32* %ptr1, i32* %ptr0)
-; ATTRIBUTOR: tail call void @test8(i32* align 4 %ptr1, i32* align 4 %ptr1, i32* %ptr0)
- tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
-; ATTRIBUTOR: tail call void @test8(i32* align 8 %ptr2, i32* align 4 %ptr1, i32* align 4 %ptr1)
- tail call void @test8(i32* %ptr2, i32* %ptr1, i32* %ptr1)
-; ATTRIBUTOR: tail call void @test8(i32* align 8 %ptr2, i32* align 4 %ptr1, i32* align 4 %ptr1)
- ret void
-}
-
-declare void @user_i32_ptr(i32*) readnone nounwind
-define internal void @test8(i32* %a, i32* %b, i32* %c) {
-; ATTRIBUTOR: define internal void @test8(i32* nocapture readnone align 4 %a, i32* nocapture readnone align 4 %b, i32* nocapture readnone %c)
- call void @user_i32_ptr(i32* %a)
- call void @user_i32_ptr(i32* %b)
- call void @user_i32_ptr(i32* %c)
- ret void
-}
-
-declare void @test9_helper(i32* %A)
-define void @test9_traversal(i1 %c, i32* align 4 %B, i32* align 8 %C) {
- %sel = select i1 %c, i32* %B, i32* %C
- call void @test9_helper(i32* %sel)
- ret void
-}
-
-; FIXME: This will work with an upcoming patch (D66618 or similar)
-; define align 32 i32* @test10a(i32* align 32 "no-capture-maybe-returned" %p)
-; ATTRIBUTOR: define i32* @test10a(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" %p)
-define i32* @test10a(i32* align 32 %p) {
-; ATTRIBUTOR: %l = load i32, i32* %p, align 32
- %l = load i32, i32* %p
- %c = icmp eq i32 %l, 0
- br i1 %c, label %t, label %f
-t:
- %r = call i32* @test10a(i32* %p)
-; FIXME: This will work with an upcoming patch (D66618 or similar)
-; store i32 1, i32* %r, align 32
-; ATTRIBUTOR: store i32 1, i32* %r
- store i32 1, i32* %r
- %g0 = getelementptr i32, i32* %p, i32 8
- br label %e
-f:
- %g1 = getelementptr i32, i32* %p, i32 8
-; FIXME: This will work with an upcoming patch (D66618 or similar)
-; store i32 -1, i32* %g1, align 32
-; ATTRIBUTOR: store i32 -1, i32* %g1
- store i32 -1, i32* %g1
- br label %e
-e:
- %phi = phi i32* [%g0, %t], [%g1, %f]
- ret i32* %phi
-}
-
-; FIXME: This will work with an upcoming patch (D66618 or similar)
-; define align 32 i32* @test10b(i32* align 32 "no-capture-maybe-returned" %p)
-; ATTRIBUTOR: define i32* @test10b(i32* nofree nonnull align 32 dereferenceable(4) "no-capture-maybe-returned" %p)
-define i32* @test10b(i32* align 32 %p) {
-; ATTRIBUTOR: %l = load i32, i32* %p, align 32
- %l = load i32, i32* %p
- %c = icmp eq i32 %l, 0
- br i1 %c, label %t, label %f
-t:
- %r = call i32* @test10b(i32* %p)
-; FIXME: This will work with an upcoming patch (D66618 or similar)
-; store i32 1, i32* %r, align 32
-; ATTRIBUTOR: store i32 1, i32* %r
- store i32 1, i32* %r
- %g0 = getelementptr i32, i32* %p, i32 8
- br label %e
-f:
- %g1 = getelementptr i32, i32* %p, i32 -8
-; FIXME: This will work with an upcoming patch (D66618 or similar)
-; store i32 -1, i32* %g1, align 32
-; ATTRIBUTOR: store i32 -1, i32* %g1
- store i32 -1, i32* %g1
- br label %e
-e:
- %phi = phi i32* [%g0, %t], [%g1, %f]
- ret i32* %phi
-}
-
-
-; ATTRIBUTOR: define i64 @test11(i32* nocapture nofree nonnull readonly align 8 dereferenceable(8) %p)
-define i64 @test11(i32* %p) {
- %p-cast = bitcast i32* %p to i64*
- %ret = load i64, i64* %p-cast, align 8
- ret i64 %ret
-}
-
-; TEST 12
-; Test for deduction using must-be-executed-context and GEP instruction
-
-; FXIME: %p should have nonnull
-; ATTRIBUTOR: define i64 @test12-1(i32* nocapture nofree readonly align 16 %p)
-define i64 @test12-1(i32* align 4 %p) {
- %p-cast = bitcast i32* %p to i64*
- %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
- %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
- %ret = load i64, i64* %arrayidx1, align 16
- ret i64 %ret
-}
-
-; ATTRIBUTOR: define i64 @test12-2(i32* nocapture nofree nonnull readonly align 16 dereferenceable(8) %p)
-define i64 @test12-2(i32* align 4 %p) {
- %p-cast = bitcast i32* %p to i64*
- %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
- %ret = load i64, i64* %arrayidx0, align 16
- ret i64 %ret
-}
-
-; FXIME: %p should have nonnull
-; ATTRIBUTOR: define void @test12-3(i32* nocapture nofree writeonly align 16 %p)
-define void @test12-3(i32* align 4 %p) {
- %p-cast = bitcast i32* %p to i64*
- %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
- %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
- store i64 0, i64* %arrayidx1, align 16
- ret void
-}
-
-; ATTRIBUTOR: define void @test12-4(i32* nocapture nofree nonnull writeonly align 16 dereferenceable(8) %p)
-define void @test12-4(i32* align 4 %p) {
- %p-cast = bitcast i32* %p to i64*
- %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
- store i64 0, i64* %arrayidx0, align 16
- ret void
-}
-
-declare void @use(i64*) willreturn nounwind
-
-; ATTRIBUTOR: define void @test12-5(i32* align 16 %p)
-define void @test12-5(i32* align 4 %p) {
- %p-cast = bitcast i32* %p to i64*
- %arrayidx0 = getelementptr i64, i64* %p-cast, i64 1
- %arrayidx1 = getelementptr i64, i64* %arrayidx0, i64 3
- tail call void @use(i64* align 16 %arrayidx1)
- ret void
-}
-
-; ATTRIBUTOR: define void @test12-6(i32* align 16 %p)
-define void @test12-6(i32* align 4 %p) {
- %p-cast = bitcast i32* %p to i64*
- %arrayidx0 = getelementptr i64, i64* %p-cast, i64 0
- tail call void @use(i64* align 16 %arrayidx0)
- ret void
-}
-
-attributes #0 = { nounwind uwtable noinline }
-attributes #1 = { uwtable noinline }
diff --git a/llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll b/llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
deleted file mode 100644
index 79075268ed4..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/arg_nocapture.ll
+++ /dev/null
@@ -1,471 +0,0 @@
-; RUN: opt -functionattrs -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s
-;
-; Test cases specifically designed for the "no-capture" argument attribute.
-; We use FIXME's to indicate problems and missing attributes.
-;
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-; TEST comparison against NULL
-;
-; int is_null_return(int *p) {
-; return p == 0;
-; }
-;
-; FIXME: no-capture missing for %p
-; CHECK: define i32 @is_null_return(i32* nofree readnone %p)
-define i32 @is_null_return(i32* %p) #0 {
-entry:
- %cmp = icmp eq i32* %p, null
- %conv = zext i1 %cmp to i32
- ret i32 %conv
-}
-
-; TEST comparison against NULL in control flow
-;
-; int is_null_control(int *p) {
-; if (p == 0)
-; return 1;
-; if (0 == p)
-; return 1;
-; return 0;
-; }
-;
-; FIXME: no-capture missing for %p
-; CHECK: define i32 @is_null_control(i32* nofree readnone %p)
-define i32 @is_null_control(i32* %p) #0 {
-entry:
- %retval = alloca i32, align 4
- %cmp = icmp eq i32* %p, null
- br i1 %cmp, label %if.then, label %if.end
-
-if.then: ; preds = %entry
- store i32 1, i32* %retval, align 4
- br label %return
-
-if.end: ; preds = %entry
- %cmp1 = icmp eq i32* null, %p
- br i1 %cmp1, label %if.then2, label %if.end3
-
-if.then2: ; preds = %if.end
- store i32 1, i32* %retval, align 4
- br label %return
-
-if.end3: ; preds = %if.end
- store i32 0, i32* %retval, align 4
- br label %return
-
-return: ; preds = %if.end3, %if.then2, %if.then
- %0 = load i32, i32* %retval, align 4
- ret i32 %0
-}
-
-; TEST singleton SCC
-;
-; double *srec0(double *a) {
-; srec0(a);
-; return 0;
-; }
-;
-; CHECK: define noalias nonnull align 536870912 dereferenceable(4294967295) double* @srec0(double* nocapture nofree readnone %a)
-define double* @srec0(double* %a) #0 {
-entry:
- %call = call double* @srec0(double* %a)
- ret double* null
-}
-
-; TEST singleton SCC with lots of nested recursive calls
-;
-; int* srec16(int* a) {
-; return srec16(srec16(srec16(srec16(
-; srec16(srec16(srec16(srec16(
-; srec16(srec16(srec16(srec16(
-; srec16(srec16(srec16(srec16(
-; a
-; ))))))))))))))));
-; }
-;
-; Other arguments are possible here due to the no-return behavior.
-;
-; CHECK: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @srec16(i32* nocapture nofree readnone %a)
-define i32* @srec16(i32* %a) #0 {
-entry:
- %call = call i32* @srec16(i32* %a)
-; CHECK-NOT: %call
-; CHECK: unreachable
- %call1 = call i32* @srec16(i32* %call)
- %call2 = call i32* @srec16(i32* %call1)
- %call3 = call i32* @srec16(i32* %call2)
- %call4 = call i32* @srec16(i32* %call3)
- %call5 = call i32* @srec16(i32* %call4)
- %call6 = call i32* @srec16(i32* %call5)
- %call7 = call i32* @srec16(i32* %call6)
- %call8 = call i32* @srec16(i32* %call7)
- %call9 = call i32* @srec16(i32* %call8)
- %call10 = call i32* @srec16(i32* %call9)
- %call11 = call i32* @srec16(i32* %call10)
- %call12 = call i32* @srec16(i32* %call11)
- %call13 = call i32* @srec16(i32* %call12)
- %call14 = call i32* @srec16(i32* %call13)
- %call15 = call i32* @srec16(i32* %call14)
- ret i32* %call15
-}
-
-; TEST SCC with various calls, casts, and comparisons agains NULL
-;
-; CHECK: define dereferenceable_or_null(4) float* @scc_A(i32* nofree readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" %a)
-;
-; CHECK: define dereferenceable_or_null(8) i64* @scc_B(double* nofree readnone returned dereferenceable_or_null(8) "no-capture-maybe-returned" %a)
-;
-; CHECK: define dereferenceable_or_null(4) i8* @scc_C(i16* nofree readnone returned dereferenceable_or_null(4) "no-capture-maybe-returned" %a)
-;
-; float *scc_A(int *a) {
-; return (float*)(a ? (int*)scc_A((int*)scc_B((double*)scc_C((short*)a))) : a);
-; }
-;
-; long *scc_B(double *a) {
-; return (long*)(a ? scc_C((short*)scc_B((double*)scc_A((int*)a))) : a);
-; }
-;
-; void *scc_C(short *a) {
-; return scc_A((int*)(scc_A(a) ? scc_B((double*)a) : scc_C(a)));
-; }
-define float* @scc_A(i32* dereferenceable_or_null(4) %a) {
-entry:
- %tobool = icmp ne i32* %a, null
- br i1 %tobool, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- %0 = bitcast i32* %a to i16*
- %call = call i8* @scc_C(i16* %0)
- %1 = bitcast i8* %call to double*
- %call1 = call i64* @scc_B(double* %1)
- %2 = bitcast i64* %call1 to i32*
- %call2 = call float* @scc_A(i32* %2)
- %3 = bitcast float* %call2 to i32*
- br label %cond.end
-
-cond.false: ; preds = %entry
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
- %cond = phi i32* [ %3, %cond.true ], [ %a, %cond.false ]
- %4 = bitcast i32* %cond to float*
- ret float* %4
-}
-
-define i64* @scc_B(double* dereferenceable_or_null(8) %a) {
-entry:
- %tobool = icmp ne double* %a, null
- br i1 %tobool, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- %0 = bitcast double* %a to i32*
- %call = call float* @scc_A(i32* %0)
- %1 = bitcast float* %call to double*
- %call1 = call i64* @scc_B(double* %1)
- %2 = bitcast i64* %call1 to i16*
- %call2 = call i8* @scc_C(i16* %2)
- br label %cond.end
-
-cond.false: ; preds = %entry
- %3 = bitcast double* %a to i8*
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
- %cond = phi i8* [ %call2, %cond.true ], [ %3, %cond.false ]
- %4 = bitcast i8* %cond to i64*
- ret i64* %4
-}
-
-define i8* @scc_C(i16* dereferenceable_or_null(2) %a) {
-entry:
- %bc = bitcast i16* %a to i32*
- %call = call float* @scc_A(i32* %bc)
- %bc2 = bitcast float* %call to i8*
- %tobool = icmp ne i8* %bc2, null
- br i1 %tobool, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- %0 = bitcast i16* %a to double*
- %call1 = call i64* @scc_B(double* %0)
- %1 = bitcast i64* %call1 to i8*
- br label %cond.end
-
-cond.false: ; preds = %entry
- %call2 = call i8* @scc_C(i16* %a)
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
- %cond = phi i8* [ %1, %cond.true ], [ %call2, %cond.false ]
- %2 = bitcast i8* %cond to i32*
- %call3 = call float* @scc_A(i32* %2)
- %3 = bitcast float* %call3 to i8*
- ret i8* %3
-}
-
-
-; TEST call to external function, marked no-capture
-;
-; void external_no_capture(int /* no-capture */ *p);
-; void test_external_no_capture(int *p) {
-; external_no_capture(p);
-; }
-;
-; CHECK: define void @test_external_no_capture(i32* nocapture %p)
-declare void @external_no_capture(i32* nocapture)
-
-define void @test_external_no_capture(i32* %p) #0 {
-entry:
- call void @external_no_capture(i32* %p)
- ret void
-}
-
-; TEST call to external var-args function, marked no-capture
-;
-; void test_var_arg_call(char *p, int a) {
-; printf(p, a);
-; }
-;
-; CHECK: define void @test_var_arg_call(i8* nocapture %p, i32 %a)
-define void @test_var_arg_call(i8* %p, i32 %a) #0 {
-entry:
- %call = call i32 (i8*, ...) @printf(i8* %p, i32 %a)
- ret void
-}
-
-declare i32 @printf(i8* nocapture, ...)
-
-
-; TEST "captured" only through return
-;
-; long *not_captured_but_returned_0(long *a) {
-; *a1 = 0;
-; return a;
-; }
-;
-; There should *not* be a no-capture attribute on %a
-; CHECK: define nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_0(i64* nofree nonnull returned writeonly align 8 dereferenceable(8) "no-capture-maybe-returned" %a)
-
-define i64* @not_captured_but_returned_0(i64* %a) #0 {
-entry:
- store i64 0, i64* %a, align 8
- ret i64* %a
-}
-
-; TEST "captured" only through return
-;
-; long *not_captured_but_returned_1(long *a) {
-; *(a+1) = 1;
-; return a + 1;
-; }
-;
-; There should *not* be a no-capture attribute on %a
-; CHECK: define nonnull align 8 dereferenceable(8) i64* @not_captured_but_returned_1(i64* nofree nonnull writeonly align 8 dereferenceable(16) "no-capture-maybe-returned" %a)
-define i64* @not_captured_but_returned_1(i64* %a) #0 {
-entry:
- %add.ptr = getelementptr inbounds i64, i64* %a, i64 1
- store i64 1, i64* %add.ptr, align 8
- ret i64* %add.ptr
-}
-
-; TEST calls to "captured" only through return functions
-;
-; void test_not_captured_but_returned_calls(long *a) {
-; not_captured_but_returned_0(a);
-; not_captured_but_returned_1(a);
-; }
-;
-; CHECK: define void @test_not_captured_but_returned_calls(i64* nocapture nofree writeonly %a)
-define void @test_not_captured_but_returned_calls(i64* %a) #0 {
-entry:
- %call = call i64* @not_captured_but_returned_0(i64* %a)
- %call1 = call i64* @not_captured_but_returned_1(i64* %a)
- ret void
-}
-
-; TEST "captured" only through transitive return
-;
-; long* negative_test_not_captured_but_returned_call_0a(long *a) {
-; return not_captured_but_returned_0(a);
-; }
-;
-; There should *not* be a no-capture attribute on %a
-; CHECK: define i64* @negative_test_not_captured_but_returned_call_0a(i64* nofree returned writeonly "no-capture-maybe-returned" %a)
-define i64* @negative_test_not_captured_but_returned_call_0a(i64* %a) #0 {
-entry:
- %call = call i64* @not_captured_but_returned_0(i64* %a)
- ret i64* %call
-}
-
-; TEST captured through write
-;
-; void negative_test_not_captured_but_returned_call_0b(long *a) {
-; *a = (long)not_captured_but_returned_0(a);
-; }
-;
-; There should *not* be a no-capture attribute on %a
-; CHECK: define void @negative_test_not_captured_but_returned_call_0b(i64* nofree writeonly %a)
-define void @negative_test_not_captured_but_returned_call_0b(i64* %a) #0 {
-entry:
- %call = call i64* @not_captured_but_returned_0(i64* %a)
- %0 = ptrtoint i64* %call to i64
- store i64 %0, i64* %a, align 8
- ret void
-}
-
-; TEST "captured" only through transitive return
-;
-; long* negative_test_not_captured_but_returned_call_1a(long *a) {
-; return not_captured_but_returned_1(a);
-; }
-;
-; There should *not* be a no-capture attribute on %a
-; CHECK: define nonnull align 8 dereferenceable(8) i64* @negative_test_not_captured_but_returned_call_1a(i64* nofree writeonly "no-capture-maybe-returned" %a)
-define i64* @negative_test_not_captured_but_returned_call_1a(i64* %a) #0 {
-entry:
- %call = call i64* @not_captured_but_returned_1(i64* %a)
- ret i64* %call
-}
-
-; TEST captured through write
-;
-; void negative_test_not_captured_but_returned_call_1b(long *a) {
-; *a = (long)not_captured_but_returned_1(a);
-; }
-;
-; There should *not* be a no-capture attribute on %a
-; CHECK: define void @negative_test_not_captured_but_returned_call_1b(i64* nofree writeonly %a)
-define void @negative_test_not_captured_but_returned_call_1b(i64* %a) #0 {
-entry:
- %call = call i64* @not_captured_but_returned_1(i64* %a)
- %0 = ptrtoint i64* %call to i64
- store i64 %0, i64* %call, align 8
- ret void
-}
-
-; TEST return argument or unknown call result
-;
-; int* ret_arg_or_unknown(int* b) {
-; if (b == 0)
-; return b;
-; return unknown();
-; }
-;
-; Verify we do *not* assume b is returned or not captured.
-;
-; CHECK: define i32* @ret_arg_or_unknown(i32* readnone %b)
-; CHECK: define i32* @ret_arg_or_unknown_through_phi(i32* readnone %b)
-
-declare i32* @unknown()
-
-define i32* @ret_arg_or_unknown(i32* %b) #0 {
-entry:
- %cmp = icmp eq i32* %b, null
- br i1 %cmp, label %ret_arg, label %ret_unknown
-
-ret_arg:
- ret i32* %b
-
-ret_unknown:
- %call = call i32* @unknown()
- ret i32* %call
-}
-
-define i32* @ret_arg_or_unknown_through_phi(i32* %b) #0 {
-entry:
- %cmp = icmp eq i32* %b, null
- br i1 %cmp, label %ret_arg, label %ret_unknown
-
-ret_arg:
- br label %r
-
-ret_unknown:
- %call = call i32* @unknown()
- br label %r
-
-r:
- %phi = phi i32* [ %b, %ret_arg ], [ %call, %ret_unknown ]
- ret i32* %phi
-}
-
-
-; TEST not captured by readonly external function
-;
-; CHECK: define void @not_captured_by_readonly_call(i32* nocapture readonly %b)
-declare i32* @readonly_unknown(i32*, i32*) readonly
-
-define void @not_captured_by_readonly_call(i32* %b) #0 {
-entry:
- %call = call i32* @readonly_unknown(i32* %b, i32* %b)
- ret void
-}
-
-
-; TEST not captured by readonly external function if return chain is known
-;
-; Make sure the returned flag on %r is strong enough to justify nocapture on %b but **not** on %r.
-;
-; CHECK: define i32* @not_captured_by_readonly_call_not_returned_either1(i32* nocapture readonly %b, i32* readonly returned %r)
-;
-; CHECK: define i32* @not_captured_by_readonly_call_not_returned_either2(i32* nocapture readonly %b, i32* readonly returned %r)
-; CHECK: define i32* @not_captured_by_readonly_call_not_returned_either3(i32* nocapture readonly %b, i32* readonly returned %r)
-;
-; CHECK: define i32* @not_captured_by_readonly_call_not_returned_either4(i32* nocapture readonly %b, i32* readonly returned %r)
-define i32* @not_captured_by_readonly_call_not_returned_either1(i32* %b, i32* returned %r) {
-entry:
- %call = call i32* @readonly_unknown(i32* %b, i32* %r) nounwind
- ret i32* %call
-}
-
-declare i32* @readonly_unknown_r1a(i32*, i32* returned) readonly
-define i32* @not_captured_by_readonly_call_not_returned_either2(i32* %b, i32* %r) {
-entry:
- %call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r) nounwind
- ret i32* %call
-}
-
-declare i32* @readonly_unknown_r1b(i32*, i32* returned) readonly nounwind
-define i32* @not_captured_by_readonly_call_not_returned_either3(i32* %b, i32* %r) {
-entry:
- %call = call i32* @readonly_unknown_r1b(i32* %b, i32* %r)
- ret i32* %call
-}
-
-define i32* @not_captured_by_readonly_call_not_returned_either4(i32* %b, i32* %r) nounwind {
-entry:
- %call = call i32* @readonly_unknown_r1a(i32* %b, i32* %r)
- ret i32* %call
-}
-
-
-declare i32* @unknown_i32p(i32*)
-define void @nocapture_is_not_subsumed_1(i32* nocapture %b) {
-; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_1
-; CHECK-SAME: (i32* nocapture [[B:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = call i32* @unknown_i32p(i32* [[B:%.*]])
-; CHECK-NEXT: store i32 0, i32* [[CALL]]
-; CHECK-NEXT: ret void
-;
-entry:
- %call = call i32* @unknown_i32p(i32* %b)
- store i32 0, i32* %call
- ret void
-}
-
-declare i32* @readonly_i32p(i32*) readonly
-define void @nocapture_is_not_subsumed_2(i32* nocapture %b) {
-; CHECK-LABEL: define {{[^@]+}}@nocapture_is_not_subsumed_2
-; CHECK-SAME: (i32* nocapture nofree [[B:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[CALL:%.*]] = call i32* @readonly_i32p(i32* readonly [[B:%.*]])
-; CHECK-NEXT: store i32 0, i32* [[CALL]]
-; CHECK-NEXT: ret void
-;
-entry:
- %call = call i32* @readonly_i32p(i32* %b)
- store i32 0, i32* %call
- ret void
-}
-
-attributes #0 = { noinline nounwind uwtable }
diff --git a/llvm/test/Transforms/FunctionAttrs/arg_returned.ll b/llvm/test/Transforms/FunctionAttrs/arg_returned.ll
index 5572c0124a0..0adf91cd9aa 100644
--- a/llvm/test/Transforms/FunctionAttrs/arg_returned.ll
+++ b/llvm/test/Transforms/FunctionAttrs/arg_returned.ll
@@ -1,6 +1,4 @@
; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefix=FNATTR
-; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
-; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-annotate-decl-cs -functionattrs -S < %s | FileCheck %s --check-prefix=BOTH
;
; Test cases specifically designed for the "returned" argument attribute.
; We use FIXME's to indicate problems and missing attributes.
@@ -8,24 +6,12 @@
; TEST SCC test returning an integer value argument
;
-; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; BOTH-NEXT: define i32 @sink_r0(i32 returned %r)
-; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; BOTH-NEXT: define i32 @scc_r1(i32 %a, i32 returned %r, i32 %b)
-; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; BOTH-NEXT: define i32 @scc_r2(i32 %a, i32 %b, i32 returned %r)
-; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; BOTH-NEXT: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
;
; FNATTR: define i32 @sink_r0(i32 returned %r)
; FNATTR: define i32 @scc_r1(i32 %a, i32 %r, i32 %b)
; FNATTR: define i32 @scc_r2(i32 %a, i32 %b, i32 %r)
; FNATTR: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
;
-; ATTRIBUTOR: define i32 @sink_r0(i32 returned %r)
-; ATTRIBUTOR: define i32 @scc_r1(i32 %a, i32 returned %r, i32 %b)
-; ATTRIBUTOR: define i32 @scc_r2(i32 %a, i32 %b, i32 returned %r)
-; ATTRIBUTOR: define i32 @scc_rX(i32 %a, i32 %b, i32 %r)
;
; int scc_r1(int a, int b, int r);
; int scc_r2(int a, int b, int r);
@@ -163,12 +149,6 @@ return: ; preds = %cond.end, %if.then3
; FNATTR: define double* @ptr_scc_r1(double* %a, double* readnone %r, double* nocapture readnone %b)
; FNATTR: define double* @ptr_scc_r2(double* readnone %a, double* readnone %b, double* readnone %r)
;
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double* @ptr_sink_r0(double* nofree readnone returned "no-capture-maybe-returned" %r)
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double* @ptr_scc_r1(double* nofree readnone %a, double* nofree readnone returned %r, double* nocapture nofree readnone %b)
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double* @ptr_scc_r2(double* nofree readnone %a, double* nofree readnone %b, double* nofree readnone returned %r)
;
; double* ptr_scc_r1(double* a, double* b, double* r);
; double* ptr_scc_r2(double* a, double* b, double* r);
@@ -253,8 +233,6 @@ return: ; preds = %cond.end, %if.then3
; }
;
; FNATTR: define i32* @rt0(i32* readonly %a)
-; BOTH: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readonly uwtable
-; BOTH-NEXT: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @rt0(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %a)
define i32* @rt0(i32* %a) #0 {
entry:
%v = load i32, i32* %a, align 4
@@ -271,8 +249,6 @@ entry:
; }
;
; FNATTR: define noalias i32* @rt1(i32* nocapture readonly %a)
-; BOTH: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readonly uwtable
-; BOTH-NEXT: define noalias nonnull align 536870912 dereferenceable(4294967295) i32* @rt1(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %a)
define i32* @rt1(i32* %a) #0 {
entry:
%v = load i32, i32* %a, align 4
@@ -286,8 +262,6 @@ entry:
;
; FNATTR: define i32* @rt2_helper(i32* %a)
; FNATTR: define i32* @rt2(i32* readnone %a, i32* readnone %b)
-; BOTH: define i32* @rt2_helper(i32* nofree readnone returned %a)
-; BOTH: define i32* @rt2(i32* nofree readnone %a, i32* nofree readnone "no-capture-maybe-returned" %b)
define i32* @rt2_helper(i32* %a) #0 {
entry:
%call = call i32* @rt2(i32* %a, i32* %a)
@@ -312,8 +286,6 @@ if.end:
;
; FNATTR: define i32* @rt3_helper(i32* %a, i32* %b)
; FNATTR: define i32* @rt3(i32* readnone %a, i32* readnone %b)
-; BOTH: define i32* @rt3_helper(i32* nofree readnone %a, i32* nofree readnone returned "no-capture-maybe-returned" %b)
-; BOTH: define i32* @rt3(i32* nofree readnone %a, i32* nofree readnone returned "no-capture-maybe-returned" %b)
define i32* @rt3_helper(i32* %a, i32* %b) #0 {
entry:
%call = call i32* @rt3(i32* %a, i32* %b)
@@ -343,12 +315,8 @@ if.end:
; return r;
; }
;
-; BOTH: declare void @unknown_fn(i32* (i32*)*)
;
-; BOTH: Function Attrs: noinline nounwind uwtable
-; BOTH-NEXT: define i32* @calls_unknown_fn(i32* readnone returned "no-capture-maybe-returned" %r)
; FNATTR: define i32* @calls_unknown_fn(i32* readnone returned %r)
-; ATTRIBUTOR: define i32* @calls_unknown_fn(i32* readnone returned "no-capture-maybe-returned" %r)
declare void @unknown_fn(i32* (i32*)*) #0
define i32* @calls_unknown_fn(i32* %r) #0 {
@@ -357,41 +325,6 @@ define i32* @calls_unknown_fn(i32* %r) #0 {
}
-; TEST call to a function that might be redifined at link time
-;
-; int *maybe_redefined_fn(int *r) {
-; return r;
-; }
-;
-; int *calls_maybe_redefined_fn(int *r) {
-; maybe_redefined_fn(r);
-; return r;
-; }
-;
-; Verify the maybe-redefined function is not annotated:
-;
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR: define linkonce_odr i32* @maybe_redefined_fn(i32* %r)
-;
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR: define i32* @calls_maybe_redefined_fn(i32* returned %r)
-;
-; BOTH: Function Attrs: noinline nounwind uwtable
-; BOTH-NEXT: define linkonce_odr i32* @maybe_redefined_fn(i32* %r)
-;
-; BOTH: Function Attrs: noinline nounwind uwtable
-; BOTH-NEXT: define i32* @calls_maybe_redefined_fn(i32* returned %r)
-define linkonce_odr i32* @maybe_redefined_fn(i32* %r) #0 {
-entry:
- ret i32* %r
-}
-
-define i32* @calls_maybe_redefined_fn(i32* %r) #0 {
-entry:
- %call = call i32* @maybe_redefined_fn(i32* %r)
- ret i32* %r
-}
-
; TEST return call to a function that might be redifined at link time
;
; int *maybe_redefined_fn2(int *r) {
@@ -404,13 +337,8 @@ entry:
;
; Verify the maybe-redefined function is not annotated:
;
-; BOTH: Function Attrs: noinline nounwind uwtable
-; BOTH-NEXT: define linkonce_odr i32* @maybe_redefined_fn2(i32* %r)
-; BOTH: Function Attrs: noinline nounwind uwtable
-; BOTH-NEXT: define i32* @calls_maybe_redefined_fn2(i32* %r)
;
; FNATTR: define i32* @calls_maybe_redefined_fn2(i32* %r)
-; ATTRIBUTOR: define i32* @calls_maybe_redefined_fn2(i32* %r)
define linkonce_odr i32* @maybe_redefined_fn2(i32* %r) #0 {
entry:
ret i32* %r
@@ -432,12 +360,8 @@ entry:
; return b == 0? b : x;
; }
;
-; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; BOTH-NEXT: define double @select_and_phi(double returned %b)
;
; FNATTR: define double @select_and_phi(double %b)
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double @select_and_phi(double returned %b)
define double @select_and_phi(double %b) #0 {
entry:
%cmp = fcmp ogt double %b, 0.000000e+00
@@ -463,13 +387,9 @@ if.end: ; preds = %if.then, %entry
; return b == 0? b : x;
; }
;
-; BOTH: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; BOTH-NEXT: define double @recursion_select_and_phi(i32 %a, double returned %b)
;
; FNATTR: define double @recursion_select_and_phi(i32 %a, double %b)
;
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double @recursion_select_and_phi(i32 %a, double returned %b)
define double @recursion_select_and_phi(i32 %a, double %b) #0 {
entry:
%dec = add nsw i32 %a, -1
@@ -494,13 +414,9 @@ if.end: ; preds = %if.then, %entry
; return (double*)b;
; }
;
-; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; BOTH-NEXT: define double* @bitcast(i32* nofree readnone returned "no-capture-maybe-returned" %b)
;
; FNATTR: define double* @bitcast(i32* readnone %b)
;
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double* @bitcast(i32* nofree readnone returned "no-capture-maybe-returned" %b)
define double* @bitcast(i32* %b) #0 {
entry:
%bc0 = bitcast i32* %b to double*
@@ -517,13 +433,9 @@ entry:
; return b != 0 ? b : x;
; }
;
-; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; BOTH-NEXT: define double* @bitcasts_select_and_phi(i32* nofree readnone returned %b)
;
; FNATTR: define double* @bitcasts_select_and_phi(i32* readnone %b)
;
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double* @bitcasts_select_and_phi(i32* nofree readnone returned %b)
define double* @bitcasts_select_and_phi(i32* %b) #0 {
entry:
%bc0 = bitcast i32* %b to double*
@@ -555,13 +467,9 @@ if.end: ; preds = %if.then, %entry
; /* return undef */
; }
;
-; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; BOTH-NEXT: define double* @ret_arg_arg_undef(i32* nofree readnone returned %b)
;
; FNATTR: define double* @ret_arg_arg_undef(i32* readnone %b)
;
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double* @ret_arg_arg_undef(i32* nofree readnone returned %b)
define double* @ret_arg_arg_undef(i32* %b) #0 {
entry:
%bc0 = bitcast i32* %b to double*
@@ -593,13 +501,9 @@ ret_undef:
; /* return undef */
; }
;
-; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; BOTH-NEXT: define double* @ret_undef_arg_arg(i32* nofree readnone returned %b)
;
; FNATTR: define double* @ret_undef_arg_arg(i32* readnone %b)
;
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define double* @ret_undef_arg_arg(i32* nofree readnone returned %b)
define double* @ret_undef_arg_arg(i32* %b) #0 {
entry:
%bc0 = bitcast i32* %b to double*
@@ -631,11 +535,8 @@ ret_arg1:
; /* return undef */
; }
;
-; BOTH: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; BOTH-NEXT: define double* @ret_undef_arg_undef(i32* nofree readnone returned %b)
;
; FNATTR: define double* @ret_undef_arg_undef(i32* readnone %b)
-; ATTRIBUTOR: define double* @ret_undef_arg_undef(i32* nofree readnone returned %b)
define double* @ret_undef_arg_undef(i32* %b) #0 {
entry:
%bc0 = bitcast i32* %b to double*
@@ -667,10 +568,6 @@ ret_undef1:
;
; FNATTR: define i32* @ret_arg_or_unknown(i32* %b)
; FNATTR: define i32* @ret_arg_or_unknown_through_phi(i32* %b)
-; ATTRIBUTOR: define i32* @ret_arg_or_unknown(i32* %b)
-; ATTRIBUTOR: define i32* @ret_arg_or_unknown_through_phi(i32* %b)
-; BOTH: define i32* @ret_arg_or_unknown(i32* %b)
-; BOTH: define i32* @ret_arg_or_unknown_through_phi(i32* %b)
declare i32* @unknown(i32*)
define i32* @ret_arg_or_unknown(i32* %b) #0 {
@@ -709,14 +606,6 @@ r:
; FNATTR: define i32 @deadblockcall2(i32 %A)
; FNATTR: define i32 @deadblockphi1(i32 %A)
; FNATTR: define i32 @deadblockphi2(i32 %A)
-; ATTRIBUTOR: define i32 @deadblockcall1(i32 returned %A)
-; ATTRIBUTOR: define i32 @deadblockcall2(i32 returned %A)
-; ATTRIBUTOR: define i32 @deadblockphi1(i32 returned %A)
-; ATTRIBUTOR: define i32 @deadblockphi2(i32 returned %A)
-; BOTH: define i32 @deadblockcall1(i32 returned %A)
-; BOTH: define i32 @deadblockcall2(i32 returned %A)
-; BOTH: define i32 @deadblockphi1(i32 returned %A)
-; BOTH: define i32 @deadblockphi2(i32 returned %A)
define i32 @deadblockcall1(i32 %A) #0 {
entry:
ret i32 %A
@@ -789,51 +678,4 @@ r:
ret i32 %PHI2
}
-define weak_odr i32 @non_exact_0() {
- ret i32 0
-}
-define weak_odr i32 @non_exact_1(i32 %a) {
- ret i32 %a
-}
-define weak_odr i32 @non_exact_2(i32 returned %a) {
- ret i32 %a
-}
-define weak_odr i32* @non_exact_3(i32* align 32 returned %a) {
- ret i32* %a
-}
-define i32 @exact(i32* %a) {
- %c0 = call i32 @non_exact_0()
- %c1 = call i32 @non_exact_1(i32 1)
- %c2 = call i32 @non_exact_2(i32 2)
- %c3 = call i32* @non_exact_3(i32* %a)
-; We can use the information of the weak function non_exact_3 because it was
-; given to us and not derived (the alignment of the returned argument).
-; ATTRIBUTOR: %c4 = load i32, i32* %c3, align 32
- %c4 = load i32, i32* %c3
-; FIXME: %c2 and %c3 should be replaced but not %c0 or %c1!
-; ATTRIBUTOR: %add1 = add i32 %c0, %c1
-; ATTRIBUTOR: %add2 = add i32 %add1, %c2
-; ATTRIBUTOR: %add3 = add i32 %add2, %c4
- %add1 = add i32 %c0, %c1
- %add2 = add i32 %add1, %c2
- %add3 = add i32 %add2, %c4
- ret i32 %add3
-}
-
-@G = external global i8
-define i32* @ret_const() #0 {
- %bc = bitcast i8* @G to i32*
- ret i32* %bc
-}
-define i32* @use_const() #0 {
- %c = call i32* @ret_const()
- ; ATTRIBUTOR: ret i32* bitcast (i8* @G to i32*)
- ret i32* %c
-}
-define i32* @dont_use_const() #0 {
- %c = musttail call i32* @ret_const()
- ; ATTRIBUTOR: ret i32* %c
- ret i32* %c
-}
-
attributes #0 = { noinline nounwind uwtable }
diff --git a/llvm/test/Transforms/FunctionAttrs/callbacks.ll b/llvm/test/Transforms/FunctionAttrs/callbacks.ll
deleted file mode 100644
index f79d81c3969..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/callbacks.ll
+++ /dev/null
@@ -1,65 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; FIXME: Add -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations below.
-; This flag was removed because max iterations is 2 in most cases, but in windows it is 1.
-; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s
-; ModuleID = 'callback_simple.c'
-target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
-
-; Test 0
-;
-; Make sure we propagate information from the caller to the callback callee but
-; only for arguments that are mapped through the callback metadata. Here, the
-; first two arguments of the call and the callback callee do not correspond to
-; each other but argument 3-5 of the transitive call site in the caller match
-; arguments 2-4 of the callback callee. Here we should see information and value
-; transfer in both directions.
-; FIXME: The callee -> call site direction is not working yet.
-
-define void @t0_caller(i32* %a) {
-; CHECK-LABEL: @t0_caller(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[B:%.*]] = alloca i32, align 32
-; CHECK-NEXT: [[C:%.*]] = alloca i32*, align 64
-; CHECK-NEXT: [[PTR:%.*]] = alloca i32, align 128
-; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
-; CHECK-NEXT: store i32 42, i32* [[B]], align 32
-; CHECK-NEXT: store i32* [[B]], i32** [[C]], align 64
-; CHECK-NEXT: call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* [[A:%.*]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
-; CHECK-NEXT: ret void
-;
-entry:
- %b = alloca i32, align 32
- %c = alloca i32*, align 64
- %ptr = alloca i32, align 128
- %0 = bitcast i32* %b to i8*
- store i32 42, i32* %b, align 4
- store i32* %b, i32** %c, align 8
- call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c)
- ret void
-}
-
-; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
-; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
-define internal void @t0_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
-; CHECK-LABEL: @t0_callback_callee(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[PTR_VAL:%.*]] = load i32, i32* [[PTR:%.*]], align 8
-; CHECK-NEXT: store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL:%.*]]
-; CHECK-NEXT: [[TMP0:%.*]] = load i32*, i32** [[C:%.*]], align 64
-; CHECK-NEXT: tail call void @t0_check(i32* align 256 [[A:%.*]], i64 99, i32* [[TMP0]])
-; CHECK-NEXT: ret void
-;
-entry:
- %ptr_val = load i32, i32* %ptr, align 8
- store i32 %ptr_val, i32* %is_not_null
- %0 = load i32*, i32** %c, align 8
- tail call void @t0_check(i32* %a, i64 %b, i32* %0)
- ret void
-}
-
-declare void @t0_check(i32* align 256, i64, i32*)
-
-declare !callback !0 void @t0_callback_broker(i32*, i32*, void (i32*, i32*, ...)*, ...)
-
-!0 = !{!1}
-!1 = !{i64 2, i64 -1, i64 -1, i1 true}
diff --git a/llvm/test/Transforms/FunctionAttrs/dereferenceable.ll b/llvm/test/Transforms/FunctionAttrs/dereferenceable.ll
deleted file mode 100644
index 951b5047747..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/dereferenceable.ll
+++ /dev/null
@@ -1,209 +0,0 @@
-; RUN: opt -attributor -attributor-manifest-internal --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
-
-
-declare void @deref_phi_user(i32* %a);
-
-; TEST 1
-; take mininimum of return values
-;
-define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
-; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test1(i32* nofree nonnull readnone dereferenceable(4) "no-capture-maybe-returned" %0, double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %1, i1 zeroext %2)
- %4 = bitcast double* %1 to i32*
- %5 = select i1 %2, i32* %0, i32* %4
- ret i32* %5
-}
-
-; TEST 2
-define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr {
-; ATTRIBUTOR: define dereferenceable_or_null(4) i32* @test2(i32* nofree readnone dereferenceable_or_null(4) "no-capture-maybe-returned" %0, double* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %1, i1 zeroext %2)
- %4 = bitcast double* %1 to i32*
- %5 = select i1 %2, i32* %0, i32* %4
- ret i32* %5
-}
-
-; TEST 3
-; GEP inbounds
-define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr {
-; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_1(i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %0)
- %ret = getelementptr inbounds i32, i32* %0, i64 1
- ret i32* %ret
-}
-
-define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr {
-; ATTRIBUTOR: define nonnull dereferenceable(16) i32* @test3_2(i32* nofree nonnull readnone dereferenceable(32) "no-capture-maybe-returned" %0)
- %ret = getelementptr inbounds i32, i32* %0, i64 4
- ret i32* %ret
-}
-
-define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr {
-; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_3(i32* nofree nonnull readnone dereferenceable(8) "no-capture-maybe-returned" %0, i32* nofree nonnull readnone dereferenceable(16) "no-capture-maybe-returned" %1, i1 %2) local_unnamed_addr
- %ret1 = getelementptr inbounds i32, i32* %0, i64 1
- %ret2 = getelementptr inbounds i32, i32* %1, i64 2
- %ret = select i1 %2, i32* %ret1, i32* %ret2
- ret i32* %ret
-}
-
-; TEST 4
-; Better than known in IR.
-
-define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_addr {
-; ATTRIBUTOR: define nonnull dereferenceable(8) i32* @test4(i32* nofree nonnull readnone returned dereferenceable(8) "no-capture-maybe-returned" %0)
- ret i32* %0
-}
-
-; TEST 5
-; loop in which dereferenceabily "grows"
-define void @deref_phi_growing(i32* dereferenceable(4000) %a) {
-entry:
- br label %for.cond
-
-for.cond: ; preds = %for.inc, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
- %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ]
-; ATTRIBUTOR: call void @deref_phi_user(i32* nonnull dereferenceable(4000) %a.addr.0)
- call void @deref_phi_user(i32* %a.addr.0)
- %tmp = load i32, i32* %a.addr.0, align 4
- %cmp = icmp slt i32 %i.0, %tmp
- br i1 %cmp, label %for.body, label %for.cond.cleanup
-
-for.cond.cleanup: ; preds = %for.cond
- br label %for.end
-
-for.body: ; preds = %for.cond
- br label %for.inc
-
-for.inc: ; preds = %for.body
- %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 -1
- %inc = add nuw nsw i32 %i.0, 1
- br label %for.cond
-
-for.end: ; preds = %for.cond.cleanup
- ret void
-}
-
-; TEST 6
-; loop in which dereferenceabily "shrinks"
-define void @deref_phi_shrinking(i32* dereferenceable(4000) %a) {
-entry:
- br label %for.cond
-
-for.cond: ; preds = %for.inc, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
- %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ]
-; ATTRIBUTOR: call void @deref_phi_user(i32* nonnull %a.addr.0)
- call void @deref_phi_user(i32* %a.addr.0)
- %tmp = load i32, i32* %a.addr.0, align 4
- %cmp = icmp slt i32 %i.0, %tmp
- br i1 %cmp, label %for.body, label %for.cond.cleanup
-
-for.cond.cleanup: ; preds = %for.cond
- br label %for.end
-
-for.body: ; preds = %for.cond
- br label %for.inc
-
-for.inc: ; preds = %for.body
- %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 1
- %inc = add nuw nsw i32 %i.0, 1
- br label %for.cond
-
-for.end: ; preds = %for.cond.cleanup
- ret void
-}
-
-; TEST 7
-; share known infomation in must-be-executed-context
-declare i32* @unkown_ptr() willreturn nounwind
-declare i32 @unkown_f(i32*) willreturn nounwind
-define i32* @f7_0(i32* %ptr) {
-; ATTRIBUTOR: define nonnull dereferenceable(8) i32* @f7_0(i32* nonnull returned dereferenceable(8) %ptr)
- %T = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
- ret i32* %ptr
-}
-
-; ATTRIBUTOR: define void @f7_1(i32* nonnull dereferenceable(4) %ptr, i1 %c)
-define void @f7_1(i32* %ptr, i1 %c) {
-
-; ATTRIBUTOR: %A = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
- %A = tail call i32 @unkown_f(i32* %ptr)
-
- %ptr.0 = load i32, i32* %ptr
- ; deref 4 hold
-
-; FIXME: this should be %B = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
-; ATTRIBUTOR: %B = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
- %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr)
-
- br i1%c, label %if.true, label %if.false
-if.true:
-; ATTRIBUTOR: %C = tail call i32 @unkown_f(i32* nonnull dereferenceable(8) %ptr)
- %C = tail call i32 @unkown_f(i32* %ptr)
-
-; ATTRIBUTOR: %D = tail call i32 @unkown_f(i32* nonnull dereferenceable(8) %ptr)
- %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
-
-; FIXME: This should be tail call i32 @unkown_f(i32* nonnull dereferenceable(8) %ptr)
-; Making must-be-executed-context backward exploration will fix this.
-; ATTRIBUTOR: %E = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
- %E = tail call i32 @unkown_f(i32* %ptr)
-
- ret void
-
-if.false:
- ret void
-}
-
-; ATTRIBUTOR: define void @f7_2(i1 %c)
-define void @f7_2(i1 %c) {
-
- %ptr = tail call i32* @unkown_ptr()
-
-; ATTRIBUTOR: %A = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
- %A = tail call i32 @unkown_f(i32* %ptr)
-
- %arg_a.0 = load i32, i32* %ptr
- ; deref 4 hold
-
-; ATTRIBUTOR: %B = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
- %B = tail call i32 @unkown_f(i32* dereferenceable(1) %ptr)
-
- br i1%c, label %if.true, label %if.false
-if.true:
-
-; ATTRIBUTOR: %C = tail call i32 @unkown_f(i32* nonnull dereferenceable(8) %ptr)
- %C = tail call i32 @unkown_f(i32* %ptr)
-
-; ATTRIBUTOR: %D = tail call i32 @unkown_f(i32* nonnull dereferenceable(8) %ptr)
- %D = tail call i32 @unkown_f(i32* dereferenceable(8) %ptr)
-
- %E = tail call i32 @unkown_f(i32* %ptr)
-; FIXME: This should be @unkown_f(i32* nonnull dereferenceable(8) %ptr)
-; Making must-be-executed-context backward exploration will fix this.
-; ATTRIBUTOR: %E = tail call i32 @unkown_f(i32* nonnull dereferenceable(4) %ptr)
-
- ret void
-
-if.false:
- ret void
-}
-
-define i32* @f7_3() {
-; ATTRIBUTOR: define nonnull align 16 dereferenceable(4) i32* @f7_3()
- %ptr = tail call i32* @unkown_ptr()
- store i32 10, i32* %ptr, align 16
- ret i32* %ptr
-}
-
-define i32* @test_for_minus_index(i32* %p) {
-; FIXME: This should have a return dereferenceable(8) but we need to make sure it will work in loops as well.
-; ATTRIBUTOR: define nonnull i32* @test_for_minus_index(i32* nofree nonnull writeonly "no-capture-maybe-returned" %p)
- %q = getelementptr inbounds i32, i32* %p, i32 -2
- store i32 1, i32* %q
- ret i32* %q
-}
-
-define void @deref_or_null_and_nonnull(i32* dereferenceable_or_null(100) %0) {
-; ATTRIBUTOR: define void @deref_or_null_and_nonnull(i32* nocapture nofree nonnull writeonly dereferenceable(100) %0)
- store i32 1, i32* %0
- ret void
-}
diff --git a/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll b/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll
deleted file mode 100644
index 2b15e0780df..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/fn_noreturn.ll
+++ /dev/null
@@ -1,149 +0,0 @@
-; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s
-;
-; Test cases specifically designed for the "no-return" function attribute.
-; We use FIXME's to indicate problems and missing attributes.
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-
-; TEST 1, singleton SCC void return type
-;
-; void srec0() {
-; return srec0();
-; }
-;
-; CHECK: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; CHECK: define void @srec0()
-;
-define void @srec0() #0 {
-entry:
- call void @srec0()
- ret void
-}
-
-
-; TEST 2: singleton SCC int return type with a lot of recursive calls
-;
-; int srec16(int a) {
-; return srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(srec16(a))))))))))))))));
-; }
-;
-; CHECK: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; CHECK: define i32 @srec16(i32 %a)
-;
-define i32 @srec16(i32 %a) #0 {
-entry:
- %call = call i32 @srec16(i32 %a)
- %call1 = call i32 @srec16(i32 %call)
- %call2 = call i32 @srec16(i32 %call1)
- %call3 = call i32 @srec16(i32 %call2)
- %call4 = call i32 @srec16(i32 %call3)
- %call5 = call i32 @srec16(i32 %call4)
- %call6 = call i32 @srec16(i32 %call5)
- %call7 = call i32 @srec16(i32 %call6)
- %call8 = call i32 @srec16(i32 %call7)
- %call9 = call i32 @srec16(i32 %call8)
- %call10 = call i32 @srec16(i32 %call9)
- %call11 = call i32 @srec16(i32 %call10)
- %call12 = call i32 @srec16(i32 %call11)
- %call13 = call i32 @srec16(i32 %call12)
- %call14 = call i32 @srec16(i32 %call13)
- %call15 = call i32 @srec16(i32 %call14)
- br label %exit
-
-exit:
- ret i32 %call15
-}
-
-
-; TEST 3: endless loop, no return instruction
-;
-; int endless_loop(int a) {
-; while (1);
-; }
-;
-; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
-; CHECK: define i32 @endless_loop(i32 %a)
-;
-define i32 @endless_loop(i32 %a) #0 {
-entry:
- br label %while.body
-
-while.body: ; preds = %entry, %while.body
- br label %while.body
-}
-
-
-; TEST 4: endless loop, dead return instruction
-;
-; int endless_loop(int a) {
-; while (1);
-; return a;
-; }
-;
-; FIXME: no-return missing (D65243 should fix this)
-; CHECK: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
-; CHECK: define i32 @dead_return(i32 returned %a)
-;
-define i32 @dead_return(i32 %a) #0 {
-entry:
- br label %while.body
-
-while.body: ; preds = %entry, %while.body
- br label %while.body
-
-return: ; No predecessors!
- ret i32 %a
-}
-
-
-; TEST 5: all paths contain a no-return function call
-;
-; int multiple_noreturn_calls(int a) {
-; return a == 0 ? endless_loop(a) : srec16(a);
-; }
-;
-; CHECK: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; CHECK: define i32 @multiple_noreturn_calls(i32 %a)
-;
-define i32 @multiple_noreturn_calls(i32 %a) #0 {
-entry:
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- %call = call i32 @endless_loop(i32 %a)
- br label %cond.end
-
-cond.false: ; preds = %entry
- %call1 = call i32 @srec16(i32 %a)
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
- %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ]
- ret i32 %cond
-}
-
-
-; TEST 6a: willreturn means *not* no-return or UB
-; FIXME: we should derive "UB" as an argument and report it to the user on request.
-
-; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
-; CHECK-NEXT: define i32 @endless_loop_but_willreturn
-define i32 @endless_loop_but_willreturn() willreturn {
-entry:
- br label %while.body
-
-while.body: ; preds = %entry, %while.body
- br label %while.body
-}
-
-; TEST 6b: willreturn means *not* no-return or UB
-; CHECK: Function Attrs: nofree norecurse noreturn nosync nounwind readnone willreturn
-; CHECK-NEXT: define i32 @UB_and_willreturn
-define i32 @UB_and_willreturn() willreturn {
-entry:
- unreachable
-}
-
-attributes #0 = { noinline nounwind uwtable }
diff --git a/llvm/test/Transforms/FunctionAttrs/heap_to_stack.ll b/llvm/test/Transforms/FunctionAttrs/heap_to_stack.ll
deleted file mode 100644
index 1f7be75ef16..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/heap_to_stack.ll
+++ /dev/null
@@ -1,376 +0,0 @@
-; RUN: opt -passes=attributor --attributor-disable=false -attributor-annotate-decl-cs -S < %s | FileCheck %s
-
-declare noalias i8* @malloc(i64)
-
-declare void @nocapture_func_frees_pointer(i8* nocapture)
-
-declare void @func_throws(...)
-
-declare void @sync_func(i8* %p)
-
-declare void @sync_will_return(i8* %p) willreturn nounwind
-
-declare void @no_sync_func(i8* nocapture %p) nofree nosync willreturn
-
-declare void @nofree_func(i8* nocapture %p) nofree nosync willreturn
-
-declare void @foo(i32* %p)
-
-declare void @foo_nounw(i32* %p) nounwind nofree
-
-declare i32 @no_return_call() noreturn
-
-declare void @free(i8* nocapture)
-
-declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) nounwind
-
-; CHECK: @nofree_arg_only(i8* nocapture nofree %p1, i8* nocapture %p2)
-define void @nofree_arg_only(i8* %p1, i8* %p2) {
- tail call void @free(i8* %p2)
- tail call void @nofree_func(i8* %p1)
- ret void
-}
-
-; TEST 1 - negative, pointer freed in another function.
-
-define void @test1() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: @malloc(i64 4)
- ; CHECK-NEXT: @nocapture_func_frees_pointer(i8* noalias nocapture %1)
- tail call void @nocapture_func_frees_pointer(i8* %1)
- tail call void (...) @func_throws()
- tail call void @free(i8* %1)
- ret void
-}
-
-; TEST 2 - negative, call to a sync function.
-
-define void @test2() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: @malloc(i64 4)
- ; CHECK-NEXT: @sync_func(i8* %1)
- tail call void @sync_func(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-; TEST 3 - 1 malloc, 1 free
-
-define void @test3() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %1 = alloca i8, i64 4
- ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
- tail call void @no_sync_func(i8* %1)
- ; CHECK-NOT: @free(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-define void @test3a(i8* %p) {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %1 = alloca i8, i64 4
- ; CHECK-NEXT: tail call void @nofree_arg_only
- tail call void @nofree_arg_only(i8* %1, i8* %p)
- ; CHECK-NOT: @free(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-declare noalias i8* @calloc(i64, i64)
-
-define void @test0() {
- %1 = tail call noalias i8* @calloc(i64 2, i64 4)
- ; CHECK: %1 = alloca i8, i64 8
- ; CHECK-NEXT: %calloc_bc = bitcast i8* %1 to i8*
- ; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* %calloc_bc, i8 0, i64 8, i1 false)
- ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
- tail call void @no_sync_func(i8* %1)
- ; CHECK-NOT: @free(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-; TEST 4
-define void @test4() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %1 = alloca i8, i64 4
- ; CHECK-NEXT: @nofree_func(i8* noalias nocapture nofree %1)
- tail call void @nofree_func(i8* %1)
- ret void
-}
-
-; TEST 5 - not all exit paths have a call to free, but all uses of malloc
-; are in nofree functions and are not captured
-
-define void @test5(i32, i8* %p) {
- %2 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %2 = alloca i8, i64 4
- ; CHECK-NEXT: icmp eq i32 %0, 0
- %3 = icmp eq i32 %0, 0
- br i1 %3, label %5, label %4
-
-4: ; preds = %1
- tail call void @nofree_func(i8* %2)
- br label %6
-
-5: ; preds = %1
- tail call void @nofree_arg_only(i8* %2, i8* %p)
- tail call void @free(i8* %2)
- ; CHECK-NOT: @free(i8* %2)
- br label %6
-
-6: ; preds = %5, %4
- ret void
-}
-
-; TEST 6 - all exit paths have a call to free
-
-define void @test6(i32) {
- %2 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %2 = alloca i8, i64 4
- ; CHECK-NEXT: icmp eq i32 %0, 0
- %3 = icmp eq i32 %0, 0
- br i1 %3, label %5, label %4
-
-4: ; preds = %1
- tail call void @nofree_func(i8* %2)
- tail call void @free(i8* %2)
- ; CHECK-NOT: @free(i8* %2)
- br label %6
-
-5: ; preds = %1
- tail call void @free(i8* %2)
- ; CHECK-NOT: @free(i8* %2)
- br label %6
-
-6: ; preds = %5, %4
- ret void
-}
-
-; TEST 7 - free is dead.
-
-define void @test7() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: alloca i8, i64 4
- ; CHECK-NEXT: tail call i32 @no_return_call()
- tail call i32 @no_return_call()
- ; CHECK-NOT: @free(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-; TEST 8 - Negative: bitcast pointer used in capture function
-
-define void @test8() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1)
- tail call void @no_sync_func(i8* %1)
- %2 = bitcast i8* %1 to i32*
- store i32 10, i32* %2
- %3 = load i32, i32* %2
- tail call void @foo(i32* %2)
- ; CHECK: @free(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-; TEST 9 - FIXME: malloc should be converted.
-define void @test9() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1)
- tail call void @no_sync_func(i8* %1)
- %2 = bitcast i8* %1 to i32*
- store i32 10, i32* %2
- %3 = load i32, i32* %2
- tail call void @foo_nounw(i32* %2)
- ; CHECK: @free(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-; TEST 10 - 1 malloc, 1 free
-
-define i32 @test10() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %1 = alloca i8, i64 4
- ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
- tail call void @no_sync_func(i8* %1)
- %2 = bitcast i8* %1 to i32*
- store i32 10, i32* %2
- %3 = load i32, i32* %2
- ; CHECK-NOT: @free(i8* %1)
- tail call void @free(i8* %1)
- ret i32 %3
-}
-
-define i32 @test_lifetime() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: %1 = alloca i8, i64 4
- ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
- tail call void @no_sync_func(i8* %1)
- call void @llvm.lifetime.start.p0i8(i64 4, i8* %1)
- %2 = bitcast i8* %1 to i32*
- store i32 10, i32* %2
- %3 = load i32, i32* %2
- ; CHECK-NOT: @free(i8* %1)
- tail call void @free(i8* %1)
- ret i32 %3
-}
-
-; TEST 11
-
-define void @test11() {
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK: test11
- ; CHECK-NEXT: alloc
- ; CHECK-NEXT: @sync_will_return(i8* %1)
- tail call void @sync_will_return(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-; TEST 12
-define i32 @irreducible_cfg(i32 %0) {
- ; CHECK: alloca i8, i64 4
- ; CHECK-NEXT: %3 = bitcast
- %2 = call noalias i8* @malloc(i64 4)
- %3 = bitcast i8* %2 to i32*
- store i32 10, i32* %3, align 4
- %4 = icmp eq i32 %0, 1
- br i1 %4, label %5, label %7
-
-5: ; preds = %1
- %6 = add nsw i32 %0, 5
- br label %13
-
-7: ; preds = %1
- br label %8
-
-8: ; preds = %13, %7
- %.0 = phi i32 [ %14, %13 ], [ 1, %7 ]
- %9 = load i32, i32* %3, align 4
- %10 = add nsw i32 %9, -1
- store i32 %10, i32* %3, align 4
- %11 = icmp ne i32 %9, 0
- br i1 %11, label %12, label %15
-
-12: ; preds = %8
- br label %13
-
-13: ; preds = %12, %5
- %.1 = phi i32 [ %6, %5 ], [ %.0, %12 ]
- %14 = add nsw i32 %.1, 1
- br label %8
-
-15: ; preds = %8
- %16 = load i32, i32* %3, align 4
- %17 = bitcast i32* %3 to i8*
- call void @free(i8* %17)
- %18 = load i32, i32* %3, align 4
- ret i32 %18
-}
-
-
-define i32 @malloc_in_loop(i32 %0) {
- %2 = alloca i32, align 4
- %3 = alloca i32*, align 8
- store i32 %0, i32* %2, align 4
- br label %4
-
-4: ; preds = %8, %1
- %5 = load i32, i32* %2, align 4
- %6 = add nsw i32 %5, -1
- store i32 %6, i32* %2, align 4
- %7 = icmp sgt i32 %6, 0
- br i1 %7, label %8, label %11
-
-8: ; preds = %4
- %9 = call noalias i8* @malloc(i64 4)
- ; CHECK: alloca i8, i64 4
- %10 = bitcast i8* %9 to i32*
- store i32 1, i32* %10, align 8
- br label %4
-
-11: ; preds = %4
- ret i32 5
-}
-
-; Malloc/Calloc too large
-define i32 @test13() {
- %1 = tail call noalias i8* @malloc(i64 256)
- ; CHECK: %1 = tail call noalias i8* @malloc(i64 256)
- ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1)
- tail call void @no_sync_func(i8* %1)
- %2 = bitcast i8* %1 to i32*
- store i32 10, i32* %2
- %3 = load i32, i32* %2
- tail call void @free(i8* %1)
- ; CHECK: tail call void @free(i8* noalias %1)
- ret i32 %3
-}
-
-define void @test14() {
- %1 = tail call noalias i8* @calloc(i64 64, i64 4)
- ; CHECK: %1 = tail call noalias i8* @calloc(i64 64, i64 4)
- ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1)
- tail call void @no_sync_func(i8* %1)
- tail call void @free(i8* %1)
- ; CHECK: tail call void @free(i8* noalias %1)
- ret void
-}
-
-define void @test15(i64 %S) {
- ; CHECK: %1 = tail call noalias i8* @malloc(i64 %S)
- %1 = tail call noalias i8* @malloc(i64 %S)
- ; CHECK-NEXT: @no_sync_func(i8* noalias nofree %1)
- tail call void @no_sync_func(i8* %1)
- ; CHECK-NEXT: @free(i8* noalias %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-define void @test16a(i8 %v, i8** %P) {
- ; CHECK: %1 = alloca
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK-NEXT: store i8 %v, i8* %1
- store i8 %v, i8* %1
- ; CHECK-NEXT: @no_sync_func(i8* noalias nocapture nofree %1)
- tail call void @no_sync_func(i8* %1)
- ; CHECK-NOT: @free(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-define void @test16b(i8 %v, i8** %P) {
- ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK-NEXT: store i8* %1, i8** %P
- store i8* %1, i8** %P
- ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1)
- tail call void @no_sync_func(i8* %1)
- ; CHECK-NEXT: @free(i8* %1)
- tail call void @free(i8* %1)
- ret void
-}
-
-define void @test16c(i8 %v, i8** %P) {
- ; CHECK: %1 = alloca
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK-NEXT: store i8* %1, i8** %P
- store i8* %1, i8** %P
- ; CHECK-NEXT: @no_sync_func(i8* nocapture nofree %1)
- tail call void @no_sync_func(i8* %1) nounwind
- ; CHECK-NOT: @free
- tail call void @free(i8* %1)
- ret void
-}
-
-define void @test16d(i8 %v, i8** %P) {
- ; CHECK: %1 = tail call noalias i8* @malloc(i64 4)
- %1 = tail call noalias i8* @malloc(i64 4)
- ; CHECK-NEXT: store i8* %1, i8** %P
- store i8* %1, i8** %P
- ret void
-}
diff --git a/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll b/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll
deleted file mode 100644
index fd6e17bc77f..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/internal-noalias.ll
+++ /dev/null
@@ -1,48 +0,0 @@
-; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 < %s | FileCheck %s
-
-define dso_local i32 @visible(i32* noalias %A, i32* noalias %B) #0 {
-entry:
- %call1 = call i32 @noalias_args(i32* %A, i32* %B)
- %call2 = call i32 @noalias_args_argmem(i32* %A, i32* %B)
- %add = add nsw i32 %call1, %call2
- ret i32 %add
-}
-
-; CHECK: define private i32 @noalias_args(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %A, i32* noalias nocapture nofree nonnull readonly align 4 dereferenceable(4) %B)
-
-define private i32 @noalias_args(i32* %A, i32* %B) #0 {
-entry:
- %0 = load i32, i32* %A, align 4
- %1 = load i32, i32* %B, align 4
- %add = add nsw i32 %0, %1
- %call = call i32 @noalias_args_argmem(i32* %A, i32* %B)
- %add2 = add nsw i32 %add, %call
- ret i32 %add2
-}
-
-
-; FIXME: Should be something like this.
-; define internal i32 @noalias_args_argmem(i32* noalias nocapture readonly %A, i32* noalias nocapture readonly %B)
-; CHECK: define internal i32 @noalias_args_argmem(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %A, i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %B)
-
-;
-define internal i32 @noalias_args_argmem(i32* %A, i32* %B) #1 {
-entry:
- %0 = load i32, i32* %A, align 4
- %1 = load i32, i32* %B, align 4
- %add = add nsw i32 %0, %1
- ret i32 %add
-}
-
-define dso_local i32 @visible_local(i32* %A) #0 {
-entry:
- %B = alloca i32, align 4
- store i32 5, i32* %B, align 4
- %call1 = call i32 @noalias_args(i32* %A, i32* nonnull %B)
- %call2 = call i32 @noalias_args_argmem(i32* %A, i32* nonnull %B)
- %add = add nsw i32 %call1, %call2
- ret i32 %add
-}
-
-attributes #0 = { noinline nounwind uwtable willreturn }
-attributes #1 = { argmemonly noinline nounwind uwtable willreturn}
diff --git a/llvm/test/Transforms/FunctionAttrs/liveness.ll b/llvm/test/Transforms/FunctionAttrs/liveness.ll
deleted file mode 100644
index 4fea57ff921..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/liveness.ll
+++ /dev/null
@@ -1,857 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
-; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=4 -S < %s | FileCheck %s
-; UTC_ARGS: --turn off
-
-; CHECK: @dead_with_blockaddress_users.l = constant [2 x i8*] [i8* inttoptr (i32 1 to i8*), i8* inttoptr (i32 1 to i8*)]
-@dead_with_blockaddress_users.l = constant [2 x i8*] [i8* blockaddress(@dead_with_blockaddress_users, %lab0), i8* blockaddress(@dead_with_blockaddress_users, %end)]
-
-declare void @no_return_call() nofree noreturn nounwind readnone
-
-declare void @normal_call() readnone
-
-declare i32 @foo()
-
-declare i32 @foo_nounwind() nounwind
-
-declare i32 @foo_noreturn_nounwind() noreturn nounwind
-
-declare i32 @foo_noreturn() noreturn
-
-declare i32 @bar() nosync readnone
-
-; This internal function has no live call sites, so all its BBs are considered dead,
-; and nothing should be deduced for it.
-
-; CHECK-NOT: define internal i32 @dead_internal_func(i32 %0)
-define internal i32 @dead_internal_func(i32 %0) {
- %2 = icmp slt i32 %0, 1
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %5, %1
- %4 = phi i32 [ 1, %1 ], [ %8, %5 ]
- ret i32 %4
-
-; <label>:5: ; preds = %1, %5
- %6 = phi i32 [ %9, %5 ], [ 1, %1 ]
- %7 = phi i32 [ %8, %5 ], [ 1, %1 ]
- %8 = mul nsw i32 %6, %7
- %9 = add nuw nsw i32 %6, 1
- %10 = icmp eq i32 %6, %0
- br i1 %10, label %3, label %5
-}
-
-; CHECK: Function Attrs: nofree norecurse nounwind uwtable willreturn
-define i32 @volatile_load(i32*) norecurse nounwind uwtable {
- %2 = load volatile i32, i32* %0, align 4
- ret i32 %2
-}
-
-; CHECK-NOT: internal_load
-define internal i32 @internal_load(i32*) norecurse nounwind uwtable {
- %2 = load i32, i32* %0, align 4
- ret i32 %2
-}
-; TEST 1: Only first block is live.
-
-; CHECK: Function Attrs: nofree noreturn nosync nounwind
-; CHECK-NEXT: define i32 @first_block_no_return(i32 %a, i32* nocapture nofree nonnull readonly %ptr1, i32* nocapture nofree readnone %ptr2)
-define i32 @first_block_no_return(i32 %a, i32* nonnull %ptr1, i32* %ptr2) #0 {
-entry:
- call i32 @internal_load(i32* %ptr1)
- call void @no_return_call()
- ; CHECK: call void @no_return_call()
- ; CHECK-NEXT: unreachable
- call i32 @dead_internal_func(i32 10)
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- call i32 @internal_load(i32* %ptr2)
- %load = call i32 @volatile_load(i32* %ptr1)
- call void @normal_call()
- %call = call i32 @foo()
- br label %cond.end
-
-cond.false: ; preds = %entry
- call void @normal_call()
- %call1 = call i32 @bar()
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
- %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ]
- ret i32 %cond
-}
-
-; TEST 2: cond.true is dead, but cond.end is not, since cond.false is live
-
-; This is just an example. For example we can put a sync call in a
-; dead block and check if it is deduced.
-
-; CHECK: Function Attrs: nosync
-; CHECK-NEXT: define i32 @dead_block_present(i32 %a, i32* nocapture nofree readnone %ptr1)
-define i32 @dead_block_present(i32 %a, i32* %ptr1) #0 {
-entry:
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- call void @no_return_call()
- ; CHECK: call void @no_return_call()
- ; CHECK-NEXT: unreachable
- %call = call i32 @volatile_load(i32* %ptr1)
- br label %cond.end
-
-cond.false: ; preds = %entry
- call void @normal_call()
- %call1 = call i32 @bar()
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
-; CHECK: cond.end:
-; CHECK-NEXT: ret i32 %call1
- %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ]
- ret i32 %cond
-}
-
-; TEST 3: both cond.true and cond.false are dead, therfore cond.end is dead as well.
-
-define i32 @all_dead(i32 %a) #0 {
-entry:
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- call void @no_return_call()
- ; CHECK: call void @no_return_call()
- ; CHECK-NEXT: unreachable
- call i32 @dead_internal_func(i32 10)
- ; CHECK-NOT: call
- %call = call i32 @foo()
- br label %cond.end
-
-cond.false: ; preds = %entry
- call void @no_return_call()
- ; CHECK: call void @no_return_call()
- ; CHECK-NEXT: unreachable
- call i32 @dead_internal_func(i32 10)
- %call1 = call i32 @bar()
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
- %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ]
- ret i32 %cond
-}
-
-declare i32 @__gxx_personality_v0(...)
-
-; TEST 4: All blocks are live.
-
-; CHECK: define i32 @all_live(i32 %a)
-define i32 @all_live(i32 %a) #0 {
-entry:
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- call void @normal_call()
- %call = call i32 @foo_noreturn()
- br label %cond.end
-
-cond.false: ; preds = %entry
- call void @normal_call()
- %call1 = call i32 @bar()
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %cond.true
- %cond = phi i32 [ %call, %cond.true ], [ %call1, %cond.false ]
- ret i32 %cond
-}
-
-; TEST 5.1 noreturn invoke instruction with a unreachable normal successor block.
-
-; CHECK: define i32 @invoke_noreturn(i32 %a)
-define i32 @invoke_noreturn(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-entry:
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- call void @normal_call()
- %call = invoke i32 @foo_noreturn() to label %continue
- unwind label %cleanup
- ; CHECK: %call = invoke i32 @foo_noreturn()
- ; CHECK-NEXT: to label %continue unwind label %cleanup
-
-cond.false: ; preds = %entry
- call void @normal_call()
- %call1 = call i32 @bar()
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %continue
- %cond = phi i32 [ %call, %continue ], [ %call1, %cond.false ]
- ret i32 %cond
-
-continue:
- ; CHECK: continue:
- ; CHECK-NEXT: unreachable
- br label %cond.end
-
-cleanup:
- %res = landingpad { i8*, i32 }
- catch i8* null
- ret i32 0
-}
-
-; TEST 5.2 noreturn invoke instruction replaced by a call and an unreachable instruction
-; put after it.
-
-; CHECK: define i32 @invoke_noreturn_nounwind(i32 %a)
-define i32 @invoke_noreturn_nounwind(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-entry:
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- call void @normal_call()
- %call = invoke i32 @foo_noreturn_nounwind() to label %continue
- unwind label %cleanup
- ; CHECK: call void @normal_call()
- ; CHECK-NEXT: call i32 @foo_noreturn_nounwind()
- ; CHECK-NEXT: unreachable
-
- ; CHECK-NOT: @foo_noreturn_nounwind()
-
-cond.false: ; preds = %entry
- call void @normal_call()
- %call1 = call i32 @bar()
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %continue
- %cond = phi i32 [ %call, %continue ], [ %call1, %cond.false ]
- ret i32 %cond
-
-continue:
- br label %cond.end
-
-cleanup:
- %res = landingpad { i8*, i32 }
- catch i8* null
- ret i32 0
-}
-
-; TEST 5.3 unounwind invoke instruction replaced by a call and a branch instruction put after it.
-define i32 @invoke_nounwind(i32 %a) personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-; CHECK-LABEL: define {{[^@]+}}@invoke_nounwind
-; CHECK: cond.true:
-; CHECK-NEXT: call void @normal_call()
-; CHECK-NEXT: [[CALL:%.*]] = call i32 @foo_nounwind()
-; CHECK-NEXT: br label [[CONTINUE:%.*]]
-; CHECK: continue:
-; CHECK-NEXT: br label [[COND_END:%.*]]
-;
-entry:
- %cmp = icmp eq i32 %a, 0
- br i1 %cmp, label %cond.true, label %cond.false
-
-cond.true: ; preds = %entry
- call void @normal_call()
- %call = invoke i32 @foo_nounwind() to label %continue
- unwind label %cleanup
-
-cond.false: ; preds = %entry
- call void @normal_call()
- %call1 = call i32 @bar()
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %continue
- %cond = phi i32 [ %call, %continue ], [ %call1, %cond.false ]
- ret i32 %cond
-
-continue:
- br label %cond.end
-
-cleanup:
- %res = landingpad { i8*, i32 }
- catch i8* null
- ret i32 0
-}
-
-; UTC_ARGS: --turn off
-
-; TEST 6: Undefined behvior, taken from LangRef.
-; FIXME: Should be able to detect undefined behavior.
-
-; CHECK: define void @ub(i32* nocapture nofree writeonly %0)
-define void @ub(i32* %0) {
- %poison = sub nuw i32 0, 1 ; Results in a poison value.
- %still_poison = and i32 %poison, 0 ; 0, but also poison.
- %poison_yet_again = getelementptr i32, i32* %0, i32 %still_poison
- store i32 0, i32* %poison_yet_again ; Undefined behavior due to store to poison.
- ret void
-}
-
-define void @inf_loop() #0 {
-entry:
- br label %while.body
-
-while.body: ; preds = %entry, %while.body
- br label %while.body
-}
-
-; TEST 7: Infinite loop.
-; FIXME: Detect infloops, and mark affected blocks dead.
-
-define i32 @test5(i32, i32) #0 {
- %3 = icmp sgt i32 %0, %1
- br i1 %3, label %cond.if, label %cond.elseif
-
-cond.if: ; preds = %2
- %4 = tail call i32 @bar()
- br label %cond.end
-
-cond.elseif: ; preds = %2
- call void @inf_loop()
- %5 = icmp slt i32 %0, %1
- br i1 %5, label %cond.end, label %cond.else
-
-cond.else: ; preds = %cond.elseif
- %6 = tail call i32 @foo()
- br label %cond.end
-
-cond.end: ; preds = %cond.if, %cond.else, %cond.elseif
- %7 = phi i32 [ %1, %cond.elseif ], [ 0, %cond.else ], [ 0, %cond.if ]
- ret i32 %7
-}
-
-define void @rec() #0 {
-entry:
- call void @rec()
- ret void
-}
-
-; TEST 8: Recursion
-; FIXME: everything after first block should be marked dead
-; and unreachable should be put after call to @rec().
-
-define i32 @test6(i32, i32) #0 {
- call void @rec()
- %3 = icmp sgt i32 %0, %1
- br i1 %3, label %cond.if, label %cond.elseif
-
-cond.if: ; preds = %2
- %4 = tail call i32 @bar()
- br label %cond.end
-
-cond.elseif: ; preds = %2
- call void @rec()
- %5 = icmp slt i32 %0, %1
- br i1 %5, label %cond.end, label %cond.else
-
-cond.else: ; preds = %cond.elseif
- %6 = tail call i32 @foo()
- br label %cond.end
-
-cond.end: ; preds = %cond.if, %cond.else, %cond.elseif
- %7 = phi i32 [ %1, %cond.elseif ], [ 0, %cond.else ], [ 0, %cond.if ]
- ret i32 %7
-}
-; TEST 9: Recursion
-; FIXME: contains recursive call to itself in cond.elseif block
-
-define i32 @test7(i32, i32) #0 {
- %3 = icmp sgt i32 %0, %1
- br i1 %3, label %cond.if, label %cond.elseif
-
-cond.if: ; preds = %2
- %4 = tail call i32 @bar()
- br label %cond.end
-
-cond.elseif: ; preds = %2
- %5 = tail call i32 @test7(i32 %0, i32 %1)
- %6 = icmp slt i32 %0, %1
- br i1 %6, label %cond.end, label %cond.else
-
-cond.else: ; preds = %cond.elseif
- %7 = tail call i32 @foo()
- br label %cond.end
-
-cond.end: ; preds = %cond.if, %cond.else, %cond.elseif
- %8 = phi i32 [ %1, %cond.elseif ], [ 0, %cond.else ], [ 0, %cond.if ]
- ret i32 %8
-}
-
-; SCC test
-;
-; char a1 __attribute__((aligned(8)));
-; char a2 __attribute__((aligned(16)));
-;
-; char* f1(char* a ){
-; return a?a:f2(&a1);
-; }
-; char* f2(char* a){
-; return a?f1(a):f3(&a2);
-; }
-;
-; char* f3(char* a){
-; return a?&a1: f1(&a2);
-; }
-
-@a1 = common global i8 0, align 8
-@a2 = common global i8 0, align 16
-
-define internal i8* @f1(i8* readnone %0) local_unnamed_addr #0 {
-; ATTRIBUTOR: define internal i8* @f1(i8* readnone %0)
- %2 = icmp eq i8* %0, null
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %1
-; ATTRIBUTOR: %4 = tail call i8* undef(i8* nonnull align 8 @a1)
- %4 = tail call i8* @f2(i8* nonnull @a1)
- br label %5
-
-; <label>:5: ; preds = %1, %3
- %6 = phi i8* [ %4, %3 ], [ %0, %1 ]
- ret i8* %6
-}
-
-define internal i8* @f2(i8* readnone %0) local_unnamed_addr #0 {
-; ATTRIBUTOR: define internal i8* @f2(i8* readnone %0)
- %2 = icmp eq i8* %0, null
- br i1 %2, label %5, label %3
-
-; <label>:3: ; preds = %1
-
-; ATTRIBUTOR: %4 = tail call i8* undef(i8* nonnull align 8 %0)
- %4 = tail call i8* @f1(i8* nonnull %0)
- br label %7
-
-; <label>:5: ; preds = %1
-; ATTRIBUTOR: %6 = tail call i8* undef(i8* nonnull align 16 @a2)
- %6 = tail call i8* @f3(i8* nonnull @a2)
- br label %7
-
-; <label>:7: ; preds = %5, %3
- %8 = phi i8* [ %4, %3 ], [ %6, %5 ]
- ret i8* %8
-}
-
-define internal i8* @f3(i8* readnone %0) local_unnamed_addr #0 {
-; ATTRIBUTOR: define internal i8* @f3(i8* readnone %0)
- %2 = icmp eq i8* %0, null
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %1
-; ATTRIBUTOR: %4 = tail call i8* undef(i8* nonnull align 16 @a2)
- %4 = tail call i8* @f1(i8* nonnull @a2)
- br label %5
-
-; <label>:5: ; preds = %1, %3
- %6 = phi i8* [ %4, %3 ], [ @a1, %1 ]
- ret i8* %6
-}
-
-define void @test_unreachable() {
-; CHECK: define void @test_unreachable()
-; CHECK-NEXT: call void @test_unreachable()
-; CHECK-NEXT: unreachable
-; CHECK-NEXT: }
- call void @test_unreachable()
- unreachable
-}
-
-define linkonce_odr void @non_exact1() {
- call void @non_dead_a0()
- call void @non_dead_a1()
- call void @non_dead_a2()
- call void @non_dead_a3()
- call void @non_dead_a4()
- call void @non_dead_a5()
- call void @non_dead_a6()
- call void @non_dead_a7()
- call void @non_dead_a8()
- call void @non_dead_a9()
- call void @non_dead_a10()
- call void @non_dead_a11()
- call void @non_dead_a12()
- call void @non_dead_a13()
- call void @non_dead_a14()
- call void @non_dead_a15()
- call void @middle()
- ret void
-}
-define internal void @middle() {
-bb0:
- call void @non_dead_b0()
- call void @non_dead_b1()
- call void @non_dead_b2()
- call void @non_dead_b3()
-br label %bb1
-bb1:
- call void @non_dead_b4()
- call void @non_dead_b5()
- call void @non_dead_b6()
- call void @non_dead_b7()
-br label %bb2
-bb2:
- call void @non_dead_b8()
- call void @non_dead_b9()
- call void @non_dead_b10()
- call void @non_dead_b11()
-br label %bb3
-bb3:
- call void @non_dead_b12()
- call void @non_dead_b13()
- call void @non_dead_b14()
- call void @non_dead_b15()
-br label %bb4
-bb4:
- call void @non_exact2()
- ret void
-}
-define linkonce_odr void @non_exact2() {
- call void @non_dead_c0()
- call void @non_dead_c1()
- call void @non_dead_c2()
- call void @non_dead_c3()
- call void @non_dead_c4()
- call void @non_dead_c5()
- call void @non_dead_c6()
- call void @non_dead_c7()
- call void @non_dead_c8()
- call void @non_dead_c9()
- call void @non_dead_c10()
- call void @non_dead_c11()
- call void @non_dead_c12()
- call void @non_dead_c13()
- call void @non_dead_c14()
- call void @non_dead_c15()
- call void @non_exact3()
- ret void
-}
-define linkonce_odr void @non_exact3() {
- call void @non_dead_d0()
- call void @non_dead_d1()
- call void @non_dead_d2()
- call void @non_dead_d3()
- call void @non_dead_d4()
- call void @non_dead_d5()
- call void @non_dead_d6()
- call void @non_dead_d7()
- call void @non_dead_d8()
- call void @non_dead_d9()
- call void @non_dead_d10()
- call void @non_dead_d11()
- call void @non_dead_d12()
- call void @non_dead_d13()
- call void @non_dead_d14()
- call void @non_dead_d15()
- %nr = call i32 @foo_noreturn()
- call void @dead_e1()
- ret void
-}
-; CHECK: define linkonce_odr void @non_exact3() {
-; CHECK-NEXT: call void @non_dead_d0()
-; CHECK-NEXT: call void @non_dead_d1()
-; CHECK-NEXT: call void @non_dead_d2()
-; CHECK-NEXT: call void @non_dead_d3()
-; CHECK-NEXT: call void @non_dead_d4()
-; CHECK-NEXT: call void @non_dead_d5()
-; CHECK-NEXT: call void @non_dead_d6()
-; CHECK-NEXT: call void @non_dead_d7()
-; CHECK-NEXT: call void @non_dead_d8()
-; CHECK-NEXT: call void @non_dead_d9()
-; CHECK-NEXT: call void @non_dead_d10()
-; CHECK-NEXT: call void @non_dead_d11()
-; CHECK-NEXT: call void @non_dead_d12()
-; CHECK-NEXT: call void @non_dead_d13()
-; CHECK-NEXT: call void @non_dead_d14()
-; CHECK-NEXT: call void @non_dead_d15()
-; CHECK-NEXT: %nr = call i32 @foo_noreturn()
-; CHECK-NEXT: unreachable
-
-define internal void @non_dead_a0() { ret void }
-define internal void @non_dead_a1() { ret void }
-define internal void @non_dead_a2() { ret void }
-define internal void @non_dead_a3() { ret void }
-define internal void @non_dead_a4() { ret void }
-define internal void @non_dead_a5() { ret void }
-define internal void @non_dead_a6() { ret void }
-define internal void @non_dead_a7() { ret void }
-define internal void @non_dead_a8() { ret void }
-define internal void @non_dead_a9() { ret void }
-define internal void @non_dead_a10() { ret void }
-define internal void @non_dead_a11() { ret void }
-define internal void @non_dead_a12() { ret void }
-define internal void @non_dead_a13() { ret void }
-define internal void @non_dead_a14() { ret void }
-define internal void @non_dead_a15() { ret void }
-define internal void @non_dead_b0() { ret void }
-define internal void @non_dead_b1() { ret void }
-define internal void @non_dead_b2() { ret void }
-define internal void @non_dead_b3() { ret void }
-define internal void @non_dead_b4() { ret void }
-define internal void @non_dead_b5() { ret void }
-define internal void @non_dead_b6() { ret void }
-define internal void @non_dead_b7() { ret void }
-define internal void @non_dead_b8() { ret void }
-define internal void @non_dead_b9() { ret void }
-define internal void @non_dead_b10() { ret void }
-define internal void @non_dead_b11() { ret void }
-define internal void @non_dead_b12() { ret void }
-define internal void @non_dead_b13() { ret void }
-define internal void @non_dead_b14() { ret void }
-define internal void @non_dead_b15() { ret void }
-define internal void @non_dead_c0() { ret void }
-define internal void @non_dead_c1() { ret void }
-define internal void @non_dead_c2() { ret void }
-define internal void @non_dead_c3() { ret void }
-define internal void @non_dead_c4() { ret void }
-define internal void @non_dead_c5() { ret void }
-define internal void @non_dead_c6() { ret void }
-define internal void @non_dead_c7() { ret void }
-define internal void @non_dead_c8() { ret void }
-define internal void @non_dead_c9() { ret void }
-define internal void @non_dead_c10() { ret void }
-define internal void @non_dead_c11() { ret void }
-define internal void @non_dead_c12() { ret void }
-define internal void @non_dead_c13() { ret void }
-define internal void @non_dead_c14() { ret void }
-define internal void @non_dead_c15() { ret void }
-define internal void @non_dead_d0() { ret void }
-define internal void @non_dead_d1() { ret void }
-define internal void @non_dead_d2() { ret void }
-define internal void @non_dead_d3() { ret void }
-define internal void @non_dead_d4() { ret void }
-define internal void @non_dead_d5() { ret void }
-define internal void @non_dead_d6() { ret void }
-define internal void @non_dead_d7() { ret void }
-define internal void @non_dead_d8() { ret void }
-define internal void @non_dead_d9() { ret void }
-define internal void @non_dead_d10() { ret void }
-define internal void @non_dead_d11() { ret void }
-define internal void @non_dead_d12() { ret void }
-define internal void @non_dead_d13() { ret void }
-define internal void @non_dead_d14() { ret void }
-define internal void @non_dead_d15() { ret void }
-define internal void @dead_e0() { call void @dead_e1() ret void }
-define internal void @dead_e1() { call void @dead_e2() ret void }
-define internal void @dead_e2() { ret void }
-
-; CHECK: define internal void @non_dead_a0()
-; CHECK: define internal void @non_dead_a1()
-; CHECK: define internal void @non_dead_a2()
-; CHECK: define internal void @non_dead_a3()
-; CHECK: define internal void @non_dead_a4()
-; CHECK: define internal void @non_dead_a5()
-; CHECK: define internal void @non_dead_a6()
-; CHECK: define internal void @non_dead_a7()
-; CHECK: define internal void @non_dead_a8()
-; CHECK: define internal void @non_dead_a9()
-; CHECK: define internal void @non_dead_a10()
-; CHECK: define internal void @non_dead_a11()
-; CHECK: define internal void @non_dead_a12()
-; CHECK: define internal void @non_dead_a13()
-; CHECK: define internal void @non_dead_a14()
-; CHECK: define internal void @non_dead_a15()
-; CHECK: define internal void @non_dead_b0()
-; CHECK: define internal void @non_dead_b1()
-; CHECK: define internal void @non_dead_b2()
-; CHECK: define internal void @non_dead_b3()
-; CHECK: define internal void @non_dead_b4()
-; CHECK: define internal void @non_dead_b5()
-; CHECK: define internal void @non_dead_b6()
-; CHECK: define internal void @non_dead_b7()
-; CHECK: define internal void @non_dead_b8()
-; CHECK: define internal void @non_dead_b9()
-; CHECK: define internal void @non_dead_b10()
-; CHECK: define internal void @non_dead_b11()
-; CHECK: define internal void @non_dead_b12()
-; CHECK: define internal void @non_dead_b13()
-; CHECK: define internal void @non_dead_b14()
-; CHECK: define internal void @non_dead_b15()
-; CHECK: define internal void @non_dead_c0()
-; CHECK: define internal void @non_dead_c1()
-; CHECK: define internal void @non_dead_c2()
-; CHECK: define internal void @non_dead_c3()
-; CHECK: define internal void @non_dead_c4()
-; CHECK: define internal void @non_dead_c5()
-; CHECK: define internal void @non_dead_c6()
-; CHECK: define internal void @non_dead_c7()
-; CHECK: define internal void @non_dead_c8()
-; CHECK: define internal void @non_dead_c9()
-; CHECK: define internal void @non_dead_c10()
-; CHECK: define internal void @non_dead_c11()
-; CHECK: define internal void @non_dead_c12()
-; CHECK: define internal void @non_dead_c13()
-; CHECK: define internal void @non_dead_c14()
-; CHECK: define internal void @non_dead_c15()
-; CHECK: define internal void @non_dead_d0()
-; CHECK: define internal void @non_dead_d1()
-; CHECK: define internal void @non_dead_d2()
-; CHECK: define internal void @non_dead_d3()
-; CHECK: define internal void @non_dead_d4()
-; CHECK: define internal void @non_dead_d5()
-; CHECK: define internal void @non_dead_d6()
-; CHECK: define internal void @non_dead_d7()
-; CHECK: define internal void @non_dead_d8()
-; CHECK: define internal void @non_dead_d9()
-; CHECK: define internal void @non_dead_d10()
-; CHECK: define internal void @non_dead_d11()
-; CHECK: define internal void @non_dead_d12()
-; CHECK: define internal void @non_dead_d13()
-; CHECK: define internal void @non_dead_d14()
-; Verify we actually deduce information for these functions.
-; CHECK: Function Attrs: nofree nosync nounwind readnone willreturn
-; CHECK-NEXT: define internal void @non_dead_d15()
-; CHECK-NOT: define internal void @dead_e
-
-
-declare void @blowup() noreturn
-define void @live_with_dead_entry() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-; CHECK: define void @live_with_dead_entry(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: invoke void @blowup()
-; CHECK-NEXT: to label %live_with_dead_entry.dead unwind label %lpad
-; CHECK: lpad: ; preds = %entry
-; CHECK-NEXT: %0 = landingpad { i8*, i32 }
-; CHECK-NEXT: catch i8* null
-; CHECK-NEXT: br label %live_with_dead_entry
-; CHECK: live_with_dead_entry.dead: ; preds = %entry
-; CHECK-NEXT: unreachable
-; CHECK: live_with_dead_entry: ; preds = %lpad
-; CHECK-NEXT: ret void
-entry:
- invoke void @blowup() to label %live_with_dead_entry unwind label %lpad
-lpad:
- %0 = landingpad { i8*, i32 } catch i8* null
- br label %live_with_dead_entry
-live_with_dead_entry:
- ret void
-}
-
-define void @live_with_dead_entry_lp() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
-; CHECK: define void @live_with_dead_entry_lp(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: invoke void @blowup()
-; CHECK-NEXT: to label %live_with_dead_entry.dead unwind label %lp1
-; CHECK: lp1: ; preds = %entry
-; CHECK-NEXT: %lp = landingpad { i8*, i32 }
-; CHECK-NEXT: catch i8* null
-; CHECK-NEXT: invoke void @blowup()
-; CHECK-NEXT: to label %live_with_dead_entry.dead1 unwind label %lp2
-; CHECK: lp2: ; preds = %lp1
-; CHECK-NEXT: %0 = landingpad { i8*, i32 }
-; CHECK-NEXT: catch i8* null
-; CHECK-NEXT: br label %live_with_dead_entry
-; CHECK: live_with_dead_entry.dead:
-; CHECK-NEXT: unreachable
-; CHECK: live_with_dead_entry.dead1:
-; CHECK-NEXT: unreachable
-; CHECK: live_with_dead_entry: ; preds = %lp2
-; CHECK-NEXT: ret void
-entry:
- invoke void @blowup() to label %live_with_dead_entry unwind label %lp1
-lp1:
- %lp = landingpad { i8*, i32 } catch i8* null
- invoke void @blowup() to label %live_with_dead_entry unwind label %lp2
-lp2:
- %0 = landingpad { i8*, i32 } catch i8* null
- br label %live_with_dead_entry
-live_with_dead_entry:
- ret void
-}
-
-; CHECK: define internal void @useless_arg_sink(i32* nocapture nofree readnone %a)
-define internal void @useless_arg_sink(i32* %a) {
- ret void
-}
-
-; CHECK: define internal void @useless_arg_almost_sink(i32* nocapture nofree readnone %a)
-define internal void @useless_arg_almost_sink(i32* %a) {
-; CHECK: call void @useless_arg_sink(i32* nofree undef)
- call void @useless_arg_sink(i32* %a)
- ret void
-}
-
-; Check we do not annotate the function interface of this weak function.
-; CHECK: define weak_odr void @useless_arg_ext(i32* %a)
-define weak_odr void @useless_arg_ext(i32* %a) {
-; CHECK: call void @useless_arg_almost_sink(i32* nofree undef)
- call void @useless_arg_almost_sink(i32* %a)
- ret void
-}
-
-; CHECK: define internal void @useless_arg_ext_int(i32* %a)
-define internal void @useless_arg_ext_int(i32* %a) {
-; CHECK: call void @useless_arg_ext(i32* %a)
- call void @useless_arg_ext(i32* %a)
- ret void
-}
-
-define void @useless_arg_ext_int_ext(i32* %a) {
-; CHECK: call void @useless_arg_ext_int(i32* %a)
- call void @useless_arg_ext_int(i32* %a)
- ret void
-}
-
-; UTC_ARGS: --turn on
-
-; FIXME: We should fold terminators.
-
-define internal i32 @switch_default(i64 %i) nounwind {
-; CHECK-LABEL: define {{[^@]+}}@switch_default
-; CHECK-SAME: (i64 [[I:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: switch i64 0, label [[SW_DEFAULT:%.*]] [
-; CHECK-NEXT: i64 3, label [[RETURN:%.*]]
-; CHECK-NEXT: i64 10, label [[RETURN]]
-; CHECK-NEXT: ]
-; CHECK: sw.default:
-; CHECK-NEXT: ret i32 123
-; CHECK: return:
-; CHECK-NEXT: unreachable
-;
-entry:
- switch i64 %i, label %sw.default [
- i64 3, label %return
- i64 10, label %return
- ]
-
-sw.default:
- ret i32 123
-
-return:
- ret i32 0
-}
-
-define i32 @switch_default_caller() {
-; CHECK-LABEL: define {{[^@]+}}@switch_default_caller()
-; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @switch_default(i64 0)
-; CHECK-NEXT: ret i32 123
-;
- %call2 = tail call i32 @switch_default(i64 0)
- ret i32 %call2
-}
-; UTC_ARGS: --turn off
-
-; Allow blockaddress users
-; CHECK-NOT @dead_with_blockaddress_users
-define internal void @dead_with_blockaddress_users(i32* nocapture %pc) nounwind readonly {
-entry:
- br label %indirectgoto
-
-lab0: ; preds = %indirectgoto
- %indvar.next = add i32 %indvar, 1 ; <i32> [#uses=1]
- br label %indirectgoto
-
-end: ; preds = %indirectgoto
- ret void
-
-indirectgoto: ; preds = %lab0, %entry
- %indvar = phi i32 [ %indvar.next, %lab0 ], [ 0, %entry ] ; <i32> [#uses=2]
- %pc.addr.0 = getelementptr i32, i32* %pc, i32 %indvar ; <i32*> [#uses=1]
- %tmp1.pn = load i32, i32* %pc.addr.0 ; <i32> [#uses=1]
- %indirect.goto.dest.in = getelementptr inbounds [2 x i8*], [2 x i8*]* @dead_with_blockaddress_users.l, i32 0, i32 %tmp1.pn ; <i8**> [#uses=1]
- %indirect.goto.dest = load i8*, i8** %indirect.goto.dest.in ; <i8*> [#uses=1]
- indirectbr i8* %indirect.goto.dest, [label %lab0, label %end]
-}
diff --git a/llvm/test/Transforms/FunctionAttrs/misc.ll b/llvm/test/Transforms/FunctionAttrs/misc.ll
deleted file mode 100644
index 7b9e25809d9..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/misc.ll
+++ /dev/null
@@ -1,105 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
-; RUN: opt -S -attributor -attributor-disable=false < %s | FileCheck %s --check-prefixes=ALL,CHECK
-; RUN: opt -S -aa-pipeline='basic-aa' -passes=attributor -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s --check-prefixes=ALL,DECL_CS
-;
-; Mostly check we do not crash on these uses
-
-define internal void @internal(void (i8*)* %fp) {
-; CHECK-LABEL: define {{[^@]+}}@internal
-; CHECK-SAME: (void (i8*)* [[FP:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @foo(i32* nocapture nofree nonnull align 4 dereferenceable(4) undef)
-; CHECK-NEXT: call void [[FP:%.*]](i8* bitcast (void (i32*)* @foo to i8*))
-; CHECK-NEXT: call void @callback1(void (i32*)* nonnull @foo)
-; CHECK-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
-; CHECK-NEXT: call void @callback2(void (i8*)* [[FP]])
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void [[FP]](i8* [[TMP1]])
-; CHECK-NEXT: ret void
-;
-; DECL_CS-LABEL: define {{[^@]+}}@internal
-; DECL_CS-SAME: (void (i8*)* [[FP:%.*]])
-; DECL_CS-NEXT: entry:
-; DECL_CS-NEXT: [[A:%.*]] = alloca i32, align 4
-; DECL_CS-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
-; DECL_CS-NEXT: call void @foo(i32* nocapture nofree nonnull align 4 dereferenceable(4) undef)
-; DECL_CS-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
-; DECL_CS-NEXT: call void @callback1(void (i32*)* nonnull @foo)
-; DECL_CS-NEXT: call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
-; DECL_CS-NEXT: call void @callback2(void (i8*)* [[FP]])
-; DECL_CS-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; DECL_CS-NEXT: call void [[FP]](i8* [[TMP1]])
-; DECL_CS-NEXT: ret void
-;
-entry:
- %a = alloca i32, align 4
- %tmp = bitcast i32* %a to i8*
- call void @foo(i32* nonnull %a)
- call void %fp(i8* bitcast (void (i32*)* @foo to i8*))
- call void @callback1(void (i32*)* nonnull @foo)
- call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
- call void @callback2(void (i8*)* %fp)
- %tmp1 = bitcast i32* %a to i8*
- call void %fp(i8* %tmp1)
- ret void
-}
-
-define void @external(void (i8*)* %fp) {
-; CHECK-LABEL: define {{[^@]+}}@external
-; CHECK-SAME: (void (i8*)* [[FP:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void @foo(i32* nocapture nofree nonnull align 4 dereferenceable(4) undef)
-; CHECK-NEXT: call void @callback1(void (i32*)* nonnull @foo)
-; CHECK-NEXT: call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
-; CHECK-NEXT: call void @callback2(void (i8*)* [[FP]])
-; CHECK-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
-; CHECK-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; CHECK-NEXT: call void [[FP]](i8* [[TMP1]])
-; CHECK-NEXT: call void @internal(void (i8*)* [[FP]])
-; CHECK-NEXT: ret void
-;
-; DECL_CS-LABEL: define {{[^@]+}}@external
-; DECL_CS-SAME: (void (i8*)* [[FP:%.*]])
-; DECL_CS-NEXT: entry:
-; DECL_CS-NEXT: [[A:%.*]] = alloca i32, align 4
-; DECL_CS-NEXT: [[TMP:%.*]] = bitcast i32* [[A]] to i8*
-; DECL_CS-NEXT: call void @foo(i32* nocapture nofree nonnull align 4 dereferenceable(4) undef)
-; DECL_CS-NEXT: call void @callback1(void (i32*)* nonnull @foo)
-; DECL_CS-NEXT: call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
-; DECL_CS-NEXT: call void @callback2(void (i8*)* [[FP]])
-; DECL_CS-NEXT: call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
-; DECL_CS-NEXT: [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
-; DECL_CS-NEXT: call void [[FP]](i8* [[TMP1]])
-; DECL_CS-NEXT: call void @internal(void (i8*)* [[FP]])
-; DECL_CS-NEXT: ret void
-;
-entry:
- %a = alloca i32, align 4
- %tmp = bitcast i32* %a to i8*
- call void @foo(i32* nonnull %a)
- call void @callback1(void (i32*)* nonnull @foo)
- call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
- call void @callback2(void (i8*)* %fp)
- call void %fp(i8* bitcast (void (i32*)* @foo to i8*))
- %tmp1 = bitcast i32* %a to i8*
- call void %fp(i8* %tmp1)
- call void @internal(void (i8*)* %fp)
- ret void
-}
-
-define internal void @foo(i32* %a) {
-; CHECK-LABEL: define {{[^@]+}}@foo
-; CHECK-SAME: (i32* nocapture nofree readnone [[A:%.*]])
-; CHECK-NEXT: entry:
-; CHECK-NEXT: ret void
-;
-entry:
- ret void
-}
-
-declare void @callback1(void (i32*)*)
-declare void @callback2(void (i8*)*)
diff --git a/llvm/test/Transforms/FunctionAttrs/new_attributes.ll b/llvm/test/Transforms/FunctionAttrs/new_attributes.ll
deleted file mode 100644
index 6e87cffeb02..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/new_attributes.ll
+++ /dev/null
@@ -1,43 +0,0 @@
-; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-disable=false -attributor-max-iterations=0 -S | FileCheck %s
-; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-disable=false -attributor-max-iterations=1 -S | FileCheck %s
-; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-disable=false -attributor-max-iterations=2 -S | FileCheck %s
-; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-disable=false -attributor-max-iterations=3 -S | FileCheck %s
-; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-disable=false -attributor-max-iterations=4 -S | FileCheck %s
-; RUN: opt < %s -attributor -attributor-annotate-decl-cs -attributor-disable=false -attributor-max-iterations=2147483647 -S | FileCheck %s
-
-; CHECK-NOT: Function
-; CHECK: declare i32 @foo1()
-; CHECK-NOT: Function
-; CHECK: declare i32 @foo2()
-; CHECK-NOT: Function
-; CHECK: declare i32 @foo3()
-declare i32 @foo1()
-declare i32 @foo2()
-declare i32 @foo3()
-
-; CHECK-NOT: Function
-; CHECK: define internal i32 @bar() {
-; CHECK-NEXT: %1 = call i32 @foo1()
-; CHECK-NEXT: %2 = call i32 @foo2()
-; CHECK-NEXT: %3 = call i32 @foo3()
-; CHECK-NEXT: ret i32 undef
-; CHECK-NEXT: }
-define internal i32 @bar() {
- %1 = call i32 @foo1()
- %2 = call i32 @foo2()
- %3 = call i32 @foo3()
- ret i32 1
-}
-
-; CHECK-NOT: Function
-; CHECK: define i32 @baz() {
-; CHECK-NEXT: %1 = call i32 @bar()
-; CHECK-NEXT: ret i32 0
-; CHECK-NEXT: }
-define i32 @baz() {
- %1 = call i32 @bar()
- ret i32 0
-}
-
-; We should never derive anything here
-; CHECK-NOT: attributes
diff --git a/llvm/test/Transforms/FunctionAttrs/noalias_returned.ll b/llvm/test/Transforms/FunctionAttrs/noalias_returned.ll
deleted file mode 100644
index 587727dc311..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/noalias_returned.ll
+++ /dev/null
@@ -1,270 +0,0 @@
-; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 < %s | FileCheck %s
-
-; TEST 1 - negative.
-
-; void *G;
-; void *foo(){
-; void *V = malloc(4);
-; G = V;
-; return V;
-; }
-
-@G = external global i8*
-
-; CHECK: define i8* @foo()
-define i8* @foo() {
- %1 = tail call noalias i8* @malloc(i64 4)
- store i8* %1, i8** @G, align 8
- ret i8* %1
-}
-
-declare noalias i8* @malloc(i64)
-
-; TEST 2
-; call noalias function in return instruction.
-
-; CHECK: define noalias i8* @return_noalias()
-define i8* @return_noalias(){
- %1 = tail call noalias i8* @malloc(i64 4)
- ret i8* %1
-}
-
-define void @nocapture(i8* %a){
- ret void
-}
-
-; CHECK: define noalias i8* @return_noalias_looks_like_capture()
-define i8* @return_noalias_looks_like_capture(){
- %1 = tail call noalias i8* @malloc(i64 4)
- call void @nocapture(i8* %1)
- ret i8* %1
-}
-
-declare i8* @alias()
-
-; TEST 3
-; CHECK: define i8* @call_alias()
-; CHECK-NOT: noalias
-define i8* @call_alias(){
- %1 = tail call i8* @alias()
- ret i8* %1
-}
-
-; TEST 4
-; void *baz();
-; void *foo(int a);
-;
-; void *bar() {
-; foo(0);
-; return baz();
-; }
-;
-; void *foo(int a) {
-; if (a)
-; bar();
-; return malloc(4);
-; }
-
-; CHECK: define i8* @bar()
-define i8* @bar() nounwind uwtable {
- %1 = tail call i8* (...) @baz()
- ret i8* %1
-}
-
-; CHECK: define noalias i8* @foo1(i32 %0)
-define i8* @foo1(i32 %0) nounwind uwtable {
- %2 = icmp eq i32 %0, 0
- br i1 %2, label %5, label %3
-
-3: ; preds = %1
- %4 = tail call i8* (...) @baz()
- br label %5
-
-5: ; preds = %1, %3
- %6 = tail call noalias i8* @malloc(i64 4)
- ret i8* %6
-}
-
-declare i8* @baz(...) nounwind uwtable
-
-; TEST 5
-
-; Returning global pointer. Should not be noalias.
-; CHECK: define nonnull align 8 dereferenceable(8) i8** @getter()
-define i8** @getter() {
- ret i8** @G
-}
-
-; Returning global pointer. Should not be noalias.
-; CHECK: define nonnull align 8 dereferenceable(8) i8** @calle1()
-define i8** @calle1(){
- %1 = call i8** @getter()
- ret i8** %1
-}
-
-; TEST 6
-declare noalias i8* @strdup(i8* nocapture) nounwind
-
-; CHECK: define noalias i8* @test6()
-define i8* @test6() nounwind uwtable ssp {
- %x = alloca [2 x i8], align 1
- %arrayidx = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 0
- store i8 97, i8* %arrayidx, align 1
- %arrayidx1 = getelementptr inbounds [2 x i8], [2 x i8]* %x, i64 0, i64 1
- store i8 0, i8* %arrayidx1, align 1
- %call = call noalias i8* @strdup(i8* %arrayidx) nounwind
- ret i8* %call
-}
-
-; TEST 7
-
-; CHECK: define noalias i8* @test7()
-define i8* @test7() nounwind {
-entry:
- %A = call noalias i8* @malloc(i64 4) nounwind
- %tobool = icmp eq i8* %A, null
- br i1 %tobool, label %return, label %if.end
-
-if.end:
- store i8 7, i8* %A
- br label %return
-
-return:
- %retval.0 = phi i8* [ %A, %if.end ], [ null, %entry ]
- ret i8* %retval.0
-}
-
-; TEST 8
-
-; CHECK: define noalias i8* @test8(i32* %0)
-define i8* @test8(i32* %0) nounwind uwtable {
- %2 = tail call noalias i8* @malloc(i64 4)
- %3 = icmp ne i32* %0, null
- br i1 %3, label %4, label %5
-
-4: ; preds = %1
- store i8 10, i8* %2
- br label %5
-
-5: ; preds = %1, %4
- ret i8* %2
-}
-
-; TEST 9
-; Simple Argument Test
-define internal void @test9(i8* %a, i8* %b) {
-; CHECK: define internal void @test9(i8* noalias nocapture nofree readnone %a, i8* nocapture nofree readnone %b)
- ret void
-}
-define void @test9_helper(i8* %a, i8* %b) {
- tail call void @test9(i8* noalias %a, i8* %b)
- tail call void @test9(i8* noalias %b, i8* noalias %a)
- ret void
-}
-
-
-; TEST 10
-; Simple CallSite Test
-
-declare void @test10_helper_1(i8* %a)
-define void @test10_helper_2(i8* noalias %a) {
-; CHECK: tail call void @test10_helper_1(i8* %a)
- tail call void @test10_helper_1(i8* %a)
- ret void
-}
-define void @test10(i8* noalias %a) {
-; CHECK: define void @test10(i8* noalias %a)
-; FIXME: missing noalias
-; CHECK-NEXT: tail call void @test10_helper_1(i8* %a)
- tail call void @test10_helper_1(i8* %a)
-
-; CHECK-NEXT: tail call void @test10_helper_2(i8* noalias %a)
- tail call void @test10_helper_2(i8* %a)
- ret void
-}
-
-; TEST 11
-; CallSite Test
-
-declare void @test11_helper(i8* %a, i8 *%b)
-define void @test11(i8* noalias %a) {
-; CHECK: define void @test11(i8* noalias %a)
-; CHECK-NEXT: tail call void @test11_helper(i8* %a, i8* %a)
- tail call void @test11_helper(i8* %a, i8* %a)
- ret void
-}
-
-
-; TEST 12
-; CallSite Argument
-declare void @use_nocapture(i8* nocapture)
-declare void @use(i8*)
-define void @test12_1() {
-; CHECK-LABEL: @test12_1(
-; CHECK-NEXT: [[A:%.*]] = alloca i8, align 4
-; CHECK-NEXT: [[B:%.*]] = tail call noalias i8* @malloc(i64 4)
-; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nonnull align 4 dereferenceable(1) [[A]])
-; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nonnull align 4 dereferenceable(1) [[A]])
-; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture [[B]])
-; CHECK-NEXT: tail call void @use_nocapture(i8* noalias nocapture [[B]])
-; CHECK-NEXT: ret void
-;
- %A = alloca i8, align 4
- %B = tail call noalias i8* @malloc(i64 4)
- tail call void @use_nocapture(i8* %A)
- tail call void @use_nocapture(i8* %A)
- tail call void @use_nocapture(i8* %B)
- tail call void @use_nocapture(i8* %B)
- ret void
-}
-
-define void @test12_2(){
-; CHECK-LABEL: @test12_2(
-; CHECK-NEXT: [[A:%.*]] = tail call noalias i8* @malloc(i64 4)
-; FIXME: This should be @use_nocapture(i8* noalias [[A]])
-; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture [[A]])
-; FIXME: This should be @use_nocapture(i8* noalias nocapture [[A]])
-; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture [[A]])
-; CHECK-NEXT: tail call void @use(i8* [[A]])
-; CHECK-NEXT: tail call void @use_nocapture(i8* nocapture [[A]])
-; CHECK-NEXT: ret void
-;
- %A = tail call noalias i8* @malloc(i64 4)
- tail call void @use_nocapture(i8* %A)
- tail call void @use_nocapture(i8* %A)
- tail call void @use(i8* %A)
- tail call void @use_nocapture(i8* %A)
- ret void
-}
-
-declare void @two_args(i8* nocapture , i8* nocapture)
-define void @test12_3(){
-; CHECK-LABEL: @test12_3(
- %A = tail call noalias i8* @malloc(i64 4)
-; CHECK: tail call void @two_args(i8* nocapture %A, i8* nocapture %A)
- tail call void @two_args(i8* %A, i8* %A)
- ret void
-}
-
-define void @test12_4(){
-; CHECK-LABEL: @test12_4(
- %A = tail call noalias i8* @malloc(i64 4)
- %B = tail call noalias i8* @malloc(i64 4)
- %A_0 = getelementptr i8, i8* %A, i64 0
- %A_1 = getelementptr i8, i8* %A, i64 1
- %B_0 = getelementptr i8, i8* %B, i64 0
-
-; CHECK: tail call void @two_args(i8* noalias nocapture %A, i8* noalias nocapture %B)
- tail call void @two_args(i8* %A, i8* %B)
-
-; CHECK: tail call void @two_args(i8* nocapture %A, i8* nocapture %A_0)
- tail call void @two_args(i8* %A, i8* %A_0)
-
-; CHECK: tail call void @two_args(i8* nocapture %A, i8* nocapture %A_1)
- tail call void @two_args(i8* %A, i8* %A_1)
-
-; FIXME: This should be @two_args(i8* noalias nocapture %A_0, i8* noalias nocapture %B_0)
-; CHECK: tail call void @two_args(i8* nocapture %A_0, i8* nocapture %B_0)
- tail call void @two_args(i8* %A_0, i8* %B_0)
- ret void
-}
diff --git a/llvm/test/Transforms/FunctionAttrs/nocapture.ll b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
index a78af104167..25759cffe13 100644
--- a/llvm/test/Transforms/FunctionAttrs/nocapture.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nocapture.ll
@@ -1,18 +1,14 @@
-; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefixes=FNATTR,EITHER
-; RUN: opt -passes=function-attrs -S < %s | FileCheck %s --check-prefixes=FNATTR,EITHER
-; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -S -attributor-annotate-decl-cs < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,EITHER
-; RUN: opt -passes=attributor -attributor-manifest-internal -attributor-disable=false -S -attributor-annotate-decl-cs < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,EITHER
+; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefixes=FNATTR
+; RUN: opt -passes=function-attrs -S < %s | FileCheck %s --check-prefixes=FNATTR
@g = global i32* null ; <i32**> [#uses=1]
; FNATTR: define i32* @c1(i32* readnone returned %q)
-; ATTRIBUTOR: define i32* @c1(i32* nofree readnone returned "no-capture-maybe-returned" %q)
define i32* @c1(i32* %q) {
ret i32* %q
}
; FNATTR: define void @c2(i32* %q)
-; ATTRIBUTOR: define void @c2(i32* nofree writeonly %q)
; It would also be acceptable to mark %q as readnone. Update @c3 too.
define void @c2(i32* %q) {
store i32* %q, i32** @g
@@ -20,14 +16,12 @@ define void @c2(i32* %q) {
}
; FNATTR: define void @c3(i32* %q)
-; ATTRIBUTOR: define void @c3(i32* nofree writeonly %q)
define void @c3(i32* %q) {
call void @c2(i32* %q)
ret void
}
; FNATTR: define i1 @c4(i32* %q, i32 %bitno)
-; ATTRIBUTOR: define i1 @c4(i32* nofree readnone %q, i32 %bitno)
define i1 @c4(i32* %q, i32 %bitno) {
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -41,7 +35,6 @@ l1:
; c4b is c4 but without the escaping part
; FNATTR: define i1 @c4b(i32* %q, i32 %bitno)
-; ATTRIBUTOR: define i1 @c4b(i32* nocapture nofree readnone %q, i32 %bitno)
define i1 @c4b(i32* %q, i32 %bitno) {
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -56,7 +49,6 @@ l1:
@lookup_table = global [2 x i1] [ i1 0, i1 1 ]
; FNATTR: define i1 @c5(i32* %q, i32 %bitno)
-; ATTRIBUTOR: define i1 @c5(i32* nofree readonly %q, i32 %bitno)
define i1 @c5(i32* %q, i32 %bitno) {
%tmp = ptrtoint i32* %q to i32
%tmp2 = lshr i32 %tmp, %bitno
@@ -69,7 +61,7 @@ define i1 @c5(i32* %q, i32 %bitno) {
declare void @throw_if_bit_set(i8*, i8) readonly
-; EITHER: define i1 @c6(i8* readonly %q, i8 %bit)
+; FNATTR: define i1 @c6(i8* readonly %q, i8 %bit)
define i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 {
invoke void @throw_if_bit_set(i8* %q, i8 %bit)
to label %ret0 unwind label %ret1
@@ -92,7 +84,6 @@ define i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind {
}
; FNATTR: define i1 @c7(i32* readonly %q, i32 %bitno)
-; ATTRIBUTOR: define i1 @c7(i32* nofree readonly %q, i32 %bitno)
define i1 @c7(i32* %q, i32 %bitno) {
%ptr = call i1* @lookup_bit(i32* %q, i32 %bitno)
%val = load i1, i1* %ptr
@@ -101,7 +92,6 @@ define i1 @c7(i32* %q, i32 %bitno) {
; FNATTR: define i32 @nc1(i32* %q, i32* nocapture %p, i1 %b)
-; ATTRIBUTOR: define i32 @nc1(i32* nofree %q, i32* nocapture nofree %p, i1 %b)
define i32 @nc1(i32* %q, i32* %p, i1 %b) {
e:
br label %l
@@ -117,7 +107,6 @@ l:
}
; FNATTR: define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* nocapture %p, i1 %b)
-; ATTRIBUTOR: define i32 @nc1_addrspace(i32* nofree %q, i32 addrspace(1)* nocapture nofree %p, i1 %b)
define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) {
e:
br label %l
@@ -133,7 +122,6 @@ l:
}
; FNATTR: define void @nc2(i32* nocapture %p, i32* %q)
-; ATTRIBUTOR: define void @nc2(i32* nocapture nofree %p, i32* nofree %q)
define void @nc2(i32* %p, i32* %q) {
%1 = call i32 @nc1(i32* %q, i32* %p, i1 0) ; <i32> [#uses=0]
ret void
@@ -141,21 +129,19 @@ define void @nc2(i32* %p, i32* %q) {
; FNATTR: define void @nc3(void ()* nocapture %p)
-; ATTRIBUTOR: define void @nc3(void ()* nocapture nofree nonnull %p)
define void @nc3(void ()* %p) {
call void %p()
ret void
}
declare void @external(i8*) readonly nounwind
-; EITHER: define void @nc4(i8* nocapture readonly %p)
+; FNATTR: define void @nc4(i8* nocapture readonly %p)
define void @nc4(i8* %p) {
call void @external(i8* %p)
ret void
}
; FNATTR: define void @nc5(void (i8*)* nocapture %f, i8* nocapture %p)
-; ATTRIBUTOR: define void @nc5(void (i8*)* nocapture nofree nonnull %f, i8* nocapture %p)
define void @nc5(void (i8*)* %f, i8* %p) {
call void %f(i8* %p) readonly nounwind
call void %f(i8* nocapture %p)
@@ -163,7 +149,6 @@ define void @nc5(void (i8*)* %f, i8* %p) {
}
; FNATTR: define void @test1_1(i8* nocapture readnone %x1_1, i8* %y1_1, i1 %c)
-; ATTRIBUTOR: define void @test1_1(i8* nocapture nofree readnone %x1_1, i8* nocapture nofree readnone %y1_1, i1 %c)
; It would be acceptable to add readnone to %y1_1 and %y1_2.
define void @test1_1(i8* %x1_1, i8* %y1_1, i1 %c) {
call i8* @test1_2(i8* %x1_1, i8* %y1_1, i1 %c)
@@ -172,7 +157,6 @@ define void @test1_1(i8* %x1_1, i8* %y1_1, i1 %c) {
}
; FNATTR: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* returned %y1_2, i1 %c)
-; ATTRIBUTOR: define i8* @test1_2(i8* nocapture nofree readnone %x1_2, i8* nofree readnone returned "no-capture-maybe-returned" %y1_2, i1 %c)
define i8* @test1_2(i8* %x1_2, i8* %y1_2, i1 %c) {
br i1 %c, label %t, label %f
t:
@@ -184,7 +168,6 @@ f:
}
; FNATTR: define void @test2(i8* nocapture readnone %x2)
-; ATTRIBUTOR: define void @test2(i8* nocapture nofree readnone %x2)
define void @test2(i8* %x2) {
call void @test2(i8* %x2)
store i32* null, i32** @g
@@ -192,7 +175,6 @@ define void @test2(i8* %x2) {
}
; FNATTR: define void @test3(i8* nocapture readnone %x3, i8* nocapture readnone %y3, i8* nocapture readnone %z3)
-; ATTRIBUTOR: define void @test3(i8* nocapture nofree readnone %x3, i8* nocapture nofree readnone %y3, i8* nocapture nofree readnone %z3)
define void @test3(i8* %x3, i8* %y3, i8* %z3) {
call void @test3(i8* %z3, i8* %y3, i8* %x3)
store i32* null, i32** @g
@@ -200,7 +182,6 @@ define void @test3(i8* %x3, i8* %y3, i8* %z3) {
}
; FNATTR: define void @test4_1(i8* %x4_1, i1 %c)
-; ATTRIBUTOR: define void @test4_1(i8* nocapture nofree readnone %x4_1, i1 %c)
define void @test4_1(i8* %x4_1, i1 %c) {
call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1, i1 %c)
store i32* null, i32** @g
@@ -208,7 +189,6 @@ define void @test4_1(i8* %x4_1, i1 %c) {
}
; FNATTR: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone returned %y4_2, i8* nocapture readnone %z4_2, i1 %c)
-; ATTRIBUTOR: define i8* @test4_2(i8* nocapture nofree readnone %x4_2, i8* nofree readnone returned "no-capture-maybe-returned" %y4_2, i8* nocapture nofree readnone %z4_2, i1 %c)
define i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2, i1 %c) {
br i1 %c, label %t, label %f
t:
@@ -221,7 +201,7 @@ f:
declare i8* @test5_1(i8* %x5_1)
-; EITHER: define void @test5_2(i8* %x5_2)
+; FNATTR: define void @test5_2(i8* %x5_2)
define void @test5_2(i8* %x5_2) {
call i8* @test5_1(i8* %x5_2)
store i32* null, i32** @g
@@ -230,7 +210,7 @@ define void @test5_2(i8* %x5_2) {
declare void @test6_1(i8* %x6_1, i8* nocapture %y6_1, ...)
-; EITHER: define void @test6_2(i8* %x6_2, i8* nocapture %y6_2, i8* %z6_2)
+; FNATTR: define void @test6_2(i8* %x6_2, i8* nocapture %y6_2, i8* %z6_2)
define void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) {
call void (i8*, i8*, ...) @test6_1(i8* %x6_2, i8* %y6_2, i8* %z6_2)
store i32* null, i32** @g
@@ -238,28 +218,24 @@ define void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) {
}
; FNATTR: define void @test_cmpxchg(i32* nocapture %p)
-; ATTRIBUTOR: define void @test_cmpxchg(i32* nocapture nofree nonnull dereferenceable(4) %p)
define void @test_cmpxchg(i32* %p) {
cmpxchg i32* %p, i32 0, i32 1 acquire monotonic
ret void
}
; FNATTR: define void @test_cmpxchg_ptr(i32** nocapture %p, i32* %q)
-; ATTRIBUTOR: define void @test_cmpxchg_ptr(i32** nocapture nofree nonnull dereferenceable(8) %p, i32* nofree %q)
define void @test_cmpxchg_ptr(i32** %p, i32* %q) {
cmpxchg i32** %p, i32* null, i32* %q acquire monotonic
ret void
}
; FNATTR: define void @test_atomicrmw(i32* nocapture %p)
-; ATTRIBUTOR: define void @test_atomicrmw(i32* nocapture nofree nonnull dereferenceable(4) %p)
define void @test_atomicrmw(i32* %p) {
atomicrmw add i32* %p, i32 1 seq_cst
ret void
}
; FNATTR: define void @test_volatile(i32* %x)
-; ATTRIBUTOR: define void @test_volatile(i32* nofree align 4 %x)
define void @test_volatile(i32* %x) {
entry:
%gep = getelementptr i32, i32* %x, i64 1
@@ -267,7 +243,7 @@ entry:
ret void
}
-; EITHER: nocaptureLaunder(i8* nocapture %p)
+; FNATTR: nocaptureLaunder(i8* nocapture %p)
define void @nocaptureLaunder(i8* %p) {
entry:
%b = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
@@ -276,7 +252,7 @@ entry:
}
@g2 = global i8* null
-; EITHER: define void @captureLaunder(i8* %p)
+; FNATTR: define void @captureLaunder(i8* %p)
define void @captureLaunder(i8* %p) {
%b = call i8* @llvm.launder.invariant.group.p0i8(i8* %p)
store i8* %b, i8** @g2
@@ -284,7 +260,6 @@ define void @captureLaunder(i8* %p) {
}
; FNATTR: @nocaptureStrip(i8* nocapture %p)
-; ATTRIBUTOR: @nocaptureStrip(i8* nocapture writeonly %p)
define void @nocaptureStrip(i8* %p) {
entry:
%b = call i8* @llvm.strip.invariant.group.p0i8(i8* %p)
@@ -294,7 +269,6 @@ entry:
@g3 = global i8* null
; FNATTR: define void @captureStrip(i8* %p)
-; ATTRIBUTOR: define void @captureStrip(i8* writeonly %p)
define void @captureStrip(i8* %p) {
%b = call i8* @llvm.strip.invariant.group.p0i8(i8* %p)
store i8* %b, i8** @g3
@@ -302,21 +276,18 @@ define void @captureStrip(i8* %p) {
}
; FNATTR: define i1 @captureICmp(i32* readnone %x)
-; ATTRIBUTOR: define i1 @captureICmp(i32* nofree readnone %x)
define i1 @captureICmp(i32* %x) {
%1 = icmp eq i32* %x, null
ret i1 %1
}
; FNATTR: define i1 @captureICmpRev(i32* readnone %x)
-; ATTRIBUTOR: define i1 @captureICmpRev(i32* nofree readnone %x)
define i1 @captureICmpRev(i32* %x) {
%1 = icmp eq i32* null, %x
ret i1 %1
}
; FNATTR: define i1 @nocaptureInboundsGEPICmp(i32* nocapture readnone %x)
-; ATTRIBUTOR: define i1 @nocaptureInboundsGEPICmp(i32* nocapture nofree nonnull readnone %x)
define i1 @nocaptureInboundsGEPICmp(i32* %x) {
%1 = getelementptr inbounds i32, i32* %x, i32 5
%2 = bitcast i32* %1 to i8*
@@ -325,7 +296,6 @@ define i1 @nocaptureInboundsGEPICmp(i32* %x) {
}
; FNATTR: define i1 @nocaptureInboundsGEPICmpRev(i32* nocapture readnone %x)
-; ATTRIBUTOR: define i1 @nocaptureInboundsGEPICmpRev(i32* nocapture nofree nonnull readnone %x)
define i1 @nocaptureInboundsGEPICmpRev(i32* %x) {
%1 = getelementptr inbounds i32, i32* %x, i32 5
%2 = bitcast i32* %1 to i8*
@@ -334,7 +304,6 @@ define i1 @nocaptureInboundsGEPICmpRev(i32* %x) {
}
; FNATTR: define i1 @nocaptureDereferenceableOrNullICmp(i32* nocapture readnone dereferenceable_or_null(4) %x)
-; ATTRIBUTOR: define i1 @nocaptureDereferenceableOrNullICmp(i32* nocapture nofree readnone dereferenceable_or_null(4) %x)
define i1 @nocaptureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) {
%1 = bitcast i32* %x to i8*
%2 = icmp eq i8* %1, null
@@ -342,36 +311,11 @@ define i1 @nocaptureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x
}
; FNATTR: define i1 @captureDereferenceableOrNullICmp(i32* readnone dereferenceable_or_null(4) %x)
-; ATTRIBUTOR: define i1 @captureDereferenceableOrNullICmp(i32* nofree readnone dereferenceable_or_null(4) %x)
define i1 @captureDereferenceableOrNullICmp(i32* dereferenceable_or_null(4) %x) "null-pointer-is-valid"="true" {
%1 = bitcast i32* %x to i8*
%2 = icmp eq i8* %1, null
ret i1 %2
}
-declare void @unknown(i8*)
-define void @test_callsite() {
-entry:
-; We know that 'null' in AS 0 does not alias anything and cannot be captured. Though the latter is not qurried -> derived atm.
-; ATTRIBUTOR: call void @unknown(i8* noalias null)
- call void @unknown(i8* null)
- ret void
-}
-
-declare i8* @unknownpi8pi8(i8*,i8* returned)
-define i8* @test_returned1(i8* %A, i8* returned %B) nounwind readonly {
-; ATTRIBUTOR: define i8* @test_returned1(i8* nocapture readonly %A, i8* readonly returned %B)
-entry:
- %p = call i8* @unknownpi8pi8(i8* %A, i8* %B)
- ret i8* %p
-}
-
-define i8* @test_returned2(i8* %A, i8* %B) {
-; ATTRIBUTOR: define i8* @test_returned2(i8* nocapture readonly %A, i8* readonly returned %B)
-entry:
- %p = call i8* @unknownpi8pi8(i8* %A, i8* %B) nounwind readonly
- ret i8* %p
-}
-
declare i8* @llvm.launder.invariant.group.p0i8(i8*)
declare i8* @llvm.strip.invariant.group.p0i8(i8*)
diff --git a/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll b/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll
index 1c007ee11b4..8ac037e5cd8 100644
--- a/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nofree-attributor.ll
@@ -1,5 +1,4 @@
; RUN: opt -functionattrs --disable-nofree-inference=false -S < %s | FileCheck %s --check-prefix=FNATTR
-; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -15,8 +14,6 @@ declare void @_ZdaPv(i8*) local_unnamed_addr #2
; TEST 1 (positive case)
; FNATTR: Function Attrs: noinline norecurse nounwind readnone uwtable
; FNATTR-NEXT: define void @only_return()
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @only_return()
define void @only_return() #0 {
ret void
}
@@ -30,9 +27,6 @@ define void @only_return() #0 {
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NEXT: define void @only_free(i8* nocapture %0) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: nofree
-; ATTRIBUTOR-NEXT: define void @only_free(i8* nocapture %0) local_unnamed_addr #1
define void @only_free(i8* nocapture %0) local_unnamed_addr #0 {
tail call void @free(i8* %0) #1
ret void
@@ -52,9 +46,6 @@ define void @only_free(i8* nocapture %0) local_unnamed_addr #0 {
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NEXT: define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: nofree
-; ATTRIBUTOR-NEXT :define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr
define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr #0 {
tail call void @free_in_scc2(i8* %0) #1
ret void
@@ -63,9 +54,6 @@ define void @free_in_scc1(i8* nocapture %0) local_unnamed_addr #0 {
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NEXT: define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: nofree
-; ATTRIBUTOR: define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr
define void @free_in_scc2(i8* nocapture %0) local_unnamed_addr #0 {
%cmp = icmp eq i8* %0, null
br i1 %cmp, label %rec, label %call
@@ -92,8 +80,6 @@ end:
; FNATTR: Function Attrs: noinline nounwind readnone uwtable
; FNATTR-NEXT: define void @mutual_recursion1()
-; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @mutual_recursion1()
define void @mutual_recursion1() #0 {
call void @mutual_recursion2()
ret void
@@ -101,8 +87,6 @@ define void @mutual_recursion1() #0 {
; FNATTR: Function Attrs: noinline nounwind readnone uwtable
; FNATTR-NEXT: define void @mutual_recursion2()
-; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @mutual_recursion2()
define void @mutual_recursion2() #0 {
call void @mutual_recursion1()
ret void
@@ -117,9 +101,6 @@ define void @mutual_recursion2() #0 {
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NEXT: define void @_Z9delete_opPc(i8* %0) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: nofree
-; ATTRIBUTOR-NEXT: define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #1
define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #0 {
%2 = icmp eq i8* %0, null
br i1 %2, label %4, label %3
@@ -137,9 +118,6 @@ define void @_Z9delete_opPc(i8* %0) local_unnamed_addr #0 {
; Call realloc
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NEXT: define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: nofree
-; ATTRIBUTOR-NEXT: define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr
define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr #0 {
%ret = tail call i8* @realloc(i8* %0, i64 %1) #2
ret i8* %ret
@@ -152,14 +130,10 @@ define noalias i8* @call_realloc(i8* nocapture %0, i64 %1) local_unnamed_addr #0
; FNATTR: Function Attrs: nofree noinline nounwind readnone uwtable
; FNATTR-NEXT: declare void @nofree_function()
-; ATTRIBUTOR: Function Attrs: nofree noinline nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: declare void @nofree_function()
declare void @nofree_function() nofree readnone #0
; FNATTR: Function Attrs: noinline nounwind readnone uwtable
; FNATTR-NEXT: define void @call_nofree_function()
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @call_nofree_function()
define void @call_nofree_function() #0 {
tail call void @nofree_function()
ret void
@@ -169,16 +143,11 @@ define void @call_nofree_function() #0 {
; Call function declaration without "nofree"
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NEXT: declare void @maybe_free()
declare void @maybe_free() #0
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR: define void @call_maybe_free()
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: nofree
-; ATTRIBUTOR-NEXT: define void @call_maybe_free()
define void @call_maybe_free() #0 {
tail call void @maybe_free()
ret void
@@ -190,9 +159,6 @@ define void @call_maybe_free() #0 {
; FNATTR: Function Attrs: noinline nounwind uwtable
; FNATTR-NEXT: define void @call_both()
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: nofree
-; ATTRIBUTOR-NEXT: define void @call_both()
define void @call_both() #0 {
tail call void @maybe_free()
tail call void @nofree_function()
@@ -204,15 +170,11 @@ define void @call_both() #0 {
; Call intrinsic function
; FNATTRS: Function Attrs: noinline readnone speculatable
; FNATTRS-NEXT: declare float @llvm.floor.f32(float %0)
-; ATTRIBUTOR: Function Attrs: nounwind readnone speculatable
-; ATTRIBUTOR-NEXT: declare float @llvm.floor.f32(float)
declare float @llvm.floor.f32(float)
; FNATTRS: Function Attrs: noinline nounwind uwtable
; FNATTRS-NEXT: define void @call_floor(float %a)
; FIXME: missing nofree
-; ATTRIBUTOR: Function Attrs: noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @call_floor(float %a)
define void @call_floor(float %a) #0 {
tail call float @llvm.floor.f32(float %a)
@@ -224,8 +186,6 @@ define void @call_floor(float %a) #0 {
; FNATTRS: Function Attrs: noinline nounwind uwtable
; FNATTRS-NEXT: define void @f1()
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @f1()
define void @f1() #0 {
tail call void @nofree_function()
ret void
@@ -233,40 +193,11 @@ define void @f1() #0 {
; FNATTRS: Function Attrs: noinline nounwind uwtable
; FNATTRS-NEXT: define void @f2()
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @f2()
define void @f2() #0 {
tail call void @f1()
ret void
}
-; TEST 12 NoFree argument - positive.
-; ATTRIBUTOR: define double @test12(double* nocapture nofree nonnull readonly align 8 dereferenceable(8) %a)
-define double @test12(double* nocapture readonly %a) {
-entry:
- %0 = load double, double* %a, align 8
- %call = tail call double @cos(double %0) #2
- ret double %call
-}
-
-declare double @cos(double) nobuiltin nounwind nofree
-
-; FIXME: %a should be nofree.
-; TEST 13 NoFree argument - positive.
-; ATTRIBUTOR: define noalias i32* @test13(i64* nocapture nonnull readonly align 8 dereferenceable(8) %a)
-define noalias i32* @test13(i64* nocapture readonly %a) {
-entry:
- %0 = load i64, i64* %a, align 8
- %call = tail call noalias i8* @malloc(i64 %0) #2
- %1 = bitcast i8* %call to i32*
- ret i32* %1
-}
-
-; ATTRIBUTOR: define void @test14(i8* nocapture %0, i8* nocapture nofree readnone %1)
-define void @test14(i8* nocapture %0, i8* nocapture %1) {
- tail call void @free(i8* %0) #1
- ret void
-}
declare noalias i8* @malloc(i64)
diff --git a/llvm/test/Transforms/FunctionAttrs/nonnull.ll b/llvm/test/Transforms/FunctionAttrs/nonnull.ll
index 42923cee770..128a2bdbe50 100644
--- a/llvm/test/Transforms/FunctionAttrs/nonnull.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nonnull.ll
@@ -1,8 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -functionattrs -enable-nonnull-arg-prop %s | FileCheck %s --check-prefixes=BOTH,FNATTR,OLD
-; RUN: opt -S -passes=function-attrs -enable-nonnull-arg-prop %s | FileCheck %s --check-prefixes=BOTH,FNATTR,OLD
-; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=BOTH,OLD,ATTRIBUTOR,ATTRIBUTOR_OPM
-; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=5 -S < %s | FileCheck %s --check-prefixes=BOTH,ATTRIBUTOR,ATTRIBUTOR_NPM
+; RUN: opt -S -functionattrs -enable-nonnull-arg-prop %s | FileCheck %s --check-prefixes=FNATTR
+; RUN: opt -S -passes=function-attrs -enable-nonnull-arg-prop %s | FileCheck %s --check-prefixes=FNATTR
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -10,14 +8,14 @@ declare nonnull i8* @ret_nonnull()
; Return a pointer trivially nonnull (call return attribute)
define i8* @test1() {
-; BOTH: define nonnull i8* @test1
+; FNATTR: define nonnull i8* @test1
%ret = call i8* @ret_nonnull()
ret i8* %ret
}
; Return a pointer trivially nonnull (argument attribute)
define i8* @test2(i8* nonnull %p) {
-; BOTH: define nonnull i8* @test2
+; FNATTR: define nonnull i8* @test2
ret i8* %p
}
@@ -25,7 +23,6 @@ define i8* @test2(i8* nonnull %p) {
; can we still mark the other one which is trivially nonnull
define i8* @scc_binder(i1 %c) {
; FNATTR: define i8* @scc_binder
-; ATTRIBUTOR: define noalias i8* @scc_binder
br i1 %c, label %rec, label %end
rec:
call i8* @test3(i1 %c)
@@ -35,7 +32,7 @@ end:
}
define i8* @test3(i1 %c) {
-; BOTH: define nonnull i8* @test3
+; FNATTR: define nonnull i8* @test3
call i8* @scc_binder(i1 %c)
%ret = call i8* @ret_nonnull()
ret i8* %ret
@@ -46,14 +43,12 @@ define i8* @test3(i1 %c) {
; just never return period.)
define i8* @test4_helper() {
; FNATTR: define noalias nonnull i8* @test4_helper
-; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i8* @test4_helper
%ret = call i8* @test4()
ret i8* %ret
}
define i8* @test4() {
; FNATTR: define noalias nonnull i8* @test4
-; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i8* @test4
%ret = call i8* @test4_helper()
ret i8* %ret
}
@@ -62,7 +57,6 @@ define i8* @test4() {
; make sure we haven't marked them as nonnull.
define i8* @test5_helper(i1 %c) {
; FNATTR: define noalias i8* @test5_helper
-; ATTRIBUTOR: define noalias i8* @test5_helper
br i1 %c, label %rec, label %end
rec:
%ret = call i8* @test5(i1 %c)
@@ -73,14 +67,11 @@ end:
define i8* @test5(i1 %c) {
; FNATTR: define noalias i8* @test5
-; ATTRIBUTOR: define noalias i8* @test5
%ret = call i8* @test5_helper(i1 %c)
ret i8* %ret
}
; Local analysis, but going through a self recursive phi
-; ATTRIBUTOR: Function Attrs: noreturn
-; ATTRIBUTOR: define noalias nonnull align 536870912 dereferenceable(4294967295) i8* @test6a()
define i8* @test6a() {
entry:
%ret = call i8* @ret_nonnull()
@@ -92,7 +83,6 @@ exit:
ret i8* %phi
}
-; ATTRIBUTOR: define nonnull i8* @test6b(i1 %c)
define i8* @test6b(i1 %c) {
entry:
%ret = call i8* @ret_nonnull()
@@ -104,19 +94,19 @@ exit:
ret i8* %phi
}
-; BOTH: define i8* @test7
+; FNATTR: define i8* @test7
define i8* @test7(i8* %a) {
%b = getelementptr inbounds i8, i8* %a, i64 0
ret i8* %b
}
-; BOTH: define nonnull i8* @test8
+; FNATTR: define nonnull i8* @test8
define i8* @test8(i8* %a) {
%b = getelementptr inbounds i8, i8* %a, i64 1
ret i8* %b
}
-; BOTH: define i8* @test9
+; FNATTR: define i8* @test9
define i8* @test9(i8* %a, i64 %n) {
%b = getelementptr inbounds i8, i8* %a, i64 %n
ret i8* %b
@@ -125,7 +115,6 @@ define i8* @test9(i8* %a, i64 %n) {
declare void @llvm.assume(i1)
; FNATTR: define i8* @test10
; FIXME: missing nonnull
-; ATTRIBUTOR: define i8* @test10
define i8* @test10(i8* %a, i64 %n) {
%cmp = icmp ne i64 %n, 0
call void @llvm.assume(i1 %cmp)
@@ -139,7 +128,6 @@ define i8* @test10(i8* %a, i64 %n) {
; }
; FNATTR: define i8* @test11
; FIXME: missing nonnull
-; ATTRIBUTOR: define i8* @test11
define i8* @test11(i8*) local_unnamed_addr {
%2 = icmp eq i8* %0, null
br i1 %2, label %3, label %5
@@ -157,8 +145,6 @@ define i8* @test11(i8*) local_unnamed_addr {
; Simple CallSite Test
declare void @test12_helper(i8*)
define void @test12(i8* nonnull %a) {
-; ATTRIBUTOR: define void @test12(i8* nonnull %a)
-; ATTRIBUTOR-NEXT: tail call void @test12_helper(i8* nonnull %a)
tail call void @test12_helper(i8* %a)
ret void
}
@@ -174,7 +160,6 @@ define void @test13_helper() {
ret void
}
define internal void @test13(i8* %a, i8* %b, i8* %c) {
-; ATTRIBUTOR: define internal void @test13(i8* nocapture nofree nonnull readnone %a, i8* nocapture nofree readnone %b, i8* nocapture nofree readnone %c)
ret void
}
@@ -194,7 +179,6 @@ declare nonnull i8* @nonnull()
define internal i32* @f1(i32* %arg) {
; FIXME: missing nonnull It should be nonnull @f1(i32* nonnull readonly %arg)
-; ATTRIBUTOR: define internal nonnull i32* @f1(i32* nofree readonly %arg)
bb:
%tmp = icmp eq i32* %arg, null
@@ -207,14 +191,12 @@ bb1: ; preds = %bb
bb4: ; preds = %bb1
%tmp5 = getelementptr inbounds i32, i32* %arg, i64 1
-; ATTRIBUTOR: %tmp5b = tail call nonnull i32* @f3(i32* nofree nonnull %tmp5)
%tmp5b = tail call i32* @f3(i32* %tmp5)
%tmp5c = getelementptr inbounds i32, i32* %tmp5b, i64 -1
br label %bb9
bb6: ; preds = %bb1
; FIXME: missing nonnull. It should be @f2(i32* nonnull %arg)
-; ATTRIBUTOR: %tmp7 = tail call nonnull i32* @f2(i32* nofree %arg)
%tmp7 = tail call i32* @f2(i32* %arg)
ret i32* %tmp7
@@ -225,28 +207,23 @@ bb9: ; preds = %bb4, %bb
define internal i32* @f2(i32* %arg) {
; FIXME: missing nonnull. It should be nonnull @f2(i32* nonnull %arg)
-; ATTRIBUTOR: define internal nonnull i32* @f2(i32* nofree readonly %arg)
bb:
; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
-; ATTRIBUTOR: %tmp = tail call nonnull i32* @f1(i32* nofree %arg)
%tmp = tail call i32* @f1(i32* %arg)
ret i32* %tmp
}
define dso_local noalias i32* @f3(i32* %arg) {
; FIXME: missing nonnull. It should be nonnull @f3(i32* nonnull readonly %arg)
-; ATTRIBUTOR: define dso_local noalias nonnull i32* @f3(i32* nofree readonly %arg)
bb:
; FIXME: missing nonnull. It should be @f1(i32* nonnull readonly %arg)
-; ATTRIBUTOR: %tmp = call nonnull i32* @f1(i32* nofree %arg)
%tmp = call i32* @f1(i32* %arg)
ret i32* %tmp
}
; TEST 15
define void @f15(i8* %arg) {
-; ATTRIBUTOR: tail call void @use1(i8* nonnull dereferenceable(4) %arg)
tail call void @use1(i8* dereferenceable(4) %arg)
ret void
@@ -264,7 +241,6 @@ declare void @fun3(i8*, i8*, i8*) #1
; We can say that %a is nonnull but %b is not.
define void @f16(i8* %a, i8 * %b, i8 %c) {
; FIXME: missing nonnull on %a
-; ATTRIBUTOR: define void @f16(i8* %a, i8* %b, i8 %c)
%cmp = icmp eq i8 %c, 0
br i1 %cmp, label %if.then, label %if.else
if.then:
@@ -282,7 +258,6 @@ if.else:
; fun1(nonnull %a)
; We can say that %a is nonnull
define void @f17(i8* %a, i8 %c) {
-; ATTRIBUTOR: define void @f17(i8* nonnull %a, i8 %c)
%cmp = icmp eq i8 %c, 0
br i1 %cmp, label %if.then, label %if.else
if.then:
@@ -307,7 +282,6 @@ cont:
; fun1(nonnull %a)
define void @f18(i8* %a, i8* %b, i8 %c) {
-; ATTRIBUTOR: define void @f18(i8* nonnull %a, i8* %b, i8 %c)
%cmp1 = icmp eq i8 %c, 0
br i1 %cmp1, label %if.then, label %if.else
if.then:
@@ -334,7 +308,6 @@ cont2:
define void @f19(i8* %a, i8* %b, i8 %c) {
; FIXME: missing nonnull on %b
-; ATTRIBUTOR: define void @f19(i8* %a, i8* %b, i8 %c)
br label %loop.header
loop.header:
%cmp2 = icmp eq i8 %c, 0
@@ -363,11 +336,10 @@ declare i8 @use1safecall(i8* %x) readonly nounwind ; readonly+nounwind guarantee
; Can't extend non-null to parent for any argument because the 2nd call is not guaranteed to execute.
define void @parent1(i8* %a, i8* %b, i8* %c) {
-; BOTH-LABEL: @parent1(i8* %a, i8* %b, i8* %c)
-; BOTH-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
+; FNATTR-LABEL: @parent1(i8* %a, i8* %b, i8* %c)
+; FNATTR-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
; FNATTR-NEXT: call void @use3nonnull(i8* %b, i8* %c, i8* %a)
-; ATTRIBUTOR-NEXT: call void @use3nonnull(i8* nonnull %b, i8* nonnull %c, i8* nonnull %a)
-; BOTH-NEXT: ret void
+; FNATTR-NEXT: ret void
call void @use3(i8* %c, i8* %a, i8* %b)
call void @use3nonnull(i8* %b, i8* %c, i8* %a)
ret void
@@ -380,11 +352,8 @@ define void @parent2(i8* %a, i8* %b, i8* %c) {
; FNATTR-NEXT: call void @use3nonnull(i8* %b, i8* %c, i8* %a)
; FNATTR-NEXT: call void @use3(i8* %c, i8* %a, i8* %b)
-; ATTRIBUTOR-LABEL: @parent2(i8* nonnull %a, i8* nonnull %b, i8* nonnull %c)
-; ATTRIBUTOR-NEXT: call void @use3nonnull(i8* nonnull %b, i8* nonnull %c, i8* nonnull %a)
-; ATTRIBUTOR-NEXT: call void @use3(i8* nonnull %c, i8* nonnull %a, i8* nonnull %b)
-; BOTH-NEXT: ret void
+; FNATTR-NEXT: ret void
call void @use3nonnull(i8* %b, i8* %c, i8* %a)
call void @use3(i8* %c, i8* %a, i8* %b)
ret void
@@ -397,11 +366,8 @@ define void @parent3(i8* %a, i8* %b, i8* %c) {
; FNATTR-NEXT: call void @use1nonnull(i8* %a)
; FNATTR-NEXT: call void @use3(i8* %c, i8* %b, i8* %a)
-; ATTRIBUTOR-LABEL: @parent3(i8* nonnull %a, i8* %b, i8* %c)
-; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
-; ATTRIBUTOR-NEXT: call void @use3(i8* %c, i8* %b, i8* nonnull %a)
-; BOTH-NEXT: ret void
+; FNATTR-NEXT: ret void
call void @use1nonnull(i8* %a)
call void @use3(i8* %c, i8* %b, i8* %a)
@@ -416,12 +382,8 @@ define void @parent4(i8* %a, i8* %b, i8* %c) {
; CHECK-NEXT: call void @use2(i8* %a, i8* %c)
; CHECK-NEXT: call void @use1(i8* %b)
-; ATTRIBUTOR-LABEL: @parent4(i8* %a, i8* nonnull %b, i8* nonnull %c)
-; ATTRIBUTOR-NEXT: call void @use2nonnull(i8* nonnull %c, i8* nonnull %b)
-; ATTRIBUTOR-NEXT: call void @use2(i8* %a, i8* nonnull %c)
-; ATTRIBUTOR-NEXT: call void @use1(i8* nonnull %b)
-; BOTH: ret void
+; FNATTR: ret void
call void @use2nonnull(i8* %c, i8* %b)
call void @use2(i8* %a, i8* %c)
@@ -434,14 +396,13 @@ define void @parent4(i8* %a, i8* %b, i8* %c) {
; because it would incorrectly propagate the wrong information to its callers.
define void @parent5(i8* %a, i1 %a_is_notnull) {
-; BOTH: @parent5(i8* %a, i1 %a_is_notnull)
-; BOTH-NEXT: br i1 %a_is_notnull, label %t, label %f
-; BOTH: t:
+; FNATTR: @parent5(i8* %a, i1 %a_is_notnull)
+; FNATTR-NEXT: br i1 %a_is_notnull, label %t, label %f
+; FNATTR: t:
; FNATTR-NEXT: call void @use1nonnull(i8* %a)
-; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
-; BOTH-NEXT: ret void
-; BOTH: f:
-; BOTH-NEXT: ret void
+; FNATTR-NEXT: ret void
+; FNATTR: f:
+; FNATTR-NEXT: ret void
br i1 %a_is_notnull, label %t, label %f
t:
@@ -456,11 +417,9 @@ f:
define i8 @parent6(i8* %a, i8* %b) {
; FNATTR-LABEL: @parent6(i8* nonnull %a, i8* %b)
-; ATTRIBUTOR-LABEL: @parent6(i8* nonnull %a, i8* %b)
-; BOTH-NEXT: [[C:%.*]] = load volatile i8, i8* %b
+; FNATTR-NEXT: [[C:%.*]] = load volatile i8, i8* %b
; FNATTR-NEXT: call void @use1nonnull(i8* %a)
-; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
-; BOTH-NEXT: ret i8 [[C]]
+; FNATTR-NEXT: ret i8 [[C]]
%c = load volatile i8, i8* %b
call void @use1nonnull(i8* %a)
@@ -475,11 +434,8 @@ define i8 @parent7(i8* %a) {
; FNATTR-NEXT: call void @use1nonnull(i8* %a)
-; ATTRIBUTOR-LABEL: @parent7(i8* nonnull %a)
-; ATTRIBUTOR-NEXT: [[RET:%.*]] = call i8 @use1safecall(i8* nonnull %a)
-; ATTRIBUTOR-NEXT: call void @use1nonnull(i8* nonnull %a)
-; BOTH-NEXT: ret i8 [[RET]]
+; FNATTR-NEXT: ret i8 [[RET]]
%ret = call i8 @use1safecall(i8* %a)
call void @use1nonnull(i8* %a)
@@ -492,18 +448,16 @@ declare i32 @esfp(...)
define i1 @parent8(i8* %a, i8* %bogus1, i8* %b) personality i8* bitcast (i32 (...)* @esfp to i8*){
; FNATTR-LABEL: @parent8(i8* nonnull %a, i8* nocapture readnone %bogus1, i8* nonnull %b)
-; ATTRIBUTOR-LABEL: @parent8(i8* nonnull %a, i8* nocapture nofree readnone %bogus1, i8* nonnull %b)
-; BOTH-NEXT: entry:
+; FNATTR-NEXT: entry:
; FNATTR-NEXT: invoke void @use2nonnull(i8* %a, i8* %b)
-; ATTRIBUTOR-NEXT: invoke void @use2nonnull(i8* nonnull %a, i8* nonnull %b)
-; BOTH-NEXT: to label %cont unwind label %exc
-; BOTH: cont:
-; BOTH-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %b, null
-; BOTH-NEXT: ret i1 [[NULL_CHECK]]
-; BOTH: exc:
-; BOTH-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
-; BOTH-NEXT: filter [0 x i8*] zeroinitializer
-; BOTH-NEXT: unreachable
+; FNATTR-NEXT: to label %cont unwind label %exc
+; FNATTR: cont:
+; FNATTR-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %b, null
+; FNATTR-NEXT: ret i1 [[NULL_CHECK]]
+; FNATTR: exc:
+; FNATTR-NEXT: [[LP:%.*]] = landingpad { i8*, i32 }
+; FNATTR-NEXT: filter [0 x i8*] zeroinitializer
+; FNATTR-NEXT: unreachable
entry:
invoke void @use2nonnull(i8* %a, i8* %b)
@@ -519,7 +473,7 @@ exc:
unreachable
}
-; BOTH: define nonnull i32* @gep1(
+; FNATTR: define nonnull i32* @gep1(
define i32* @gep1(i32* %p) {
%q = getelementptr inbounds i32, i32* %p, i32 1
ret i32* %q
@@ -527,12 +481,12 @@ define i32* @gep1(i32* %p) {
define i32* @gep1_no_null_opt(i32* %p) #0 {
; Should't be able to derive nonnull based on gep.
-; BOTH: define i32* @gep1_no_null_opt(
+; FNATTR: define i32* @gep1_no_null_opt(
%q = getelementptr inbounds i32, i32* %p, i32 1
ret i32* %q
}
-; BOTH: define i32 addrspace(3)* @gep2(
+; FNATTR: define i32 addrspace(3)* @gep2(
define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
%q = getelementptr inbounds i32, i32 addrspace(3)* %p, i32 1
ret i32 addrspace(3)* %q
@@ -540,12 +494,11 @@ define i32 addrspace(3)* @gep2(i32 addrspace(3)* %p) {
; FNATTR: define i32 addrspace(3)* @as(i32 addrspace(3)* readnone returned dereferenceable(4) %p)
; FIXME: We should propagate dereferenceable here but *not* nonnull
-; ATTRIBUTOR: define dereferenceable_or_null(4) i32 addrspace(3)* @as(i32 addrspace(3)* nofree readnone returned dereferenceable(4) dereferenceable_or_null(4) %p)
define i32 addrspace(3)* @as(i32 addrspace(3)* dereferenceable(4) %p) {
ret i32 addrspace(3)* %p
}
-; BOTH: define internal nonnull i32* @g2()
+; FNATTR: define internal nonnull i32* @g2()
define internal i32* @g2() {
ret i32* inttoptr (i64 4 to i32*)
}
@@ -556,33 +509,28 @@ define i32* @g1() {
}
declare void @use_i32_ptr(i32*) readnone nounwind
-; ATTRIBUTOR: define internal void @called_by_weak(i32* nocapture nonnull readnone %a)
define internal void @called_by_weak(i32* %a) {
call void @use_i32_ptr(i32* %a)
ret void
}
; Check we do not annotate the function interface of this weak function.
-; ATTRIBUTOR: define weak_odr void @weak_caller(i32* nonnull %a)
define weak_odr void @weak_caller(i32* nonnull %a) {
call void @called_by_weak(i32* %a)
ret void
}
; Expect nonnull
-; ATTRIBUTOR: define internal void @control(i32* nocapture nonnull readnone align 16 dereferenceable(8) %a)
define internal void @control(i32* dereferenceable(4) %a) {
call void @use_i32_ptr(i32* %a)
ret void
}
; Avoid nonnull as we do not touch naked functions
-; ATTRIBUTOR: define internal void @naked(i32* dereferenceable(4) %a)
define internal void @naked(i32* dereferenceable(4) %a) naked {
call void @use_i32_ptr(i32* %a)
ret void
}
; Avoid nonnull as we do not touch optnone
-; ATTRIBUTOR: define internal void @optnone(i32* dereferenceable(4) %a)
define internal void @optnone(i32* dereferenceable(4) %a) optnone noinline {
call void @use_i32_ptr(i32* %a)
ret void
@@ -618,20 +566,6 @@ define i32 @nonnull_exec_ctx_1(i32* %a, i32 %b) {
; FNATTR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
; FNATTR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1
-; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
-; ATTRIBUTOR-NEXT: en:
-; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
-; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
-; ATTRIBUTOR: ex:
-; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
-; ATTRIBUTOR-NEXT: ret i32 [[TMP5]]
-; ATTRIBUTOR: hd:
-; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
-; ATTRIBUTOR-NEXT: tail call void @h(i32* [[A]])
-; ATTRIBUTOR-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
-; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
-; ATTRIBUTOR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
en:
%tmp3 = icmp eq i32 %b, 0
@@ -667,22 +601,6 @@ define i32 @nonnull_exec_ctx_1b(i32* %a, i32 %b) {
; FNATTR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
; FNATTR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_1b
-; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
-; ATTRIBUTOR-NEXT: en:
-; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
-; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
-; ATTRIBUTOR: ex:
-; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
-; ATTRIBUTOR-NEXT: ret i32 [[TMP5]]
-; ATTRIBUTOR: hd:
-; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
-; ATTRIBUTOR-NEXT: tail call void @h(i32* [[A]])
-; ATTRIBUTOR-NEXT: br label [[HD2]]
-; ATTRIBUTOR: hd2:
-; ATTRIBUTOR-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
-; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
-; ATTRIBUTOR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
en:
%tmp3 = icmp eq i32 %b, 0
@@ -719,20 +637,6 @@ define i32 @nonnull_exec_ctx_2(i32* %a, i32 %b) willreturn nounwind {
; FNATTR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
; FNATTR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2
-; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
-; ATTRIBUTOR-NEXT: en:
-; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
-; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
-; ATTRIBUTOR: ex:
-; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
-; ATTRIBUTOR-NEXT: ret i32 [[TMP5]]
-; ATTRIBUTOR: hd:
-; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD]] ], [ 0, [[EN:%.*]] ]
-; ATTRIBUTOR-NEXT: tail call void @h(i32* nonnull [[A]])
-; ATTRIBUTOR-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
-; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
-; ATTRIBUTOR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
en:
%tmp3 = icmp eq i32 %b, 0
@@ -768,22 +672,6 @@ define i32 @nonnull_exec_ctx_2b(i32* %a, i32 %b) willreturn nounwind {
; FNATTR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
; FNATTR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
-; ATTRIBUTOR-LABEL: define {{[^@]+}}@nonnull_exec_ctx_2b
-; ATTRIBUTOR-SAME: (i32* [[A:%.*]], i32 [[B:%.*]])
-; ATTRIBUTOR-NEXT: en:
-; ATTRIBUTOR-NEXT: [[TMP3:%.*]] = icmp eq i32 [[B:%.*]], 0
-; ATTRIBUTOR-NEXT: br i1 [[TMP3]], label [[EX:%.*]], label [[HD:%.*]]
-; ATTRIBUTOR: ex:
-; ATTRIBUTOR-NEXT: [[TMP5:%.*]] = tail call i32 @g(i32* nonnull [[A:%.*]])
-; ATTRIBUTOR-NEXT: ret i32 [[TMP5]]
-; ATTRIBUTOR: hd:
-; ATTRIBUTOR-NEXT: [[TMP7:%.*]] = phi i32 [ [[TMP8:%.*]], [[HD2:%.*]] ], [ 0, [[EN:%.*]] ]
-; ATTRIBUTOR-NEXT: tail call void @h(i32* nonnull [[A]])
-; ATTRIBUTOR-NEXT: br label [[HD2]]
-; ATTRIBUTOR: hd2:
-; ATTRIBUTOR-NEXT: [[TMP8]] = add nuw i32 [[TMP7]], 1
-; ATTRIBUTOR-NEXT: [[TMP9:%.*]] = icmp eq i32 [[TMP8]], [[B]]
-; ATTRIBUTOR-NEXT: br i1 [[TMP9]], label [[EX]], label [[HD]]
;
en:
%tmp3 = icmp eq i32 %b, 0
@@ -809,21 +697,21 @@ declare void @sink(i32*)
; FIXME: the sink argument should be marked nonnull as in @PR43833_simple.
define void @PR43833(i32* %0, i32 %1) {
-; BOTH-LABEL: @PR43833(
-; BOTH-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1:%.*]], 1
-; BOTH-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
-; BOTH: 4:
-; BOTH-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
-; BOTH-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]]
-; BOTH-NEXT: br label [[TMP8:%.*]]
-; BOTH: 7:
-; BOTH-NEXT: ret void
-; BOTH: 8:
-; BOTH-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
-; BOTH-NEXT: tail call void @sink(i32* [[TMP6]])
-; BOTH-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
-; BOTH-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
-; BOTH-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
+; FNATTR-LABEL: @PR43833(
+; FNATTR-NEXT: [[TMP3:%.*]] = icmp sgt i32 [[TMP1:%.*]], 1
+; FNATTR-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
+; FNATTR: 4:
+; FNATTR-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
+; FNATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]]
+; FNATTR-NEXT: br label [[TMP8:%.*]]
+; FNATTR: 7:
+; FNATTR-NEXT: ret void
+; FNATTR: 8:
+; FNATTR-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
+; FNATTR-NEXT: tail call void @sink(i32* [[TMP6]])
+; FNATTR-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
+; FNATTR-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
+; FNATTR-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
;
%3 = icmp sgt i32 %1, 1
br i1 %3, label %4, label %7
@@ -846,37 +734,22 @@ define void @PR43833(i32* %0, i32 %1) {
; Adjusted from PR43833
define void @PR43833_simple(i32* %0, i32 %1) {
-; OLD-LABEL: @PR43833_simple(
-; OLD-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0
-; OLD-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
-; OLD: 4:
-; OLD-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
-; OLD-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]]
-; OLD-NEXT: br label [[TMP8:%.*]]
-; OLD: 7:
-; OLD-NEXT: ret void
-; OLD: 8:
-; OLD-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
-; OLD-NEXT: tail call void @sink(i32* [[TMP6]])
-; OLD-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
-; OLD-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
-; OLD-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
+; FNATTR-LABEL: @PR43833_simple(
+; FNATTR-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0
+; FNATTR-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
+; FNATTR: 4:
+; FNATTR-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
+; FNATTR-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]]
+; FNATTR-NEXT: br label [[TMP8:%.*]]
+; FNATTR: 7:
+; FNATTR-NEXT: ret void
+; FNATTR: 8:
+; FNATTR-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
+; FNATTR-NEXT: tail call void @sink(i32* [[TMP6]])
+; FNATTR-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
+; FNATTR-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
+; FNATTR-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
;
-; ATTRIBUTOR_NPM-LABEL: @PR43833_simple(
-; ATTRIBUTOR_NPM-NEXT: [[TMP3:%.*]] = icmp ne i32 [[TMP1:%.*]], 0
-; ATTRIBUTOR_NPM-NEXT: br i1 [[TMP3]], label [[TMP4:%.*]], label [[TMP7:%.*]]
-; ATTRIBUTOR_NPM: 4:
-; ATTRIBUTOR_NPM-NEXT: [[TMP5:%.*]] = zext i32 [[TMP1]] to i64
-; ATTRIBUTOR_NPM-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, i32* [[TMP0:%.*]], i64 [[TMP5]]
-; ATTRIBUTOR_NPM-NEXT: br label [[TMP8:%.*]]
-; ATTRIBUTOR_NPM: 7:
-; ATTRIBUTOR_NPM-NEXT: ret void
-; ATTRIBUTOR_NPM: 8:
-; ATTRIBUTOR_NPM-NEXT: [[TMP9:%.*]] = phi i32 [ 1, [[TMP4]] ], [ [[TMP10:%.*]], [[TMP8]] ]
-; ATTRIBUTOR_NPM-NEXT: tail call void @sink(i32* [[TMP6]])
-; ATTRIBUTOR_NPM-NEXT: [[TMP10]] = add nuw nsw i32 [[TMP9]], 1
-; ATTRIBUTOR_NPM-NEXT: [[TMP11:%.*]] = icmp eq i32 [[TMP10]], [[TMP1]]
-; ATTRIBUTOR_NPM-NEXT: br i1 [[TMP11]], label [[TMP7]], label [[TMP8]]
;
%3 = icmp ne i32 %1, 0
br i1 %3, label %4, label %7
diff --git a/llvm/test/Transforms/FunctionAttrs/norecurse.ll b/llvm/test/Transforms/FunctionAttrs/norecurse.ll
index de5d35d6342..b780bb7b718 100644
--- a/llvm/test/Transforms/FunctionAttrs/norecurse.ll
+++ b/llvm/test/Transforms/FunctionAttrs/norecurse.ll
@@ -1,88 +1,83 @@
-; RUN: opt < %s -basicaa -functionattrs -rpo-functionattrs -S | FileCheck %s --check-prefixes=CHECK,BOTH
-; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs),rpo-functionattrs' -S | FileCheck %s --check-prefixes=CHECK,BOTH
-; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR,BOTH
+; RUN: opt < %s -basicaa -functionattrs -rpo-functionattrs -S | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs),rpo-functionattrs' -S | FileCheck %s
; CHECK: Function Attrs
; CHECK-SAME: norecurse nounwind readnone
-; ATTRIBUTOR: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
-; BOTH-NEXT: define i32 @leaf()
+; CHECK-NEXT: define i32 @leaf()
define i32 @leaf() {
ret i32 1
}
-; BOTH: Function Attrs
-; BOTH-SAME: readnone
-; BOTH-NOT: norecurse
-; BOTH-NEXT: define i32 @self_rec()
+; CHECK: Function Attrs
+; CHECK-SAME: readnone
+; CHECK-NOT: norecurse
+; CHECK-NEXT: define i32 @self_rec()
define i32 @self_rec() {
%a = call i32 @self_rec()
ret i32 4
}
-; BOTH: Function Attrs
-; BOTH-SAME: readnone
-; BOTH-NOT: norecurse
-; BOTH-NEXT: define i32 @indirect_rec()
+; CHECK: Function Attrs
+; CHECK-SAME: readnone
+; CHECK-NOT: norecurse
+; CHECK-NEXT: define i32 @indirect_rec()
define i32 @indirect_rec() {
%a = call i32 @indirect_rec2()
ret i32 %a
}
-; BOTH: Function Attrs
-; BOTH-SAME: readnone
-; BOTH-NOT: norecurse
-; BOTH-NEXT: define i32 @indirect_rec2()
+; CHECK: Function Attrs
+; CHECK-SAME: readnone
+; CHECK-NOT: norecurse
+; CHECK-NEXT: define i32 @indirect_rec2()
define i32 @indirect_rec2() {
%a = call i32 @indirect_rec()
ret i32 %a
}
-; BOTH: Function Attrs
-; BOTH-SAME: readnone
-; BOTH-NOT: norecurse
-; BOTH-NEXT: define i32 @extern()
+; CHECK: Function Attrs
+; CHECK-SAME: readnone
+; CHECK-NOT: norecurse
+; CHECK-NEXT: define i32 @extern()
define i32 @extern() {
%a = call i32 @k()
ret i32 %a
}
-; BOTH: Function Attrs
-; BOTH-NEXT: declare i32 @k()
+; CHECK: Function Attrs
+; CHECK-NEXT: declare i32 @k()
declare i32 @k() readnone
-; BOTH: Function Attrs
+; CHECK: Function Attrs
; CHECK-SAME: nounwind
-; BOTH-NOT: norecurse
+; CHECK-NOT: norecurse
; CHECK-NEXT: define void @intrinsic(i8* nocapture %dest, i8* nocapture readonly %src, i32 %len)
-; ATTRIBUTOR-NEXT: define void @intrinsic(i8* nocapture writeonly %dest, i8* nocapture readonly %src, i32 %len)
define void @intrinsic(i8* %dest, i8* %src, i32 %len) {
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dest, i8* %src, i32 %len, i1 false)
ret void
}
-; BOTH: Function Attrs
-; BOTH-NEXT: declare void @llvm.memcpy.p0i8.p0i8.i32
+; CHECK: Function Attrs
+; CHECK-NEXT: declare void @llvm.memcpy.p0i8.p0i8.i32
declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i1)
-; BOTH: Function Attrs
+; CHECK: Function Attrs
; CHECK-SAME: norecurse readnone
; FIXME: missing "norecurse"
-; ATTRIBUTOR-SAME: nosync readnone
; CHECK-NEXT: define internal i32 @called_by_norecurse()
define internal i32 @called_by_norecurse() {
%a = call i32 @k()
ret i32 %a
}
-; BOTH: Function Attrs
-; BOTH-NEXT: define void @m()
+; CHECK: Function Attrs
+; CHECK-NEXT: define void @m()
define void @m() norecurse {
%a = call i32 @called_by_norecurse()
ret void
}
-; BOTH: Function Attrs
+; CHECK: Function Attrs
; CHECK-SAME: norecurse readnone
; FIXME: missing "norecurse"
-; ATTRIBUTOR-SAME: nosync
; CHECK-NEXT: define internal i32 @called_by_norecurse_indirectly()
define internal i32 @called_by_norecurse_indirectly() {
%a = call i32 @k()
@@ -96,61 +91,3 @@ define void @p() norecurse {
call void @o()
ret void
}
-
-; ATTRIBUTOR: Function Attrs: nofree nosync nounwind
-; ATTRIBUTOR-NEXT: define void @f(i32 %x)
-define void @f(i32 %x) {
-entry:
- %x.addr = alloca i32, align 4
- store i32 %x, i32* %x.addr, align 4
- %0 = load i32, i32* %x.addr, align 4
- %tobool = icmp ne i32 %0, 0
- br i1 %tobool, label %if.then, label %if.end
-
-if.then:
- call void @g() norecurse
- br label %if.end
-
-if.end:
- ret void
-}
-
-; BOTH: define void @g()
-define void @g() norecurse {
-entry:
- call void @f(i32 0)
- ret void
-}
-
-; ATTRIBUTOR-NOT: Function Attrs
-; ATTRIBUTOR: define linkonce_odr i32 @leaf_redefinable()
-define linkonce_odr i32 @leaf_redefinable() {
- ret i32 1
-}
-
-; Call through a function pointer
-; ATTRIBUTOR-NOT: Function Attrs
-; ATTRIBUTOR: define i32 @eval_func1(i32 (i32)* nocapture nofree nonnull %0, i32 %1)
-define i32 @eval_func1(i32 (i32)* , i32) local_unnamed_addr {
- %3 = tail call i32 %0(i32 %1) #2
- ret i32 %3
-}
-
-; ATTRIBUTOR-NOT: Function Attrs
-; ATTRIBUTOR: define i32 @eval_func2(i32 (i32)* nocapture nofree %0, i32 %1)
-define i32 @eval_func2(i32 (i32)* , i32) local_unnamed_addr "null-pointer-is-valid"="true"{
- %3 = tail call i32 %0(i32 %1) #2
- ret i32 %3
-}
-
-declare void @unknown()
-; Call an unknown function in a dead block.
-; ATTRIBUTOR: Function Attrs: nofree norecurse nosync nounwind readnone willreturn
-; ATTRIBUTOR: define i32 @call_unknown_in_dead_block()
-define i32 @call_unknown_in_dead_block() local_unnamed_addr {
- ret i32 0
-Dead:
- tail call void @unknown()
- ret i32 1
-}
-
diff --git a/llvm/test/Transforms/FunctionAttrs/noreturn_async.ll b/llvm/test/Transforms/FunctionAttrs/noreturn_async.ll
deleted file mode 100644
index 3d2dd9f47da..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/noreturn_async.ll
+++ /dev/null
@@ -1,142 +0,0 @@
-; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s
-;
-; This file is the same as noreturn_sync.ll but with a personality which
-; indicates that the exception handler *can* catch asynchronous exceptions. As
-; a consequence, invokes to noreturn and nounwind functions are not translated
-; to calls followed by an unreachable but the unwind edge is considered live.
-;
-; https://reviews.llvm.org/D59978#inline-586873
-;
-; Make sure we handle invoke of a noreturn function correctly.
-;
-; This test is also a reminder of how we handle (=ignore) stackoverflow exception handling.
-;
-target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-windows-msvc19.16.27032"
-
-@"??_C@_0BG@CMNEKHOP@Exception?5NOT?5caught?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [22 x i8] c"Exception NOT caught\0A\00", align 1
-@"??_C@_0BC@NKPAGFFJ@Exception?5caught?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [18 x i8] c"Exception caught\0A\00", align 1
-@"??_C@_0BK@JHJLGDKL@Done?5execution?5result?$DN?$CFi?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [26 x i8] c"Done execution result=%i\0A\00", align 1
-@"?_OptionsStorage@?1??__local_stdio_printf_options@@9@4_KA" = linkonce_odr dso_local global i64 0, align 8
-
-
-define dso_local void @"?overflow@@YAXXZ"() {
-entry:
-; CHECK: Function Attrs: nofree noreturn nosync nounwind
-; CHECK-NEXT: define
-; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @"?overflow@@YAXXZ"()
-; CHECK-NEXT: unreachable
- call void @"?overflow@@YAXXZ"()
- %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@NKPAGFFJ@Exception?5caught?6?$AA@", i64 0, i64 0))
- ret void
-}
-
-
-; CHECK-NOT: nounwind
-; CHECK-NOT: noreturn
-; CHECK: define
-; CHECK-SAME: @"?catchoverflow@@YAHXZ"()
-define dso_local i32 @"?catchoverflow@@YAHXZ"() personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
-entry:
- %retval = alloca i32, align 4
- %__exception_code = alloca i32, align 4
-; CHECK: invoke void @"?overflow@@YAXXZ"()
-; CHECK: to label %invoke.cont unwind label %catch.dispatch
- invoke void @"?overflow@@YAXXZ"()
- to label %invoke.cont unwind label %catch.dispatch
-
-invoke.cont: ; preds = %entry
-; CHECK: invoke.cont:
-; CHECK-NEXT: unreachable
- br label %invoke.cont1
-
-catch.dispatch: ; preds = %invoke.cont, %entry
- %0 = catchswitch within none [label %__except] unwind to caller
-
-__except: ; preds = %catch.dispatch
- %1 = catchpad within %0 [i8* null]
- catchret from %1 to label %__except2
-
-__except2: ; preds = %__except
- %2 = call i32 @llvm.eh.exceptioncode(token %1)
- store i32 1, i32* %retval, align 4
- br label %return
-
-invoke.cont1: ; preds = %invoke.cont
- store i32 0, i32* %retval, align 4
- br label %return
-
-__try.cont: ; No predecessors!
- store i32 2, i32* %retval, align 4
- br label %return
-
-return: ; preds = %__try.cont, %__except2, %invoke.cont1
- %3 = load i32, i32* %retval, align 4
- ret i32 %3
-}
-
-
-define dso_local void @"?overflow@@YAXXZ_may_throw"() {
-entry:
-; CHECK: Function Attrs: noreturn
-; CHECK-NOT: nounwind
-; CHECK-NEXT: define
-; CHECK-NEXT: entry:
-; CHECK-NEXT: %call3 = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(18) getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@NKPAGFFJ@Exception?5caught?6?$AA@", i64 0, i64 0))
-; CHECK-NEXT: call void @"?overflow@@YAXXZ_may_throw"()
-; CHECK-NEXT: unreachable
- %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@NKPAGFFJ@Exception?5caught?6?$AA@", i64 0, i64 0))
- call void @"?overflow@@YAXXZ_may_throw"()
- ret void
-}
-
-
-; CHECK-NOT: nounwind
-; CHECK-NOT: noreturn
-; CHECK: define
-; CHECK-SAME: @"?catchoverflow@@YAHXZ_may_throw"()
-define dso_local i32 @"?catchoverflow@@YAHXZ_may_throw"() personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) {
-entry:
- %retval = alloca i32, align 4
- %__exception_code = alloca i32, align 4
-; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"()
-; CHECK: to label %invoke.cont unwind label %catch.dispatch
- invoke void @"?overflow@@YAXXZ_may_throw"()
- to label %invoke.cont unwind label %catch.dispatch
-
-invoke.cont: ; preds = %entry
-; CHECK: invoke.cont:
-; CHECK-NEXT: unreachable
- br label %invoke.cont1
-
-catch.dispatch: ; preds = %invoke.cont, %entry
- %0 = catchswitch within none [label %__except] unwind to caller
-
-__except: ; preds = %catch.dispatch
- %1 = catchpad within %0 [i8* null]
- catchret from %1 to label %__except2
-
-__except2: ; preds = %__except
- %2 = call i32 @llvm.eh.exceptioncode(token %1)
- store i32 1, i32* %retval, align 4
- br label %return
-
-invoke.cont1: ; preds = %invoke.cont
- store i32 0, i32* %retval, align 4
- br label %return
-
-__try.cont: ; No predecessors!
- store i32 2, i32* %retval, align 4
- br label %return
-
-return: ; preds = %__try.cont, %__except2, %invoke.cont1
- %3 = load i32, i32* %retval, align 4
- ret i32 %3
-}
-
-declare dso_local i32 @__C_specific_handler(...)
-
-declare dso_local i32 @printf(i8* %_Format, ...)
-
-declare i32 @llvm.eh.exceptioncode(token)
diff --git a/llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll b/llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll
deleted file mode 100644
index b5a70e76271..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/noreturn_sync.ll
+++ /dev/null
@@ -1,138 +0,0 @@
-; RUN: opt -functionattrs -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s
-;
-; This file is the same as noreturn_async.ll but with a personality which
-; indicates that the exception handler *cannot* catch asynchronous exceptions.
-; As a consequence, invokes to noreturn and nounwind functions are translated
-; to calls followed by an unreachable.
-;
-; https://reviews.llvm.org/D59978#inline-586873
-;
-; Make sure we handle invoke of a noreturn function correctly.
-;
-; This test is also a reminder of how we handle (=ignore) stackoverflow exception handling.
-;
-target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
-target triple = "x86_64-pc-linux-gnu"
-
-@"??_C@_0BG@CMNEKHOP@Exception?5NOT?5caught?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [22 x i8] c"Exception NOT caught\0A\00", align 1
-@"??_C@_0BC@NKPAGFFJ@Exception?5caught?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [18 x i8] c"Exception caught\0A\00", align 1
-@"??_C@_0BK@JHJLGDKL@Done?5execution?5result?$DN?$CFi?6?$AA@" = linkonce_odr dso_local unnamed_addr constant [26 x i8] c"Done execution result=%i\0A\00", align 1
-@"?_OptionsStorage@?1??__local_stdio_printf_options@@9@4_KA" = linkonce_odr dso_local global i64 0, align 8
-
-
-define dso_local void @"?overflow@@YAXXZ"() {
-entry:
-; CHECK: Function Attrs: nofree noreturn nosync nounwind
-; CHECK-NEXT: define
-; CHECK-NEXT: entry:
-; CHECK-NEXT: call void @"?overflow@@YAXXZ"()
-; CHECK-NEXT: unreachable
- call void @"?overflow@@YAXXZ"()
- %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@NKPAGFFJ@Exception?5caught?6?$AA@", i64 0, i64 0))
- ret void
-}
-
-
-; CHECK: Function Attrs: nofree noreturn nosync nounwind
-; CHECK-NEXT: @"?catchoverflow@@YAHXZ"()
-define dso_local i32 @"?catchoverflow@@YAHXZ"() personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*) {
-entry:
- %retval = alloca i32, align 4
- %__exception_code = alloca i32, align 4
- invoke void @"?overflow@@YAXXZ"()
- to label %invoke.cont unwind label %catch.dispatch
-; CHECK: call void @"?overflow@@YAXXZ"()
-; CHECK-NEXT: unreachable
-
-invoke.cont: ; preds = %entry
- br label %invoke.cont1
-
-catch.dispatch: ; preds = %invoke.cont, %entry
- %0 = catchswitch within none [label %__except] unwind to caller
-
-__except: ; preds = %catch.dispatch
- %1 = catchpad within %0 [i8* null]
- catchret from %1 to label %__except2
-
-__except2: ; preds = %__except
- %2 = call i32 @llvm.eh.exceptioncode(token %1)
- store i32 1, i32* %retval, align 4
- br label %return
-
-invoke.cont1: ; preds = %invoke.cont
- store i32 0, i32* %retval, align 4
- br label %return
-
-__try.cont: ; No predecessors!
- store i32 2, i32* %retval, align 4
- br label %return
-
-return: ; preds = %__try.cont, %__except2, %invoke.cont1
- %3 = load i32, i32* %retval, align 4
- ret i32 %3
-}
-
-
-define dso_local void @"?overflow@@YAXXZ_may_throw"() {
-entry:
-; CHECK: Function Attrs: noreturn
-; CHECK-NOT: nounwind
-; CHECK-NEXT: define
-; CHECK-NEXT: entry:
-; CHECK-NEXT: %call3 = call i32 (i8*, ...) @printf(i8* nonnull dereferenceable(18) getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@NKPAGFFJ@Exception?5caught?6?$AA@", i64 0, i64 0))
-; CHECK-NEXT: call void @"?overflow@@YAXXZ_may_throw"()
-; CHECK-NEXT: unreachable
- %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([18 x i8], [18 x i8]* @"??_C@_0BC@NKPAGFFJ@Exception?5caught?6?$AA@", i64 0, i64 0))
- call void @"?overflow@@YAXXZ_may_throw"()
- ret void
-}
-
-
-; CHECK-NOT: nounwind
-; CHECK-NOT: noreturn
-; CHECK: define
-; CHECK-SAME: @"?catchoverflow@@YAHXZ_may_throw"()
-define dso_local i32 @"?catchoverflow@@YAHXZ_may_throw"() personality i8* bitcast (i32 (...)* @__gcc_personality_v0 to i8*) {
-entry:
- %retval = alloca i32, align 4
- %__exception_code = alloca i32, align 4
-; CHECK: invoke void @"?overflow@@YAXXZ_may_throw"()
-; CHECK: to label %invoke.cont unwind label %catch.dispatch
- invoke void @"?overflow@@YAXXZ_may_throw"()
- to label %invoke.cont unwind label %catch.dispatch
-
-invoke.cont: ; preds = %entry
-; CHECK: invoke.cont:
-; CHECK-NEXT: unreachable
- br label %invoke.cont1
-
-catch.dispatch: ; preds = %invoke.cont, %entry
- %0 = catchswitch within none [label %__except] unwind to caller
-
-__except: ; preds = %catch.dispatch
- %1 = catchpad within %0 [i8* null]
- catchret from %1 to label %__except2
-
-__except2: ; preds = %__except
- %2 = call i32 @llvm.eh.exceptioncode(token %1)
- store i32 1, i32* %retval, align 4
- br label %return
-
-invoke.cont1: ; preds = %invoke.cont
- store i32 0, i32* %retval, align 4
- br label %return
-
-__try.cont: ; No predecessors!
- store i32 2, i32* %retval, align 4
- br label %return
-
-return: ; preds = %__try.cont, %__except2, %invoke.cont1
- %3 = load i32, i32* %retval, align 4
- ret i32 %3
-}
-
-declare dso_local i32 @__gcc_personality_v0(...)
-
-declare dso_local i32 @printf(i8* %_Format, ...)
-
-declare i32 @llvm.eh.exceptioncode(token)
diff --git a/llvm/test/Transforms/FunctionAttrs/nosync.ll b/llvm/test/Transforms/FunctionAttrs/nosync.ll
deleted file mode 100644
index abb40cf2669..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/nosync.ll
+++ /dev/null
@@ -1,356 +0,0 @@
-; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefix=FNATTR
-; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-; Test cases designed for the nosync function attribute.
-; FIXME's are used to indicate problems and missing attributes.
-
-; struct RT {
-; char A;
-; int B[10][20];
-; char C;
-; };
-; struct ST {
-; int X;
-; double Y;
-; struct RT Z;
-; };
-;
-; int *foo(struct ST *s) {
-; return &s[1].Z.B[5][13];
-; }
-
-; TEST 1
-; non-convergent and readnone implies nosync
-%struct.RT = type { i8, [10 x [20 x i32]], i8 }
-%struct.ST = type { i32, double, %struct.RT }
-
-; FNATTR: Function Attrs: norecurse nounwind optsize readnone ssp uwtable
-; FNATTR-NEXT: define nonnull i32* @foo(%struct.ST* readnone %s)
-; ATTRIBUTOR: Function Attrs: nofree nosync nounwind optsize readnone ssp uwtable
-; ATTRIBUTOR-NEXT: define nonnull i32* @foo(%struct.ST* nofree nonnull readnone "no-capture-maybe-returned" %s)
-define i32* @foo(%struct.ST* %s) nounwind uwtable readnone optsize ssp {
-entry:
- %arrayidx = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1, i32 2, i32 1, i64 5, i64 13
- ret i32* %arrayidx
-}
-
-; TEST 2
-; atomic load with monotonic ordering
-; int load_monotonic(_Atomic int *num) {
-; int n = atomic_load_explicit(num, memory_order_relaxed);
-; return n;
-; }
-
-; FNATTR: Function Attrs: nofree norecurse nounwind uwtable
-; FNATTR-NEXT: define i32 @load_monotonic(i32* nocapture readonly %0)
-; ATTRIBUTOR: Function Attrs: nofree norecurse nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define i32 @load_monotonic(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %0)
-define i32 @load_monotonic(i32* nocapture readonly %0) norecurse nounwind uwtable {
- %2 = load atomic i32, i32* %0 monotonic, align 4
- ret i32 %2
-}
-
-
-; TEST 3
-; atomic store with monotonic ordering.
-; void store_monotonic(_Atomic int *num) {
-; atomic_load_explicit(num, memory_order_relaxed);
-; }
-
-; FNATTR: Function Attrs: nofree norecurse nounwind uwtable
-; FNATTR-NEXT: define void @store_monotonic(i32* nocapture %0)
-; ATTRIBUTOR: Function Attrs: nofree norecurse nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: define void @store_monotonic(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) %0)
-define void @store_monotonic(i32* nocapture %0) norecurse nounwind uwtable {
- store atomic i32 10, i32* %0 monotonic, align 4
- ret void
-}
-
-; TEST 4 - negative, should not deduce nosync
-; atomic load with acquire ordering.
-; int load_acquire(_Atomic int *num) {
-; int n = atomic_load_explicit(num, memory_order_acquire);
-; return n;
-; }
-
-; FNATTR: Function Attrs: nofree norecurse nounwind uwtable
-; FNATTR-NEXT: define i32 @load_acquire(i32* nocapture readonly %0)
-; ATTRIBUTOR: Function Attrs: nofree norecurse nounwind uwtable
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR-NEXT: define i32 @load_acquire(i32* nocapture nofree nonnull readonly align 4 dereferenceable(4) %0)
-define i32 @load_acquire(i32* nocapture readonly %0) norecurse nounwind uwtable {
- %2 = load atomic i32, i32* %0 acquire, align 4
- ret i32 %2
-}
-
-; TEST 5 - negative, should not deduce nosync
-; atomic load with release ordering
-; void load_release(_Atomic int *num) {
-; atomic_store_explicit(num, 10, memory_order_release);
-; }
-
-; FNATTR: Function Attrs: nofree norecurse nounwind uwtable
-; FNATTR-NEXT: define void @load_release(i32* nocapture %0)
-; ATTRIBUTOR: Function Attrs: nofree norecurse nounwind uwtable
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR-NEXT: define void @load_release(i32* nocapture nofree writeonly align 4 %0)
-define void @load_release(i32* nocapture %0) norecurse nounwind uwtable {
- store atomic volatile i32 10, i32* %0 release, align 4
- ret void
-}
-
-; TEST 6 - negative volatile, relaxed atomic
-
-; FNATTR: Function Attrs: nofree norecurse nounwind uwtable
-; FNATTR-NEXT: define void @load_volatile_release(i32* nocapture %0)
-; ATTRIBUTOR: Function Attrs: nofree norecurse nounwind uwtable
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR-NEXT: define void @load_volatile_release(i32* nocapture nofree writeonly align 4 %0)
-define void @load_volatile_release(i32* nocapture %0) norecurse nounwind uwtable {
- store atomic volatile i32 10, i32* %0 release, align 4
- ret void
-}
-
-; TEST 7 - negative, should not deduce nosync
-; volatile store.
-; void volatile_store(volatile int *num) {
-; *num = 14;
-; }
-
-; FNATTR: Function Attrs: nofree norecurse nounwind uwtable
-; FNATTR-NEXT: define void @volatile_store(i32* %0)
-; ATTRIBUTOR: Function Attrs: nofree norecurse nounwind uwtable
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR-NEXT: define void @volatile_store(i32* nofree align 4 %0)
-define void @volatile_store(i32* %0) norecurse nounwind uwtable {
- store volatile i32 14, i32* %0, align 4
- ret void
-}
-
-; TEST 8 - negative, should not deduce nosync
-; volatile load.
-; int volatile_load(volatile int *num) {
-; int n = *num;
-; return n;
-; }
-
-; FNATTR: Function Attrs: nofree norecurse nounwind uwtable
-; FNATTR-NEXT: define i32 @volatile_load(i32* %0)
-; ATTRIBUTOR: Function Attrs: nofree norecurse nounwind uwtable
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR-NEXT: define i32 @volatile_load(i32* nofree align 4 %0)
-define i32 @volatile_load(i32* %0) norecurse nounwind uwtable {
- %2 = load volatile i32, i32* %0, align 4
- ret i32 %2
-}
-
-; TEST 9
-
-; FNATTR: Function Attrs: noinline nosync nounwind uwtable
-; FNATTR-NEXT: declare void @nosync_function()
-; ATTRIBUTOR: Function Attrs: noinline nosync nounwind uwtable
-; ATTRIBUTOR-NEXT: declare void @nosync_function()
-declare void @nosync_function() noinline nounwind uwtable nosync
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NEXT: define void @call_nosync_function()
-; ATTRIBUTOR: Function Attrs: noinline nosync nounwind uwtable
-; ATTRIBUTOR-next: define void @call_nosync_function()
-define void @call_nosync_function() nounwind uwtable noinline {
- tail call void @nosync_function() noinline nounwind uwtable
- ret void
-}
-
-; TEST 10 - negative, should not deduce nosync
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NEXT: declare void @might_sync()
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NEXT: declare void @might_sync()
-declare void @might_sync() noinline nounwind uwtable
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NEXT: define void @call_might_sync()
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR-NEXT: define void @call_might_sync()
-define void @call_might_sync() nounwind uwtable noinline {
- tail call void @might_sync() noinline nounwind uwtable
- ret void
-}
-
-; TEST 11 - positive, should deduce nosync
-; volatile operation in same scc but dead. Call volatile_load defined in TEST 8.
-
-; FNATTR: Function Attrs: nofree noinline nounwind uwtable
-; FNATTR-NEXT: define i32 @scc1(i32* %0)
-; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define i32 @scc1(i32* nocapture nofree readnone %0)
-define i32 @scc1(i32* %0) noinline nounwind uwtable {
- tail call void @scc2(i32* %0);
- %val = tail call i32 @volatile_load(i32* %0);
- ret i32 %val;
-}
-
-; FNATTR: Function Attrs: nofree noinline nounwind uwtable
-; FNATTR-NEXT: define void @scc2(i32* %0)
-; ATTRIBUTOR: Function Attrs: nofree noinline noreturn nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @scc2(i32* nocapture nofree readnone %0)
-define void @scc2(i32* %0) noinline nounwind uwtable {
- tail call i32 @scc1(i32* %0);
- ret void;
-}
-
-; TEST 12 - fences, negative
-;
-; void foo1(int *a, std::atomic<bool> flag){
-; *a = 100;
-; atomic_thread_fence(std::memory_order_release);
-; flag.store(true, std::memory_order_relaxed);
-; }
-;
-; void bar(int *a, std::atomic<bool> flag){
-; while(!flag.load(std::memory_order_relaxed))
-; ;
-;
-; atomic_thread_fence(std::memory_order_acquire);
-; int b = *a;
-; }
-
-%"struct.std::atomic" = type { %"struct.std::__atomic_base" }
-%"struct.std::__atomic_base" = type { i8 }
-
-; FNATTR: Function Attrs: nofree norecurse nounwind
-; FNATTR-NEXT: define void @foo1(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @foo1(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) %0, %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) %1)
-
-define void @foo1(i32* %0, %"struct.std::atomic"* %1) {
- store i32 100, i32* %0, align 4
- fence release
- %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
- store atomic i8 1, i8* %3 monotonic, align 1
- ret void
-}
-
-; FNATTR: Function Attrs: nofree norecurse nounwind
-; FNATTR-NEXT: define void @bar(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR: define void @bar(i32* nocapture nofree readnone %0, %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) %1)
-define void @bar(i32* %0, %"struct.std::atomic"* %1) {
- %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
- br label %4
-
-4: ; preds = %4, %2
- %5 = load atomic i8, i8* %3 monotonic, align 1
- %6 = and i8 %5, 1
- %7 = icmp eq i8 %6, 0
- br i1 %7, label %4, label %8
-
-8: ; preds = %4
- fence acquire
- ret void
-}
-
-; TEST 13 - Fence syncscope("singlethread") seq_cst
-; FNATTR: Function Attrs: nofree norecurse nounwind
-; FNATTR-NEXT: define void @foo1_singlethread(i32* nocapture %0, %"struct.std::atomic"* nocapture %1)
-; ATTRIBUTOR: Function Attrs: nofree nosync nounwind willreturn
-; ATTRIBUTOR: define void @foo1_singlethread(i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) %0, %"struct.std::atomic"* nocapture nofree nonnull writeonly dereferenceable(1) %1)
-
-define void @foo1_singlethread(i32* %0, %"struct.std::atomic"* %1) {
- store i32 100, i32* %0, align 4
- fence syncscope("singlethread") release
- %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
- store atomic i8 1, i8* %3 monotonic, align 1
- ret void
-}
-
-; FNATTR: Function Attrs: nofree norecurse nounwind
-; FNATTR-NEXT: define void @bar_singlethread(i32* nocapture readnone %0, %"struct.std::atomic"* nocapture readonly %1)
-; ATTRIBUTOR: Function Attrs: nofree nosync nounwind
-; ATTRIBUTOR: define void @bar_singlethread(i32* nocapture nofree readnone %0, %"struct.std::atomic"* nocapture nofree nonnull readonly dereferenceable(1) %1)
-define void @bar_singlethread(i32* %0, %"struct.std::atomic"* %1) {
- %3 = getelementptr inbounds %"struct.std::atomic", %"struct.std::atomic"* %1, i64 0, i32 0, i32 0
- br label %4
-
-4: ; preds = %4, %2
- %5 = load atomic i8, i8* %3 monotonic, align 1
- %6 = and i8 %5, 1
- %7 = icmp eq i8 %6, 0
- br i1 %7, label %4, label %8
-
-8: ; preds = %4
- fence syncscope("singlethread") acquire
- ret void
-}
-
-declare void @llvm.memcpy(i8* %dest, i8* %src, i32 %len, i1 %isvolatile)
-declare void @llvm.memset(i8* %dest, i8 %val, i32 %len, i1 %isvolatile)
-
-; TEST 14 - negative, checking volatile intrinsics.
-
-; It is odd to add nocapture but a result of the llvm.memcpy nocapture.
-;
-; ATTRIBUTOR: Function Attrs: nounwind
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR-NEXT: define i32 @memcpy_volatile(i8* nocapture writeonly %ptr1, i8* nocapture readonly %ptr2)
-define i32 @memcpy_volatile(i8* %ptr1, i8* %ptr2) {
- call void @llvm.memcpy(i8* %ptr1, i8* %ptr2, i32 8, i1 1)
- ret i32 4
-}
-
-; TEST 15 - positive, non-volatile intrinsic.
-
-; It is odd to add nocapture but a result of the llvm.memset nocapture.
-;
-; ATTRIBUTOR: Function Attrs: nosync
-; ATTRIBUTOR-NEXT: define i32 @memset_non_volatile(i8* nocapture writeonly %ptr1, i8 %val)
-define i32 @memset_non_volatile(i8* %ptr1, i8 %val) {
- call void @llvm.memset(i8* %ptr1, i8 %val, i32 8, i1 0)
- ret i32 4
-}
-
-; TEST 16 - negative, inline assembly.
-
-; ATTRIBUTOR: define i32 @inline_asm_test(i32 %x)
-define i32 @inline_asm_test(i32 %x) {
- call i32 asm "bswap $0", "=r,r"(i32 %x)
- ret i32 4
-}
-
-declare void @readnone_test() convergent readnone
-
-; ATTRIBUTOR: define void @convergent_readnone()
-; TEST 17 - negative. Convergent
-define void @convergent_readnone(){
- call void @readnone_test()
- ret void
-}
-
-; ATTRIBUTOR: Function Attrs: nounwind
-; ATTRIBUTOR-NEXT: declare void @llvm.x86.sse2.clflush(i8*)
-declare void @llvm.x86.sse2.clflush(i8*)
-@a = common global i32 0, align 4
-
-; TEST 18 - negative. Synchronizing intrinsic
-
-; ATTRIBUTOR: Function Attrs: nounwind
-; ATTRIBUTOR-NOT: nosync
-; ATTRIBUTOR-NEXT: define void @i_totally_sync()
-define void @i_totally_sync() {
- tail call void @llvm.x86.sse2.clflush(i8* bitcast (i32* @a to i8*))
- ret void
-}
-
-declare float @llvm.cos(float %val) readnone
-
-; TEST 19 - positive, readnone & non-convergent intrinsic.
-
-; ATTRIBUTOR: Function Attrs: nosync nounwind
-; ATTRIBUTOR-NEXT: define i32 @cos_test(float %x)
-define i32 @cos_test(float %x) {
- call float @llvm.cos(float %x)
- ret i32 4
-}
diff --git a/llvm/test/Transforms/FunctionAttrs/nounwind.ll b/llvm/test/Transforms/FunctionAttrs/nounwind.ll
index ed7576c970b..6d5e3a2ea5b 100644
--- a/llvm/test/Transforms/FunctionAttrs/nounwind.ll
+++ b/llvm/test/Transforms/FunctionAttrs/nounwind.ll
@@ -1,11 +1,8 @@
; RUN: opt < %s -functionattrs -S | FileCheck %s
-; RUN: opt < %s -attributor -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S | FileCheck %s --check-prefix=ATTRIBUTOR
; TEST 1
; CHECK: Function Attrs: norecurse nounwind readnone
; CHECK-NEXT: define i32 @foo1()
-; ATTRIBUTOR: Function Attrs: nofree nosync nounwind
-; ATTRIBUTOR-NEXT: define i32 @foo1()
define i32 @foo1() {
ret i32 1
}
@@ -13,8 +10,6 @@ define i32 @foo1() {
; TEST 2
; CHECK: Function Attrs: nounwind readnone
; CHECK-NEXT: define i32 @scc1_foo()
-; ATTRIBUTOR: Function Attrs: nofree noreturn nosync nounwind
-; ATTRIBUTOR-NEXT: define i32 @scc1_foo()
define i32 @scc1_foo() {
%1 = call i32 @scc1_bar()
ret i32 1
@@ -24,8 +19,6 @@ define i32 @scc1_foo() {
; TEST 3
; CHECK: Function Attrs: nounwind readnone
; CHECK-NEXT: define i32 @scc1_bar()
-; ATTRIBUTOR: Function Attrs: nofree noreturn nosync nounwind
-; ATTRIBUTOR-NEXT: define i32 @scc1_bar()
define i32 @scc1_bar() {
%1 = call i32 @scc1_foo()
ret i32 1
@@ -36,7 +29,6 @@ declare i32 @non_nounwind()
; TEST 4
; CHECK: define void @call_non_nounwind() {
-; ATTRIBUTOR: define void @call_non_nounwind() {
define void @call_non_nounwind(){
tail call i32 @non_nounwind()
ret void
@@ -51,7 +43,6 @@ define void @call_non_nounwind(){
; }
; CHECK: define i32 @maybe_throw(i1 zeroext %0)
-; ATTRIBUTOR: define i32 @maybe_throw(i1 zeroext %0)
define i32 @maybe_throw(i1 zeroext %0) {
br i1 %0, label %2, label %3
@@ -75,7 +66,6 @@ declare void @__cxa_rethrow()
; }
; CHECK: define i32 @catch_thing()
-; ATTRIBUTOR: define i32 @catch_thing()
define i32 @catch_thing() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) {
invoke void @__cxa_rethrow() #1
to label %1 unwind label %2
@@ -93,9 +83,6 @@ define i32 @catch_thing() personality i8* bitcast (i32 (...)* @__gxx_personality
}
define i32 @catch_thing_user() {
-; ATTRIBUTOR: define i32 @catch_thing_user
-; ATTRIBUTOR-NEXT: %catch_thing_call = call
-; ATTRIBUTOR-NEXT: ret i32 -1
%catch_thing_call = call i32 @catch_thing()
ret i32 %catch_thing_call
}
diff --git a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll b/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
deleted file mode 100644
index 72d062b7616..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll
+++ /dev/null
@@ -1,165 +0,0 @@
-; RUN: opt -functionattrs -enable-nonnull-arg-prop -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=6 -S < %s | FileCheck %s
-;
-; This is an evolved example to stress test SCC parameter attribute propagation.
-; The SCC in this test is made up of the following six function, three of which
-; are internal and three externally visible:
-;
-; static int *internal_ret0_nw(int *n0, int *w0);
-; static int *internal_ret1_rw(int *r0, int *w0);
-; static int *internal_ret1_rrw(int *r0, int *r1, int *w0);
-; int *external_ret2_nrw(int *n0, int *r0, int *w0);
-; int *external_sink_ret2_nrw(int *n0, int *r0, int *w0);
-; int *external_source_ret2_nrw(int *n0, int *r0, int *w0);
-;
-; The top four functions call each other while the "sink" function will not
-; call anything and the "source" function will not be called in this module.
-; The names of the functions define the returned parameter (X for "_retX_"),
-; as well as how the parameters are (transitively) used (n = readnone,
-; r = readonly, w = writeonly).
-;
-; What we should see is something along the lines of:
-; 1 - Number of functions marked as norecurse
-; 6 - Number of functions marked argmemonly
-; 6 - Number of functions marked as nounwind
-; 16 - Number of arguments marked nocapture
-; 4 - Number of arguments marked readnone
-; 6 - Number of arguments marked writeonly
-; 6 - Number of arguments marked readonly
-; 6 - Number of arguments marked returned
-;
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-; CHECK: Function Attrs: nofree nosync nounwind
-; CHECK-NEXT: define i32* @external_ret2_nrw(i32* nofree %n0, i32* nofree %r0, i32* nofree returned %w0)
-define i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
-entry:
- %call = call i32* @internal_ret0_nw(i32* %n0, i32* %w0)
- %call1 = call i32* @internal_ret1_rrw(i32* %r0, i32* %r0, i32* %w0)
- %call2 = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
- %call3 = call i32* @internal_ret1_rw(i32* %r0, i32* %w0)
- ret i32* %call3
-}
-
-; CHECK: Function Attrs: nofree nosync nounwind
-; CHECK-NEXT: define internal i32* @internal_ret0_nw(i32* nofree returned %n0, i32* nofree %w0)
-define internal i32* @internal_ret0_nw(i32* %n0, i32* %w0) {
-entry:
- %r0 = alloca i32, align 4
- %r1 = alloca i32, align 4
- %tobool = icmp ne i32* %n0, null
- br i1 %tobool, label %if.end, label %if.then
-
-if.then: ; preds = %entry
- br label %return
-
-if.end: ; preds = %entry
- store i32 3, i32* %r0, align 4
- store i32 5, i32* %r1, align 4
- store i32 1, i32* %w0, align 4
- %call = call i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0)
- %call1 = call i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
- %call2 = call i32* @external_ret2_nrw(i32* %n0, i32* %r1, i32* %w0)
- %call3 = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
- %call4 = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r1, i32* %w0)
- %call5 = call i32* @internal_ret0_nw(i32* %n0, i32* %w0)
- br label %return
-
-return: ; preds = %if.end, %if.then
- %retval.0 = phi i32* [ %call5, %if.end ], [ %n0, %if.then ]
- ret i32* %retval.0
-}
-
-; CHECK: Function Attrs: nofree nosync nounwind
-; CHECK-NEXT: define internal i32* @internal_ret1_rrw(i32* nofree nonnull align 4 dereferenceable(4) %r0, i32* nofree returned %r1, i32* nofree %w0)
-define internal i32* @internal_ret1_rrw(i32* %r0, i32* %r1, i32* %w0) {
-entry:
- %0 = load i32, i32* %r0, align 4
- %tobool = icmp ne i32 %0, 0
- br i1 %tobool, label %if.end, label %if.then
-
-if.then: ; preds = %entry
- br label %return
-
-if.end: ; preds = %entry
- %call = call i32* @internal_ret1_rw(i32* %r0, i32* %w0)
- %1 = load i32, i32* %r0, align 4
- %2 = load i32, i32* %r1, align 4
- %add = add nsw i32 %1, %2
- store i32 %add, i32* %w0, align 4
- %call1 = call i32* @internal_ret1_rw(i32* %r1, i32* %w0)
- %call2 = call i32* @internal_ret0_nw(i32* %r0, i32* %w0)
- %call3 = call i32* @internal_ret0_nw(i32* %w0, i32* %w0)
- %call4 = call i32* @external_ret2_nrw(i32* %r0, i32* %r1, i32* %w0)
- %call5 = call i32* @external_ret2_nrw(i32* %r1, i32* %r0, i32* %w0)
- %call6 = call i32* @external_sink_ret2_nrw(i32* %r0, i32* %r1, i32* %w0)
- %call7 = call i32* @external_sink_ret2_nrw(i32* %r1, i32* %r0, i32* %w0)
- %call8 = call i32* @internal_ret0_nw(i32* %r1, i32* %w0)
- br label %return
-
-return: ; preds = %if.end, %if.then
- %retval.0 = phi i32* [ %call8, %if.end ], [ %r1, %if.then ]
- ret i32* %retval.0
-}
-
-; CHECK: Function Attrs: nofree norecurse nosync nounwind
-; CHECK-NEXT: define i32* @external_sink_ret2_nrw(i32* nofree readnone %n0, i32* nocapture nofree readonly %r0, i32* nofree returned writeonly "no-capture-maybe-returned" %w0)
-define i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
-entry:
- %tobool = icmp ne i32* %n0, null
- br i1 %tobool, label %if.end, label %if.then
-
-if.then: ; preds = %entry
- br label %return
-
-if.end: ; preds = %entry
- %0 = load i32, i32* %r0, align 4
- store i32 %0, i32* %w0, align 4
- br label %return
-
-return: ; preds = %if.end, %if.then
- ret i32* %w0
-}
-
-; CHECK: Function Attrs: nofree nosync nounwind
-; CHECK-NEXT: define internal i32* @internal_ret1_rw(i32* nofree nonnull align 4 dereferenceable(4) %r0, i32* nofree returned %w0)
-define internal i32* @internal_ret1_rw(i32* %r0, i32* %w0) {
-entry:
- %0 = load i32, i32* %r0, align 4
- %tobool = icmp ne i32 %0, 0
- br i1 %tobool, label %if.end, label %if.then
-
-if.then: ; preds = %entry
- br label %return
-
-if.end: ; preds = %entry
- %call = call i32* @internal_ret1_rrw(i32* %r0, i32* %r0, i32* %w0)
- %1 = load i32, i32* %r0, align 4
- store i32 %1, i32* %w0, align 4
- %call1 = call i32* @internal_ret0_nw(i32* %r0, i32* %w0)
- %call2 = call i32* @internal_ret0_nw(i32* %w0, i32* %w0)
- %call3 = call i32* @external_sink_ret2_nrw(i32* %r0, i32* %r0, i32* %w0)
- %call4 = call i32* @external_ret2_nrw(i32* %r0, i32* %r0, i32* %w0)
- br label %return
-
-return: ; preds = %if.end, %if.then
- %retval.0 = phi i32* [ %call4, %if.end ], [ %w0, %if.then ]
- ret i32* %retval.0
-}
-
-; CHECK: Function Attrs: nofree nosync nounwind
-; CHECK-NEXT: define i32* @external_source_ret2_nrw(i32* nofree %n0, i32* nofree %r0, i32* nofree returned %w0)
-define i32* @external_source_ret2_nrw(i32* %n0, i32* %r0, i32* %w0) {
-entry:
- %call = call i32* @external_sink_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
- %call1 = call i32* @external_ret2_nrw(i32* %n0, i32* %r0, i32* %w0)
- ret i32* %call1
-}
-
-; Verify that we see only expected attribute sets, the above lines only check
-; for a subset relation.
-;
-; CHECK-NOT: attributes #
-; CHECK: attributes #{{.*}} = { nofree nosync nounwind }
-; CHECK: attributes #{{.*}} = { nofree norecurse nosync nounwind }
-; CHECK: attributes #{{.*}} = { nosync }
-; CHECK-NOT: attributes #
diff --git a/llvm/test/Transforms/FunctionAttrs/readattrs.ll b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
index dc1fbf652f9..b11b3edcebf 100644
--- a/llvm/test/Transforms/FunctionAttrs/readattrs.ll
+++ b/llvm/test/Transforms/FunctionAttrs/readattrs.ll
@@ -1,7 +1,5 @@
-; RUN: opt < %s -functionattrs -S | FileCheck %s --check-prefixes=CHECK,FNATTR
-; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs)' -S | FileCheck %s --check-prefixes=CHECK,FNATTR
-; RUN: opt < %s -attributor -attributor-disable=false -S -attributor-annotate-decl-cs | FileCheck %s --check-prefixes=CHECK,ATTRIBUTOR
-; RUN: opt < %s -aa-pipeline=basic-aa -passes='attributor' -attributor-disable=false -S -attributor-annotate-decl-cs | FileCheck %s --check-prefixes=CHECK,ATTRIBUTOR
+; RUN: opt < %s -functionattrs -S | FileCheck %s
+; RUN: opt < %s -aa-pipeline=basic-aa -passes='cgscc(function-attrs)' -S | FileCheck %s
@x = global i32 0
@@ -9,23 +7,20 @@ declare void @test1_1(i8* %x1_1, i8* readonly %y1_1, ...)
; NOTE: readonly for %y1_2 would be OK here but not for the similar situation in test13.
;
-; FNATTR: define void @test1_2(i8* %x1_2, i8* readonly %y1_2, i8* %z1_2)
-; ATTRIBUTOR: define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2)
+; CHECK: define void @test1_2(i8* %x1_2, i8* readonly %y1_2, i8* %z1_2)
define void @test1_2(i8* %x1_2, i8* %y1_2, i8* %z1_2) {
call void (i8*, i8*, ...) @test1_1(i8* %x1_2, i8* %y1_2, i8* %z1_2)
store i32 0, i32* @x
ret void
}
-; FNATTR: define i8* @test2(i8* readnone returned %p)
-; ATTRIBUTOR: define i8* @test2(i8* nofree readnone returned %p)
+; CHECK: define i8* @test2(i8* readnone returned %p)
define i8* @test2(i8* %p) {
store i32 0, i32* @x
ret i8* %p
}
-; FNATTR: define i1 @test3(i8* readnone %p, i8* readnone %q)
-; ATTRIBUTOR: define i1 @test3(i8* nofree readnone %p, i8* nofree readnone %q)
+; CHECK: define i1 @test3(i8* readnone %p, i8* readnone %q)
define i1 @test3(i8* %p, i8* %q) {
%A = icmp ult i8* %p, %q
ret i1 %A
@@ -39,8 +34,7 @@ define void @test4_2(i8* %p) {
ret void
}
-; FNATTR: define void @test5(i8** nocapture %p, i8* %q)
-; ATTRIBUTOR: define void @test5(i8** nocapture nofree nonnull writeonly dereferenceable(8) %p, i8* nofree writeonly %q)
+; CHECK: define void @test5(i8** nocapture %p, i8* %q)
; Missed optz'n: we could make %q readnone, but don't break test6!
define void @test5(i8** %p, i8* %q) {
store i8* %q, i8** %p
@@ -48,8 +42,7 @@ define void @test5(i8** %p, i8* %q) {
}
declare void @test6_1()
-; FNATTR: define void @test6_2(i8** nocapture %p, i8* %q)
-; ATTRIBUTOR: define void @test6_2(i8** nocapture nonnull writeonly dereferenceable(8) %p, i8* %q)
+; CHECK: define void @test6_2(i8** nocapture %p, i8* %q)
; This is not a missed optz'n.
define void @test6_2(i8** %p, i8* %q) {
store i8* %q, i8** %p
@@ -57,22 +50,19 @@ define void @test6_2(i8** %p, i8* %q) {
ret void
}
-; FNATTR: define void @test7_1(i32* inalloca nocapture %a)
-; ATTRIBUTOR: define void @test7_1(i32* inalloca nocapture nofree writeonly %a)
+; CHECK: define void @test7_1(i32* inalloca nocapture %a)
; inalloca parameters are always considered written
define void @test7_1(i32* inalloca %a) {
ret void
}
-; FNATTR: define i32* @test8_1(i32* readnone returned %p)
-; ATTRIBUTOR: define i32* @test8_1(i32* nofree readnone returned %p)
+; CHECK: define i32* @test8_1(i32* readnone returned %p)
define i32* @test8_1(i32* %p) {
entry:
ret i32* %p
}
-; FNATTR: define void @test8_2(i32* %p)
-; ATTRIBUTOR: define void @test8_2(i32* nocapture nofree writeonly %p)
+; CHECK: define void @test8_2(i32* %p)
define void @test8_2(i32* %p) {
entry:
%call = call i32* @test8_1(i32* %p)
@@ -136,11 +126,9 @@ declare void @escape_readonly_ptr(i8** %addr, i8* readonly %ptr)
;
; FIXME: This test currently exposes a bug in functionattrs!
;
-; FNATTR: define void @unsound_readnone(i8* nocapture readnone %ignored, i8* readnone %escaped_then_written)
-; FNATTR: define void @unsound_readonly(i8* nocapture readnone %ignored, i8* readonly %escaped_then_written)
+; CHECK: define void @unsound_readnone(i8* nocapture readnone %ignored, i8* readnone %escaped_then_written)
+; CHECK: define void @unsound_readonly(i8* nocapture readnone %ignored, i8* readonly %escaped_then_written)
;
-; ATTRIBUTOR: define void @unsound_readnone(i8* nocapture nofree readnone %ignored, i8* %escaped_then_written)
-; ATTRIBUTOR: define void @unsound_readonly(i8* nocapture nofree readnone %ignored, i8* %escaped_then_written)
define void @unsound_readnone(i8* %ignored, i8* %escaped_then_written) {
%addr = alloca i8*
call void @escape_readnone_ptr(i8** %addr, i8* %escaped_then_written)
diff --git a/llvm/test/Transforms/FunctionAttrs/value-simplify.ll b/llvm/test/Transforms/FunctionAttrs/value-simplify.ll
deleted file mode 100644
index 4e765cc233f..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/value-simplify.ll
+++ /dev/null
@@ -1,276 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
-; RUN: opt -attributor --attributor-disable=false -attributor-annotate-decl-cs -S < %s | FileCheck %s
-; TODO: Add max-iteration check
-
-; Disable update test checks and enable it where required.
-; UTC_ARGS: --turn off
-
-; ModuleID = 'value-simplify.ll'
-source_filename = "value-simplify.ll"
-target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
-declare void @f(i32)
-
-; Test1: Replace argument with constant
-define internal void @test1(i32 %a) {
-; CHECK: tail call void @f(i32 1)
- tail call void @f(i32 %a)
- ret void
-}
-
-define void @test1_helper() {
- tail call void @test1(i32 1)
- ret void
-}
-
-; TEST 2 : Simplify return value
-define i32 @return0() {
- ret i32 0
-}
-
-define i32 @return1() {
- ret i32 1
-}
-
-; CHECK: define i32 @test2_1(i1 %c)
-define i32 @test2_1(i1 %c) {
- br i1 %c, label %if.true, label %if.false
-if.true:
- %call = tail call i32 @return0()
-
-; FIXME: %ret0 should be replaced with i32 1.
-; CHECK: %ret0 = add i32 0, 1
- %ret0 = add i32 %call, 1
- br label %end
-if.false:
- %ret1 = tail call i32 @return1()
- br label %end
-end:
-
-; FIXME: %ret should be replaced with i32 1.
-; CHECK: %ret = phi i32 [ %ret0, %if.true ], [ 1, %if.false ]
- %ret = phi i32 [ %ret0, %if.true ], [ %ret1, %if.false ]
-
-; FIXME: ret i32 1
-; CHECK: ret i32 %ret
- ret i32 %ret
-}
-
-
-
-; CHECK: define i32 @test2_2(i1 %c)
-define i32 @test2_2(i1 %c) {
-; FIXME: %ret should be replaced with i32 1.
- %ret = tail call i32 @test2_1(i1 %c)
-; FIXME: ret i32 1
-; CHECK: ret i32 %ret
- ret i32 %ret
-}
-
-declare void @use(i32)
-; CHECK: define void @test3(i1 %c)
-define void @test3(i1 %c) {
- br i1 %c, label %if.true, label %if.false
-if.true:
- br label %end
-if.false:
- %ret1 = tail call i32 @return1()
- br label %end
-end:
-
-; CHECK: %r = phi i32 [ 1, %if.true ], [ 1, %if.false ]
- %r = phi i32 [ 1, %if.true ], [ %ret1, %if.false ]
-
-; CHECK: tail call void @use(i32 1)
- tail call void @use(i32 %r)
- ret void
-}
-
-define void @test-select-phi(i1 %c) {
- %select-same = select i1 %c, i32 1, i32 1
- ; CHECK: tail call void @use(i32 1)
- tail call void @use(i32 %select-same)
-
- %select-not-same = select i1 %c, i32 1, i32 0
- ; CHECK: tail call void @use(i32 %select-not-same)
- tail call void @use(i32 %select-not-same)
- br i1 %c, label %if-true, label %if-false
-if-true:
- br label %end
-if-false:
- br label %end
-end:
- %phi-same = phi i32 [ 1, %if-true ], [ 1, %if-false ]
- %phi-not-same = phi i32 [ 0, %if-true ], [ 1, %if-false ]
- %phi-same-prop = phi i32 [ 1, %if-true ], [ %select-same, %if-false ]
- %phi-same-undef = phi i32 [ 1, %if-true ], [ undef, %if-false ]
- %select-not-same-undef = select i1 %c, i32 %phi-not-same, i32 undef
-
-
- ; CHECK: tail call void @use(i32 1)
- tail call void @use(i32 %phi-same)
-
- ; CHECK: tail call void @use(i32 %phi-not-same)
- tail call void @use(i32 %phi-not-same)
-
- ; CHECK: tail call void @use(i32 1)
- tail call void @use(i32 %phi-same-prop)
-
- ; CHECK: tail call void @use(i32 1)
- tail call void @use(i32 %phi-same-undef)
-
- ; CHECK: tail call void @use(i32 %select-not-same-undef)
- tail call void @use(i32 %select-not-same-undef)
-
- ret void
-
-}
-
-define i32 @ipccp1(i32 %a) {
-; CHECK-LABEL: define {{[^@]+}}@ipccp1
-; CHECK-SAME: (i32 returned [[A:%.*]]) #0
-; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]]
-; CHECK: t:
-; CHECK-NEXT: ret i32 [[A:%.*]]
-; CHECK: f:
-; CHECK-NEXT: unreachable
-;
- br i1 true, label %t, label %f
-t:
- ret i32 %a
-f:
- %r = call i32 @ipccp1(i32 5)
- ret i32 %r
-}
-
-define internal i1 @ipccp2i(i1 %a) {
-; CHECK-LABEL: define {{[^@]+}}@ipccp2i
-; CHECK-SAME: (i1 returned [[A:%.*]]) #0
-; CHECK-NEXT: br i1 true, label [[T:%.*]], label [[F:%.*]]
-; CHECK: t:
-; CHECK-NEXT: ret i1 true
-; CHECK: f:
-; CHECK-NEXT: unreachable
-;
- br i1 %a, label %t, label %f
-t:
- ret i1 %a
-f:
- %r = call i1 @ipccp2i(i1 false)
- ret i1 %r
-}
-
-define i1 @ipccp2() {
-; CHECK-LABEL: define {{[^@]+}}@ipccp2() #1
-; CHECK-NEXT: [[R:%.*]] = call i1 @ipccp2i(i1 true) #0
-; CHECK-NEXT: ret i1 [[R]]
-;
- %r = call i1 @ipccp2i(i1 true)
- ret i1 %r
-}
-
-define internal i32 @ipccp3i(i32 %a) {
-; CHECK-LABEL: define {{[^@]+}}@ipccp3i
-; CHECK-SAME: (i32 [[A:%.*]]) #1
-; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[A:%.*]], 7
-; CHECK-NEXT: br i1 [[C]], label [[T:%.*]], label [[F:%.*]]
-; CHECK: t:
-; CHECK-NEXT: ret i32 [[A]]
-; CHECK: f:
-; CHECK-NEXT: [[R:%.*]] = call i32 @ipccp3i(i32 5) #1
-; CHECK-NEXT: ret i32 [[R]]
-;
- %c = icmp eq i32 %a, 7
- br i1 %c, label %t, label %f
-t:
- ret i32 %a
-f:
- %r = call i32 @ipccp3i(i32 5)
- ret i32 %r
-}
-
-define i32 @ipccp3() {
-; CHECK-LABEL: define {{[^@]+}}@ipccp3() #1
-; CHECK-NEXT: [[R:%.*]] = call i32 @ipccp3i(i32 7) #1
-; CHECK-NEXT: ret i32 [[R]]
-;
- %r = call i32 @ipccp3i(i32 7)
- ret i32 %r
-}
-
-; UTC_ARGS: --turn on
-
-; Do not touch complicated arguments (for now)
-%struct.X = type { i8* }
-define internal i32* @test_inalloca(i32* inalloca %a) {
-; CHECK-LABEL: define {{[^@]+}}@test_inalloca
-; CHECK-SAME: (i32* inalloca noalias nofree returned writeonly [[A:%.*]])
-; CHECK-NEXT: ret i32* [[A]]
-;
- ret i32* %a
-}
-define i32* @complicated_args_inalloca() {
-; CHECK-LABEL: define {{[^@]+}}@complicated_args_inalloca()
-; CHECK-NEXT: [[CALL:%.*]] = call i32* @test_inalloca(i32* noalias nofree null)
-; CHECK-NEXT: ret i32* [[CALL]]
-;
- %call = call i32* @test_inalloca(i32* null)
- ret i32* %call
-}
-
-define internal void @test_sret(%struct.X* sret %a, %struct.X** %b) {
-; CHECK-LABEL: define {{[^@]+}}@test_sret
-; CHECK-SAME: (%struct.X* nofree sret writeonly [[A:%.*]], %struct.X** nocapture nofree nonnull writeonly dereferenceable(8) [[B:%.*]])
-; CHECK-NEXT: store %struct.X* [[A]], %struct.X** [[B]]
-; CHECK-NEXT: ret void
-;
- store %struct.X* %a, %struct.X** %b
- ret void
-}
-define void @complicated_args_sret(%struct.X** %b) {
-; CHECK-LABEL: define {{[^@]+}}@complicated_args_sret
-; CHECK-SAME: (%struct.X** nocapture nofree writeonly [[B:%.*]])
-; CHECK-NEXT: call void @test_sret(%struct.X* nofree null, %struct.X** nocapture nofree writeonly [[B]])
-; CHECK-NEXT: ret void
-;
- call void @test_sret(%struct.X* null, %struct.X** %b)
- ret void
-}
-
-define internal %struct.X* @test_nest(%struct.X* nest %a) {
-; CHECK-LABEL: define {{[^@]+}}@test_nest
-; CHECK-SAME: (%struct.X* nest noalias nofree readnone returned [[A:%.*]])
-; CHECK-NEXT: ret %struct.X* [[A]]
-;
- ret %struct.X* %a
-}
-define %struct.X* @complicated_args_nest() {
-; CHECK-LABEL: define {{[^@]+}}@complicated_args_nest()
-; CHECK-NEXT: [[CALL:%.*]] = call %struct.X* @test_nest(%struct.X* noalias nofree null)
-; CHECK-NEXT: ret %struct.X* [[CALL]]
-;
- %call = call %struct.X* @test_nest(%struct.X* null)
- ret %struct.X* %call
-}
-
-@S = external global %struct.X
-define internal void @test_byval(%struct.X* byval %a) {
-; CHECK-LABEL: define {{[^@]+}}@test_byval
-; CHECK-SAME: (%struct.X* nocapture nofree nonnull writeonly byval align 8 dereferenceable(8) [[A:%.*]])
-; CHECK-NEXT: [[G0:%.*]] = getelementptr [[STRUCT_X:%.*]], %struct.X* [[A]], i32 0, i32 0
-; CHECK-NEXT: store i8* null, i8** [[G0]], align 8
-; CHECK-NEXT: ret void
-;
- %g0 = getelementptr %struct.X, %struct.X* %a, i32 0, i32 0
- store i8* null, i8** %g0
- ret void
-}
-define void @complicated_args_byval() {
-; CHECK-LABEL: define {{[^@]+}}@complicated_args_byval()
-; CHECK-NEXT: call void @test_byval(%struct.X* nofree nonnull align 8 dereferenceable(8) @S)
-; CHECK-NEXT: ret void
-;
- call void @test_byval(%struct.X* @S)
- ret void
-}
-
-; UTC_ARGS: --turn off
diff --git a/llvm/test/Transforms/FunctionAttrs/willreturn.ll b/llvm/test/Transforms/FunctionAttrs/willreturn.ll
deleted file mode 100644
index 8f7e46837c1..00000000000
--- a/llvm/test/Transforms/FunctionAttrs/willreturn.ll
+++ /dev/null
@@ -1,553 +0,0 @@
-; RUN: opt -functionattrs -S < %s | FileCheck %s --check-prefix=FNATTR
-; RUN: opt -passes=attributor --attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=2 -S < %s | FileCheck %s --check-prefix=ATTRIBUTOR
-
-
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-
-; Test cases specifically designed for the "willreturn" function attribute.
-; We use FIXME's to indicate problems and missing attributes.
-
-
-; TEST 1 (positive case)
-; FNATTR: Function Attrs: noinline norecurse nounwind readnone uwtable
-; FNATTR-NEXT: define void @only_return()
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
-; ATTRIBUTOR-NEXT: define void @only_return()
-define void @only_return() #0 {
- ret void
-}
-
-
-; TEST 2 (positive & negative case)
-; 2.1 (positive case)
-; recursive function which will halt
-; int fib(int n){
-; return n<=1? n : fib(n-1) + fib(n-2);
-; }
-
-; FNATTR: Function Attrs: noinline nounwind readnone uwtable
-; FNATTR-NEXT: define i32 @fib(i32 %0)
-; FIXME: missing willreturn
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define i32 @fib(i32 %0) local_unnamed_addr
-define i32 @fib(i32 %0) local_unnamed_addr #0 {
- %2 = icmp slt i32 %0, 2
- br i1 %2, label %9, label %3
-
-; <label>:3: ; preds = %1
- %4 = add nsw i32 %0, -1
- %5 = tail call i32 @fib(i32 %4)
- %6 = add nsw i32 %0, -2
- %7 = tail call i32 @fib(i32 %6)
- %8 = add nsw i32 %7, %5
- ret i32 %8
-
-; <label>:9: ; preds = %1
- ret i32 %0
-}
-
-; 2.2 (negative case)
-; recursive function which doesn't stop for some input.
-; int fact_maybe_not_halt(int n) {
-; if (n==0) {
-; return 1;
-; }
-; return fact_maybe_not_halt( n > 0 ? n-1 : n) * n;
-; }
-; fact_maybe_not(-1) doesn't stop.
-
-; FNATTR: Function Attrs: noinline norecurse nounwind readnone uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr
-define i32 @fact_maybe_not_halt(i32 %0) local_unnamed_addr #0 {
- %2 = icmp eq i32 %0, 0
- br i1 %2, label %11, label %3
-
-; <label>:3: ; preds = %1, %3
- %4 = phi i32 [ %8, %3 ], [ %0, %1 ]
- %5 = phi i32 [ %9, %3 ], [ 1, %1 ]
- %6 = icmp sgt i32 %4, 0
- %7 = sext i1 %6 to i32
- %8 = add nsw i32 %4, %7
- %9 = mul nsw i32 %4, %5
- %10 = icmp eq i32 %8, 0
- br i1 %10, label %11, label %3
-
-; <label>:11: ; preds = %3, %1
- %12 = phi i32 [ 1, %1 ], [ %9, %3 ]
- ret i32 %12
-}
-
-
-; TEST 3 (positive case)
-; loop
-; int fact_loop(int n ){
-; int ans = 1;
-; for(int i = 1;i<=n;i++){
-; ans *= i;
-; }
-; return ans;
-; }
-
-; FIXME: missing willreturn
-; FNATTR: Function Attrs: noinline norecurse nounwind readnone uwtable
-; FNATTR-NEXT: define i32 @fact_loop(i32 %0)
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define i32 @fact_loop(i32 %0) local_unnamed_addr
-define i32 @fact_loop(i32 %0) local_unnamed_addr #0 {
- %2 = icmp slt i32 %0, 1
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %5, %1
- %4 = phi i32 [ 1, %1 ], [ %8, %5 ]
- ret i32 %4
-
-; <label>:5: ; preds = %1, %5
- %6 = phi i32 [ %9, %5 ], [ 1, %1 ]
- %7 = phi i32 [ %8, %5 ], [ 1, %1 ]
- %8 = mul nsw i32 %6, %7
- %9 = add nuw nsw i32 %6, 1
- %10 = icmp eq i32 %6, %0
- br i1 %10, label %3, label %5
-}
-
-; TEST 4 (negative case)
-; mutual recursion
-; void mutual_recursion1(){
-; mutual_recursion2();
-; }
-; void mutual_recursion2(){
-; mutual_recursion1();
-; }
-
-; FNATTR: Function Attrs: noinline nounwind readnone uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @mutual_recursion1(i1 %c)
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @mutual_recursion1(i1 %c)
-define void @mutual_recursion1(i1 %c) #0 {
- br i1 %c, label %rec, label %end
-rec:
- call void @mutual_recursion2(i1 %c)
- br label %end
-end:
- ret void
-}
-
-
-; FNATTR: Function Attrs: noinline nounwind readnone uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @mutual_recursion2(i1 %c)
-; ATTRIBUTOR: Function Attrs: nofree noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @mutual_recursion2(i1 %c)
-define void @mutual_recursion2(i1 %c) #0 {
- call void @mutual_recursion1(i1 %c)
- ret void
-}
-
-
-; TEST 5 (negative case)
-; call exit/abort (has noreturn attribute)
-; FNATTR: Function Attrs: noreturn
-; FNATTR-NEXT: declare void @exit(i32) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: noreturn
-; ATTRIBUTOR-NEXT: declare void @exit(i32) local_unnamed_add
-declare void @exit(i32 %0) local_unnamed_addr noreturn
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @only_exit()
-; ATTRIBUTOR: Function Attrs: noinline noreturn nounwind uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @only_exit() local_unnamed_addr
-define void @only_exit() local_unnamed_addr #0 {
- tail call void @exit(i32 0)
- unreachable
-}
-
-; conditional exit
-; void conditional_exit(int cond, int *p){
-; if(cond){
-; exit(0);
-; }
-; if(*p){
-; exit(1);
-; }
-; return;
-; }
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @conditional_exit(i32 %0, i32* nocapture readonly %1) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @conditional_exit(i32 %0, i32* nocapture readonly %1) local_unnamed_addr
-define void @conditional_exit(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 {
- %3 = icmp eq i32 %0, 0
- br i1 %3, label %5, label %4
-
-; <label>:4: ; preds = %2
- tail call void @exit(i32 0)
- unreachable
-
-; <label>:5: ; preds = %2
- %6 = load i32, i32* %1, align 4
- %7 = icmp eq i32 %6, 0
- br i1 %7, label %9, label %8
-
-; <label>:8: ; preds = %5
- tail call void @exit(i32 1)
- unreachable
-
-; <label>:9: ; preds = %5
- ret void
-}
-
-; TEST 6 (positive case)
-; Call intrinsic function
-; FIXME: missing willreturn
-; FNATTRS: Function Attrs: noinline readnone speculatable
-; FNATTRS-NEXT: declare float @llvm.floor.f32(float %0)
-; ATTRIBUTOR: Function Attrs: nounwind readnone speculatable
-; ATTRIBUTOR-NEXT: declare float @llvm.floor.f32(float)
-declare float @llvm.floor.f32(float)
-
-; FNATTRS: Function Attrs: noinline nounwind readnone uwtable
-; FNATTRS-NEXT: define void @call_floor(float %a)
-; FIXME: missing willreturn
-; ATTRIBUTOR: Function Attrs: noinline nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define void @call_floor(float %a)
-define void @call_floor(float %a) #0 {
- tail call float @llvm.floor.f32(float %a)
- ret void
-}
-
-
-; TEST 7 (negative case)
-; Call function declaration without willreturn
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: declare void @maybe_noreturn()
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: declare void @maybe_noreturn()
-declare void @maybe_noreturn() #0
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @call_maybe_noreturn()
-; ATTRIBUTOR: Function Attrs: noinline nounwind uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @call_maybe_noreturn()
-define void @call_maybe_noreturn() #0 {
- tail call void @maybe_noreturn()
- ret void
-}
-
-
-; TEST 8 (positive case)
-; Check propagation.
-
-; FNATTR: Function Attrs: norecurse willreturn
-; FNATTR-NEXT: declare void @will_return()
-; ATTRIBUTOR: Function Attrs: norecurse willreturn
-; ATTRIBUTOR-NEXT: declare void @will_return()
-declare void @will_return() willreturn norecurse
-
-; FNATTR: Function Attrs: noinline norecurse nounwind uwtable
-; FNATTR-NEXT: define void @f1()
-; ATTRIBUTOR: Function Attrs: noinline norecurse nounwind uwtable willreturn
-; ATTRIBUTOR-NEXT: define void @f1()
-define void @f1() #0 {
- tail call void @will_return()
- ret void
-}
-
-; FNATTR: Function Attrs: noinline norecurse nounwind uwtable
-; FNATTR-NEXT: define void @f2()
-; ATTRIBUTOR: Function Attrs: noinline norecurse nounwind uwtable willreturn
-; ATTRIBUTOR-NEXT: define void @f2()
-define void @f2() #0 {
- tail call void @f1()
- ret void
-}
-
-
-; TEST 9 (negative case)
-; call willreturn function in endless loop.
-
-; FNATTR: Function Attrs: noinline norecurse nounwind uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @call_will_return_but_has_loop()
-; ATTRIBUTOR: Function Attrs: noinline norecurse noreturn nounwind uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @call_will_return_but_has_loop()
-define void @call_will_return_but_has_loop() #0 {
- br label %label1
-label1:
- tail call void @will_return()
- br label %label2
-label2:
- br label %label1
-}
-
-
-; TEST 10 (positive case)
-; invoke a function with willreturn
-
-; FNATTR: Function Attrs: noinline uwtable willreturn
-; FNATTR-NEXT: declare i1 @maybe_raise_exception()
-; ATTRIBUTOR: Function Attrs: noinline uwtable willreturn
-; ATTRIBUTOR-NEXT: declare i1 @maybe_raise_exception()
-declare i1 @maybe_raise_exception() #1 willreturn
-
-; FNATTR: Function Attrs: nounwind
-; FNATTR-NEXT: define void @invoke_test()
-; ATTRIBUTOR: Function Attrs: nounwind willreturn
-; ATTRIBUTOR-NEXT: define void @invoke_test()
-define void @invoke_test() personality i32 (...)* @__gxx_personality_v0 {
- invoke i1 @maybe_raise_exception()
- to label %N unwind label %F
- N:
- ret void
- F:
- %val = landingpad { i8*, i32 }
- catch i8* null
- ret void
-}
-
-declare i32 @__gxx_personality_v0(...)
-
-
-; TEST 11 (positive case)
-; counstant trip count
-; int loop_constant_trip_count(int*p){
-; int ans = 0;
-; for(int i = 0;i<10;i++){
-; ans += p[i];
-; }
-; return ans;
-; }
-
-; FIXME: missing willreturn
-; FNATTR: Function Attrs: noinline norecurse nounwind readonly uwtable
-; FNATTR-NEXT: define i32 @loop_constant_trip_count(i32* nocapture readonly %0)
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse nosync nounwind readonly uwtable
-; ATTRIBUTOR-NEXT: define i32 @loop_constant_trip_count(i32* nocapture nofree readonly %0)
-define i32 @loop_constant_trip_count(i32* nocapture readonly %0) #0 {
- br label %3
-
-; <label>:2: ; preds = %3
- ret i32 %8
-
-; <label>:3: ; preds = %3, %1
- %4 = phi i64 [ 0, %1 ], [ %9, %3 ]
- %5 = phi i32 [ 0, %1 ], [ %8, %3 ]
- %6 = getelementptr inbounds i32, i32* %0, i64 %4
- %7 = load i32, i32* %6, align 4
- %8 = add nsw i32 %7, %5
- %9 = add nuw nsw i64 %4, 1
- %10 = icmp eq i64 %9, 10
- br i1 %10, label %2, label %3
-}
-
-
-; TEST 12 (negative case)
-; unbounded trip count
-
-; int loop_trip_count_unbound(unsigned s,unsigned e, int *p, int offset){
-; int ans = 0;
-; for(unsigned i = s;i != e;i+=offset){
-; ans += p[i];
-; }
-; return ans;
-; }
-; FNATTR: Function Attrs: noinline norecurse nounwind readonly uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture readonly %2, i32 %3) local_unnamed_addr
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse nosync nounwind readonly uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture nofree readonly %2, i32 %3) local_unnamed_addr
-define i32 @loop_trip_count_unbound(i32 %0, i32 %1, i32* nocapture readonly %2, i32 %3) local_unnamed_addr #0 {
- %5 = icmp eq i32 %0, %1
- br i1 %5, label %6, label %8
-
-; <label>:6: ; preds = %8, %4
- %7 = phi i32 [ 0, %4 ], [ %14, %8 ]
- ret i32 %7
-
-; <label>:8: ; preds = %4, %8
- %9 = phi i32 [ %15, %8 ], [ %0, %4 ]
- %10 = phi i32 [ %14, %8 ], [ 0, %4 ]
- %11 = zext i32 %9 to i64
- %12 = getelementptr inbounds i32, i32* %2, i64 %11
- %13 = load i32, i32* %12, align 4
- %14 = add nsw i32 %13, %10
- %15 = add i32 %9, %3
- %16 = icmp eq i32 %15, %1
- br i1 %16, label %6, label %8
-}
-
-
-; TEST 13 (positive case)
-; Function Attrs: norecurse nounwind readonly uwtable
-; int loop_trip_dec(int n, int *p){
-; int ans = 0;
-; for(;n >= 0;n--){
-; ans += p[n];
-; }
-; return ans;
-; }
-
-
-; FIXME: missing willreturn
-; FNATTR: Function Attrs: noinline norecurse nounwind readonly uwtable
-; FNATTR-NEXT: define i32 @loop_trip_dec(i32 %0, i32* nocapture readonly %1)
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse nosync nounwind readonly uwtable
-; ATTRIBUTOR-NEXT: define i32 @loop_trip_dec(i32 %0, i32* nocapture nofree readonly %1) local_unnamed_addr
-
-define i32 @loop_trip_dec(i32 %0, i32* nocapture readonly %1) local_unnamed_addr #0 {
- %3 = icmp sgt i32 %0, -1
- br i1 %3, label %4, label %14
-
-; <label>:4: ; preds = %2
- %5 = sext i32 %0 to i64
- br label %6
-
-; <label>:6: ; preds = %4, %6
- %7 = phi i64 [ %5, %4 ], [ %12, %6 ]
- %8 = phi i32 [ 0, %4 ], [ %11, %6 ]
- %9 = getelementptr inbounds i32, i32* %1, i64 %7
- %10 = load i32, i32* %9, align 4
- %11 = add nsw i32 %10, %8
- %12 = add nsw i64 %7, -1
- %13 = icmp sgt i64 %7, 0
- br i1 %13, label %6, label %14
-
-; <label>:14: ; preds = %6, %2
- %15 = phi i32 [ 0, %2 ], [ %11, %6 ]
- ret i32 %15
-}
-
-; TEST 14 (positive case)
-; multiple return
-
-; FNATTR: Function Attrs: noinline norecurse nounwind readnone uwtable
-; FNATTR-NEXT: define i32 @multiple_return(i32 %a)
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable willreturn
-; ATTRIBUTOR-NEXT: define i32 @multiple_return(i32 %a)
-define i32 @multiple_return(i32 %a) #0 {
- %b = icmp eq i32 %a, 0
- br i1 %b, label %t, label %f
-
-t:
- ret i32 1
-f:
- ret i32 0
-}
-
-; TEST 15 (positive & negative case)
-; unreachable exit
-
-; 15.1 (positive case)
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NEXT: define void @unreachable_exit_positive1()
-; ATTRIBUTOR: Function Attrs: noinline norecurse nounwind uwtable willreturn
-; ATTRIBUTOR-NEXT: define void @unreachable_exit_positive1()
-define void @unreachable_exit_positive1() #0 {
- tail call void @will_return()
- ret void
-
-unreachable_label:
- tail call void @exit(i32 0)
- unreachable
-}
-
-; FIXME: missing willreturn
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NEXT: define i32 @unreachable_exit_positive2(i32 %0)
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse nosync nounwind readnone uwtable
-; ATTRIBUTOR-NEXT: define i32 @unreachable_exit_positive2(i32 %0)
-define i32 @unreachable_exit_positive2(i32) local_unnamed_addr #0 {
- %2 = icmp slt i32 %0, 1
- br i1 %2, label %3, label %5
-
-; <label>:3: ; preds = %5, %1
- %4 = phi i32 [ 1, %1 ], [ %8, %5 ]
- ret i32 %4
-
-; <label>:5: ; preds = %1, %5
- %6 = phi i32 [ %9, %5 ], [ 1, %1 ]
- %7 = phi i32 [ %8, %5 ], [ 1, %1 ]
- %8 = mul nsw i32 %6, %7
- %9 = add nuw nsw i32 %6, 1
- %10 = icmp eq i32 %6, %0
- br i1 %10, label %3, label %5
-
-unreachable_label:
- tail call void @exit(i32 0)
- unreachable
-}
-
-
-;15.2
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @unreachable_exit_negative1()
-; ATTRIBUTOR: Function Attrs: noinline noreturn nounwind uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @unreachable_exit_negative1()
-define void @unreachable_exit_negative1() #0 {
- tail call void @exit(i32 0)
- ret void
-
-unreachable_label:
- tail call void @exit(i32 0)
- unreachable
-}
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @unreachable_exit_negative2()
-; ATTRIBUTOR: Function Attrs: nofree noinline norecurse noreturn nosync nounwind readnone uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @unreachable_exit_negative2()
-define void @unreachable_exit_negative2() #0 {
-
- br label %L1
-L1:
- br label %L2
-L2:
- br label %L1
-
-unreachable_label:
- tail call void @exit(i32 0)
- unreachable
-}
-
-; FNATTR: Function Attrs: noreturn nounwind
-; FNATTR-NEXT: declare void @llvm.eh.sjlj.longjmp(i8*)
-; ATTRIBUTOR: Function Attrs: noreturn nounwind
-; ATTRIBUTOR-NEXT: declare void @llvm.eh.sjlj.longjmp(i8*)
-declare void @llvm.eh.sjlj.longjmp(i8*)
-
-; FNATTR: Function Attrs: noinline nounwind uwtable
-; FNATTR-NOT: willreturn
-; FNATTR-NEXT: define void @call_longjmp(i8* nocapture readnone %0) local_unnamed_addr #3 {
-; ATTRIBUTOR: Function Attrs: noinline noreturn nounwind uwtable
-; ATTRIBUTOR-NOT: willreturn
-; ATTRIBUTOR-NEXT: define void @call_longjmp(i8* nocapture readnone %0) local_unnamed_addr
-define void @call_longjmp(i8* nocapture readnone %0) local_unnamed_addr #0 {
- tail call void @llvm.eh.sjlj.longjmp(i8* %0)
- ret void
-}
-
-
-attributes #0 = { nounwind uwtable noinline }
-attributes #1 = { uwtable noinline }
OpenPOWER on IntegriCloud