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