OLD | NEW |
(Empty) | |
| 1 ; RUN: opt < %s -nacl-expand-tls-constant-expr -S | FileCheck %s |
| 2 |
| 3 @tvar = thread_local global i32 0 |
| 4 |
| 5 |
| 6 define i32 @test_converting_ptrtoint() { |
| 7 ret i32 ptrtoint (i32* @tvar to i32) |
| 8 } |
| 9 ; CHECK: define i32 @test_converting_ptrtoint() |
| 10 ; CHECK: %expanded = ptrtoint i32* @tvar to i32 |
| 11 ; CHECK: ret i32 %expanded |
| 12 |
| 13 |
| 14 define i32 @test_converting_add() { |
| 15 ret i32 add (i32 ptrtoint (i32* @tvar to i32), i32 4) |
| 16 } |
| 17 ; CHECK: define i32 @test_converting_add() |
| 18 ; CHECK: %expanded1 = ptrtoint i32* @tvar to i32 |
| 19 ; CHECK: %expanded = add i32 %expanded1, 4 |
| 20 ; CHECK: ret i32 %expanded |
| 21 |
| 22 |
| 23 define i32 @test_converting_multiple_operands() { |
| 24 ret i32 add (i32 ptrtoint (i32* @tvar to i32), |
| 25 i32 ptrtoint (i32* @tvar to i32)) |
| 26 } |
| 27 ; CHECK: define i32 @test_converting_multiple_operands() |
| 28 ; CHECK: %expanded1 = ptrtoint i32* @tvar to i32 |
| 29 ; CHECK: %expanded = add i32 %expanded1, %expanded1 |
| 30 ; CHECK: ret i32 %expanded |
| 31 |
| 32 |
| 33 define i32 @test_allocating_new_var_name(i32 %expanded) { |
| 34 %result = add i32 %expanded, ptrtoint (i32* @tvar to i32) |
| 35 ret i32 %result |
| 36 } |
| 37 ; CHECK: define i32 @test_allocating_new_var_name(i32 %expanded) |
| 38 ; CHECK: %expanded1 = ptrtoint i32* @tvar to i32 |
| 39 ; CHECK: %result = add i32 %expanded, %expanded1 |
| 40 ; CHECK: ret i32 %result |
| 41 |
| 42 |
| 43 define i8* @test_converting_bitcast() { |
| 44 ret i8* bitcast (i32* @tvar to i8*) |
| 45 } |
| 46 ; CHECK: define i8* @test_converting_bitcast() |
| 47 ; CHECK: %expanded = bitcast i32* @tvar to i8* |
| 48 ; CHECK: ret i8* %expanded |
| 49 |
| 50 |
| 51 define i32* @test_converting_getelementptr() { |
| 52 ; Use an index >1 to ensure that "inbounds" is not added automatically. |
| 53 ret i32* getelementptr (i32* @tvar, i32 2) |
| 54 } |
| 55 ; CHECK: define i32* @test_converting_getelementptr() |
| 56 ; CHECK: %expanded = getelementptr i32* @tvar, i32 2 |
| 57 ; CHECK: ret i32* %expanded |
| 58 |
| 59 |
| 60 ; This is identical to @test_converting_getelementptr(). |
| 61 ; We need to check that both copies of getelementptr are fixed. |
| 62 define i32* @test_converting_getelementptr_copy() { |
| 63 ret i32* getelementptr (i32* @tvar, i32 2) |
| 64 } |
| 65 ; CHECK: define i32* @test_converting_getelementptr_copy() |
| 66 ; CHECK: %expanded = getelementptr i32* @tvar, i32 2 |
| 67 ; CHECK: ret i32* %expanded |
| 68 |
| 69 |
| 70 define i32* @test_converting_getelementptr_inbounds() { |
| 71 ret i32* getelementptr inbounds (i32* @tvar, i32 2) |
| 72 } |
| 73 ; CHECK: define i32* @test_converting_getelementptr_inbounds() |
| 74 ; CHECK: %expanded = getelementptr inbounds i32* @tvar, i32 2 |
| 75 ; CHECK: ret i32* %expanded |
| 76 |
| 77 |
| 78 define i32* @test_converting_phi(i1 %cmp) { |
| 79 entry: |
| 80 br i1 %cmp, label %return, label %else |
| 81 |
| 82 else: |
| 83 br label %return |
| 84 |
| 85 return: |
| 86 %result = phi i32* [ getelementptr (i32* @tvar, i32 1), %entry ], [ null, %els
e ] |
| 87 ret i32* %result |
| 88 } |
| 89 ; The converted ConstantExprs get pushed back into the PHI node's |
| 90 ; incoming block, which might be suboptimal but works in all cases. |
| 91 ; CHECK: define i32* @test_converting_phi(i1 %cmp) |
| 92 ; CHECK: entry: |
| 93 ; CHECK: %expanded = getelementptr inbounds i32* @tvar, i32 1 |
| 94 ; CHECK: else: |
| 95 ; CHECK: return: |
| 96 ; CHECK: %result = phi i32* [ %expanded, %entry ], [ null, %else ] |
| 97 |
| 98 |
| 99 @addr1 = global i8* blockaddress(@test_converting_phi_with_indirectbr, %return) |
| 100 @addr2 = global i8* blockaddress(@test_converting_phi_with_indirectbr, %else) |
| 101 define i32* @test_converting_phi_with_indirectbr(i8* %addr) { |
| 102 entry: |
| 103 indirectbr i8* %addr, [ label %return, label %else ] |
| 104 |
| 105 else: |
| 106 br label %return |
| 107 |
| 108 return: |
| 109 %result = phi i32* [ getelementptr (i32* @tvar, i32 1), %entry ], [ null, %els
e ] |
| 110 ret i32* %result |
| 111 } |
| 112 ; CHECK: define i32* @test_converting_phi_with_indirectbr(i8* %addr) |
| 113 ; CHECK: entry: |
| 114 ; CHECK: %expanded = getelementptr inbounds i32* @tvar, i32 1 |
| 115 ; CHECK: return: |
| 116 ; CHECK: %result = phi i32* [ %expanded, %entry ], [ null, %else ] |
| 117 |
| 118 |
| 119 ; This tests that ExpandTlsConstantExpr correctly handles a PHI node |
| 120 ; that contains the same ConstantExpr twice. Using |
| 121 ; replaceAllUsesWith() is not correct on a PHI node when the new |
| 122 ; instruction has to be added to an incoming block. |
| 123 define i32 @test_converting_phi_twice(i1 %arg) { |
| 124 br i1 %arg, label %iftrue, label %iffalse |
| 125 iftrue: |
| 126 br label %exit |
| 127 iffalse: |
| 128 br label %exit |
| 129 exit: |
| 130 %result = phi i32 [ ptrtoint (i32* @tvar to i32), %iftrue ], |
| 131 [ ptrtoint (i32* @tvar to i32), %iffalse ] |
| 132 ret i32 %result |
| 133 } |
| 134 ; CHECK: define i32 @test_converting_phi_twice(i1 %arg) |
| 135 ; CHECK: iftrue: |
| 136 ; CHECK: %expanded{{.*}} = ptrtoint i32* @tvar to i32 |
| 137 ; CHECK: iffalse: |
| 138 ; CHECK: %expanded{{.*}} = ptrtoint i32* @tvar to i32 |
| 139 ; CHECK: exit: |
| 140 ; CHECK: %result = phi i32 [ %expanded1, %iftrue ], [ %expanded, %iffalse ] |
| 141 |
| 142 |
| 143 define i32 @test_converting_phi_multiple_entry(i1 %arg) { |
| 144 entry: |
| 145 br i1 %arg, label %done, label %done |
| 146 done: |
| 147 %result = phi i32 [ ptrtoint (i32* @tvar to i32), %entry ], |
| 148 [ ptrtoint (i32* @tvar to i32), %entry ] |
| 149 ret i32 %result |
| 150 } |
| 151 ; CHECK: define i32 @test_converting_phi_multiple_entry(i1 %arg) |
| 152 ; CHECK: %result = phi i32 [ %expanded, %entry ], [ %expanded, %entry ] |
OLD | NEW |