| OLD | NEW |
| 1 ; Tests basics and corner cases of x86-32 sandboxing, using -Om1 in | 1 ; Tests basics and corner cases of x86-32 sandboxing, using -Om1 in |
| 2 ; the hope that the output will remain stable. When packing bundles, | 2 ; the hope that the output will remain stable. When packing bundles, |
| 3 ; we try to limit to a few instructions with well known sizes and | 3 ; we try to limit to a few instructions with well known sizes and |
| 4 ; minimal use of registers and stack slots in the lowering sequence. | 4 ; minimal use of registers and stack slots in the lowering sequence. |
| 5 | 5 |
| 6 ; XFAIL: filtype=asm | 6 ; XFAIL: filtype=asm |
| 7 ; RUN: %p2i -i %s --sandbox --filetype=obj --disassemble --args -Om1 \ | 7 ; RUN: %p2i -i %s --sandbox --filetype=obj --disassemble --args -Om1 \ |
| 8 ; RUN: -allow-externally-defined-symbols \ | 8 ; RUN: -allow-externally-defined-symbols \ |
| 9 ; RUN: -ffunction-sections | FileCheck %s | 9 ; RUN: -ffunction-sections | FileCheck %s |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 define internal void @test_direct_call() { | 21 define internal void @test_direct_call() { |
| 22 entry: | 22 entry: |
| 23 call void @call_target() | 23 call void @call_target() |
| 24 ret void | 24 ret void |
| 25 } | 25 } |
| 26 ; CHECK-LABEL: test_direct_call | 26 ; CHECK-LABEL: test_direct_call |
| 27 ; CHECK: nop | 27 ; CHECK: nop |
| 28 ; CHECK: 1b: {{.*}} call 1c | 28 ; CHECK: 1b: {{.*}} call 1c |
| 29 ; CHECK-NEXT: 20: | 29 ; CHECK-NEXT: 20: |
| 30 ; X8664-LABEL: test_direct_call | 30 ; X8664-LABEL: test_direct_call |
| 31 ; X8664: push {{.*}}$local$__0 | 31 ; X8664: push {{.*}} R_X86_64_32S test_direct_call+{{.*}}20 |
| 32 ; X8664: jmp {{.*}} call_target | 32 ; X8664: jmp {{.*}} call_target |
| 33 ; X8664: {{0+}}20 <{{.*}}$local$__0>: | |
| 34 | 33 |
| 35 ; An indirect call sequence uses the right mask and register-call sequence. | 34 ; An indirect call sequence uses the right mask and register-call sequence. |
| 36 define internal void @test_indirect_call(i32 %target) { | 35 define internal void @test_indirect_call(i32 %target) { |
| 37 entry: | 36 entry: |
| 38 %__1 = inttoptr i32 %target to void ()* | 37 %__1 = inttoptr i32 %target to void ()* |
| 39 call void %__1() | 38 call void %__1() |
| 40 ret void | 39 ret void |
| 41 } | 40 } |
| 42 ; CHECK-LABEL: test_indirect_call | 41 ; CHECK-LABEL: test_indirect_call |
| 43 ; CHECK: mov [[REG:.*]],DWORD PTR [esp | 42 ; CHECK: mov [[REG:.*]],DWORD PTR [esp |
| 44 ; CHECK-NEXT: nop | 43 ; CHECK-NEXT: nop |
| 45 ; CHECK: 1b: {{.*}} and [[REG]],0xffffffe0 | 44 ; CHECK: 1b: {{.*}} and [[REG]],0xffffffe0 |
| 46 ; CHECK-NEXT: call [[REG]] | 45 ; CHECK-NEXT: call [[REG]] |
| 47 ; CHECk-NEXT: 20: | 46 ; CHECk-NEXT: 20: |
| 48 ; X8664-LABEL: test_indirect_call | 47 ; X8664-LABEL: test_indirect_call |
| 49 ; X8664: push {{.*}}$local$__0 | 48 ; X8664: push {{.*}} R_X86_64_32S test_indirect_call+{{.*}}20 |
| 50 ; X8664: {{.*}} and e[[REG:..]],0xffffffe0 | 49 ; X8664: {{.*}} and e[[REG:..]],0xffffffe0 |
| 51 ; X8664: add r[[REG]],r15 | 50 ; X8664: add r[[REG]],r15 |
| 52 ; X8664: jmp r[[REG]] | 51 ; X8664: jmp r[[REG]] |
| 53 ; X8664: {{0+}}20 <{{.*}}$local$__0>: | |
| 54 | 52 |
| 55 ; A return sequence uses the right pop / mask / jmp sequence. | 53 ; A return sequence uses the right pop / mask / jmp sequence. |
| 56 define internal void @test_ret() { | 54 define internal void @test_ret() { |
| 57 entry: | 55 entry: |
| 58 ret void | 56 ret void |
| 59 } | 57 } |
| 60 ; CHECK-LABEL: test_ret | 58 ; CHECK-LABEL: test_ret |
| 61 ; CHECK: pop ecx | 59 ; CHECK: pop ecx |
| 62 ; CHECK-NEXT: and ecx,0xffffffe0 | 60 ; CHECK-NEXT: and ecx,0xffffffe0 |
| 63 ; CHECK-NEXT: jmp ecx | 61 ; CHECK-NEXT: jmp ecx |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 i32 %arg3, i32 %arg4, | 262 i32 %arg3, i32 %arg4, |
| 265 i32 %arg5, i32 %arg6) { | 263 i32 %arg5, i32 %arg6) { |
| 266 call void @call_target() | 264 call void @call_target() |
| 267 ; bundle boundary | 265 ; bundle boundary |
| 268 %x = add i32 %arg5, %arg6 ; 12 bytes | 266 %x = add i32 %arg5, %arg6 ; 12 bytes |
| 269 %y = trunc i32 %x to i16 ; 10 bytes | 267 %y = trunc i32 %x to i16 ; 10 bytes |
| 270 call void @call_target() ; 10 bytes | 268 call void @call_target() ; 10 bytes |
| 271 ; bundle boundary | 269 ; bundle boundary |
| 272 ret void | 270 ret void |
| 273 } | 271 } |
| 274 ; X8664-LABEL: bundle_lock_pad_to_end_padding_0$local$__0 | 272 ; X8664: 56: {{.*}} push {{.*}} R_X86_64_32S bundle_lock_pad_to_end_padding_0+{{
.*}}60 |
| 275 ; X8664: 56: {{.*}} push {{.*}}$local$__1 | |
| 276 ; X8664: 5b: {{.*}} jmp {{.*}} call_target | 273 ; X8664: 5b: {{.*}} jmp {{.*}} call_target |
| 277 ; X8664: 60: {{.*}} add | 274 ; X8664: 60: {{.*}} add |
| 278 | 275 |
| 279 ; Tests the pad_to_end bundle alignment with 11 padding bytes needed, and some | 276 ; Tests the pad_to_end bundle alignment with 11 padding bytes needed, and some |
| 280 ; instructions before the call. | 277 ; instructions before the call. |
| 281 define internal void @bundle_lock_pad_to_end_padding_11(i32 %arg0, i32 %arg1, | 278 define internal void @bundle_lock_pad_to_end_padding_11(i32 %arg0, i32 %arg1, |
| 282 i32 %arg3, i32 %arg4, | 279 i32 %arg3, i32 %arg4, |
| 283 i32 %arg5, i32 %arg6) { | 280 i32 %arg5, i32 %arg6) { |
| 284 call void @call_target() | 281 call void @call_target() |
| 285 ; bundle boundary | 282 ; bundle boundary |
| 286 %x = add i32 %arg5, %arg6 ; 11 bytes | 283 %x = add i32 %arg5, %arg6 ; 11 bytes |
| 287 call void @call_target() ; 10 bytes | 284 call void @call_target() ; 10 bytes |
| 288 ; 11 bytes of nop | 285 ; 11 bytes of nop |
| 289 ; bundle boundary | 286 ; bundle boundary |
| 290 ret void | 287 ret void |
| 291 } | 288 } |
| 292 ; X8664-LABEL: bundle_lock_pad_to_end_padding_11$local$__0 | 289 ; X8664: 4b: {{.*}} push {{.*}} R_X86_64_32S bundle_lock_pad_to_end_padding_11+{
{.*}}60 |
| 293 ; X8664: 4b: {{.*}} push {{.*}}$local$__1 | |
| 294 ; X8664: 50: {{.*}} jmp {{.*}} call_target | 290 ; X8664: 50: {{.*}} jmp {{.*}} call_target |
| 295 ; X8664: 55: {{.*}} nop | 291 ; X8664: 55: {{.*}} nop |
| 296 ; X8664: 5d: {{.*}} nop | 292 ; X8664: 5d: {{.*}} nop |
| 297 ; X8664: 60: {{.*}} add | 293 ; X8664: 60: {{.*}} add |
| 298 | 294 |
| 299 ; Tests the pad_to_end bundle alignment with 22 padding bytes needed, and no | 295 ; Tests the pad_to_end bundle alignment with 22 padding bytes needed, and no |
| 300 ; instructions before the call. | 296 ; instructions before the call. |
| 301 define internal void @bundle_lock_pad_to_end_padding_22(i32 %arg0, i32 %arg1, | 297 define internal void @bundle_lock_pad_to_end_padding_22(i32 %arg0, i32 %arg1, |
| 302 i32 %arg3, i32 %arg4, | 298 i32 %arg3, i32 %arg4, |
| 303 i32 %arg5, i32 %arg6) { | 299 i32 %arg5, i32 %arg6) { |
| 304 call void @call_target() | 300 call void @call_target() |
| 305 ; bundle boundary | 301 ; bundle boundary |
| 306 call void @call_target() ; 10 bytes | 302 call void @call_target() ; 10 bytes |
| 307 ; 22 bytes of nop | 303 ; 22 bytes of nop |
| 308 ; bundle boundary | 304 ; bundle boundary |
| 309 ret void | 305 ret void |
| 310 } | 306 } |
| 311 ; X8664-LABEL: bundle_lock_pad_to_end_padding_22$local$__0 | 307 ; X8664: 40: {{.*}} push {{.*}} R_X86_64_32S bundle_lock_pad_to_end_padding_22+{
{.*}}60 |
| 312 ; X8664: 40: {{.*}} push {{.*}}$local$__1 | |
| 313 ; X8664: 45: {{.*}} jmp {{.*}} call_target | 308 ; X8664: 45: {{.*}} jmp {{.*}} call_target |
| 314 ; X8664: 4a: {{.*}} nop | 309 ; X8664: 4a: {{.*}} nop |
| 315 ; X8664: 52: {{.*}} nop | 310 ; X8664: 52: {{.*}} nop |
| 316 ; X8664: 5a: {{.*}} nop | 311 ; X8664: 5a: {{.*}} nop |
| 317 ; X8664: 60: {{.*}} add | 312 ; X8664: 60: {{.*}} add |
| 318 | 313 |
| 319 ; Stack adjustment state during an argument push sequence gets | 314 ; Stack adjustment state during an argument push sequence gets |
| 320 ; properly checkpointed and restored during the two passes, as | 315 ; properly checkpointed and restored during the two passes, as |
| 321 ; observed by the stack adjustment for accessing stack-allocated | 316 ; observed by the stack adjustment for accessing stack-allocated |
| 322 ; variables. | 317 ; variables. |
| 323 define internal void @checkpoint_restore_stack_adjustment(i32 %arg) { | 318 define internal void @checkpoint_restore_stack_adjustment(i32 %arg) { |
| 324 entry: | 319 entry: |
| 325 call void @call_target() | 320 call void @call_target() |
| 326 ; bundle boundary | 321 ; bundle boundary |
| 327 call void @checkpoint_restore_stack_adjustment(i32 %arg) | 322 call void @checkpoint_restore_stack_adjustment(i32 %arg) |
| 328 ret void | 323 ret void |
| 329 } | 324 } |
| 330 ; CHECK-LABEL: checkpoint_restore_stack_adjustment | 325 ; CHECK-LABEL: checkpoint_restore_stack_adjustment |
| 331 ; CHECK: sub esp,0x1c | 326 ; CHECK: sub esp,0x1c |
| 332 ; CHECK: call | 327 ; CHECK: call |
| 333 ; The address of %arg should be [esp+0x20], not [esp+0x30]. | 328 ; The address of %arg should be [esp+0x20], not [esp+0x30]. |
| 334 ; CHECK-NEXT: mov [[REG:.*]],DWORD PTR [esp+0x20] | 329 ; CHECK-NEXT: mov [[REG:.*]],DWORD PTR [esp+0x20] |
| 335 ; CHECK-NEXT: mov DWORD PTR [esp],[[REG]] | 330 ; CHECK-NEXT: mov DWORD PTR [esp],[[REG]] |
| 336 ; CHECK: call | 331 ; CHECK: call |
| 337 ; CHECK: add esp,0x1c | 332 ; CHECK: add esp,0x1c |
| OLD | NEW |