|
| 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals |
| 2 | +; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT |
| 3 | +; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC |
| 4 | +; |
| 5 | +; #include <pthread.h> |
| 6 | +; |
| 7 | +; ptr GlobalVPtr; |
| 8 | +; |
| 9 | +; static ptr foo(ptr arg) { return arg; } |
| 10 | +; static ptr bar(ptr arg) { return arg; } |
| 11 | +; |
| 12 | +; int main() { |
| 13 | +; pthread_t thread; |
| 14 | +; pthread_create(&thread, NULL, foo, NULL); |
| 15 | +; pthread_create(&thread, NULL, bar, &GlobalVPtr); |
| 16 | +; return 0; |
| 17 | +; } |
| 18 | +; |
| 19 | +; Verify the constant values NULL and &GlobalVPtr are propagated into foo and |
| 20 | +; bar, respectively. |
| 21 | +; |
| 22 | +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-z0:1-z2:neg1-z3:neg1-z5:neg1-S128" |
| 23 | + |
| 24 | +%union.pthread_attr_t = type { i64, [48 x i8] } |
| 25 | + |
| 26 | +@GlobalVPtr = common dso_local global ptr null, align 8 |
| 27 | + |
| 28 | +; FIXME: nocapture & noalias for @GlobalVPtr in %call1 |
| 29 | +; FIXME: nocapture & noalias for %alloc2 in %call3 |
| 30 | + |
| 31 | +;. |
| 32 | +; CHECK: @GlobalVPtr = common dso_local global ptr null, align 8 |
| 33 | +;. |
| 34 | +define dso_local i32 @main() { |
| 35 | +; TUNIT-LABEL: define {{[^@]+}}@main() { |
| 36 | +; TUNIT-NEXT: entry: |
| 37 | +; TUNIT-NEXT: [[ALLOC11:%.*]] = alloca i8, i32 0, align 8 |
| 38 | +; TUNIT-NEXT: [[ALLOC22:%.*]] = alloca i8, i32 0, align 8 |
| 39 | +; TUNIT-NEXT: [[THREAD:%.*]] = alloca i64, align 8 |
| 40 | +; TUNIT-NEXT: [[CALL:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @foo, ptr nofree readnone align 4294967296 undef) |
| 41 | +; TUNIT-NEXT: [[CALL1:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @bar, ptr noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) undef) |
| 42 | +; TUNIT-NEXT: [[CALL2:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @baz, ptr noalias nocapture nofree noundef nonnull readnone align 8 dereferenceable(1) [[ALLOC11]]) |
| 43 | +; TUNIT-NEXT: [[CALL3:%.*]] = call i32 @pthread_create(ptr noundef nonnull align 8 dereferenceable(8) [[THREAD]], ptr noundef align 4294967296 null, ptr noundef nonnull @buz, ptr noalias nofree noundef nonnull readnone align 8 dereferenceable(1) "no-capture-maybe-returned" [[ALLOC22]]) |
| 44 | +; TUNIT-NEXT: ret i32 0 |
| 45 | +; |
| 46 | +; CGSCC-LABEL: define {{[^@]+}}@main() { |
| 47 | +; CGSCC-NEXT: entry: |
| 48 | +; CGSCC-NEXT: [[ALLOC1:%.*]] = alloca i8, align 8 |
| 49 | +; CGSCC-NEXT: [[ALLOC2:%.*]] = alloca i8, align 8 |
| 50 | +; CGSCC-NEXT: [[THREAD:%.*]] = alloca i64, align 8 |
| 51 | +; CGSCC-NEXT: unreachable |
| 52 | +; |
| 53 | +entry: |
| 54 | + %alloc1 = alloca i8, align 8 |
| 55 | + %alloc2 = alloca i8, align 8 |
| 56 | + %thread = alloca i64, align 8 |
| 57 | + %call = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @foo, ptr null) |
| 58 | + %call1 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @bar, ptr @GlobalVPtr) |
| 59 | + %call2 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @baz, ptr nocapture %alloc1) |
| 60 | + %call3 = call i32 @pthread_create(ptr nonnull %thread, ptr null, ptr nonnull @buz, ptr %alloc2) |
| 61 | + ret i32 0 |
| 62 | +} |
| 63 | + |
| 64 | +declare !callback !0 dso_local i32 @pthread_create(ptr, ptr, ptr, ptr) |
| 65 | + |
| 66 | +define internal ptr @foo(ptr %arg) { |
| 67 | +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) |
| 68 | +; CHECK-LABEL: define {{[^@]+}}@foo |
| 69 | +; CHECK-SAME: (ptr noalias nocapture nofree nonnull readnone align 4294967296 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] { |
| 70 | +; CHECK-NEXT: entry: |
| 71 | +; CHECK-NEXT: unreachable |
| 72 | +; |
| 73 | +entry: |
| 74 | + ret ptr %arg |
| 75 | +} |
| 76 | + |
| 77 | +define internal ptr @bar(ptr %arg) { |
| 78 | +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) |
| 79 | +; CHECK-LABEL: define {{[^@]+}}@bar |
| 80 | +; CHECK-SAME: (ptr noalias nocapture nofree nonnull readnone align 8 dereferenceable(8) [[ARG:%.*]]) #[[ATTR0]] { |
| 81 | +; CHECK-NEXT: entry: |
| 82 | +; CHECK-NEXT: ret ptr @GlobalVPtr |
| 83 | +; |
| 84 | +entry: |
| 85 | + ret ptr %arg |
| 86 | +} |
| 87 | + |
| 88 | +define internal ptr @baz(ptr %arg) { |
| 89 | +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) |
| 90 | +; CHECK-LABEL: define {{[^@]+}}@baz |
| 91 | +; CHECK-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] { |
| 92 | +; CHECK-NEXT: entry: |
| 93 | +; CHECK-NEXT: ret ptr [[ARG]] |
| 94 | +; |
| 95 | +entry: |
| 96 | + ret ptr %arg |
| 97 | +} |
| 98 | + |
| 99 | +define internal ptr @buz(ptr %arg) { |
| 100 | +; CHECK: Function Attrs: mustprogress nofree norecurse nosync nounwind willreturn memory(none) |
| 101 | +; CHECK-LABEL: define {{[^@]+}}@buz |
| 102 | +; CHECK-SAME: (ptr noalias nofree noundef nonnull readnone returned align 8 dereferenceable(1) "no-capture-maybe-returned" [[ARG:%.*]]) #[[ATTR0]] { |
| 103 | +; CHECK-NEXT: entry: |
| 104 | +; CHECK-NEXT: ret ptr [[ARG]] |
| 105 | +; |
| 106 | +entry: |
| 107 | + ret ptr %arg |
| 108 | +} |
| 109 | + |
| 110 | +!1 = !{i64 2, i64 3, i1 false} |
| 111 | +!0 = !{!1} |
| 112 | +;. |
| 113 | +; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } |
| 114 | +;. |
| 115 | +; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) } |
| 116 | +;. |
| 117 | +; TUNIT: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]} |
| 118 | +; TUNIT: [[META1]] = !{i64 2, i64 3, i1 false} |
| 119 | +;. |
| 120 | +; CGSCC: [[META0:![0-9]+]] = !{[[META1:![0-9]+]]} |
| 121 | +; CGSCC: [[META1]] = !{i64 2, i64 3, i1 false} |
| 122 | +;. |
0 commit comments