CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
461 lines
14 KiB
LLVM
461 lines
14 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
|
|
; RUN: llc -mattr=+neon,+fullfp16,+fprcvt -verify-machineinstrs %s -o - | FileCheck %s
|
|
; RUN: llc -mattr=+neon -verify-machineinstrs %s -o - | FileCheck %s --check-prefix=CHECK-NO-FPRCVT
|
|
|
|
target triple = "aarch64-unknown-linux-gnu"
|
|
|
|
|
|
; To demonstrate what we have implemented, we'll want a scalar integer value in a SIMD/FP register.
|
|
; A common case for this setup is when using the result of an integer reduction intrinsic.
|
|
|
|
; SCVTF
|
|
|
|
define half @scvtf_f16i32(<4 x i32> %x) {
|
|
; CHECK-LABEL: scvtf_f16i32:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: scvtf h0, s0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f16i32:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <4 x i32> %x, i64 0
|
|
%conv = sitofp i32 %extract to half
|
|
ret half %conv
|
|
}
|
|
|
|
define half @scvtf_f16i32_neg(<4 x i32> %x) {
|
|
; CHECK-LABEL: scvtf_f16i32_neg:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w8, v0.s[1]
|
|
; CHECK-NEXT: scvtf h0, w8
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f16i32_neg:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: mov w8, v0.s[1]
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, w8
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <4 x i32> %x, i64 1
|
|
%conv = sitofp i32 %extract to half
|
|
ret half %conv
|
|
}
|
|
|
|
define <1 x half> @scvtf_f16i32_simple(<1 x i32> %x) {
|
|
; CHECK-LABEL: scvtf_f16i32_simple:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: scvtf h0, s0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f16i32_simple:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%conv = sitofp <1 x i32> %x to <1 x half>
|
|
ret <1 x half> %conv
|
|
}
|
|
|
|
define double @scvtf_f64i32(<4 x i32> %x) {
|
|
; CHECK-LABEL: scvtf_f64i32:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: scvtf d0, s0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f64i32:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: fmov w8, s0
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf d0, w8
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <4 x i32> %x, i64 0
|
|
%conv = sitofp i32 %extract to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @scvtf_f64i32_neg(<4 x i32> %x) {
|
|
; CHECK-LABEL: scvtf_f64i32_neg:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w8, v0.s[1]
|
|
; CHECK-NEXT: scvtf d0, w8
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f64i32_neg:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: mov w8, v0.s[1]
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf d0, w8
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <4 x i32> %x, i64 1
|
|
%conv = sitofp i32 %extract to double
|
|
ret double %conv
|
|
}
|
|
|
|
define <1 x double> @scvtf_f64i32_simple(<1 x i32> %x) {
|
|
; CHECK-LABEL: scvtf_f64i32_simple:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: scvtf d0, s0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f64i32_simple:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: sshll v0.2d, v0.2s, #0
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf v0.2d, v0.2d
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%conv = sitofp <1 x i32> %x to <1 x double>
|
|
ret <1 x double> %conv
|
|
}
|
|
|
|
define half @scvtf_f16i64(<2 x i64> %x) {
|
|
; CHECK-LABEL: scvtf_f16i64:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: scvtf h0, d0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f16i64:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: fmov x8, d0
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <2 x i64> %x, i64 0
|
|
%conv = sitofp i64 %extract to half
|
|
ret half %conv
|
|
}
|
|
|
|
define half @scvtf_f16i64_neg(<2 x i64> %x) {
|
|
; CHECK-LABEL: scvtf_f16i64_neg:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov x8, v0.d[1]
|
|
; CHECK-NEXT: scvtf h0, x8
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f16i64_neg:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: mov x8, v0.d[1]
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <2 x i64> %x, i64 1
|
|
%conv = sitofp i64 %extract to half
|
|
ret half %conv
|
|
}
|
|
|
|
define <1 x half> @scvtf_f16i64_simple(<1 x i64> %x) {
|
|
; CHECK-LABEL: scvtf_f16i64_simple:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: scvtf h0, d0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f16i64_simple:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NO-FPRCVT-NEXT: fmov x8, d0
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%conv = sitofp <1 x i64> %x to <1 x half>
|
|
ret <1 x half> %conv
|
|
}
|
|
|
|
define float @scvtf_f32i64(<2 x i64> %x) {
|
|
; CHECK-LABEL: scvtf_f32i64:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: scvtf s0, d0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f32i64:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: fmov x8, d0
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <2 x i64> %x, i64 0
|
|
%conv = sitofp i64 %extract to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @scvtf_f32i64_neg(<2 x i64> %x) {
|
|
; CHECK-LABEL: scvtf_f32i64_neg:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov x8, v0.d[1]
|
|
; CHECK-NEXT: scvtf s0, x8
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f32i64_neg:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: mov x8, v0.d[1]
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <2 x i64> %x, i64 1
|
|
%conv = sitofp i64 %extract to float
|
|
ret float %conv
|
|
}
|
|
|
|
; This test does not give the indended result of scvtf s0, d0
|
|
; This is due to the input being loaded as a 2 item vector and
|
|
; therefore using vector inputs that do not match the pattern
|
|
; This test will be fixed in a future revision
|
|
define <1 x float> @scvtf_f32i64_simple(<1 x i64> %x) {
|
|
; CHECK-LABEL: scvtf_f32i64_simple:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: movi d1, #0000000000000000
|
|
; CHECK-NEXT: scvtf s0, d0
|
|
; CHECK-NEXT: mov v1.s[0], v0.s[0]
|
|
; CHECK-NEXT: fmov d0, d1
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: scvtf_f32i64_simple:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NO-FPRCVT-NEXT: fmov x8, d0
|
|
; CHECK-NO-FPRCVT-NEXT: movi d1, #0000000000000000
|
|
; CHECK-NO-FPRCVT-NEXT: scvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: mov v1.s[0], v0.s[0]
|
|
; CHECK-NO-FPRCVT-NEXT: fmov d0, d1
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%conv = sitofp <1 x i64> %x to <1 x float>
|
|
ret <1 x float> %conv
|
|
}
|
|
|
|
; UCVTF
|
|
|
|
define half @ucvtf_f16i32(<4 x i32> %x) {
|
|
; CHECK-LABEL: ucvtf_f16i32:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ucvtf h0, s0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i32:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <4 x i32> %x, i64 0
|
|
%conv = uitofp i32 %extract to half
|
|
ret half %conv
|
|
}
|
|
|
|
define half @ucvtf_f16i32_neg(<4 x i32> %x) {
|
|
; CHECK-LABEL: ucvtf_f16i32_neg:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w8, v0.s[1]
|
|
; CHECK-NEXT: ucvtf h0, w8
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i32_neg:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: mov w8, v0.s[1]
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, w8
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <4 x i32> %x, i64 1
|
|
%conv = uitofp i32 %extract to half
|
|
ret half %conv
|
|
}
|
|
|
|
define <1 x half> @ucvtf_f16i32_simple(<1 x i32> %x) {
|
|
; CHECK-LABEL: ucvtf_f16i32_simple:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: ucvtf h0, s0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i32_simple:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%conv = uitofp <1 x i32> %x to <1 x half>
|
|
ret <1 x half> %conv
|
|
}
|
|
|
|
define double @ucvtf_f64i32(<4 x i32> %x) {
|
|
; CHECK-LABEL: ucvtf_f64i32:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ucvtf d0, s0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f64i32:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: fmov w8, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf d0, w8
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <4 x i32> %x, i64 0
|
|
%conv = uitofp i32 %extract to double
|
|
ret double %conv
|
|
}
|
|
|
|
define double @ucvtf_f64i32_neg(<4 x i32> %x) {
|
|
; CHECK-LABEL: ucvtf_f64i32_neg:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov w8, v0.s[1]
|
|
; CHECK-NEXT: ucvtf d0, w8
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f64i32_neg:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: mov w8, v0.s[1]
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf d0, w8
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <4 x i32> %x, i64 1
|
|
%conv = uitofp i32 %extract to double
|
|
ret double %conv
|
|
}
|
|
|
|
define <1 x double> @ucvtf_f64i32_simple(<1 x i32> %x) {
|
|
; CHECK-LABEL: ucvtf_f64i32_simple:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ucvtf d0, s0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f64i32_simple:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: ushll v0.2d, v0.2s, #0
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf v0.2d, v0.2d
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%conv = uitofp <1 x i32> %x to <1 x double>
|
|
ret <1 x double> %conv
|
|
}
|
|
|
|
define half @ucvtf_f16i64(<2 x i64> %x) {
|
|
; CHECK-LABEL: ucvtf_f16i64:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ucvtf h0, d0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i64:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: fmov x8, d0
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <2 x i64> %x, i64 0
|
|
%conv = uitofp i64 %extract to half
|
|
ret half %conv
|
|
}
|
|
|
|
define half @ucvtf_f16i64_neg(<2 x i64> %x) {
|
|
; CHECK-LABEL: ucvtf_f16i64_neg:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov x8, v0.d[1]
|
|
; CHECK-NEXT: ucvtf h0, x8
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i64_neg:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: mov x8, v0.d[1]
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <2 x i64> %x, i64 1
|
|
%conv = uitofp i64 %extract to half
|
|
ret half %conv
|
|
}
|
|
|
|
define <1 x half> @ucvtf_f16i64_simple(<1 x i64> %x) {
|
|
; CHECK-LABEL: ucvtf_f16i64_simple:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: ucvtf h0, d0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f16i64_simple:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NO-FPRCVT-NEXT: fmov x8, d0
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: fcvt h0, s0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%conv = uitofp <1 x i64> %x to <1 x half>
|
|
ret <1 x half> %conv
|
|
}
|
|
|
|
define float @ucvtf_f32i64(<2 x i64> %x) {
|
|
; CHECK-LABEL: ucvtf_f32i64:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: ucvtf s0, d0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f32i64:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: fmov x8, d0
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <2 x i64> %x, i64 0
|
|
%conv = uitofp i64 %extract to float
|
|
ret float %conv
|
|
}
|
|
|
|
define float @ucvtf_f32i64_neg(<2 x i64> %x) {
|
|
; CHECK-LABEL: ucvtf_f32i64_neg:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: mov x8, v0.d[1]
|
|
; CHECK-NEXT: ucvtf s0, x8
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f32i64_neg:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: mov x8, v0.d[1]
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%extract = extractelement <2 x i64> %x, i64 1
|
|
%conv = uitofp i64 %extract to float
|
|
ret float %conv
|
|
}
|
|
|
|
; This test does not give the indended result of ucvtf s0, d0
|
|
; This is due to the input being loaded as a 2 item vector and
|
|
; therefore using vector inputs that do not match the pattern
|
|
; This test will be fixed in a future revision
|
|
define <1 x float> @ucvtf_f32i64_simple(<1 x i64> %x) {
|
|
; CHECK-LABEL: ucvtf_f32i64_simple:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NEXT: movi d1, #0000000000000000
|
|
; CHECK-NEXT: ucvtf s0, d0
|
|
; CHECK-NEXT: mov v1.s[0], v0.s[0]
|
|
; CHECK-NEXT: fmov d0, d1
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: ucvtf_f32i64_simple:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 def $q0
|
|
; CHECK-NO-FPRCVT-NEXT: fmov x8, d0
|
|
; CHECK-NO-FPRCVT-NEXT: movi d1, #0000000000000000
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf s0, x8
|
|
; CHECK-NO-FPRCVT-NEXT: mov v1.s[0], v0.s[0]
|
|
; CHECK-NO-FPRCVT-NEXT: fmov d0, d1
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%conv = uitofp <1 x i64> %x to <1 x float>
|
|
ret <1 x float> %conv
|
|
}
|
|
|
|
define <1 x double> @uitofp_sext_v2i32_extract_lane0(<2 x i32> %x) {
|
|
; CHECK-LABEL: uitofp_sext_v2i32_extract_lane0:
|
|
; CHECK: // %bb.0:
|
|
; CHECK-NEXT: sshll v0.2d, v0.2s, #0
|
|
; CHECK-NEXT: ucvtf v0.2d, v0.2d
|
|
; CHECK-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-NEXT: ret
|
|
;
|
|
; CHECK-NO-FPRCVT-LABEL: uitofp_sext_v2i32_extract_lane0:
|
|
; CHECK-NO-FPRCVT: // %bb.0:
|
|
; CHECK-NO-FPRCVT-NEXT: sshll v0.2d, v0.2s, #0
|
|
; CHECK-NO-FPRCVT-NEXT: ucvtf v0.2d, v0.2d
|
|
; CHECK-NO-FPRCVT-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-NO-FPRCVT-NEXT: ret
|
|
%wide = sext <2 x i32> %x to <2 x i64>
|
|
%fpv2 = uitofp <2 x i64> %wide to <2 x double>
|
|
%lane0 = shufflevector <2 x double> %fpv2, <2 x double> poison, <1 x i32> zeroinitializer
|
|
ret <1 x double> %lane0
|
|
}
|
|
|