This patch teaches the backend how to lower the FCBRT DAG node to the vector math library function when using ArmPL. This is similar to what we already do for llvm.pow/FPOW, however the only way to expose this is via a DAG combine that converts FPOW(<2 x double> %x, <2 x double> <double 1.0/3.0, double 1.0/3.0>) into FCBRT(<2 x double> %x) when the appropriate fast math flags are present on the node. I've updated the DAG combine to handle vector types and only perform the transformation if there exists a vector library variant of cbrt.
123 lines
4.0 KiB
LLVM
123 lines
4.0 KiB
LLVM
; RUN: llc < %s -mtriple=thumbv7m-linux-gnueabi | FileCheck %s --check-prefixes=ANY,SOFTFLOAT
|
|
; RUN: llc < %s -mtriple=thumbv8-linux-gnueabihf -mattr=neon | FileCheck %s --check-prefixes=ANY,HARDFLOAT
|
|
|
|
declare float @llvm.pow.f32(float, float)
|
|
declare <4 x float> @llvm.pow.v4f32(<4 x float>, <4 x float>)
|
|
|
|
declare double @llvm.pow.f64(double, double)
|
|
declare <2 x double> @llvm.pow.v2f64(<2 x double>, <2 x double>)
|
|
|
|
define float @pow_f32_one_fourth_fmf(float %x) nounwind {
|
|
; ANY-LABEL: pow_f32_one_fourth_fmf:
|
|
; SOFTFLOAT: bl powf
|
|
; HARDFLOAT: vsqrt.f32
|
|
; HARDFLOAT: vsqrt.f32
|
|
%r = call nsz ninf afn float @llvm.pow.f32(float %x, float 2.5e-01)
|
|
ret float %r
|
|
}
|
|
|
|
define double @pow_f64_one_fourth_fmf(double %x) nounwind {
|
|
; ANY-LABEL: pow_f64_one_fourth_fmf:
|
|
; SOFTFLOAT: bl pow
|
|
; HARDFLOAT: vsqrt.f64
|
|
; HARDFLOAT: vsqrt.f64
|
|
%r = call nsz ninf afn double @llvm.pow.f64(double %x, double 2.5e-01)
|
|
ret double %r
|
|
}
|
|
|
|
define float @pow_f32_one_third_fmf(float %x) nounwind {
|
|
; ANY-LABEL: pow_f32_one_third_fmf:
|
|
; SOFTFLOAT: bl cbrtf
|
|
; HARDFLOAT: b cbrtf
|
|
%r = call fast float @llvm.pow.f32(float %x, float 0x3FD5555560000000)
|
|
ret float %r
|
|
}
|
|
|
|
define double @pow_f64_one_third_fmf(double %x) nounwind {
|
|
; ANY-LABEL: pow_f64_one_third_fmf:
|
|
; SOFTFLOAT: bl cbrt
|
|
; HARDFLOAT: b cbrt
|
|
%r = call fast double @llvm.pow.f64(double %x, double 0x3FD5555555555555)
|
|
ret double %r
|
|
}
|
|
|
|
define <4 x float> @pow_v4f32_one_fourth_fmf(<4 x float> %x) nounwind {
|
|
; ANY-LABEL: pow_v4f32_one_fourth_fmf:
|
|
; SOFTFLOAT: bl powf
|
|
; SOFTFLOAT: bl powf
|
|
; SOFTFLOAT: bl powf
|
|
; SOFTFLOAT: bl powf
|
|
; HARDFLOAT: vsqrt.f32
|
|
; HARDFLOAT: vsqrt.f32
|
|
; HARDFLOAT: vsqrt.f32
|
|
; HARDFLOAT: vsqrt.f32
|
|
; HARDFLOAT: vsqrt.f32
|
|
; HARDFLOAT: vsqrt.f32
|
|
; HARDFLOAT: vsqrt.f32
|
|
; HARDFLOAT: vsqrt.f32
|
|
%r = call fast <4 x float> @llvm.pow.v4f32(<4 x float> %x, <4 x float> <float 2.5e-1, float 2.5e-1, float 2.5e-01, float 2.5e-01>)
|
|
ret <4 x float> %r
|
|
}
|
|
|
|
define <2 x double> @pow_v2f64_one_fourth_fmf(<2 x double> %x) nounwind {
|
|
; ANY-LABEL: pow_v2f64_one_fourth_fmf:
|
|
; SOFTFLOAT: bl pow
|
|
; SOFTFLOAT: bl pow
|
|
; HARDFLOAT: vsqrt.f64
|
|
; HARDFLOAT: vsqrt.f64
|
|
; HARDFLOAT: vsqrt.f64
|
|
; HARDFLOAT: vsqrt.f64
|
|
%r = call fast <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.5e-1, double 2.5e-1>)
|
|
ret <2 x double> %r
|
|
}
|
|
|
|
define float @pow_f32_one_fourth_not_enough_fmf(float %x) nounwind {
|
|
; ANY-LABEL: pow_f32_one_fourth_not_enough_fmf:
|
|
; SOFTFLOAT: bl powf
|
|
; HARDFLOAT: b powf
|
|
%r = call afn ninf float @llvm.pow.f32(float %x, float 2.5e-01)
|
|
ret float %r
|
|
}
|
|
|
|
define double @pow_f64_one_fourth_not_enough_fmf(double %x) nounwind {
|
|
; ANY-LABEL: pow_f64_one_fourth_not_enough_fmf:
|
|
; SOFTFLOAT: bl pow
|
|
; HARDFLOAT: b pow
|
|
%r = call nsz ninf double @llvm.pow.f64(double %x, double 2.5e-01)
|
|
ret double %r
|
|
}
|
|
|
|
define <4 x float> @pow_v4f32_one_fourth_not_enough_fmf(<4 x float> %x) nounwind {
|
|
; ANY-LABEL: pow_v4f32_one_fourth_not_enough_fmf:
|
|
; ANY: bl powf
|
|
; ANY: bl powf
|
|
; ANY: bl powf
|
|
; ANY: bl powf
|
|
%r = call afn nsz <4 x float> @llvm.pow.v4f32(<4 x float> %x, <4 x float> <float 2.5e-1, float 2.5e-1, float 2.5e-01, float 2.5e-01>)
|
|
ret <4 x float> %r
|
|
}
|
|
|
|
define <2 x double> @pow_v2f64_one_fourth_not_enough_fmf(<2 x double> %x) nounwind {
|
|
; ANY-LABEL: pow_v2f64_one_fourth_not_enough_fmf:
|
|
; ANY: bl pow
|
|
; ANY: bl pow
|
|
%r = call nsz nnan reassoc <2 x double> @llvm.pow.v2f64(<2 x double> %x, <2 x double> <double 2.5e-1, double 2.5e-1>)
|
|
ret <2 x double> %r
|
|
}
|
|
|
|
define <4 x float> @test_pow_one_third_v4f32(<4 x float> %x) nounwind {
|
|
; SOFTFLOAT-LABEL: test_pow_one_third_v4f32:
|
|
; SOFTFLOAT: bl powf
|
|
; SOFTFLOAT: bl powf
|
|
; SOFTFLOAT: bl powf
|
|
; SOFTFLOAT: bl powf
|
|
;
|
|
; HARDFLOAT-LABEL: test_pow_one_third_v4f32:
|
|
; HARDFLOAT: bl cbrtf
|
|
; HARDFLOAT: bl cbrtf
|
|
; HARDFLOAT: bl cbrtf
|
|
; HARDFLOAT: bl cbrtf
|
|
%r = call fast <4 x float> @llvm.pow.v4f32(<4 x float> %x, <4 x float> splat (float 0x3FD5555560000000))
|
|
ret <4 x float> %r
|
|
}
|