| OLD | NEW |
| 1 ; Tests various aspects of x86 branch encodings (near vs far, | 1 ; Tests various aspects of x86 branch encodings (near vs far, |
| 2 ; forward vs backward, using CFG labels, or local labels). | 2 ; forward vs backward, using CFG labels, or local labels). |
| 3 | 3 |
| 4 ; Use -ffunction-sections so that the offsets reset for each function. | 4 ; Use -ffunction-sections so that the offsets reset for each function. |
| 5 ; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 \ | 5 ; RUN: %p2i --filetype=obj --disassemble -i %s --args -O2 \ |
| 6 ; RUN: -ffunction-sections | FileCheck %s | 6 ; RUN: -ffunction-sections | FileCheck %s |
| 7 | 7 |
| 8 ; Use atomic ops as filler, which shouldn't get optimized out. | 8 ; Use atomic ops as filler, which shouldn't get optimized out. |
| 9 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32) | 9 declare void @llvm.nacl.atomic.store.i32(i32, i32*, i32) |
| 10 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32) | 10 declare i32 @llvm.nacl.atomic.load.i32(i32*, i32) |
| 11 declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32) | 11 declare i32 @llvm.nacl.atomic.rmw.i32(i32, i32*, i32, i32) |
| 12 | 12 |
| 13 define internal void @test_near_backward(i32 %iptr, i32 %val) { | 13 define internal void @test_near_backward(i32 %iptr, i32 %val) { |
| 14 entry: | 14 entry: |
| 15 br label %next | 15 br label %next |
| 16 next: | 16 next: |
| 17 %ptr = inttoptr i32 %iptr to i32* | 17 %ptr = inttoptr i32 %iptr to i32* |
| 18 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) | 18 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) |
| 19 br label %next2 | 19 br label %next2 |
| 20 next2: | 20 next2: |
| 21 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) | 21 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) |
| 22 %cmp = icmp ult i32 %val, 0 | 22 %cmp = icmp ult i32 %val, 1 |
| 23 br i1 %cmp, label %next2, label %next | 23 br i1 %cmp, label %next2, label %next |
| 24 } | 24 } |
| 25 | 25 |
| 26 ; CHECK-LABEL: test_near_backward | 26 ; CHECK-LABEL: test_near_backward |
| 27 ; CHECK: 8: {{.*}} mov DWORD PTR | 27 ; CHECK: 8: {{.*}} mov DWORD PTR |
| 28 ; CHECK-NEXT: a: {{.*}} mfence | 28 ; CHECK-NEXT: a: {{.*}} mfence |
| 29 ; CHECK-NEXT: d: {{.*}} mov DWORD PTR | 29 ; CHECK-NEXT: d: {{.*}} mov DWORD PTR |
| 30 ; CHECK-NEXT: f: {{.*}} mfence | 30 ; CHECK-NEXT: f: {{.*}} mfence |
| 31 ; CHECK-NEXT: 12: {{.*}} cmp | 31 ; CHECK-NEXT: 12: {{.*}} cmp |
| 32 ; CHECK-NEXT: 15: 72 f6 jb d | 32 ; CHECK-NEXT: 15: 72 f6 jb d |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 ; CHECK-NEXT: 16: {{.*}} mov DWORD PTR | 124 ; CHECK-NEXT: 16: {{.*}} mov DWORD PTR |
| 125 ; CHECK-NEXT: 18: {{.*}} mfence | 125 ; CHECK-NEXT: 18: {{.*}} mfence |
| 126 ; CHECK: 8c: 0f 8e 7a ff ff ff jle c | 126 ; CHECK: 8c: 0f 8e 7a ff ff ff jle c |
| 127 ; CHECK-NEXT: 92: eb 82 jmp 16 | 127 ; CHECK-NEXT: 92: eb 82 jmp 16 |
| 128 | 128 |
| 129 define internal void @test_near_forward(i32 %iptr, i32 %val) { | 129 define internal void @test_near_forward(i32 %iptr, i32 %val) { |
| 130 entry: | 130 entry: |
| 131 br label %next1 | 131 br label %next1 |
| 132 next1: | 132 next1: |
| 133 %ptr = inttoptr i32 %iptr to i32* | 133 %ptr = inttoptr i32 %iptr to i32* |
| 134 %cmp = icmp ult i32 %val, 0 | 134 %cmp = icmp ult i32 %val, 1 |
| 135 br i1 %cmp, label %next3, label %next2 | 135 br i1 %cmp, label %next3, label %next2 |
| 136 next2: | 136 next2: |
| 137 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) | 137 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) |
| 138 br label %next3 | 138 br label %next3 |
| 139 next3: | 139 next3: |
| 140 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) | 140 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) |
| 141 br label %next1 | 141 br label %next1 |
| 142 } | 142 } |
| 143 ; Forward branches for non-local labels currently use the fully relaxed | 143 ; Forward branches for non-local labels currently use the fully relaxed |
| 144 ; form to avoid needing a relaxation pass. | 144 ; form to avoid needing a relaxation pass. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 165 %ptr = inttoptr i32 %iptr to i32* | 165 %ptr = inttoptr i32 %iptr to i32* |
| 166 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) | 166 call void @llvm.nacl.atomic.store.i32(i32 %val, i32* %ptr, i32 6) |
| 167 br label %next2 | 167 br label %next2 |
| 168 next2: | 168 next2: |
| 169 %cmp = icmp ult i64 %val64, 1 | 169 %cmp = icmp ult i64 %val64, 1 |
| 170 br i1 %cmp, label %next, label %next2 | 170 br i1 %cmp, label %next, label %next2 |
| 171 } | 171 } |
| 172 ; CHECK-LABEL: test_local_forward_then_back | 172 ; CHECK-LABEL: test_local_forward_then_back |
| 173 ; CHECK: {{.*}} mov DWORD PTR | 173 ; CHECK: {{.*}} mov DWORD PTR |
| 174 ; CHECK-NEXT: {{.*}} mfence | 174 ; CHECK-NEXT: {{.*}} mfence |
| 175 ; CHECK-NEXT: [[LABEL:[0-9a-f]+]]: {{.*}} mov {{.*}},0x1 | 175 ; CHECK-NEXT: [[LABEL:[0-9a-f]+]]: {{.*}} cmp |
| 176 ; CHECK-NEXT: {{.*}} jb |
| 177 ; CHECK-NEXT: {{.*}} ja |
| 176 ; CHECK-NEXT: {{.*}} cmp | 178 ; CHECK-NEXT: {{.*}} cmp |
| 177 ; CHECK-NEXT: {{.*}} jb | 179 ; CHECK-NEXT: {{.*}} jb |
| 178 ; CHECK: {{.*}} jne | 180 ; CHECK-NEXT: {{.*}} jmp [[LABEL]] |
| 179 ; CHECK: {{.*}} jmp [[LABEL]] | |
| 180 | 181 |
| 181 | 182 |
| 182 ; Test that backward local branches also work and are small. | 183 ; Test that backward local branches also work and are small. |
| 183 ; Some of the atomic instructions use a cmpxchg loop. | 184 ; Some of the atomic instructions use a cmpxchg loop. |
| 184 define internal void @test_local_backward(i64 %val64, i32 %iptr, i32 %val) { | 185 define internal void @test_local_backward(i64 %val64, i32 %iptr, i32 %val) { |
| 185 entry: | 186 entry: |
| 186 br label %next | 187 br label %next |
| 187 next: | 188 next: |
| 188 %ptr = inttoptr i32 %iptr to i32* | 189 %ptr = inttoptr i32 %iptr to i32* |
| 189 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %val, i32 6) | 190 %a = call i32 @llvm.nacl.atomic.rmw.i32(i32 5, i32* %ptr, i32 %val, i32 6) |
| 190 br label %next2 | 191 br label %next2 |
| 191 next2: | 192 next2: |
| 192 %success = icmp eq i32 1, %a | 193 %success = icmp eq i32 1, %a |
| 193 br i1 %success, label %next, label %next2 | 194 br i1 %success, label %next, label %next2 |
| 194 } | 195 } |
| 195 ; CHECK-LABEL: test_local_backward | 196 ; CHECK-LABEL: test_local_backward |
| 196 ; CHECK: 9: {{.*}} mov {{.*}},DWORD | 197 ; CHECK: 9: {{.*}} mov {{.*}},DWORD |
| 197 ; CHECK: b: {{.*}} mov | 198 ; CHECK: b: {{.*}} mov |
| 198 ; CHECK-NEXT: d: {{.*}} xor | 199 ; CHECK-NEXT: d: {{.*}} xor |
| 199 ; CHECK-NEXT: f: {{.*}} lock cmpxchg | 200 ; CHECK-NEXT: f: {{.*}} lock cmpxchg |
| 200 ; CHECK-NEXT: 13: 75 f6 jne b | 201 ; CHECK-NEXT: 13: 75 f6 jne b |
| 201 ; CHECK: 1c: 74 eb je 9 | 202 ; CHECK: 1c: 74 eb je 9 |
| OLD | NEW |