41 changes: 14 additions & 27 deletions llvm/test/CodeGen/ARM/fp16-vector-argument.ll
Original file line number Diff line number Diff line change
Expand Up @@ -145,26 +145,21 @@ entry:
define void @many_args_test(double, float, i16, <4 x half>, <8 x half>, <8 x half>, <8 x half>) {
; SOFT-LABEL: many_args_test:
; SOFT: @ %bb.0: @ %entry
; SOFT-NEXT: push {r11, lr}
; SOFT-NEXT: sub sp, sp, #32
; SOFT-NEXT: add r12, sp, #80
; SOFT-NEXT: add r12, sp, #40
; SOFT-NEXT: vld1.64 {d16, d17}, [r12]
; SOFT-NEXT: add r12, sp, #48
; SOFT-NEXT: add r12, sp, #8
; SOFT-NEXT: vabs.f16 q8, q8
; SOFT-NEXT: vld1.64 {d18, d19}, [r12]
; SOFT-NEXT: add r12, sp, #64
; SOFT-NEXT: add r12, sp, #24
; SOFT-NEXT: vadd.f16 q8, q8, q9
; SOFT-NEXT: vld1.64 {d18, d19}, [r12]
; SOFT-NEXT: add r12, sp, #16
; SOFT-NEXT: vmul.f16 q8, q9, q8
; SOFT-NEXT: vst1.64 {d16, d17}, [r12]
; SOFT-NEXT: mov r12, sp
; SOFT-NEXT: vldr d16, [sp, #40]
; SOFT-NEXT: vst1.16 {d16}, [r12:64]!
; SOFT-NEXT: str r3, [r12]
; SOFT-NEXT: bl use
; SOFT-NEXT: add sp, sp, #32
; SOFT-NEXT: pop {r11, pc}
; SOFT-NEXT: vldr d16, [sp]
; SOFT-NEXT: vstr d16, [sp]
; SOFT-NEXT: str r3, [sp, #8]
; SOFT-NEXT: b use
;
; HARD-LABEL: many_args_test:
; HARD: @ %bb.0: @ %entry
Expand All @@ -177,33 +172,25 @@ define void @many_args_test(double, float, i16, <4 x half>, <8 x half>, <8 x hal
;
; SOFTEB-LABEL: many_args_test:
; SOFTEB: @ %bb.0: @ %entry
; SOFTEB-NEXT: .save {r11, lr}
; SOFTEB-NEXT: push {r11, lr}
; SOFTEB-NEXT: .pad #32
; SOFTEB-NEXT: sub sp, sp, #32
; SOFTEB-NEXT: add r12, sp, #80
; SOFTEB-NEXT: mov lr, sp
; SOFTEB-NEXT: add r12, sp, #40
; SOFTEB-NEXT: vld1.64 {d16, d17}, [r12]
; SOFTEB-NEXT: add r12, sp, #48
; SOFTEB-NEXT: add r12, sp, #8
; SOFTEB-NEXT: vrev64.16 q8, q8
; SOFTEB-NEXT: vabs.f16 q8, q8
; SOFTEB-NEXT: vld1.64 {d18, d19}, [r12]
; SOFTEB-NEXT: add r12, sp, #64
; SOFTEB-NEXT: add r12, sp, #24
; SOFTEB-NEXT: vrev64.16 q9, q9
; SOFTEB-NEXT: vadd.f16 q8, q8, q9
; SOFTEB-NEXT: vld1.64 {d18, d19}, [r12]
; SOFTEB-NEXT: add r12, sp, #16
; SOFTEB-NEXT: vrev64.16 q9, q9
; SOFTEB-NEXT: vmul.f16 q8, q9, q8
; SOFTEB-NEXT: vldr d18, [sp, #40]
; SOFTEB-NEXT: vrev64.16 d18, d18
; SOFTEB-NEXT: vst1.16 {d18}, [lr:64]!
; SOFTEB-NEXT: str r3, [lr]
; SOFTEB-NEXT: vldr d18, [sp]
; SOFTEB-NEXT: vrev64.16 q8, q8
; SOFTEB-NEXT: vst1.64 {d16, d17}, [r12]
; SOFTEB-NEXT: bl use
; SOFTEB-NEXT: add sp, sp, #32
; SOFTEB-NEXT: pop {r11, pc}
; SOFTEB-NEXT: vstr d18, [sp]
; SOFTEB-NEXT: str r3, [sp, #8]
; SOFTEB-NEXT: b use
;
; HARDEB-LABEL: many_args_test:
; HARDEB: @ %bb.0: @ %entry
Expand Down
455 changes: 419 additions & 36 deletions llvm/test/CodeGen/ARM/struct_byval.ll

Large diffs are not rendered by default.

103 changes: 92 additions & 11 deletions llvm/test/CodeGen/ARM/tail-call-float.ll
Original file line number Diff line number Diff line change
@@ -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: {{.*}}