This reverts commit 9c319d5bb4.
Some issues were discovered with the bootstrap builds, which
seem like they were caused by this commit. I'm reverting to investigate.
1780 lines
53 KiB
LLVM
1780 lines
53 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: llc < %s -mtriple aarch64-unknown-unknown | FileCheck %s --check-prefixes=CHECK,CHECK-CVT,CHECK-CVT-SD
|
|
; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 | FileCheck %s --check-prefixes=CHECK,CHECK-FP16,CHECK-FP16-SD
|
|
; RUN: llc < %s -mtriple aarch64-unknown-unknown -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-CVT,CHECK-CVT-GI
|
|
; RUN: llc < %s -mtriple aarch64-unknown-unknown -mattr=+fullfp16 -global-isel | FileCheck %s --check-prefixes=CHECK,CHECK-FP16,CHECK-FP16-GI
|
|
|
|
define half @test_fadd(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fadd:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fadd s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fadd:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fadd h0, h0, h1
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fadd:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fadd s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fadd half %a, %b
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fsub(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fsub:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fsub s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fsub:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fsub h0, h0, h1
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fsub:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fsub s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fsub half %a, %b
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fmul(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fmul:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fmul s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fmul:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fmul h0, h0, h1
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fmul:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fmul s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fmul half %a, %b
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fmadd(half %a, half %b, half %c) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fmadd:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fmul s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h2
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fadd s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fmadd:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fmadd:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fmul s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h2
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fadd s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%mul = fmul fast half %a, %b
|
|
%r = fadd fast half %mul, %c
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fdiv(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fdiv:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fdiv s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fdiv:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fdiv h0, h0, h1
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fdiv:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fdiv s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fdiv half %a, %b
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_frem(half %a, half %b) #0 {
|
|
; CHECK-LABEL: test_frem:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: fcvt s1, h1
|
|
; CHECK-NEXT: bl fmodf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = frem half %a, %b
|
|
ret half %r
|
|
}
|
|
|
|
define void @test_store(half %a, ptr %b) #0 {
|
|
; CHECK-LABEL: test_store:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str h0, [x0]
|
|
; CHECK-NEXT: ret
|
|
store half %a, ptr %b
|
|
ret void
|
|
}
|
|
|
|
define half @test_load(ptr %a) #0 {
|
|
; CHECK-LABEL: test_load:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ldr h0, [x0]
|
|
; CHECK-NEXT: ret
|
|
%r = load half, ptr %a
|
|
ret half %r
|
|
}
|
|
|
|
declare half @test_callee(half %a, half %b) #0
|
|
|
|
define half @test_call(half %a, half %b) #0 {
|
|
; CHECK-LABEL: test_call:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: bl test_callee
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @test_callee(half %a, half %b)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_call_flipped(half %a, half %b) #0 {
|
|
; CHECK-LABEL: test_call_flipped:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fmov s2, s0
|
|
; CHECK-NEXT: fmov s0, s1
|
|
; CHECK-NEXT: fmov s1, s2
|
|
; CHECK-NEXT: bl test_callee
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @test_callee(half %b, half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_tailcall_flipped(half %a, half %b) #0 {
|
|
; CHECK-LABEL: test_tailcall_flipped:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: fmov s2, s0
|
|
; CHECK-NEXT: fmov s0, s1
|
|
; CHECK-NEXT: fmov s1, s2
|
|
; CHECK-NEXT: b test_callee
|
|
%r = tail call half @test_callee(half %b, half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_select(half %a, half %b, i1 zeroext %c) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_select:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-SD-NEXT: cmp w0, #0
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, ne
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_select:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: cmp w0, #0
|
|
; CHECK-FP16-SD-NEXT: fcsel h0, h0, h1, ne
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_select:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-CVT-GI-NEXT: fmov w8, s0
|
|
; CHECK-CVT-GI-NEXT: fmov w9, s1
|
|
; CHECK-CVT-GI-NEXT: tst w0, #0x1
|
|
; CHECK-CVT-GI-NEXT: csel w8, w8, w9, ne
|
|
; CHECK-CVT-GI-NEXT: fmov s0, w8
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_select:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-FP16-GI-NEXT: fmov w8, s0
|
|
; CHECK-FP16-GI-NEXT: fmov w9, s1
|
|
; CHECK-FP16-GI-NEXT: tst w0, #0x1
|
|
; CHECK-FP16-GI-NEXT: csel w8, w8, w9, ne
|
|
; CHECK-FP16-GI-NEXT: fmov s0, w8
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%r = select i1 %c, half %a, half %b
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_select_cc(half %a, half %b, half %c, half %d) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_select_cc:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s3, h3
|
|
; CHECK-CVT-SD-NEXT: fcvt s2, h2
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-CVT-SD-NEXT: fcmp s2, s3
|
|
; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, ne
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_select_cc:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: fcmp h2, h3
|
|
; CHECK-FP16-SD-NEXT: fcsel h0, h0, h1, ne
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_select_cc:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s2, h2
|
|
; CHECK-CVT-GI-NEXT: fcvt s3, h3
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-CVT-GI-NEXT: fmov w8, s0
|
|
; CHECK-CVT-GI-NEXT: fmov w9, s1
|
|
; CHECK-CVT-GI-NEXT: fcmp s2, s3
|
|
; CHECK-CVT-GI-NEXT: csel w8, w8, w9, ne
|
|
; CHECK-CVT-GI-NEXT: fmov s0, w8
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_select_cc:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-FP16-GI-NEXT: fcmp h2, h3
|
|
; CHECK-FP16-GI-NEXT: fmov w8, s0
|
|
; CHECK-FP16-GI-NEXT: fmov w9, s1
|
|
; CHECK-FP16-GI-NEXT: csel w8, w8, w9, ne
|
|
; CHECK-FP16-GI-NEXT: fmov s0, w8
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%cc = fcmp une half %c, %d
|
|
%r = select i1 %cc, half %a, half %b
|
|
ret half %r
|
|
}
|
|
|
|
define float @test_select_cc_f32_f16(float %a, float %b, half %c, half %d) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_select_cc_f32_f16:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s3, h3
|
|
; CHECK-CVT-SD-NEXT: fcvt s2, h2
|
|
; CHECK-CVT-SD-NEXT: fcmp s2, s3
|
|
; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, ne
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_select_cc_f32_f16:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h2, h3
|
|
; CHECK-FP16-NEXT: fcsel s0, s0, s1, ne
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_select_cc_f32_f16:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s2, h2
|
|
; CHECK-CVT-GI-NEXT: fcvt s3, h3
|
|
; CHECK-CVT-GI-NEXT: fcmp s2, s3
|
|
; CHECK-CVT-GI-NEXT: fcsel s0, s0, s1, ne
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%cc = fcmp une half %c, %d
|
|
%r = select i1 %cc, float %a, float %b
|
|
ret float %r
|
|
}
|
|
|
|
define half @test_select_cc_f16_f32(half %a, half %b, float %c, float %d) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_select_cc_f16_f32:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcmp s2, s3
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, ne
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_select_cc_f16_f32:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: fcmp s2, s3
|
|
; CHECK-FP16-SD-NEXT: fcsel h0, h0, h1, ne
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_select_cc_f16_f32:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-CVT-GI-NEXT: fcmp s2, s3
|
|
; CHECK-CVT-GI-NEXT: fmov w8, s0
|
|
; CHECK-CVT-GI-NEXT: fmov w9, s1
|
|
; CHECK-CVT-GI-NEXT: csel w8, w8, w9, ne
|
|
; CHECK-CVT-GI-NEXT: fmov s0, w8
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_select_cc_f16_f32:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $s1
|
|
; CHECK-FP16-GI-NEXT: fcmp s2, s3
|
|
; CHECK-FP16-GI-NEXT: fmov w8, s0
|
|
; CHECK-FP16-GI-NEXT: fmov w9, s1
|
|
; CHECK-FP16-GI-NEXT: csel w8, w8, w9, ne
|
|
; CHECK-FP16-GI-NEXT: fmov s0, w8
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%cc = fcmp une float %c, %d
|
|
%r = select i1 %cc, half %a, half %b
|
|
ret half %r
|
|
}
|
|
|
|
define i1 @test_fcmp_une(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_une:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, ne
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_une:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, ne
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_une:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, ne
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp une half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_ueq(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_ueq:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w8, eq
|
|
; CHECK-CVT-SD-NEXT: csinc w0, w8, wzr, vc
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_fcmp_ueq:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-SD-NEXT: cset w8, eq
|
|
; CHECK-FP16-SD-NEXT: csinc w0, w8, wzr, vc
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_ueq:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w8, eq
|
|
; CHECK-CVT-GI-NEXT: cset w9, vs
|
|
; CHECK-CVT-GI-NEXT: orr w0, w8, w9
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_fcmp_ueq:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-GI-NEXT: cset w8, eq
|
|
; CHECK-FP16-GI-NEXT: cset w9, vs
|
|
; CHECK-FP16-GI-NEXT: orr w0, w8, w9
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%r = fcmp ueq half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_ugt(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_ugt:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, hi
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_ugt:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, hi
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_ugt:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, hi
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp ugt half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_uge(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_uge:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, pl
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_uge:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, pl
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_uge:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, pl
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp uge half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_ult(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_ult:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, lt
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_ult:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, lt
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_ult:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, lt
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp ult half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_ule(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_ule:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, le
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_ule:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, le
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_ule:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, le
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp ule half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_uno(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_uno:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, vs
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_uno:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, vs
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_uno:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, vs
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp uno half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_one(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_one:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w8, mi
|
|
; CHECK-CVT-SD-NEXT: csinc w0, w8, wzr, le
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_fcmp_one:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-SD-NEXT: cset w8, mi
|
|
; CHECK-FP16-SD-NEXT: csinc w0, w8, wzr, le
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_one:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w8, mi
|
|
; CHECK-CVT-GI-NEXT: cset w9, gt
|
|
; CHECK-CVT-GI-NEXT: orr w0, w8, w9
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_fcmp_one:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-GI-NEXT: cset w8, mi
|
|
; CHECK-FP16-GI-NEXT: cset w9, gt
|
|
; CHECK-FP16-GI-NEXT: orr w0, w8, w9
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%r = fcmp one half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_oeq(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_oeq:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, eq
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_oeq:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, eq
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_oeq:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, eq
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp oeq half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_ogt(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_ogt:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, gt
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_ogt:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, gt
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_ogt:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, gt
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp ogt half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_oge(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_oge:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, ge
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_oge:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, ge
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_oge:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, ge
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp oge half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_olt(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_olt:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, mi
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_olt:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, mi
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_olt:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, mi
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp olt half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_ole(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_ole:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, ls
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_ole:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, ls
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_ole:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, ls
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp ole half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define i1 @test_fcmp_ord(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fcmp_ord:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: cset w0, vc
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fcmp_ord:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: cset w0, vc
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fcmp_ord:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: cset w0, vc
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = fcmp ord half %a, %b
|
|
ret i1 %r
|
|
}
|
|
|
|
define void @test_fccmp(half %in, ptr %out) {
|
|
; CHECK-CVT-SD-LABEL: test_fccmp:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h0
|
|
; CHECK-CVT-SD-NEXT: fmov s2, #5.00000000
|
|
; CHECK-CVT-SD-NEXT: adrp x8, .LCPI29_0
|
|
; CHECK-CVT-SD-NEXT: fcmp s1, s2
|
|
; CHECK-CVT-SD-NEXT: fmov s2, #8.00000000
|
|
; CHECK-CVT-SD-NEXT: fccmp s1, s2, #4, mi
|
|
; CHECK-CVT-SD-NEXT: ldr h1, [x8, :lo12:.LCPI29_0]
|
|
; CHECK-CVT-SD-NEXT: fcsel s0, s0, s1, gt
|
|
; CHECK-CVT-SD-NEXT: str h0, [x0]
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_fccmp:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: fmov h1, #5.00000000
|
|
; CHECK-FP16-SD-NEXT: fmov h2, #8.00000000
|
|
; CHECK-FP16-SD-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-SD-NEXT: fccmp h0, h2, #4, mi
|
|
; CHECK-FP16-SD-NEXT: fcsel h0, h0, h1, gt
|
|
; CHECK-FP16-SD-NEXT: str h0, [x0]
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fccmp:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: mov w8, #17664 // =0x4500
|
|
; CHECK-CVT-GI-NEXT: mov w9, #18432 // =0x4800
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-GI-NEXT: fcvt s2, h0
|
|
; CHECK-CVT-GI-NEXT: fmov s1, w8
|
|
; CHECK-CVT-GI-NEXT: fmov s3, w9
|
|
; CHECK-CVT-GI-NEXT: fmov w9, s0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcvt s3, h3
|
|
; CHECK-CVT-GI-NEXT: fcmp s2, s1
|
|
; CHECK-CVT-GI-NEXT: fccmp s2, s3, #4, mi
|
|
; CHECK-CVT-GI-NEXT: csel w8, w9, w8, gt
|
|
; CHECK-CVT-GI-NEXT: strh w8, [x0]
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_fccmp:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: fmov h1, #5.00000000
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-FP16-GI-NEXT: fmov h2, #8.00000000
|
|
; CHECK-FP16-GI-NEXT: fmov w8, s0
|
|
; CHECK-FP16-GI-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-GI-NEXT: fmov w9, s1
|
|
; CHECK-FP16-GI-NEXT: fccmp h0, h2, #4, mi
|
|
; CHECK-FP16-GI-NEXT: csel w8, w8, w9, gt
|
|
; CHECK-FP16-GI-NEXT: strh w8, [x0]
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%cmp1 = fcmp ogt half %in, 0xH4800
|
|
%cmp2 = fcmp olt half %in, 0xH4500
|
|
%cond = and i1 %cmp1, %cmp2
|
|
%result = select i1 %cond, half %in, half 0xH4500
|
|
store half %result, ptr %out
|
|
ret void
|
|
}
|
|
|
|
define void @test_br_cc(half %a, half %b, ptr %p1, ptr %p2) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_br_cc:
|
|
; CHECK-CVT-SD: // %bb.0: // %common.ret
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-SD-NEXT: csel x8, x0, x1, pl
|
|
; CHECK-CVT-SD-NEXT: str wzr, [x8]
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_br_cc:
|
|
; CHECK-FP16: // %bb.0: // %common.ret
|
|
; CHECK-FP16-NEXT: fcmp h0, h1
|
|
; CHECK-FP16-NEXT: csel x8, x0, x1, pl
|
|
; CHECK-FP16-NEXT: str wzr, [x8]
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_br_cc:
|
|
; CHECK-CVT-GI: // %bb.0: // %common.ret
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcmp s0, s1
|
|
; CHECK-CVT-GI-NEXT: csel x8, x0, x1, pl
|
|
; CHECK-CVT-GI-NEXT: str wzr, [x8]
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%c = fcmp uge half %a, %b
|
|
br i1 %c, label %then, label %else
|
|
then:
|
|
store i32 0, ptr %p1
|
|
ret void
|
|
else:
|
|
store i32 0, ptr %p2
|
|
ret void
|
|
}
|
|
|
|
define half @test_phi(ptr %p1) #0 {
|
|
; CHECK-LABEL: test_phi:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: stp d9, d8, [sp, #-32]! // 16-byte Folded Spill
|
|
; CHECK-NEXT: ldr h9, [x0]
|
|
; CHECK-NEXT: stp x30, x19, [sp, #16] // 16-byte Folded Spill
|
|
; CHECK-NEXT: mov x19, x0
|
|
; CHECK-NEXT: .LBB31_1: // %loop
|
|
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
|
; CHECK-NEXT: fmov s8, s9
|
|
; CHECK-NEXT: ldr h9, [x19]
|
|
; CHECK-NEXT: mov x0, x19
|
|
; CHECK-NEXT: bl test_dummy
|
|
; CHECK-NEXT: tbnz w0, #0, .LBB31_1
|
|
; CHECK-NEXT: // %bb.2: // %return
|
|
; CHECK-NEXT: ldp x30, x19, [sp, #16] // 16-byte Folded Reload
|
|
; CHECK-NEXT: fmov s0, s8
|
|
; CHECK-NEXT: ldp d9, d8, [sp], #32 // 16-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%a = load half, ptr %p1
|
|
br label %loop
|
|
loop:
|
|
%r = phi half [%a, %entry], [%b, %loop]
|
|
%b = load half, ptr %p1
|
|
%c = call i1 @test_dummy(ptr %p1)
|
|
br i1 %c, label %loop, label %return
|
|
return:
|
|
ret half %r
|
|
}
|
|
|
|
declare i1 @test_dummy(ptr %p1) #0
|
|
|
|
define i32 @test_fptosi_i32(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_fptosi_i32:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: fcvtzs w0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fptosi_i32:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcvtzs w0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = fptosi half %a to i32
|
|
ret i32 %r
|
|
}
|
|
|
|
define i64 @test_fptosi_i64(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_fptosi_i64:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: fcvtzs x0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fptosi_i64:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcvtzs x0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = fptosi half %a to i64
|
|
ret i64 %r
|
|
}
|
|
|
|
define i32 @test_fptoui_i32(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_fptoui_i32:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: fcvtzu w0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fptoui_i32:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcvtzu w0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = fptoui half %a to i32
|
|
ret i32 %r
|
|
}
|
|
|
|
define i64 @test_fptoui_i64(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_fptoui_i64:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: fcvtzu x0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fptoui_i64:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fcvtzu x0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = fptoui half %a to i64
|
|
ret i64 %r
|
|
}
|
|
|
|
define half @test_uitofp_i32(i32 %a) #0 {
|
|
; CHECK-CVT-LABEL: test_uitofp_i32:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: ucvtf s0, w0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_uitofp_i32:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: ucvtf h0, w0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = uitofp i32 %a to half
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_uitofp_i64(i64 %a) #0 {
|
|
; CHECK-CVT-LABEL: test_uitofp_i64:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: ucvtf s0, x0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_uitofp_i64:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: ucvtf h0, x0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = uitofp i64 %a to half
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_sitofp_i32(i32 %a) #0 {
|
|
; CHECK-CVT-LABEL: test_sitofp_i32:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: scvtf s0, w0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_sitofp_i32:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: scvtf h0, w0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = sitofp i32 %a to half
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_sitofp_i64(i64 %a) #0 {
|
|
; CHECK-CVT-LABEL: test_sitofp_i64:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: scvtf s0, x0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_sitofp_i64:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: scvtf h0, x0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = sitofp i64 %a to half
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_uitofp_i32_fadd(i32 %a, half %b) #0 {
|
|
; CHECK-CVT-LABEL: test_uitofp_i32_fadd:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: ucvtf s1, w0
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: fcvt h1, s1
|
|
; CHECK-CVT-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-NEXT: fadd s0, s0, s1
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_uitofp_i32_fadd:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: ucvtf h1, w0
|
|
; CHECK-FP16-NEXT: fadd h0, h0, h1
|
|
; CHECK-FP16-NEXT: ret
|
|
%c = uitofp i32 %a to half
|
|
%r = fadd half %b, %c
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_sitofp_i32_fadd(i32 %a, half %b) #0 {
|
|
; CHECK-CVT-LABEL: test_sitofp_i32_fadd:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: scvtf s1, w0
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: fcvt h1, s1
|
|
; CHECK-CVT-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-NEXT: fadd s0, s0, s1
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_sitofp_i32_fadd:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: scvtf h1, w0
|
|
; CHECK-FP16-NEXT: fadd h0, h0, h1
|
|
; CHECK-FP16-NEXT: ret
|
|
%c = sitofp i32 %a to half
|
|
%r = fadd half %b, %c
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fptrunc_float(float %a) #0 {
|
|
; CHECK-LABEL: test_fptrunc_float:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ret
|
|
%r = fptrunc float %a to half
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fptrunc_double(double %a) #0 {
|
|
; CHECK-LABEL: test_fptrunc_double:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: fcvt h0, d0
|
|
; CHECK-NEXT: ret
|
|
%r = fptrunc double %a to half
|
|
ret half %r
|
|
}
|
|
|
|
define float @test_fpext_float(half %a) #0 {
|
|
; CHECK-LABEL: test_fpext_float:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: ret
|
|
%r = fpext half %a to float
|
|
ret float %r
|
|
}
|
|
|
|
define double @test_fpext_double(half %a) #0 {
|
|
; CHECK-LABEL: test_fpext_double:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: fcvt d0, h0
|
|
; CHECK-NEXT: ret
|
|
%r = fpext half %a to double
|
|
ret double %r
|
|
}
|
|
|
|
define i16 @test_bitcast_halftoi16(half %a) #0 {
|
|
; CHECK-LABEL: test_bitcast_halftoi16:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-NEXT: fmov w0, s0
|
|
; CHECK-NEXT: ret
|
|
%r = bitcast half %a to i16
|
|
ret i16 %r
|
|
}
|
|
|
|
define half @test_bitcast_i16tohalf(i16 %a) #0 {
|
|
; CHECK-LABEL: test_bitcast_i16tohalf:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: fmov s0, w0
|
|
; CHECK-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-NEXT: ret
|
|
%r = bitcast i16 %a to half
|
|
ret half %r
|
|
}
|
|
|
|
declare half @llvm.sqrt.f16(half %a) #0
|
|
declare half @llvm.powi.f16.i32(half %a, i32 %b) #0
|
|
declare half @llvm.sin.f16(half %a) #0
|
|
declare half @llvm.cos.f16(half %a) #0
|
|
declare half @llvm.tan.f16(half %a) #0
|
|
declare half @llvm.asin.f16(half %a) #0
|
|
declare half @llvm.acos.f16(half %a) #0
|
|
declare half @llvm.atan.f16(half %a) #0
|
|
declare half @llvm.atan2.f16(half %a, half %b) #0
|
|
declare half @llvm.sinh.f16(half %a) #0
|
|
declare half @llvm.cosh.f16(half %a) #0
|
|
declare half @llvm.tanh.f16(half %a) #0
|
|
declare half @llvm.pow.f16(half %a, half %b) #0
|
|
declare half @llvm.exp.f16(half %a) #0
|
|
declare half @llvm.exp2.f16(half %a) #0
|
|
declare half @llvm.log.f16(half %a) #0
|
|
declare half @llvm.log10.f16(half %a) #0
|
|
declare half @llvm.log2.f16(half %a) #0
|
|
declare half @llvm.fma.f16(half %a, half %b, half %c) #0
|
|
declare half @llvm.fabs.f16(half %a) #0
|
|
declare half @llvm.minnum.f16(half %a, half %b) #0
|
|
declare half @llvm.maxnum.f16(half %a, half %b) #0
|
|
declare half @llvm.copysign.f16(half %a, half %b) #0
|
|
declare half @llvm.floor.f16(half %a) #0
|
|
declare half @llvm.ceil.f16(half %a) #0
|
|
declare half @llvm.trunc.f16(half %a) #0
|
|
declare half @llvm.rint.f16(half %a) #0
|
|
declare half @llvm.nearbyint.f16(half %a) #0
|
|
declare half @llvm.round.f16(half %a) #0
|
|
declare half @llvm.roundeven.f16(half %a) #0
|
|
declare half @llvm.fmuladd.f16(half %a, half %b, half %c) #0
|
|
|
|
|
|
define half @test_sqrt(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_sqrt:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: fsqrt s0, s0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_sqrt:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fsqrt h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.sqrt.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_powi(half %a, i32 %b) #0 {
|
|
; CHECK-LABEL: test_powi:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl __powisf2
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.powi.f16.i32(half %a, i32 %b)
|
|
ret half %r
|
|
}
|
|
|
|
|
|
define half @test_sin(half %a) #0 {
|
|
; CHECK-LABEL: test_sin:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl sinf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.sin.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_cos(half %a) #0 {
|
|
; CHECK-LABEL: test_cos:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl cosf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.cos.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_tan(half %a) #0 {
|
|
; CHECK-LABEL: test_tan:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl tanf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.tan.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_acos(half %a) #0 {
|
|
; CHECK-LABEL: test_acos:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl acosf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.acos.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_asin(half %a) #0 {
|
|
; CHECK-LABEL: test_asin:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl asinf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.asin.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_atan(half %a) #0 {
|
|
; CHECK-LABEL: test_atan:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl atanf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.atan.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_atan2(half %a, half %b) #0 {
|
|
%r = call half @llvm.atan2.f16(half %a, half %b)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_cosh(half %a) #0 {
|
|
; CHECK-LABEL: test_cosh:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl coshf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.cosh.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_sinh(half %a) #0 {
|
|
; CHECK-LABEL: test_sinh:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl sinhf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.sinh.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_tanh(half %a) #0 {
|
|
; CHECK-LABEL: test_tanh:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl tanhf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.tanh.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_pow(half %a, half %b) #0 {
|
|
; CHECK-LABEL: test_pow:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: fcvt s1, h1
|
|
; CHECK-NEXT: bl powf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.pow.f16(half %a, half %b)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_exp(half %a) #0 {
|
|
; CHECK-LABEL: test_exp:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl expf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.exp.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_exp2(half %a) #0 {
|
|
; CHECK-LABEL: test_exp2:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl exp2f
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.exp2.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_log(half %a) #0 {
|
|
; CHECK-LABEL: test_log:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl logf
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.log.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_log10(half %a) #0 {
|
|
; CHECK-LABEL: test_log10:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl log10f
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.log10.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_log2(half %a) #0 {
|
|
; CHECK-LABEL: test_log2:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-NEXT: fcvt s0, h0
|
|
; CHECK-NEXT: bl log2f
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-NEXT: ret
|
|
%r = call half @llvm.log2.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fma(half %a, half %b, half %c) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fma:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s2, h2
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fmadd s0, s0, s1, s2
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fma:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fma:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fcvt s2, h2
|
|
; CHECK-CVT-GI-NEXT: fmadd s0, s0, s1, s2
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = call half @llvm.fma.f16(half %a, half %b, half %c)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fabs(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_fabs:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 def $s0
|
|
; CHECK-CVT-NEXT: fmov w8, s0
|
|
; CHECK-CVT-NEXT: and w8, w8, #0x7fff
|
|
; CHECK-CVT-NEXT: fmov s0, w8
|
|
; CHECK-CVT-NEXT: // kill: def $h0 killed $h0 killed $s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fabs:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fabs h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.fabs.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_minnum(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_minnum:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fminnm s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_minnum:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fminnm h0, h0, h1
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_minnum:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fminnm s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = call half @llvm.minnum.f16(half %a, half %b)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_maxnum(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_maxnum:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fmaxnm s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_maxnum:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fmaxnm h0, h0, h1
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_maxnum:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fmaxnm s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = call half @llvm.maxnum.f16(half %a, half %b)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_copysign(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_copysign:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: mvni v2.4s, #128, lsl #24
|
|
; CHECK-CVT-SD-NEXT: bif v0.16b, v1.16b, v2.16b
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_copysign:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: mvni v2.8h, #128, lsl #8
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 def $q0
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h1 killed $h1 def $q1
|
|
; CHECK-FP16-SD-NEXT: bif v0.16b, v1.16b, v2.16b
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 killed $q0
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_copysign:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: mvni v2.4h, #128, lsl #8
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $d1
|
|
; CHECK-CVT-GI-NEXT: bif v0.8b, v1.8b, v2.8b
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $d0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_copysign:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: mvni v2.4h, #128, lsl #8
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $d0
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $d1
|
|
; CHECK-FP16-GI-NEXT: bif v0.8b, v1.8b, v2.8b
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $d0
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%r = call half @llvm.copysign.f16(half %a, half %b)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_copysign_f32(half %a, float %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_copysign_f32:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: mvni v2.4s, #128, lsl #24
|
|
; CHECK-CVT-SD-NEXT: // kill: def $s1 killed $s1 def $q1
|
|
; CHECK-CVT-SD-NEXT: bif v0.16b, v1.16b, v2.16b
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_copysign_f32:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: fcvt h1, s1
|
|
; CHECK-FP16-SD-NEXT: mvni v2.8h, #128, lsl #8
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 def $q0
|
|
; CHECK-FP16-SD-NEXT: bif v0.16b, v1.16b, v2.16b
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 killed $q0
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_copysign_f32:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt h1, s1
|
|
; CHECK-CVT-GI-NEXT: mvni v2.4h, #128, lsl #8
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0
|
|
; CHECK-CVT-GI-NEXT: bif v0.8b, v1.8b, v2.8b
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $d0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_copysign_f32:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: fcvt h1, s1
|
|
; CHECK-FP16-GI-NEXT: mvni v2.4h, #128, lsl #8
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $d0
|
|
; CHECK-FP16-GI-NEXT: bif v0.8b, v1.8b, v2.8b
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $d0
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%tb = fptrunc float %b to half
|
|
%r = call half @llvm.copysign.f16(half %a, half %tb)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_copysign_f64(half %a, double %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_copysign_f64:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, d1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: mvni v2.4s, #128, lsl #24
|
|
; CHECK-CVT-SD-NEXT: bif v0.16b, v1.16b, v2.16b
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_copysign_f64:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: fcvt h1, d1
|
|
; CHECK-FP16-SD-NEXT: mvni v2.8h, #128, lsl #8
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 def $q0
|
|
; CHECK-FP16-SD-NEXT: bif v0.16b, v1.16b, v2.16b
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 killed $q0
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_copysign_f64:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt h1, d1
|
|
; CHECK-CVT-GI-NEXT: mvni v2.4h, #128, lsl #8
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0
|
|
; CHECK-CVT-GI-NEXT: bif v0.8b, v1.8b, v2.8b
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 killed $d0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_copysign_f64:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: fcvt h1, d1
|
|
; CHECK-FP16-GI-NEXT: mvni v2.4h, #128, lsl #8
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $d0
|
|
; CHECK-FP16-GI-NEXT: bif v0.8b, v1.8b, v2.8b
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 killed $d0
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%tb = fptrunc double %b to half
|
|
%r = call half @llvm.copysign.f16(half %a, half %tb)
|
|
ret half %r
|
|
}
|
|
|
|
; Check that the FP promotion will use a truncating FP_ROUND, so we can fold
|
|
; away the (fpext (fp_round <result>)) here.
|
|
|
|
define float @test_copysign_extended(half %a, half %b) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_copysign_extended:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: mvni v2.4s, #128, lsl #24
|
|
; CHECK-CVT-SD-NEXT: bif v0.16b, v1.16b, v2.16b
|
|
; CHECK-CVT-SD-NEXT: // kill: def $s0 killed $s0 killed $q0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-SD-LABEL: test_copysign_extended:
|
|
; CHECK-FP16-SD: // %bb.0:
|
|
; CHECK-FP16-SD-NEXT: mvni v2.8h, #128, lsl #8
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h0 killed $h0 def $q0
|
|
; CHECK-FP16-SD-NEXT: // kill: def $h1 killed $h1 def $q1
|
|
; CHECK-FP16-SD-NEXT: bif v0.16b, v1.16b, v2.16b
|
|
; CHECK-FP16-SD-NEXT: fcvt s0, h0
|
|
; CHECK-FP16-SD-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_copysign_extended:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: mvni v2.4h, #128, lsl #8
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h0 killed $h0 def $d0
|
|
; CHECK-CVT-GI-NEXT: // kill: def $h1 killed $h1 def $d1
|
|
; CHECK-CVT-GI-NEXT: bif v0.8b, v1.8b, v2.8b
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
;
|
|
; CHECK-FP16-GI-LABEL: test_copysign_extended:
|
|
; CHECK-FP16-GI: // %bb.0:
|
|
; CHECK-FP16-GI-NEXT: mvni v2.4h, #128, lsl #8
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h0 killed $h0 def $d0
|
|
; CHECK-FP16-GI-NEXT: // kill: def $h1 killed $h1 def $d1
|
|
; CHECK-FP16-GI-NEXT: bif v0.8b, v1.8b, v2.8b
|
|
; CHECK-FP16-GI-NEXT: fcvt s0, h0
|
|
; CHECK-FP16-GI-NEXT: ret
|
|
%r = call half @llvm.copysign.f16(half %a, half %b)
|
|
%xr = fpext half %r to float
|
|
ret float %xr
|
|
}
|
|
|
|
define half @test_floor(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_floor:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: frintm s0, s0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_floor:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: frintm h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.floor.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_ceil(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_ceil:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: frintp s0, s0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_ceil:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: frintp h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.ceil.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_trunc(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_trunc:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: frintz s0, s0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_trunc:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: frintz h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.trunc.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_rint(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_rint:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: frintx s0, s0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_rint:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: frintx h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.rint.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_nearbyint(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_nearbyint:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: frinti s0, s0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_nearbyint:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: frinti h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.nearbyint.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_round(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_round:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: frinta s0, s0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_round:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: frinta h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.round.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_roundeven(half %a) #0 {
|
|
; CHECK-CVT-LABEL: test_roundeven:
|
|
; CHECK-CVT: // %bb.0:
|
|
; CHECK-CVT-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-NEXT: frintn s0, s0
|
|
; CHECK-CVT-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_roundeven:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: frintn h0, h0
|
|
; CHECK-FP16-NEXT: ret
|
|
%r = call half @llvm.roundeven.f16(half %a)
|
|
ret half %r
|
|
}
|
|
|
|
define half @test_fmuladd(half %a, half %b, half %c) #0 {
|
|
; CHECK-CVT-SD-LABEL: test_fmuladd:
|
|
; CHECK-CVT-SD: // %bb.0:
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fmul s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt s1, h2
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-SD-NEXT: fadd s0, s0, s1
|
|
; CHECK-CVT-SD-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-SD-NEXT: ret
|
|
;
|
|
; CHECK-FP16-LABEL: test_fmuladd:
|
|
; CHECK-FP16: // %bb.0:
|
|
; CHECK-FP16-NEXT: fmadd h0, h0, h1, h2
|
|
; CHECK-FP16-NEXT: ret
|
|
;
|
|
; CHECK-CVT-GI-LABEL: test_fmuladd:
|
|
; CHECK-CVT-GI: // %bb.0:
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h1
|
|
; CHECK-CVT-GI-NEXT: fmul s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt s1, h2
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: fcvt s0, h0
|
|
; CHECK-CVT-GI-NEXT: fadd s0, s0, s1
|
|
; CHECK-CVT-GI-NEXT: fcvt h0, s0
|
|
; CHECK-CVT-GI-NEXT: ret
|
|
%r = call half @llvm.fmuladd.f16(half %a, half %b, half %c)
|
|
ret half %r
|
|
}
|
|
|
|
attributes #0 = { nounwind }
|