OLD | NEW |
1 ; RUN: opt < %s -nacl-expand-tls -S | FileCheck %s | 1 ; RUN: opt < %s -nacl-expand-tls -S | FileCheck %s |
2 | 2 |
3 | 3 |
4 @tvar = thread_local global i32 123 | 4 @tvar = thread_local global i32 123 |
5 | 5 |
6 define i32* @get_tvar(i1 %cmp) { | 6 define i32* @get_tvar(i1 %cmp) { |
7 entry: | 7 entry: |
8 br i1 %cmp, label %return, label %else | 8 br i1 %cmp, label %return, label %else |
9 | 9 |
10 else: | 10 else: |
11 br label %return | 11 br label %return |
12 | 12 |
13 return: | 13 return: |
14 %result = phi i32* [ @tvar, %entry ], [ null, %else ] | 14 %result = phi i32* [ @tvar, %entry ], [ null, %else ] |
15 ret i32* %result | 15 ret i32* %result |
16 } | 16 } |
17 ; The TLS access gets pushed back into the PHI node's incoming block, | 17 ; The TLS access gets pushed back into the PHI node's incoming block, |
18 ; which might be suboptimal but works in all cases. | 18 ; which might be suboptimal but works in all cases. |
19 ; CHECK: define i32* @get_tvar(i1 %cmp) { | 19 ; CHECK: define i32* @get_tvar(i1 %cmp) { |
20 ; CHECK: entry: | 20 ; CHECK: entry: |
21 ; CHECK: %field = getelementptr %tls_struct* %tls_struct, i32 -1, i32 0, i32 0 | 21 ; CHECK: %field = getelementptr %tls_struct, %tls_struct* %tls_struct, i32 -1, i
32 0, i32 0 |
22 ; CHECK: else: | 22 ; CHECK: else: |
23 ; CHECK: return: | 23 ; CHECK: return: |
24 ; CHECK: %result = phi i32* [ %field, %entry ], [ null, %else ] | 24 ; CHECK: %result = phi i32* [ %field, %entry ], [ null, %else ] |
25 | 25 |
26 | 26 |
27 ; This tests that ExpandTls correctly handles a PHI node that contains | 27 ; This tests that ExpandTls correctly handles a PHI node that contains |
28 ; the same TLS variable twice. Using replaceAllUsesWith() is not | 28 ; the same TLS variable twice. Using replaceAllUsesWith() is not |
29 ; correct on a PHI node when the new instruction has to be added to an | 29 ; correct on a PHI node when the new instruction has to be added to an |
30 ; incoming block. | 30 ; incoming block. |
31 define i32* @tls_phi_twice(i1 %arg) { | 31 define i32* @tls_phi_twice(i1 %arg) { |
32 br i1 %arg, label %iftrue, label %iffalse | 32 br i1 %arg, label %iftrue, label %iffalse |
33 iftrue: | 33 iftrue: |
34 br label %exit | 34 br label %exit |
35 iffalse: | 35 iffalse: |
36 br label %exit | 36 br label %exit |
37 exit: | 37 exit: |
38 %result = phi i32* [ @tvar, %iftrue ], [ @tvar, %iffalse ] | 38 %result = phi i32* [ @tvar, %iftrue ], [ @tvar, %iffalse ] |
39 ret i32* %result | 39 ret i32* %result |
40 } | 40 } |
41 ; CHECK: define i32* @tls_phi_twice(i1 %arg) { | 41 ; CHECK: define i32* @tls_phi_twice(i1 %arg) { |
42 ; CHECK: iftrue: | 42 ; CHECK: iftrue: |
43 ; CHECK: %field{{.*}} = getelementptr %tls_struct* %tls_struct{{.*}}, i32 -1, i3
2 0, i32 0 | 43 ; CHECK: %field{{.*}} = getelementptr %tls_struct, %tls_struct* %tls_struct{{.*}
}, i32 -1, i32 0, i32 0 |
44 ; CHECK: iffalse: | 44 ; CHECK: iffalse: |
45 ; CHECK: %field{{.*}} = getelementptr %tls_struct* %tls_struct{{.*}}, i32 -1, i3
2 0, i32 0 | 45 ; CHECK: %field{{.*}} = getelementptr %tls_struct, %tls_struct* %tls_struct{{.*}
}, i32 -1, i32 0, i32 0 |
46 ; CHECK: exit: | 46 ; CHECK: exit: |
47 ; CHECK: %result = phi i32* [ %field{{.*}}, %iftrue ], [ %field{{.*}}, %iffalse
] | 47 ; CHECK: %result = phi i32* [ %field{{.*}}, %iftrue ], [ %field{{.*}}, %iffalse
] |
48 | 48 |
49 | 49 |
50 ; In this corner case, ExpandTls must expand out @tvar only once, | 50 ; In this corner case, ExpandTls must expand out @tvar only once, |
51 ; otherwise it will produce invalid IR. | 51 ; otherwise it will produce invalid IR. |
52 define i32* @tls_phi_multiple_entry(i1 %arg) { | 52 define i32* @tls_phi_multiple_entry(i1 %arg) { |
53 entry: | 53 entry: |
54 br i1 %arg, label %done, label %done | 54 br i1 %arg, label %done, label %done |
55 done: | 55 done: |
56 %result = phi i32* [ @tvar, %entry ], [ @tvar, %entry ] | 56 %result = phi i32* [ @tvar, %entry ], [ @tvar, %entry ] |
57 ret i32* %result | 57 ret i32* %result |
58 } | 58 } |
59 ; CHECK: define i32* @tls_phi_multiple_entry(i1 %arg) { | 59 ; CHECK: define i32* @tls_phi_multiple_entry(i1 %arg) { |
60 ; CHECK: %result = phi i32* [ %field, %entry ], [ %field, %entry ] | 60 ; CHECK: %result = phi i32* [ %field, %entry ], [ %field, %entry ] |
OLD | NEW |