We currently have an issue where bf16 patters can be used to match fp16 types, as GISel does not know about the difference between the two. This patch explicitly disables them to make sure that they are never used. The opposite can also happen too, where fp16 patterns are used for operators that should be bf16. So this also changes any operations with bf16 types to now cause a fallback to SDAG. The pass setup for GISel has been slightly adjusted to make sure that a verify pass does not get added between AMD-SDAG and SIFixSGPRCopiesPass, which otherwise can cause verifier issues when falling back.
406 lines
14 KiB
LLVM
406 lines
14 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
|
|
; RUN: llc -mtriple=aarch64 -global-isel=0 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
|
; RUN: llc -mtriple=aarch64 -global-isel=1 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
|
; RUN: llc -mtriple=aarch64 -global-isel=1 -mattr=+fullfp16,+bf16 -verify-machineinstrs %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
|
|
|
define float @fptrunc_f64_f32(double %a) {
|
|
; CHECK-LABEL: fptrunc_f64_f32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: fcvt s0, d0
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c = fptrunc double %a to float
|
|
ret float %c
|
|
}
|
|
|
|
define half @fptrunc_f64_f16(double %a) {
|
|
; CHECK-LABEL: fptrunc_f64_f16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: fcvt h0, d0
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c = fptrunc double %a to half
|
|
ret half %c
|
|
}
|
|
|
|
define half @fptrunc_f32_f16(float %a) {
|
|
; CHECK-LABEL: fptrunc_f32_f16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: fcvt h0, s0
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c = fptrunc float %a to half
|
|
ret half %c
|
|
}
|
|
|
|
|
|
define half @fptrunc_f128_f16(fp128 %a) {
|
|
; CHECK-SD-LABEL: fptrunc_f128_f16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-SD-NEXT: .cfi_offset w30, -16
|
|
; CHECK-SD-NEXT: bl __trunctfhf2
|
|
; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_f128_f16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: b __trunctfhf2
|
|
entry:
|
|
%c = fptrunc fp128 %a to half
|
|
ret half %c
|
|
}
|
|
|
|
define float @fptrunc_f128_f32(fp128 %a) {
|
|
; CHECK-SD-LABEL: fptrunc_f128_f32:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-SD-NEXT: .cfi_offset w30, -16
|
|
; CHECK-SD-NEXT: bl __trunctfsf2
|
|
; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_f128_f32:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: b __trunctfsf2
|
|
entry:
|
|
%c = fptrunc fp128 %a to float
|
|
ret float %c
|
|
}
|
|
|
|
define double @fptrunc_f128_f64(fp128 %a) {
|
|
; CHECK-SD-LABEL: fptrunc_f128_f64:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: str x30, [sp, #-16]! // 8-byte Folded Spill
|
|
; CHECK-SD-NEXT: .cfi_def_cfa_offset 16
|
|
; CHECK-SD-NEXT: .cfi_offset w30, -16
|
|
; CHECK-SD-NEXT: bl __trunctfdf2
|
|
; CHECK-SD-NEXT: ldr x30, [sp], #16 // 8-byte Folded Reload
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_f128_f64:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: b __trunctfdf2
|
|
entry:
|
|
%c = fptrunc fp128 %a to double
|
|
ret double %c
|
|
}
|
|
|
|
define <2 x half> @fptrunc_v2f128_v2f16(<2 x fp128> %a) {
|
|
; CHECK-SD-LABEL: fptrunc_v2f128_v2f16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: sub sp, sp, #48
|
|
; CHECK-SD-NEXT: str x30, [sp, #32] // 8-byte Folded Spill
|
|
; CHECK-SD-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-SD-NEXT: .cfi_offset w30, -16
|
|
; CHECK-SD-NEXT: str q0, [sp] // 16-byte Folded Spill
|
|
; CHECK-SD-NEXT: mov v0.16b, v1.16b
|
|
; CHECK-SD-NEXT: bl __trunctfhf2
|
|
; CHECK-SD-NEXT: // kill: def $h0 killed $h0 def $q0
|
|
; CHECK-SD-NEXT: str q0, [sp, #16] // 16-byte Folded Spill
|
|
; CHECK-SD-NEXT: ldr q0, [sp] // 16-byte Folded Reload
|
|
; CHECK-SD-NEXT: bl __trunctfhf2
|
|
; CHECK-SD-NEXT: ldr q1, [sp, #16] // 16-byte Folded Reload
|
|
; CHECK-SD-NEXT: // kill: def $h0 killed $h0 def $q0
|
|
; CHECK-SD-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload
|
|
; CHECK-SD-NEXT: mov v0.h[1], v1.h[0]
|
|
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-SD-NEXT: add sp, sp, #48
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_v2f128_v2f16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: sub sp, sp, #64
|
|
; CHECK-GI-NEXT: str x30, [sp, #48] // 8-byte Folded Spill
|
|
; CHECK-GI-NEXT: .cfi_def_cfa_offset 64
|
|
; CHECK-GI-NEXT: .cfi_offset w30, -16
|
|
; CHECK-GI-NEXT: mov v2.d[0], x8
|
|
; CHECK-GI-NEXT: str q1, [sp] // 16-byte Folded Spill
|
|
; CHECK-GI-NEXT: mov v2.d[1], x8
|
|
; CHECK-GI-NEXT: str q2, [sp, #32] // 16-byte Folded Spill
|
|
; CHECK-GI-NEXT: bl __trunctfhf2
|
|
; CHECK-GI-NEXT: // kill: def $h0 killed $h0 def $q0
|
|
; CHECK-GI-NEXT: str q0, [sp, #16] // 16-byte Folded Spill
|
|
; CHECK-GI-NEXT: ldr q0, [sp] // 16-byte Folded Reload
|
|
; CHECK-GI-NEXT: bl __trunctfhf2
|
|
; CHECK-GI-NEXT: // kill: def $h0 killed $h0 def $q0
|
|
; CHECK-GI-NEXT: str q0, [sp] // 16-byte Folded Spill
|
|
; CHECK-GI-NEXT: ldr q0, [sp, #32] // 16-byte Folded Reload
|
|
; CHECK-GI-NEXT: bl __trunctfhf2
|
|
; CHECK-GI-NEXT: ldr q0, [sp, #32] // 16-byte Folded Reload
|
|
; CHECK-GI-NEXT: bl __trunctfhf2
|
|
; CHECK-GI-NEXT: ldp q1, q0, [sp] // 32-byte Folded Reload
|
|
; CHECK-GI-NEXT: ldr x30, [sp, #48] // 8-byte Folded Reload
|
|
; CHECK-GI-NEXT: mov v0.h[1], v1.h[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: add sp, sp, #64
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <2 x fp128> %a to <2 x half>
|
|
ret <2 x half> %c
|
|
}
|
|
|
|
|
|
define <2 x float> @fptrunc_v2f128_v2f32(<2 x fp128> %a) {
|
|
; CHECK-SD-LABEL: fptrunc_v2f128_v2f32:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: sub sp, sp, #48
|
|
; CHECK-SD-NEXT: str x30, [sp, #32] // 8-byte Folded Spill
|
|
; CHECK-SD-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-SD-NEXT: .cfi_offset w30, -16
|
|
; CHECK-SD-NEXT: str q0, [sp] // 16-byte Folded Spill
|
|
; CHECK-SD-NEXT: mov v0.16b, v1.16b
|
|
; CHECK-SD-NEXT: bl __trunctfsf2
|
|
; CHECK-SD-NEXT: // kill: def $s0 killed $s0 def $q0
|
|
; CHECK-SD-NEXT: str q0, [sp, #16] // 16-byte Folded Spill
|
|
; CHECK-SD-NEXT: ldr q0, [sp] // 16-byte Folded Reload
|
|
; CHECK-SD-NEXT: bl __trunctfsf2
|
|
; CHECK-SD-NEXT: ldr q1, [sp, #16] // 16-byte Folded Reload
|
|
; CHECK-SD-NEXT: // kill: def $s0 killed $s0 def $q0
|
|
; CHECK-SD-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload
|
|
; CHECK-SD-NEXT: mov v0.s[1], v1.s[0]
|
|
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-SD-NEXT: add sp, sp, #48
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_v2f128_v2f32:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: sub sp, sp, #48
|
|
; CHECK-GI-NEXT: str x30, [sp, #32] // 8-byte Folded Spill
|
|
; CHECK-GI-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-GI-NEXT: .cfi_offset w30, -16
|
|
; CHECK-GI-NEXT: str q1, [sp] // 16-byte Folded Spill
|
|
; CHECK-GI-NEXT: bl __trunctfsf2
|
|
; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0
|
|
; CHECK-GI-NEXT: str q0, [sp, #16] // 16-byte Folded Spill
|
|
; CHECK-GI-NEXT: ldr q0, [sp] // 16-byte Folded Reload
|
|
; CHECK-GI-NEXT: bl __trunctfsf2
|
|
; CHECK-GI-NEXT: ldr q1, [sp, #16] // 16-byte Folded Reload
|
|
; CHECK-GI-NEXT: // kill: def $s0 killed $s0 def $q0
|
|
; CHECK-GI-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload
|
|
; CHECK-GI-NEXT: mov v1.s[1], v0.s[0]
|
|
; CHECK-GI-NEXT: fmov d0, d1
|
|
; CHECK-GI-NEXT: add sp, sp, #48
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <2 x fp128> %a to <2 x float>
|
|
ret <2 x float> %c
|
|
}
|
|
|
|
|
|
define <2 x double> @fptrunc_v2f128_v2f64(<2 x fp128> %a) {
|
|
; CHECK-SD-LABEL: fptrunc_v2f128_v2f64:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: sub sp, sp, #48
|
|
; CHECK-SD-NEXT: str x30, [sp, #32] // 8-byte Folded Spill
|
|
; CHECK-SD-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-SD-NEXT: .cfi_offset w30, -16
|
|
; CHECK-SD-NEXT: str q0, [sp] // 16-byte Folded Spill
|
|
; CHECK-SD-NEXT: mov v0.16b, v1.16b
|
|
; CHECK-SD-NEXT: bl __trunctfdf2
|
|
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-SD-NEXT: str q0, [sp, #16] // 16-byte Folded Spill
|
|
; CHECK-SD-NEXT: ldr q0, [sp] // 16-byte Folded Reload
|
|
; CHECK-SD-NEXT: bl __trunctfdf2
|
|
; CHECK-SD-NEXT: ldr q1, [sp, #16] // 16-byte Folded Reload
|
|
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-SD-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload
|
|
; CHECK-SD-NEXT: mov v0.d[1], v1.d[0]
|
|
; CHECK-SD-NEXT: add sp, sp, #48
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_v2f128_v2f64:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: sub sp, sp, #48
|
|
; CHECK-GI-NEXT: str x30, [sp, #32] // 8-byte Folded Spill
|
|
; CHECK-GI-NEXT: .cfi_def_cfa_offset 48
|
|
; CHECK-GI-NEXT: .cfi_offset w30, -16
|
|
; CHECK-GI-NEXT: str q1, [sp] // 16-byte Folded Spill
|
|
; CHECK-GI-NEXT: bl __trunctfdf2
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-GI-NEXT: str q0, [sp, #16] // 16-byte Folded Spill
|
|
; CHECK-GI-NEXT: ldr q0, [sp] // 16-byte Folded Reload
|
|
; CHECK-GI-NEXT: bl __trunctfdf2
|
|
; CHECK-GI-NEXT: ldr q1, [sp, #16] // 16-byte Folded Reload
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-GI-NEXT: ldr x30, [sp, #32] // 8-byte Folded Reload
|
|
; CHECK-GI-NEXT: mov v1.d[1], v0.d[0]
|
|
; CHECK-GI-NEXT: mov v0.16b, v1.16b
|
|
; CHECK-GI-NEXT: add sp, sp, #48
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <2 x fp128> %a to <2 x double>
|
|
ret <2 x double> %c
|
|
}
|
|
|
|
define <2 x float> @fptrunc_v2f64_v2f32(<2 x double> %a) {
|
|
; CHECK-LABEL: fptrunc_v2f64_v2f32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: fcvtn v0.2s, v0.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <2 x double> %a to <2 x float>
|
|
ret <2 x float> %c
|
|
}
|
|
|
|
define <3 x float> @fptrunc_v3f64_v3f32(<3 x double> %a) {
|
|
; CHECK-SD-LABEL: fptrunc_v3f64_v3f32:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-SD-NEXT: // kill: def $d1 killed $d1 def $q1
|
|
; CHECK-SD-NEXT: // kill: def $d2 killed $d2 def $q2
|
|
; CHECK-SD-NEXT: mov v0.d[1], v1.d[0]
|
|
; CHECK-SD-NEXT: fcvtn v0.2s, v0.2d
|
|
; CHECK-SD-NEXT: fcvtn2 v0.4s, v2.2d
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_v3f64_v3f32:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-GI-NEXT: // kill: def $d1 killed $d1 def $q1
|
|
; CHECK-GI-NEXT: fcvt s2, d2
|
|
; CHECK-GI-NEXT: mov v0.d[1], v1.d[0]
|
|
; CHECK-GI-NEXT: fcvtn v1.2s, v0.2d
|
|
; CHECK-GI-NEXT: mov v0.s[0], v1.s[0]
|
|
; CHECK-GI-NEXT: mov v0.s[1], v1.s[1]
|
|
; CHECK-GI-NEXT: mov v0.s[2], v2.s[0]
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <3 x double> %a to <3 x float>
|
|
ret <3 x float> %c
|
|
}
|
|
|
|
define <4 x float> @fptrunc_v4f64_v4f32(<4 x double> %a) {
|
|
; CHECK-LABEL: fptrunc_v4f64_v4f32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: fcvtn v0.2s, v0.2d
|
|
; CHECK-NEXT: fcvtn2 v0.4s, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <4 x double> %a to <4 x float>
|
|
ret <4 x float> %c
|
|
}
|
|
|
|
define <2 x half> @fptrunc_v2f64_v2f16(<2 x double> %a) {
|
|
; CHECK-SD-LABEL: fptrunc_v2f64_v2f16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: fcvtxn v0.2s, v0.2d
|
|
; CHECK-SD-NEXT: fcvtn v0.4h, v0.4s
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_v2f64_v2f16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: mov d1, v0.d[1]
|
|
; CHECK-GI-NEXT: fcvt h0, d0
|
|
; CHECK-GI-NEXT: fcvt h1, d1
|
|
; CHECK-GI-NEXT: mov v0.h[1], v1.h[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <2 x double> %a to <2 x half>
|
|
ret <2 x half> %c
|
|
}
|
|
|
|
define <3 x half> @fptrunc_v3f64_v3f16(<3 x double> %a) {
|
|
; CHECK-SD-LABEL: fptrunc_v3f64_v3f16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: fcvt h1, d1
|
|
; CHECK-SD-NEXT: fcvt h0, d0
|
|
; CHECK-SD-NEXT: mov v0.h[1], v1.h[0]
|
|
; CHECK-SD-NEXT: fcvt h1, d2
|
|
; CHECK-SD-NEXT: mov v0.h[2], v1.h[0]
|
|
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_v3f64_v3f16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: fcvt h0, d0
|
|
; CHECK-GI-NEXT: fcvt h1, d1
|
|
; CHECK-GI-NEXT: fcvt h2, d2
|
|
; CHECK-GI-NEXT: mov v0.h[1], v1.h[0]
|
|
; CHECK-GI-NEXT: mov v0.h[2], v2.h[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <3 x double> %a to <3 x half>
|
|
ret <3 x half> %c
|
|
}
|
|
|
|
define <4 x half> @fptrunc_v4f64_v4f16(<4 x double> %a) {
|
|
; CHECK-SD-LABEL: fptrunc_v4f64_v4f16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: fcvtxn v0.2s, v0.2d
|
|
; CHECK-SD-NEXT: fcvtxn2 v0.4s, v1.2d
|
|
; CHECK-SD-NEXT: fcvtn v0.4h, v0.4s
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_v4f64_v4f16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: mov d2, v0.d[1]
|
|
; CHECK-GI-NEXT: fcvt h0, d0
|
|
; CHECK-GI-NEXT: mov d3, v1.d[1]
|
|
; CHECK-GI-NEXT: fcvt h1, d1
|
|
; CHECK-GI-NEXT: fcvt h2, d2
|
|
; CHECK-GI-NEXT: mov v0.h[1], v2.h[0]
|
|
; CHECK-GI-NEXT: fcvt h2, d3
|
|
; CHECK-GI-NEXT: mov v0.h[2], v1.h[0]
|
|
; CHECK-GI-NEXT: mov v0.h[3], v2.h[0]
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <4 x double> %a to <4 x half>
|
|
ret <4 x half> %c
|
|
}
|
|
|
|
define <2 x half> @fptrunc_v2f32_v2f16(<2 x float> %a) {
|
|
; CHECK-SD-LABEL: fptrunc_v2f32_v2f16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-SD-NEXT: fcvtn v0.4h, v0.4s
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: fptrunc_v2f32_v2f16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-GI-NEXT: mov v1.s[0], v0.s[0]
|
|
; CHECK-GI-NEXT: mov v1.s[1], v0.s[1]
|
|
; CHECK-GI-NEXT: fcvtn v0.4h, v1.4s
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <2 x float> %a to <2 x half>
|
|
ret <2 x half> %c
|
|
}
|
|
|
|
define <3 x half> @fptrunc_v3f32_v3f16(<3 x float> %a) {
|
|
; CHECK-LABEL: fptrunc_v3f32_v3f16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: fcvtn v0.4h, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <3 x float> %a to <3 x half>
|
|
ret <3 x half> %c
|
|
}
|
|
|
|
define <4 x half> @fptrunc_v4f32_v4f16(<4 x float> %a) {
|
|
; CHECK-LABEL: fptrunc_v4f32_v4f16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: fcvtn v0.4h, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <4 x float> %a to <4 x half>
|
|
ret <4 x half> %c
|
|
}
|
|
|
|
define <8 x half> @fptrunc_v8f32_v8f16(<8 x float> %a) {
|
|
; CHECK-LABEL: fptrunc_v8f32_v8f16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: fcvtn v0.4h, v0.4s
|
|
; CHECK-NEXT: fcvtn2 v0.8h, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%c = fptrunc <8 x float> %a to <8 x half>
|
|
ret <8 x half> %c
|
|
}
|