Eric Christopher | cee313d | 2019-04-17 04:52:47 +0000 | [diff] [blame] | 1 | ; RUN: opt -ipconstprop -S < %s | FileCheck %s |
| 2 | ; |
| 3 | ; #include <pthread.h> |
| 4 | ; |
| 5 | ; void *GlobalVPtr; |
| 6 | ; |
| 7 | ; static void *foo(void *arg) { return arg; } |
| 8 | ; static void *bar(void *arg) { return arg; } |
| 9 | ; |
| 10 | ; int main() { |
| 11 | ; pthread_t thread; |
| 12 | ; pthread_create(&thread, NULL, foo, NULL); |
| 13 | ; pthread_create(&thread, NULL, bar, &GlobalVPtr); |
| 14 | ; return 0; |
| 15 | ; } |
| 16 | ; |
| 17 | ; Verify the constant values NULL and &GlobalVPtr are propagated into foo and |
| 18 | ; bar, respectively. |
| 19 | ; |
| 20 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" |
| 21 | |
| 22 | %union.pthread_attr_t = type { i64, [48 x i8] } |
| 23 | |
| 24 | @GlobalVPtr = common dso_local global i8* null, align 8 |
| 25 | |
| 26 | define dso_local i32 @main() { |
| 27 | entry: |
| 28 | %thread = alloca i64, align 8 |
| 29 | %call = call i32 @pthread_create(i64* nonnull %thread, %union.pthread_attr_t* null, i8* (i8*)* nonnull @foo, i8* null) |
| 30 | %call1 = call i32 @pthread_create(i64* nonnull %thread, %union.pthread_attr_t* null, i8* (i8*)* nonnull @bar, i8* bitcast (i8** @GlobalVPtr to i8*)) |
| 31 | ret i32 0 |
| 32 | } |
| 33 | |
| 34 | declare !callback !0 dso_local i32 @pthread_create(i64*, %union.pthread_attr_t*, i8* (i8*)*, i8*) |
| 35 | |
| 36 | define internal i8* @foo(i8* %arg) { |
| 37 | entry: |
| 38 | ; CHECK: ret i8* null |
| 39 | ret i8* %arg |
| 40 | } |
| 41 | |
| 42 | define internal i8* @bar(i8* %arg) { |
| 43 | entry: |
| 44 | ; CHECK: ret i8* bitcast (i8** @GlobalVPtr to i8*) |
| 45 | ret i8* %arg |
| 46 | } |
| 47 | |
| 48 | !1 = !{i64 2, i64 3, i1 false} |
| 49 | !0 = !{!1} |