Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 1 | ; RUN: opt < %s -globalopt -S | FileCheck %s |
Chih-Hung Hsieh | 1e85958 | 2015-07-28 16:24:05 +0000 | [diff] [blame] | 2 | ; RUN: opt -emulated-tls < %s -globalopt -S | FileCheck %s |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 3 | |
| 4 | declare void @wait() |
| 5 | declare void @signal() |
| 6 | declare void @start_thread(void ()*) |
| 7 | |
| 8 | @x = internal thread_local global [100 x i32] zeroinitializer, align 16 |
| 9 | @ip = internal global i32* null, align 8 |
| 10 | |
| 11 | ; PR14309: GlobalOpt would think that the value of @ip is always the address of |
| 12 | ; x[1]. However, that address is different for different threads so @ip cannot |
| 13 | ; be replaced with a constant. |
| 14 | |
| 15 | define i32 @f() { |
| 16 | entry: |
| 17 | ; Set @ip to point to x[1] for thread 1. |
David Blaikie | f72d05b | 2015-03-13 18:20:45 +0000 | [diff] [blame] | 18 | store i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), i32** @ip, align 8 |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 19 | |
| 20 | ; Run g on a new thread. |
| 21 | tail call void @start_thread(void ()* @g) nounwind |
| 22 | tail call void @wait() nounwind |
| 23 | |
| 24 | ; Reset x[1] for thread 1. |
David Blaikie | f72d05b | 2015-03-13 18:20:45 +0000 | [diff] [blame] | 25 | store i32 0, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), align 4 |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 26 | |
| 27 | ; Read the value of @ip, which now points at x[1] for thread 2. |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 28 | %0 = load i32*, i32** @ip, align 8 |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 29 | |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 30 | %1 = load i32, i32* %0, align 4 |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 31 | ret i32 %1 |
| 32 | |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 33 | ; CHECK-LABEL: @f( |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 34 | ; Make sure that the load from @ip hasn't been removed. |
David Blaikie | a79ac14 | 2015-02-27 21:17:42 +0000 | [diff] [blame] | 35 | ; CHECK: load i32*, i32** @ip |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 36 | ; CHECK: ret |
| 37 | } |
| 38 | |
| 39 | define internal void @g() nounwind uwtable { |
| 40 | entry: |
| 41 | ; Set @ip to point to x[1] for thread 2. |
David Blaikie | f72d05b | 2015-03-13 18:20:45 +0000 | [diff] [blame] | 42 | store i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), i32** @ip, align 8 |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 43 | |
| 44 | ; Store 50 in x[1] for thread 2. |
David Blaikie | f72d05b | 2015-03-13 18:20:45 +0000 | [diff] [blame] | 45 | store i32 50, i32* getelementptr inbounds ([100 x i32], [100 x i32]* @x, i64 0, i64 1), align 4 |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 46 | |
| 47 | tail call void @signal() nounwind |
| 48 | ret void |
| 49 | |
Stephen Lin | c1c7a13 | 2013-07-14 01:42:54 +0000 | [diff] [blame] | 50 | ; CHECK-LABEL: @g( |
Hans Wennborg | 709e015 | 2012-11-15 11:40:00 +0000 | [diff] [blame] | 51 | ; Make sure that the store to @ip hasn't been removed. |
| 52 | ; CHECK: store {{.*}} @ip |
| 53 | ; CHECK: ret |
| 54 | } |