| ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 | |
| ; RUN: llc < %s | FileCheck %s | |
| target datalayout = "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:32-n8:16:32-a:0:32-S32" | |
| target triple = "i386-pc-windows-gnu" | |
| ; This function uses esi as base pointer, the inline asm clobbers esi, so we | |
| ; should save esi using esp before the inline asm, and restore esi after the | |
| ; inline asm. | |
| define i32 @clober_bp() { | |
| ; CHECK-LABEL: clober_bp: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: pushl %ebp | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 8 | |
| ; CHECK-NEXT: .cfi_offset %ebp, -8 | |
| ; CHECK-NEXT: movl %esp, %ebp | |
| ; CHECK-NEXT: .cfi_def_cfa_register %ebp | |
| ; CHECK-NEXT: pushl %edi | |
| ; CHECK-NEXT: pushl %esi | |
| ; CHECK-NEXT: andl $-16, %esp | |
| ; CHECK-NEXT: subl $16, %esp | |
| ; CHECK-NEXT: movl %esp, %esi | |
| ; CHECK-NEXT: .cfi_offset %esi, -16 | |
| ; CHECK-NEXT: .cfi_offset %edi, -12 | |
| ; CHECK-NEXT: movl $4, 12(%esi) | |
| ; CHECK-NEXT: movl 12(%esi), %eax | |
| ; CHECK-NEXT: addl $3, %eax | |
| ; CHECK-NEXT: andl $-4, %eax | |
| ; CHECK-NEXT: calll __alloca | |
| ; CHECK-NEXT: movl %esp, %eax | |
| ; CHECK-NEXT: andl $-16, %eax | |
| ; CHECK-NEXT: movl %eax, %esp | |
| ; CHECK-NEXT: movl $1, (%eax) | |
| ; CHECK-NEXT: leal 8(%esi), %edi | |
| ; CHECK-NEXT: movl $4, %ecx | |
| ; CHECK-NEXT: pushl %esi | |
| ; CHECK-NEXT: movl %eax, %esi | |
| ; CHECK-NEXT: #APP | |
| ; CHECK-NEXT: rep movsb (%esi), %es:(%edi) | |
| ; CHECK-NEXT: #NO_APP | |
| ; CHECK-NEXT: popl %esi | |
| ; CHECK-NEXT: movl 8(%esi), %eax | |
| ; CHECK-NEXT: leal -8(%ebp), %esp | |
| ; CHECK-NEXT: popl %esi | |
| ; CHECK-NEXT: popl %edi | |
| ; CHECK-NEXT: popl %ebp | |
| ; CHECK-NEXT: retl | |
| entry: | |
| %size = alloca i32, align 4 | |
| %g = alloca i32, align 4 | |
| store volatile i32 4, ptr %size, align 4 | |
| %len = load volatile i32, ptr %size, align 4 | |
| %var_array = alloca i8, i32 %len, align 16 | |
| store i32 1, ptr %var_array, align 16 | |
| %nil = call { ptr, ptr, i32 } asm "rep movsb", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags}"(ptr %g, ptr %var_array, i32 4) | |
| %retval = load i32, ptr %g, align 4 | |
| ret i32 %retval | |
| } | |
| ; This function has the same code except the inline asm also clobbers | |
| ; frame pointer. | |
| define i32 @clobber_bpfp() { | |
| ; CHECK-LABEL: clobber_bpfp: | |
| ; CHECK: # %bb.0: # %entry | |
| ; CHECK-NEXT: pushl %ebp | |
| ; CHECK-NEXT: .cfi_def_cfa_offset 8 | |
| ; CHECK-NEXT: .cfi_offset %ebp, -8 | |
| ; CHECK-NEXT: movl %esp, %ebp | |
| ; CHECK-NEXT: .cfi_def_cfa_register %ebp | |
| ; CHECK-NEXT: pushl %edi | |
| ; CHECK-NEXT: pushl %esi | |
| ; CHECK-NEXT: andl $-16, %esp | |
| ; CHECK-NEXT: subl $16, %esp | |
| ; CHECK-NEXT: movl %esp, %esi | |
| ; CHECK-NEXT: .cfi_offset %esi, -16 | |
| ; CHECK-NEXT: .cfi_offset %edi, -12 | |
| ; CHECK-NEXT: movl $4, 12(%esi) | |
| ; CHECK-NEXT: movl 12(%esi), %eax | |
| ; CHECK-NEXT: addl $3, %eax | |
| ; CHECK-NEXT: andl $-4, %eax | |
| ; CHECK-NEXT: calll __alloca | |
| ; CHECK-NEXT: movl %esp, %eax | |
| ; CHECK-NEXT: andl $-16, %eax | |
| ; CHECK-NEXT: movl %eax, %esp | |
| ; CHECK-NEXT: movl $1, (%eax) | |
| ; CHECK-NEXT: leal 8(%esi), %edi | |
| ; CHECK-NEXT: movl $4, %ecx | |
| ; CHECK-NEXT: pushl %ebp | |
| ; CHECK-NEXT: pushl %esi | |
| ; CHECK-NEXT: .cfi_remember_state | |
| ; CHECK-NEXT: .cfi_escape 0x0f, 0x06, 0x74, 0x04, 0x06, 0x11, 0x08, 0x22 # | |
| ; CHECK-NEXT: movl %eax, %esi | |
| ; CHECK-NEXT: #APP | |
| ; CHECK-NEXT: rep movsb (%esi), %es:(%edi) | |
| ; CHECK-NEXT: #NO_APP | |
| ; CHECK-NEXT: popl %esi | |
| ; CHECK-NEXT: popl %ebp | |
| ; CHECK-NEXT: .cfi_restore_state | |
| ; CHECK-NEXT: movl 8(%esi), %eax | |
| ; CHECK-NEXT: leal -8(%ebp), %esp | |
| ; CHECK-NEXT: popl %esi | |
| ; CHECK-NEXT: popl %edi | |
| ; CHECK-NEXT: popl %ebp | |
| ; CHECK-NEXT: retl | |
| entry: | |
| %size = alloca i32, align 4 | |
| %g = alloca i32, align 4 | |
| store volatile i32 4, ptr %size, align 4 | |
| %len = load volatile i32, ptr %size, align 4 | |
| %var_array = alloca i8, i32 %len, align 16 | |
| store i32 1, ptr %var_array, align 16 | |
| %nil = call { ptr, ptr, i32 } asm "rep movsb", "={di},={si},={cx},0,1,2,~{memory},~{dirflag},~{fpsr},~{flags},~{ebp}"(ptr %g, ptr %var_array, i32 4) | |
| %retval = load i32, ptr %g, align 4 | |
| ret i32 %retval | |
| } | |