blob: bb6dc3162eb1f2283e1ca29ab225911505b531e7 [file] [edit]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f | FileCheck %s --check-prefixes=CHECK,AVX512,AVX512F
; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512f,+avx512fp16 | FileCheck %s --check-prefixes=CHECK,AVX512,AVX512FP16
; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512vl | FileCheck %s --check-prefixes=CHECK,AVX512VL,AVX512VLF
; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx512vl,+avx512fp16 | FileCheck %s --check-prefixes=CHECK,AVX512VLFP16
define half @test_half(half %x, i32 %exp) nounwind {
; AVX512F-LABEL: test_half:
; AVX512F: # %bb.0: # %entry
; AVX512F-NEXT: vcvtsi2ss %edi, %xmm15, %xmm1
; AVX512F-NEXT: vcvtph2ps %xmm0, %xmm0
; AVX512F-NEXT: vscalefss %xmm1, %xmm0, %xmm0
; AVX512F-NEXT: vcvtps2ph $4, %xmm0, %xmm0
; AVX512F-NEXT: retq
;
; AVX512FP16-LABEL: test_half:
; AVX512FP16: # %bb.0: # %entry
; AVX512FP16-NEXT: vcvtsi2sh %edi, %xmm31, %xmm1
; AVX512FP16-NEXT: vscalefsh %xmm1, %xmm0, %xmm0
; AVX512FP16-NEXT: retq
;
; AVX512VL-LABEL: test_half:
; AVX512VL: # %bb.0: # %entry
; AVX512VL-NEXT: vcvtsi2ss %edi, %xmm15, %xmm1
; AVX512VL-NEXT: vcvtph2ps %xmm0, %xmm0
; AVX512VL-NEXT: vscalefss %xmm1, %xmm0, %xmm0
; AVX512VL-NEXT: vcvtps2ph $4, %xmm0, %xmm0
; AVX512VL-NEXT: retq
;
; AVX512VLFP16-LABEL: test_half:
; AVX512VLFP16: # %bb.0: # %entry
; AVX512VLFP16-NEXT: vcvtsi2sh %edi, %xmm31, %xmm1
; AVX512VLFP16-NEXT: vscalefsh %xmm1, %xmm0, %xmm0
; AVX512VLFP16-NEXT: retq
entry:
%r = tail call fast half @llvm.ldexp.f16.i32(half %x, i32 %exp)
ret half %r
}
declare half @llvm.ldexp.f16.i32(half, i32) memory(none)
define float @test_float(float %x, i32 %exp) nounwind {
; CHECK-LABEL: test_float:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vcvtsi2ss %edi, %xmm15, %xmm1
; CHECK-NEXT: vscalefss %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
entry:
%r = tail call fast float @ldexpf(float %x, i32 %exp)
ret float %r
}
declare float @ldexpf(float, i32) memory(none)
define double @test_double(double %x, i32 %exp) nounwind {
; CHECK-LABEL: test_double:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: vcvtsi2sd %edi, %xmm15, %xmm1
; CHECK-NEXT: vscalefsd %xmm1, %xmm0, %xmm0
; CHECK-NEXT: retq
entry:
%r = tail call fast double @ldexp(double %x, i32 %exp)
ret double %r
}
declare double @ldexp(double, i32) memory(none)
define fp128 @testExpl(fp128 %x, i32 %exp) nounwind {
; CHECK-LABEL: testExpl:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: jmp ldexpl@PLT # TAILCALL
entry:
%r = tail call fast fp128 @ldexpl(fp128 %x, i32 %exp)
ret fp128 %r
}
declare fp128 @ldexpl(fp128, i32) memory(none)
define <8 x half> @test_ldexp_8xhalf(<8 x half> %x, <8 x i16> %exp) nounwind {
; AVX512F-LABEL: test_ldexp_8xhalf:
; AVX512F: # %bb.0:
; AVX512F-NEXT: vpmovsxwd %xmm1, %ymm1
; AVX512F-NEXT: vcvtph2ps %xmm0, %ymm0
; AVX512F-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; AVX512F-NEXT: vcvtps2ph $4, %ymm0, %xmm0
; AVX512F-NEXT: vzeroupper
; AVX512F-NEXT: retq
;
; AVX512FP16-LABEL: test_ldexp_8xhalf:
; AVX512FP16: # %bb.0:
; AVX512FP16-NEXT: vxorps %xmm2, %xmm2, %xmm2
; AVX512FP16-NEXT: vinsertf32x4 $0, %xmm0, %zmm2, %zmm0
; AVX512FP16-NEXT: vmovaps %xmm1, %xmm1
; AVX512FP16-NEXT: vscalefph %zmm1, %zmm0, %zmm0
; AVX512FP16-NEXT: # kill: def $xmm0 killed $xmm0 killed $zmm0
; AVX512FP16-NEXT: vzeroupper
; AVX512FP16-NEXT: retq
;
; AVX512VL-LABEL: test_ldexp_8xhalf:
; AVX512VL: # %bb.0:
; AVX512VL-NEXT: vpmovsxwd %xmm1, %ymm1
; AVX512VL-NEXT: vcvtph2ps %xmm0, %ymm0
; AVX512VL-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; AVX512VL-NEXT: vcvtps2ph $4, %ymm0, %xmm0
; AVX512VL-NEXT: vzeroupper
; AVX512VL-NEXT: retq
;
; AVX512VLFP16-LABEL: test_ldexp_8xhalf:
; AVX512VLFP16: # %bb.0:
; AVX512VLFP16-NEXT: vcvtw2ph %xmm1, %xmm1
; AVX512VLFP16-NEXT: vscalefph %xmm1, %xmm0, %xmm0
; AVX512VLFP16-NEXT: retq
%r = call <8 x half> @llvm.ldexp.v8f16.v8i16(<8 x half> %x, <8 x i16> %exp)
ret <8 x half> %r
}
declare <8 x half> @llvm.ldexp.v8f16.v8i16(<8 x half>, <8 x i16>)
define <4 x float> @test_ldexp_4xfloat(<4 x float> %x, <4 x i32> %exp) nounwind {
; AVX512-LABEL: test_ldexp_4xfloat:
; AVX512: # %bb.0:
; AVX512-NEXT: vmovaps %xmm1, %xmm1
; AVX512-NEXT: vmovaps %xmm0, %xmm0
; AVX512-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; AVX512-NEXT: # kill: def $xmm0 killed $xmm0 killed $zmm0
; AVX512-NEXT: vzeroupper
; AVX512-NEXT: retq
;
; AVX512VL-LABEL: test_ldexp_4xfloat:
; AVX512VL: # %bb.0:
; AVX512VL-NEXT: vcvtdq2ps %xmm1, %xmm1
; AVX512VL-NEXT: vscalefps %xmm1, %xmm0, %xmm0
; AVX512VL-NEXT: retq
;
; AVX512VLFP16-LABEL: test_ldexp_4xfloat:
; AVX512VLFP16: # %bb.0:
; AVX512VLFP16-NEXT: vcvtdq2ps %xmm1, %xmm1
; AVX512VLFP16-NEXT: vscalefps %xmm1, %xmm0, %xmm0
; AVX512VLFP16-NEXT: retq
%r = call <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float> %x, <4 x i32> %exp)
ret <4 x float> %r
}
declare <4 x float> @llvm.ldexp.v4f32.v4i32(<4 x float>, <4 x i32>)
define <2 x double> @test_ldexp_2xdouble(<2 x double> %x, <2 x i32> %exp) nounwind {
; CHECK-LABEL: test_ldexp_2xdouble:
; CHECK: # %bb.0:
; CHECK-NEXT: vcvtdq2pd %xmm1, %xmm2
; CHECK-NEXT: vscalefsd %xmm2, %xmm0, %xmm2
; CHECK-NEXT: vshufpd {{.*#+}} xmm0 = xmm0[1,0]
; CHECK-NEXT: vshufps {{.*#+}} xmm1 = xmm1[1,1,1,1]
; CHECK-NEXT: vcvtdq2pd %xmm1, %xmm1
; CHECK-NEXT: vscalefsd %xmm1, %xmm0, %xmm0
; CHECK-NEXT: vunpcklpd {{.*#+}} xmm0 = xmm2[0],xmm0[0]
; CHECK-NEXT: retq
%r = call <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double> %x, <2 x i32> %exp)
ret <2 x double> %r
}
declare <2 x double> @llvm.ldexp.v2f64.v2i32(<2 x double>, <2 x i32>)
define <16 x half> @test_ldexp_16xhalf(<16 x half> %x, <16 x i16> %exp) nounwind {
; AVX512F-LABEL: test_ldexp_16xhalf:
; AVX512F: # %bb.0:
; AVX512F-NEXT: vpmovsxwd %ymm1, %zmm1
; AVX512F-NEXT: vcvtph2ps %ymm0, %zmm0
; AVX512F-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; AVX512F-NEXT: vcvtps2ph $4, %zmm0, %ymm0
; AVX512F-NEXT: retq
;
; AVX512FP16-LABEL: test_ldexp_16xhalf:
; AVX512FP16: # %bb.0:
; AVX512FP16-NEXT: vxorps %xmm2, %xmm2, %xmm2
; AVX512FP16-NEXT: vinsertf64x4 $0, %ymm0, %zmm2, %zmm0
; AVX512FP16-NEXT: vmovaps %ymm1, %ymm1
; AVX512FP16-NEXT: vscalefph %zmm1, %zmm0, %zmm0
; AVX512FP16-NEXT: # kill: def $ymm0 killed $ymm0 killed $zmm0
; AVX512FP16-NEXT: retq
;
; AVX512VL-LABEL: test_ldexp_16xhalf:
; AVX512VL: # %bb.0:
; AVX512VL-NEXT: vpmovsxwd %ymm1, %zmm1
; AVX512VL-NEXT: vcvtph2ps %ymm0, %zmm0
; AVX512VL-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; AVX512VL-NEXT: vcvtps2ph $4, %zmm0, %ymm0
; AVX512VL-NEXT: retq
;
; AVX512VLFP16-LABEL: test_ldexp_16xhalf:
; AVX512VLFP16: # %bb.0:
; AVX512VLFP16-NEXT: vcvtw2ph %ymm1, %ymm1
; AVX512VLFP16-NEXT: vscalefph %ymm1, %ymm0, %ymm0
; AVX512VLFP16-NEXT: retq
%r = call <16 x half> @llvm.ldexp.v16f16.v16i16(<16 x half> %x, <16 x i16> %exp)
ret <16 x half> %r
}
declare <16 x half> @llvm.ldexp.v16f16.v16i16(<16 x half>, <16 x i16>)
define <8 x float> @test_ldexp_8xfloat(<8 x float> %x, <8 x i32> %exp) nounwind {
; AVX512-LABEL: test_ldexp_8xfloat:
; AVX512: # %bb.0:
; AVX512-NEXT: vmovaps %ymm1, %ymm1
; AVX512-NEXT: vmovaps %ymm0, %ymm0
; AVX512-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; AVX512-NEXT: # kill: def $ymm0 killed $ymm0 killed $zmm0
; AVX512-NEXT: retq
;
; AVX512VL-LABEL: test_ldexp_8xfloat:
; AVX512VL: # %bb.0:
; AVX512VL-NEXT: vcvtdq2ps %ymm1, %ymm1
; AVX512VL-NEXT: vscalefps %ymm1, %ymm0, %ymm0
; AVX512VL-NEXT: retq
;
; AVX512VLFP16-LABEL: test_ldexp_8xfloat:
; AVX512VLFP16: # %bb.0:
; AVX512VLFP16-NEXT: vcvtdq2ps %ymm1, %ymm1
; AVX512VLFP16-NEXT: vscalefps %ymm1, %ymm0, %ymm0
; AVX512VLFP16-NEXT: retq
%r = call <8 x float> @llvm.ldexp.v8f32.v8i32(<8 x float> %x, <8 x i32> %exp)
ret <8 x float> %r
}
declare <8 x float> @llvm.ldexp.v8f32.v8i32(<8 x float>, <8 x i32>)
define <4 x double> @test_ldexp_4xdouble(<4 x double> %x, <4 x i32> %exp) nounwind {
; AVX512-LABEL: test_ldexp_4xdouble:
; AVX512: # %bb.0:
; AVX512-NEXT: vmovapd %xmm1, %xmm1
; AVX512-NEXT: vmovapd %ymm0, %ymm0
; AVX512-NEXT: vscalefpd %zmm1, %zmm0, %zmm0
; AVX512-NEXT: # kill: def $ymm0 killed $ymm0 killed $zmm0
; AVX512-NEXT: retq
;
; AVX512VL-LABEL: test_ldexp_4xdouble:
; AVX512VL: # %bb.0:
; AVX512VL-NEXT: vcvtdq2pd %xmm1, %ymm1
; AVX512VL-NEXT: vscalefpd %ymm1, %ymm0, %ymm0
; AVX512VL-NEXT: retq
;
; AVX512VLFP16-LABEL: test_ldexp_4xdouble:
; AVX512VLFP16: # %bb.0:
; AVX512VLFP16-NEXT: vcvtdq2pd %xmm1, %ymm1
; AVX512VLFP16-NEXT: vscalefpd %ymm1, %ymm0, %ymm0
; AVX512VLFP16-NEXT: retq
%r = call <4 x double> @llvm.ldexp.v4f64.v4i32(<4 x double> %x, <4 x i32> %exp)
ret <4 x double> %r
}
declare <4 x double> @llvm.ldexp.v4f64.v4i32(<4 x double>, <4 x i32>)
define <32 x half> @test_ldexp_32xhalf(<32 x half> %x, <32 x i16> %exp) nounwind {
; AVX512F-LABEL: test_ldexp_32xhalf:
; AVX512F: # %bb.0:
; AVX512F-NEXT: vpmovsxwd %ymm1, %zmm2
; AVX512F-NEXT: vcvtph2ps %ymm0, %zmm3
; AVX512F-NEXT: vscalefps %zmm2, %zmm3, %zmm2
; AVX512F-NEXT: vcvtps2ph $4, %zmm2, %ymm2
; AVX512F-NEXT: vextracti64x4 $1, %zmm1, %ymm1
; AVX512F-NEXT: vpmovsxwd %ymm1, %zmm1
; AVX512F-NEXT: vextractf64x4 $1, %zmm0, %ymm0
; AVX512F-NEXT: vcvtph2ps %ymm0, %zmm0
; AVX512F-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; AVX512F-NEXT: vcvtps2ph $4, %zmm0, %ymm0
; AVX512F-NEXT: vinsertf64x4 $1, %ymm0, %zmm2, %zmm0
; AVX512F-NEXT: retq
;
; AVX512FP16-LABEL: test_ldexp_32xhalf:
; AVX512FP16: # %bb.0:
; AVX512FP16-NEXT: vcvtw2ph %zmm1, %zmm1
; AVX512FP16-NEXT: vscalefph %zmm1, %zmm0, %zmm0
; AVX512FP16-NEXT: retq
;
; AVX512VL-LABEL: test_ldexp_32xhalf:
; AVX512VL: # %bb.0:
; AVX512VL-NEXT: vpmovsxwd %ymm1, %zmm2
; AVX512VL-NEXT: vcvtph2ps %ymm0, %zmm3
; AVX512VL-NEXT: vscalefps %zmm2, %zmm3, %zmm2
; AVX512VL-NEXT: vcvtps2ph $4, %zmm2, %ymm2
; AVX512VL-NEXT: vextracti64x4 $1, %zmm1, %ymm1
; AVX512VL-NEXT: vpmovsxwd %ymm1, %zmm1
; AVX512VL-NEXT: vextractf64x4 $1, %zmm0, %ymm0
; AVX512VL-NEXT: vcvtph2ps %ymm0, %zmm0
; AVX512VL-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; AVX512VL-NEXT: vcvtps2ph $4, %zmm0, %ymm0
; AVX512VL-NEXT: vinsertf64x4 $1, %ymm0, %zmm2, %zmm0
; AVX512VL-NEXT: retq
;
; AVX512VLFP16-LABEL: test_ldexp_32xhalf:
; AVX512VLFP16: # %bb.0:
; AVX512VLFP16-NEXT: vcvtw2ph %zmm1, %zmm1
; AVX512VLFP16-NEXT: vscalefph %zmm1, %zmm0, %zmm0
; AVX512VLFP16-NEXT: retq
%r = call <32 x half> @llvm.ldexp.v32f16.v32i16(<32 x half> %x, <32 x i16> %exp)
ret <32 x half> %r
}
declare <32 x half> @llvm.ldexp.v32f16.v32i16(<32 x half>, <32 x i16>)
define <16 x float> @test_ldexp_16xfloat(<16 x float> %x, <16 x i32> %exp) nounwind {
; CHECK-LABEL: test_ldexp_16xfloat:
; CHECK: # %bb.0:
; CHECK-NEXT: vcvtdq2ps %zmm1, %zmm1
; CHECK-NEXT: vscalefps %zmm1, %zmm0, %zmm0
; CHECK-NEXT: retq
%r = call <16 x float> @llvm.ldexp.v16f32.v16i32(<16 x float> %x, <16 x i32> %exp)
ret <16 x float> %r
}
declare <16 x float> @llvm.ldexp.v16f32.v16i32(<16 x float>, <16 x i32>)
define <8 x double> @test_ldexp_8xdouble(<8 x double> %x, <8 x i32> %exp) nounwind {
; CHECK-LABEL: test_ldexp_8xdouble:
; CHECK: # %bb.0:
; CHECK-NEXT: vcvtdq2pd %ymm1, %zmm1
; CHECK-NEXT: vscalefpd %zmm1, %zmm0, %zmm0
; CHECK-NEXT: retq
%r = call <8 x double> @llvm.ldexp.v8f64.v8i32(<8 x double> %x, <8 x i32> %exp)
ret <8 x double> %r
}
declare <8 x double> @llvm.ldexp.v8f64.v8i32(<8 x double>, <8 x i32>)
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; AVX512VLF: {{.*}}