@@ -1,7 +1,8 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple armv7 -target-abi aapcs -float-abi soft -O0 -o - < %s \
; RUN: | FileCheck %s -check-prefix CHECK-SOFT -check-prefix CHECK
; RUN: | FileCheck %s -check-prefix CHECK-SOFT
; RUN: llc -mtriple armv7 -target-abi aapcs -float-abi hard -O0 -o - < %s \
; RUN: | FileCheck %s -check-prefix CHECK-HARD -check-prefix CHECK
; RUN: | FileCheck %s -check-prefix CHECK-HARD
; Tests for passing floating-point regs. Variadic functions will always use
; general-purpose registers. Standard functions will use the floating-point
Expand All
@@ -12,16 +13,42 @@ declare i1 @non_variadic_big(float, float, float, float, float, float)
declare i1 @variadic (float , ...)
define void @non_variadic_fp (float %x , float %y ) {
; CHECK-LABEL: non_variadic_fp:
; CHECK: b non_variadic
; CHECK-SOFT-LABEL: non_variadic_fp:
; CHECK-SOFT: @ %bb.0: @ %entry
; CHECK-SOFT-NEXT: mov r3, r1
; CHECK-SOFT-NEXT: mov r2, r0
; CHECK-SOFT-NEXT: mov r0, r3
; CHECK-SOFT-NEXT: mov r1, r2
; CHECK-SOFT-NEXT: b non_variadic
;
; CHECK-HARD-LABEL: non_variadic_fp:
; CHECK-HARD: @ %bb.0: @ %entry
; CHECK-HARD-NEXT: vmov.f32 s3, s1
; CHECK-HARD-NEXT: vmov.f32 s2, s0
; CHECK-HARD-NEXT: vmov.f32 s0, s3
; CHECK-HARD-NEXT: vmov.f32 s1, s2
; CHECK-HARD-NEXT: b non_variadic
entry:
%call = tail call i1 (float , float , float , float ) @non_variadic (float %y , float %x , float %x , float %y )
ret void
}
define void @variadic_fp (float %x , float %y ) {
; CHECK-LABEL: variadic_fp:
; CHECK: b variadic
; CHECK-SOFT-LABEL: variadic_fp:
; CHECK-SOFT: @ %bb.0: @ %entry
; CHECK-SOFT-NEXT: mov r3, r1
; CHECK-SOFT-NEXT: mov r2, r0
; CHECK-SOFT-NEXT: mov r0, r3
; CHECK-SOFT-NEXT: mov r1, r2
; CHECK-SOFT-NEXT: b variadic
;
; CHECK-HARD-LABEL: variadic_fp:
; CHECK-HARD: @ %bb.0: @ %entry
; CHECK-HARD-NEXT: vmov r2, s0
; CHECK-HARD-NEXT: vmov r3, s1
; CHECK-HARD-NEXT: mov r0, r3
; CHECK-HARD-NEXT: mov r1, r2
; CHECK-HARD-NEXT: b variadic
entry:
%call = tail call i1 (float , ...) @variadic (float %y , float %x , float %x , float %y )
ret void
Expand All
@@ -31,19 +58,73 @@ entry:
; of them to handle the 6 arguments. With hard-float, we have plenty of regs
; (s0-s15) to pass FP arguments.
define void @non_variadic_fp_big (float %x , float %y ) {
; CHECK-LABEL: non_variadic_fp_big:
; CHECK-SOFT: bl non_variadic_big
; CHECK-HARD: b non_variadic_big
; CHECK-SOFT-LABEL: non_variadic_fp_big:
; CHECK-SOFT: @ %bb.0: @ %entry
; CHECK-SOFT-NEXT: push {r11, lr}
; CHECK-SOFT-NEXT: sub sp, sp, #8
; CHECK-SOFT-NEXT: mov r3, r1
; CHECK-SOFT-NEXT: mov r2, r0
; CHECK-SOFT-NEXT: vmov s0, r3
; CHECK-SOFT-NEXT: vmov s0, r2
; CHECK-SOFT-NEXT: mov r0, sp
; CHECK-SOFT-NEXT: str r3, [r0, #4]
; CHECK-SOFT-NEXT: str r2, [r0]
; CHECK-SOFT-NEXT: mov r0, r3
; CHECK-SOFT-NEXT: mov r1, r2
; CHECK-SOFT-NEXT: bl non_variadic_big
; CHECK-SOFT-NEXT: add sp, sp, #8
; CHECK-SOFT-NEXT: pop {r11, pc}
;
; CHECK-HARD-LABEL: non_variadic_fp_big:
; CHECK-HARD: @ %bb.0: @ %entry
; CHECK-HARD-NEXT: vmov.f32 s5, s1
; CHECK-HARD-NEXT: vmov.f32 s4, s0
; CHECK-HARD-NEXT: vmov.f32 s0, s5
; CHECK-HARD-NEXT: vmov.f32 s1, s4
; CHECK-HARD-NEXT: vmov.f32 s2, s4
; CHECK-HARD-NEXT: vmov.f32 s3, s5
; CHECK-HARD-NEXT: b non_variadic_big
entry:
%call = tail call i1 (float , float , float , float , float , float ) @non_variadic_big (float %y , float %x , float %x , float %y , float %x , float %y )
ret void
}
; Variadic functions cannot use FP regs to pass arguments; only GP regs.
define void @variadic_fp_big (float %x , float %y ) {
; CHECK-LABEL: variadic_fp_big:
; CHECK: bl variadic
; CHECK-SOFT-LABEL: variadic_fp_big:
; CHECK-SOFT: @ %bb.0: @ %entry
; CHECK-SOFT-NEXT: push {r11, lr}
; CHECK-SOFT-NEXT: sub sp, sp, #8
; CHECK-SOFT-NEXT: mov r3, r1
; CHECK-SOFT-NEXT: mov r2, r0
; CHECK-SOFT-NEXT: vmov s0, r3
; CHECK-SOFT-NEXT: vmov s0, r2
; CHECK-SOFT-NEXT: mov r0, sp
; CHECK-SOFT-NEXT: str r3, [r0, #4]
; CHECK-SOFT-NEXT: str r2, [r0]
; CHECK-SOFT-NEXT: mov r0, r3
; CHECK-SOFT-NEXT: mov r1, r2
; CHECK-SOFT-NEXT: bl variadic
; CHECK-SOFT-NEXT: add sp, sp, #8
; CHECK-SOFT-NEXT: pop {r11, pc}
;
; CHECK-HARD-LABEL: variadic_fp_big:
; CHECK-HARD: @ %bb.0: @ %entry
; CHECK-HARD-NEXT: push {r11, lr}
; CHECK-HARD-NEXT: sub sp, sp, #8
; CHECK-HARD-NEXT: mov r0, sp
; CHECK-HARD-NEXT: vstr s1, [r0, #4]
; CHECK-HARD-NEXT: vstr s0, [r0]
; CHECK-HARD-NEXT: vmov r2, s0
; CHECK-HARD-NEXT: vmov r3, s1
; CHECK-HARD-NEXT: mov r0, r3
; CHECK-HARD-NEXT: mov r1, r2
; CHECK-HARD-NEXT: bl variadic
; CHECK-HARD-NEXT: add sp, sp, #8
; CHECK-HARD-NEXT: pop {r11, pc}
entry:
%call = tail call i1 (float , ...) @variadic (float %y , float %x , float %x , float %y , float %x , float %y )
ret void
}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CHECK: {{.*}}