summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/CodeGen')
-rw-r--r--llvm/test/CodeGen/X86/x86-32-intrcc.ll32
-rw-r--r--llvm/test/CodeGen/X86/x86-64-intrcc.ll51
-rw-r--r--llvm/test/CodeGen/X86/x86-no_caller_saved_registers-preserve.ll54
-rw-r--r--llvm/test/CodeGen/X86/x86-no_caller_saved_registers.ll31
4 files changed, 127 insertions, 41 deletions
diff --git a/llvm/test/CodeGen/X86/x86-32-intrcc.ll b/llvm/test/CodeGen/X86/x86-32-intrcc.ll
index 9794f2cb3e4..ac0e7e11e0e 100644
--- a/llvm/test/CodeGen/X86/x86-32-intrcc.ll
+++ b/llvm/test/CodeGen/X86/x86-32-intrcc.ll
@@ -57,23 +57,23 @@ define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i32 %eco
define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i32 %ecode) {
call void asm sideeffect "", "~{eax},~{ebx},~{ebp}"()
; CHECK-LABEL: test_isr_clobbers
- ; CHECK-SSE-NEXT: pushl %ebp
- ; CHECK-SSE-NEXT: pushl %ebx
- ; CHECK-SSE-NEXT; pushl %eax
- ; CHECK-SSE-NEXT: popl %eax
- ; CHECK-SSE-NEXT: popl %ebx
- ; CHECK-SSE-NEXT: popl %ebp
- ; CHECK-SSE-NEXT: addl $4, %esp
- ; CHECK-SSE-NEXT: iretl
+ ; 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-SSE-NEXT: pushl %ebp
- ; CHECK0-SSE-NEXT: pushl %ebx
- ; CHECK0-SSE-NEXT; pushl %eax
- ; CHECK0-SSE-NEXT: popl %eax
- ; CHECK0-SSE-NEXT: popl %ebx
- ; CHECK0-SSE-NEXT: popl %ebp
- ; CHECK0-SSE-NEXT: addl $4, %esp
- ; CHECK0-SSE-NEXT: iretl
+ ; 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
}
diff --git a/llvm/test/CodeGen/X86/x86-64-intrcc.ll b/llvm/test/CodeGen/X86/x86-64-intrcc.ll
index c8bc9e716ce..75ca1af79b3 100644
--- a/llvm/test/CodeGen/X86/x86-64-intrcc.ll
+++ b/llvm/test/CodeGen/X86/x86-64-intrcc.ll
@@ -59,32 +59,33 @@ define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i64 %eco
define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i64 %ecode) {
call void asm sideeffect "", "~{rax},~{rbx},~{rbp},~{r11},~{xmm0}"()
; CHECK-LABEL: test_isr_clobbers
- ; CHECK-SSE-NEXT: pushq %rax
- ; CHECK-SSE-NEXT: pushq %rax
- ; CHECK-SSE-NEXT; pushq %r11
- ; CHECK-SSE-NEXT: pushq %rbp
- ; CHECK-SSE-NEXT: pushq %rbx
- ; CHECK-SSE-NEXT: movaps %xmm0
- ; CHECK-SSE-NEXT: movaps %xmm0
- ; CHECK-SSE-NEXT: popq %rbx
- ; CHECK-SSE-NEXT: popq %rbp
- ; CHECK-SSE-NEXT: popq %r11
- ; CHECK-SSE-NEXT: popq %rax
- ; CHECK-SSE-NEXT: addq $8, %rsp
- ; CHECK-SSE-NEXT: iretq
+
+ ; CHECK: pushq %rax
+ ; CHECK: pushq %rbp
+ ; CHECK: pushq %r11
+ ; CHECK: pushq %rbx
+ ; CHECK: movaps %xmm0
+ ; CHECK: movaps {{.*}}, %xmm0
+ ; CHECK: popq %rbx
+ ; CHECK: popq %r11
+ ; CHECK: popq %rbp
+ ; CHECK: popq %rax
+ ; CHECK: addq $16, %rsp
+ ; CHECK: iretq
; CHECK0-LABEL: test_isr_clobbers
- ; CHECK0-SSE-NEXT: pushq %rax
- ; CHECK0-SSE-NEXT; pushq %r11
- ; CHECK0-SSE-NEXT: pushq %rbp
- ; CHECK0-SSE-NEXT: pushq %rbx
- ; CHECK0-SSE-NEXT: movaps %xmm0
- ; CHECK0-SSE-NEXT: movaps %xmm0
- ; CHECK0-SSE-NEXT: popq %rbx
- ; CHECK0-SSE-NEXT: popq %rbp
- ; CHECK0-SSE-NEXT: popq %r11
- ; CHECK0-SSE-NEXT: popq %rax
- ; CHECK0-SSE-NEXT: addq $16, %rsp
- ; CHECK0-SSE-NEXT: iretq
+
+ ; CHECK0: pushq %rax
+ ; CHECK0: pushq %rbp
+ ; CHECK0: pushq %r11
+ ; CHECK0: pushq %rbx
+ ; CHECK0: movaps %xmm0
+ ; CHECK0: movaps {{.*}}, %xmm0
+ ; CHECK0: popq %rbx
+ ; CHECK0: popq %r11
+ ; CHECK0: popq %rbp
+ ; CHECK0: popq %rax
+ ; CHECK0: addq $16, %rsp
+ ; CHECK0: iretq
ret void
}
diff --git a/llvm/test/CodeGen/X86/x86-no_caller_saved_registers-preserve.ll b/llvm/test/CodeGen/X86/x86-no_caller_saved_registers-preserve.ll
new file mode 100644
index 00000000000..7e370c25e31
--- /dev/null
+++ b/llvm/test/CodeGen/X86/x86-no_caller_saved_registers-preserve.ll
@@ -0,0 +1,54 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py for function "bar"
+; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
+
+;; In functions with 'no_caller_saved_registers' attribute, all registers should
+;; be preserved except for registers used for passing/returning arguments.
+;; In the following function registers %RDI, %RSI and %XMM0 are used to store
+;; arguments %a0, %a1 and %b0 accordingally. The value is returned in %RAX.
+;; The above registers should not be preserved, however other registers
+;; (that are modified by the function) should be preserved (%RDX and %XMM1).
+define x86_64_sysvcc i32 @bar(i32 %a0, i32 %a1, float %b0) #0 {
+; CHECK-LABEL: bar:
+; CHECK: # BB#0:
+; CHECK-NEXT: pushq %rdx
+; CHECK-NEXT: .Lcfi0:
+; CHECK-NEXT: .cfi_def_cfa_offset 16
+; CHECK-NEXT: movaps %xmm1, -{{[0-9]+}}(%rsp) # 16-byte Spill
+; CHECK-NEXT: .Lcfi1:
+; CHECK-NEXT: .cfi_offset %rdx, -16
+; CHECK-NEXT: .Lcfi2:
+; CHECK-NEXT: .cfi_offset %xmm1, -32
+; CHECK-NEXT: #APP
+; CHECK-NEXT: #NO_APP
+; CHECK-NEXT: movl $4, %eax
+; CHECK-NEXT: movaps -{{[0-9]+}}(%rsp), %xmm1 # 16-byte Reload
+; CHECK-NEXT: popq %rdx
+; CHECK-NEXT: retq
+ call void asm sideeffect "", "~{rax},~{rdx},~{xmm1},~{rdi},~{rsi},~{xmm0}"()
+ ret i32 4
+}
+
+;; Because "bar" has 'no_caller_saved_registers' attribute, function "foo"
+;; doesn't need to preserve registers except for the arguments passed
+;; to "bar" (%ESI, %EDI and %XMM0).
+define x86_64_sysvcc float @foo(i32 %a0, i32 %a1, float %b0) {
+; CHECK-LABEL: foo
+; CHECK: movaps %xmm0, %xmm1
+; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: movl %edi, %edx
+; CHECK-NEXT: callq bar
+; CHECK-NEXT: addl %edx, %eax
+; CHECK-NEXT: addl %ecx, %eax
+; CHECK-NEXT: xorps %xmm0, %xmm0
+; CHECK-NEXT: cvtsi2ssl %eax, %xmm0
+; CHECK-NEXT: addss %xmm0, %xmm1
+; CHECK: retq
+ %call = call i32 @bar(i32 %a0, i32 %a1, float %b0) #0
+ %c0 = add i32 %a0, %call
+ %c1 = add i32 %c0, %a1
+ %c2 = sitofp i32 %c1 to float
+ %c3 = fadd float %c2, %b0
+ ret float %c3
+}
+
+attributes #0 = { "no_caller_saved_registers" }
diff --git a/llvm/test/CodeGen/X86/x86-no_caller_saved_registers.ll b/llvm/test/CodeGen/X86/x86-no_caller_saved_registers.ll
new file mode 100644
index 00000000000..9c62e3ee6ba
--- /dev/null
+++ b/llvm/test/CodeGen/X86/x86-no_caller_saved_registers.ll
@@ -0,0 +1,31 @@
+; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-unknown-unknown -O0 < %s | FileCheck %s
+; RUN: llc -mtriple=i686-unknown-unknown -mattr=+sse2 < %s | FileCheck %s
+; RUN: llc -mtriple=i686-unknown-unknown -mattr=+sse2 -O0 < %s | FileCheck %s
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; In functions with 'no_caller_saved_registers' attribute, all registers should
+;; be preserved except for registers used for passing/returning arguments.
+;; The test checks that function "bar" preserves xmm0 register.
+;; It also checks that caller function "foo" does not store registers for callee
+;; "bar". For example, there is no store/load/access to xmm registers.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+define i32 @bar(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7, i32 %a8) #0 {
+; CHECK-LABEL: bar
+; CHECK: mov{{.*}} %xmm0
+; CHECK: mov{{.*}} {{.*}}, %xmm0
+; CHECK: ret
+ call void asm sideeffect "", "~{xmm0}"()
+ ret i32 1
+}
+
+define x86_intrcc void @foo(i8* nocapture readnone %c) {
+; CHECK-LABEL: foo
+; CHECK-NOT: xmm
+entry:
+ tail call i32 @bar(i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8) #0
+ ret void
+}
+
+attributes #0 = { "no_caller_saved_registers" }
OpenPOWER on IntegriCloud