diff --git a/llvm/test/CodeGen/X86/x86-32-intrcc.ll b/llvm/test/CodeGen/X86/x86-32-intrcc.ll index 40b795423eafd..0f465761dd6ee 100644 --- a/llvm/test/CodeGen/X86/x86-32-intrcc.ll +++ b/llvm/test/CodeGen/X86/x86-32-intrcc.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --no_x86_scrub_sp --version 2 ; RUN: llc -mtriple=i686-unknown-unknown < %s | FileCheck %s ; RUN: llc -mtriple=i686-unknown-unknown -O0 < %s | FileCheck %s -check-prefix=CHECK0 @@ -9,18 +10,27 @@ ; Spills eax, putting original esp at +4. ; No stack adjustment if declared with no error code -define x86_intrcc void @test_isr_no_ecode(ptr byval(%struct.interrupt_frame) %frame) { - ; CHECK-LABEL: test_isr_no_ecode: - ; CHECK: pushl %eax - ; CHECK: movl 12(%esp), %eax - ; CHECK: popl %eax - ; CHECK: iretl - ; CHECK0-LABEL: test_isr_no_ecode: - ; CHECK0: pushl %eax - ; CHECK0: leal 4(%esp), %eax - ; CHECK0: movl 8(%eax), %eax - ; CHECK0: popl %eax - ; CHECK0: iretl +define x86_intrcc void @test_isr_no_ecode(ptr byval(%struct.interrupt_frame) %frame) nounwind { +; CHECK-LABEL: test_isr_no_ecode: +; CHECK: # %bb.0: +; CHECK-NEXT: pushl %eax +; CHECK-NEXT: cld +; CHECK-NEXT: movl 12(%esp), %eax +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popl %eax +; CHECK-NEXT: iretl +; +; CHECK0-LABEL: test_isr_no_ecode: +; CHECK0: # %bb.0: +; CHECK0-NEXT: pushl %eax +; CHECK0-NEXT: cld +; CHECK0-NEXT: leal 4(%esp), %eax +; CHECK0-NEXT: movl 8(%eax), %eax +; CHECK0-NEXT: #APP +; CHECK0-NEXT: #NO_APP +; CHECK0-NEXT: popl %eax +; CHECK0-NEXT: iretl %pflags = getelementptr inbounds %struct.interrupt_frame, ptr %frame, i32 0, i32 2 %flags = load i32, ptr %pflags, align 4 call void asm sideeffect "", "r"(i32 %flags) @@ -29,26 +39,35 @@ define x86_intrcc void @test_isr_no_ecode(ptr byval(%struct.interrupt_frame) %fr ; Spills eax and ecx, putting original esp at +8. Stack is adjusted up another 4 bytes ; before return, popping the error code. -define x86_intrcc void @test_isr_ecode(ptr byval(%struct.interrupt_frame) %frame, i32 %ecode) { - ; CHECK-LABEL: test_isr_ecode - ; CHECK: pushl %ecx - ; CHECK: pushl %eax - ; CHECK: movl 8(%esp), %eax - ; CHECK: movl 20(%esp), %ecx - ; CHECK: popl %eax - ; CHECK: popl %ecx - ; CHECK: addl $4, %esp - ; CHECK: iretl - ; CHECK0-LABEL: test_isr_ecode - ; CHECK0: pushl %ecx - ; CHECK0: pushl %eax - ; CHECK0: movl 8(%esp), %ecx - ; CHECK0: leal 12(%esp), %eax - ; CHECK0: movl 8(%eax), %eax - ; CHECK0: popl %eax - ; CHECK0: popl %ecx - ; CHECK0: addl $4, %esp - ; CHECK0: iretl +define x86_intrcc void @test_isr_ecode(ptr byval(%struct.interrupt_frame) %frame, i32 %ecode) nounwind { +; CHECK-LABEL: test_isr_ecode: +; CHECK: # %bb.0: +; CHECK-NEXT: pushl %ecx +; CHECK-NEXT: pushl %eax +; CHECK-NEXT: cld +; CHECK-NEXT: movl 8(%esp), %eax +; CHECK-NEXT: movl 20(%esp), %ecx +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popl %eax +; CHECK-NEXT: popl %ecx +; CHECK-NEXT: addl $4, %esp +; CHECK-NEXT: iretl +; +; CHECK0-LABEL: test_isr_ecode: +; CHECK0: # %bb.0: +; CHECK0-NEXT: pushl %ecx +; CHECK0-NEXT: pushl %eax +; CHECK0-NEXT: cld +; CHECK0-NEXT: movl 8(%esp), %ecx +; CHECK0-NEXT: leal 12(%esp), %eax +; CHECK0-NEXT: movl 8(%eax), %eax +; CHECK0-NEXT: #APP +; CHECK0-NEXT: #NO_APP +; CHECK0-NEXT: popl %eax +; CHECK0-NEXT: popl %ecx +; CHECK0-NEXT: addl $4, %esp +; CHECK0-NEXT: iretl %pflags = getelementptr inbounds %struct.interrupt_frame, ptr %frame, i32 0, i32 2 %flags = load i32, ptr %pflags, align 4 call x86_fastcallcc void asm sideeffect "", "r,r"(i32 %flags, i32 %ecode) @@ -56,39 +75,59 @@ define x86_intrcc void @test_isr_ecode(ptr byval(%struct.interrupt_frame) %frame } ; All clobbered registers must be saved -define x86_intrcc void @test_isr_clobbers(ptr byval(%struct.interrupt_frame) %frame, i32 %ecode) { +define x86_intrcc void @test_isr_clobbers(ptr byval(%struct.interrupt_frame) %frame, i32 %ecode) nounwind { +; CHECK-LABEL: test_isr_clobbers: +; CHECK: # %bb.0: +; CHECK-NEXT: pushl %ebp +; CHECK-NEXT: pushl %ebx +; CHECK-NEXT: pushl %eax +; CHECK-NEXT: cld +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: popl %eax +; CHECK-NEXT: popl %ebx +; CHECK-NEXT: popl %ebp +; CHECK-NEXT: addl $4, %esp +; CHECK-NEXT: iretl +; +; CHECK0-LABEL: test_isr_clobbers: +; CHECK0: # %bb.0: +; CHECK0-NEXT: pushl %ebp +; CHECK0-NEXT: pushl %ebx +; CHECK0-NEXT: pushl %eax +; CHECK0-NEXT: cld +; CHECK0-NEXT: #APP +; CHECK0-NEXT: #NO_APP +; CHECK0-NEXT: popl %eax +; CHECK0-NEXT: popl %ebx +; CHECK0-NEXT: popl %ebp +; CHECK0-NEXT: addl $4, %esp +; CHECK0-NEXT: iretl call void asm sideeffect "", "~{eax},~{ebx},~{ebp}"() - ; CHECK-LABEL: test_isr_clobbers - ; CHECK: pushl %ebp - ; CHECK: pushl %ebx - ; CHECK: pushl %eax - ; CHECK: popl %eax - ; CHECK: popl %ebx - ; CHECK: popl %ebp - ; CHECK: addl $4, %esp - ; CHECK: iretl - ; CHECK0-LABEL: test_isr_clobbers - ; CHECK0: pushl %ebp - ; CHECK0: pushl %ebx - ; CHECK0: pushl %eax - ; CHECK0: popl %eax - ; CHECK0: popl %ebx - ; CHECK0: popl %ebp - ; CHECK0: addl $4, %esp - ; CHECK0: iretl ret void } @f80 = common global x86_fp80 0xK00000000000000000000, align 4 ; Test that the presence of x87 does not crash the FP stackifier -define x86_intrcc void @test_isr_x87(ptr byval(%struct.interrupt_frame) %frame) { - ; CHECK-LABEL: test_isr_x87 - ; CHECK-DAG: fldt f80 - ; CHECK-DAG: fld1 - ; CHECK: faddp - ; CHECK-NEXT: fstpt f80 - ; CHECK-NEXT: iretl +define x86_intrcc void @test_isr_x87(ptr byval(%struct.interrupt_frame) %frame) nounwind { +; CHECK-LABEL: test_isr_x87: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: cld +; CHECK-NEXT: fldt f80 +; CHECK-NEXT: fld1 +; CHECK-NEXT: faddp %st, %st(1) +; CHECK-NEXT: fstpt f80 +; CHECK-NEXT: iretl +; +; CHECK0-LABEL: test_isr_x87: +; CHECK0: # %bb.0: # %entry +; CHECK0-NEXT: cld +; CHECK0-NEXT: fldt f80 +; CHECK0-NEXT: fld1 +; CHECK0-NEXT: faddp %st, %st(1) +; CHECK0-NEXT: fstpt f80 +; CHECK0-NEXT: iretl entry: %ld = load x86_fp80, ptr @f80, align 4 %add = fadd x86_fp80 %ld, 0xK3FFF8000000000000000 @@ -99,17 +138,38 @@ entry: ; Use a frame pointer to check the offsets. No return address, arguments start ; at EBP+4. define dso_local x86_intrcc void @test_fp_1(ptr byval(%struct.interrupt_frame) %p) #0 { - ; CHECK-LABEL: test_fp_1: - ; CHECK: # %bb.0: # %entry - ; CHECK-NEXT: pushl %ebp - ; CHECK-NEXT: movl %esp, %ebp - ; CHECK: cld - ; CHECK-DAG: leal 4(%ebp), %[[R1:[^ ]*]] - ; CHECK-DAG: leal 20(%ebp), %[[R2:[^ ]*]] - ; CHECK: movl %[[R1]], sink_address - ; CHECK: movl %[[R2]], sink_address - ; CHECK: popl %ebp - ; CHECK: iretl +; CHECK-LABEL: test_fp_1: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushl %ebp +; CHECK-NEXT: movl %esp, %ebp +; CHECK-NEXT: pushl %ecx +; CHECK-NEXT: pushl %eax +; CHECK-NEXT: cld +; CHECK-NEXT: leal 20(%ebp), %eax +; CHECK-NEXT: leal 4(%ebp), %ecx +; CHECK-NEXT: movl %ecx, sink_address +; CHECK-NEXT: movl %eax, sink_address +; CHECK-NEXT: popl %eax +; CHECK-NEXT: popl %ecx +; CHECK-NEXT: popl %ebp +; CHECK-NEXT: iretl +; +; CHECK0-LABEL: test_fp_1: +; CHECK0: # %bb.0: # %entry +; CHECK0-NEXT: pushl %ebp +; CHECK0-NEXT: movl %esp, %ebp +; CHECK0-NEXT: pushl %ecx +; CHECK0-NEXT: pushl %eax +; CHECK0-NEXT: cld +; CHECK0-NEXT: leal 4(%ebp), %ecx +; CHECK0-NEXT: movl %ecx, %eax +; CHECK0-NEXT: addl $16, %eax +; CHECK0-NEXT: movl %ecx, sink_address +; CHECK0-NEXT: movl %eax, sink_address +; CHECK0-NEXT: popl %eax +; CHECK0-NEXT: popl %ecx +; CHECK0-NEXT: popl %ebp +; CHECK0-NEXT: iretl entry: %arrayidx2 = getelementptr inbounds %struct.interrupt_frame, ptr %p, i32 0, i32 4 store volatile ptr %p, ptr @sink_address @@ -119,19 +179,48 @@ entry: ; The error code is between EBP and the interrupt_frame. define dso_local x86_intrcc void @test_fp_2(ptr byval(%struct.interrupt_frame) %p, i32 %err) #0 { - ; CHECK-LABEL: test_fp_2: - ; CHECK: # %bb.0: # %entry - ; CHECK-NEXT: pushl %ebp - ; CHECK-NEXT: movl %esp, %ebp - ; CHECK: cld - ; CHECK-DAG: movl 4(%ebp), %[[R3:[^ ]*]] - ; CHECK-DAG: leal 8(%ebp), %[[R1:[^ ]*]] - ; CHECK-DAG: leal 24(%ebp), %[[R2:[^ ]*]] - ; CHECK: movl %[[R1]], sink_address - ; CHECK: movl %[[R2]], sink_address - ; CHECK: movl %[[R3]], sink_i32 - ; CHECK: popl %ebp - ; CHECK: iretl +; CHECK-LABEL: test_fp_2: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushl %ebp +; CHECK-NEXT: movl %esp, %ebp +; CHECK-NEXT: pushl %edx +; CHECK-NEXT: pushl %ecx +; CHECK-NEXT: pushl %eax +; CHECK-NEXT: cld +; CHECK-NEXT: movl 4(%ebp), %eax +; CHECK-NEXT: leal 24(%ebp), %ecx +; CHECK-NEXT: leal 8(%ebp), %edx +; CHECK-NEXT: movl %edx, sink_address +; CHECK-NEXT: movl %ecx, sink_address +; CHECK-NEXT: movl %eax, sink_i32 +; CHECK-NEXT: popl %eax +; CHECK-NEXT: popl %ecx +; CHECK-NEXT: popl %edx +; CHECK-NEXT: popl %ebp +; CHECK-NEXT: addl $4, %esp +; CHECK-NEXT: iretl +; +; CHECK0-LABEL: test_fp_2: +; CHECK0: # %bb.0: # %entry +; CHECK0-NEXT: pushl %ebp +; CHECK0-NEXT: movl %esp, %ebp +; CHECK0-NEXT: pushl %edx +; CHECK0-NEXT: pushl %ecx +; CHECK0-NEXT: pushl %eax +; CHECK0-NEXT: cld +; CHECK0-NEXT: movl 4(%ebp), %eax +; CHECK0-NEXT: leal 8(%ebp), %edx +; CHECK0-NEXT: movl %edx, %ecx +; CHECK0-NEXT: addl $16, %ecx +; CHECK0-NEXT: movl %edx, sink_address +; CHECK0-NEXT: movl %ecx, sink_address +; CHECK0-NEXT: movl %eax, sink_i32 +; CHECK0-NEXT: popl %eax +; CHECK0-NEXT: popl %ecx +; CHECK0-NEXT: popl %edx +; CHECK0-NEXT: popl %ebp +; CHECK0-NEXT: addl $4, %esp +; CHECK0-NEXT: iretl entry: %arrayidx2 = getelementptr inbounds %struct.interrupt_frame, ptr %p, i32 0, i32 4 store volatile ptr %p, ptr @sink_address @@ -142,13 +231,32 @@ entry: ; Test argument copy elision when copied to a local alloca. define x86_intrcc void @test_copy_elide(ptr byval(%struct.interrupt_frame) %frame, i32 %err) #0 { - ; CHECK-LABEL: test_copy_elide: - ; CHECK: # %bb.0: # %entry - ; CHECK-NEXT: pushl %ebp - ; CHECK-NEXT: movl %esp, %ebp - ; CHECK: cld - ; CHECK: leal 4(%ebp), %[[R1:[^ ]*]] - ; CHECK: movl %[[R1]], sink_address +; CHECK-LABEL: test_copy_elide: +; CHECK: # %bb.0: # %entry +; CHECK-NEXT: pushl %ebp +; CHECK-NEXT: movl %esp, %ebp +; CHECK-NEXT: pushl %eax +; CHECK-NEXT: cld +; CHECK-NEXT: leal 4(%ebp), %eax +; CHECK-NEXT: movl %eax, sink_address +; CHECK-NEXT: popl %eax +; CHECK-NEXT: popl %ebp +; CHECK-NEXT: addl $4, %esp +; CHECK-NEXT: iretl +; +; CHECK0-LABEL: test_copy_elide: +; CHECK0: # %bb.0: # %entry +; CHECK0-NEXT: pushl %ebp +; CHECK0-NEXT: movl %esp, %ebp +; CHECK0-NEXT: pushl %eax +; CHECK0-NEXT: cld +; CHECK0-NEXT: movl 4(%ebp), %eax +; CHECK0-NEXT: leal 4(%ebp), %eax +; CHECK0-NEXT: movl %eax, sink_address +; CHECK0-NEXT: popl %eax +; CHECK0-NEXT: popl %ebp +; CHECK0-NEXT: addl $4, %esp +; CHECK0-NEXT: iretl entry: %err.addr = alloca i32, align 4 store i32 %err, ptr %err.addr, align 4