mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
d9107e9132
On PowerPC, we have vnmsubfp Altivec instruction for fnmsub operation on v4f32 type. Default pattern for this instruction never works since we don't have legal fneg for v4f32 when VSX disabled. Reviewed By: steven.zhang Differential Revision: https://reviews.llvm.org/D80617
324 lines
9.8 KiB
LLVM
324 lines
9.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
|
; RUN: llc < %s -mtriple powerpc64le -verify-machineinstrs \
|
|
; RUN: | FileCheck -check-prefix=VSX %s
|
|
; RUN: llc < %s -mtriple powerpc64le -verify-machineinstrs -mattr=-vsx \
|
|
; RUN: | FileCheck -check-prefix=NO-VSX %s
|
|
|
|
define double @test_mul_sub_f64(double %a, double %b, double %c) {
|
|
; VSX-LABEL: test_mul_sub_f64:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsnegdp 0, 2
|
|
; VSX-NEXT: xsmaddadp 1, 0, 3
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_mul_sub_f64:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fneg 0, 2
|
|
; NO-VSX-NEXT: fmadd 1, 0, 3, 1
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fmul contract reassoc double %b, %c
|
|
%1 = fsub contract reassoc double %a, %0
|
|
ret double %1
|
|
}
|
|
|
|
define double @test_2mul_sub_f64(double %a, double %b, double %c, double %d) {
|
|
; VSX-LABEL: test_2mul_sub_f64:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsmuldp 0, 3, 4
|
|
; VSX-NEXT: xsmsubadp 0, 1, 2
|
|
; VSX-NEXT: fmr 1, 0
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_2mul_sub_f64:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fmul 0, 3, 4
|
|
; NO-VSX-NEXT: fmsub 1, 1, 2, 0
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fmul contract reassoc double %a, %b
|
|
%1 = fmul contract reassoc double %c, %d
|
|
%2 = fsub contract reassoc double %0, %1
|
|
ret double %2
|
|
}
|
|
|
|
define double @test_neg_fma_f64(double %a, double %b, double %c) {
|
|
; VSX-LABEL: test_neg_fma_f64:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsnegdp 0, 1
|
|
; VSX-NEXT: xsmaddadp 3, 0, 2
|
|
; VSX-NEXT: fmr 1, 3
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_neg_fma_f64:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fneg 0, 1
|
|
; NO-VSX-NEXT: fmadd 1, 0, 2, 3
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fsub contract reassoc double -0.0, %a
|
|
%1 = call contract reassoc double @llvm.fma.f64(double %0, double %b,
|
|
double %c)
|
|
ret double %1
|
|
}
|
|
|
|
define float @test_mul_sub_f32(float %a, float %b, float %c) {
|
|
; VSX-LABEL: test_mul_sub_f32:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsnegdp 0, 2
|
|
; VSX-NEXT: xsmaddasp 1, 0, 3
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_mul_sub_f32:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fneg 0, 2
|
|
; NO-VSX-NEXT: fmadds 1, 0, 3, 1
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fmul contract reassoc float %b, %c
|
|
%1 = fsub contract reassoc float %a, %0
|
|
ret float %1
|
|
}
|
|
|
|
define float @test_2mul_sub_f32(float %a, float %b, float %c, float %d) {
|
|
; VSX-LABEL: test_2mul_sub_f32:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsmulsp 0, 3, 4
|
|
; VSX-NEXT: xsmsubasp 0, 1, 2
|
|
; VSX-NEXT: fmr 1, 0
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_2mul_sub_f32:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fmuls 0, 3, 4
|
|
; NO-VSX-NEXT: fmsubs 1, 1, 2, 0
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fmul contract reassoc float %a, %b
|
|
%1 = fmul contract reassoc float %c, %d
|
|
%2 = fsub contract reassoc float %0, %1
|
|
ret float %2
|
|
}
|
|
|
|
define float @test_neg_fma_f32(float %a, float %b, float %c) {
|
|
; VSX-LABEL: test_neg_fma_f32:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsnegdp 0, 1
|
|
; VSX-NEXT: xsmaddasp 3, 0, 2
|
|
; VSX-NEXT: fmr 1, 3
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_neg_fma_f32:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fneg 0, 1
|
|
; NO-VSX-NEXT: fmadds 1, 0, 2, 3
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fsub contract reassoc float -0.0, %a
|
|
%1 = call contract reassoc float @llvm.fma.f32(float %0, float %b, float %c)
|
|
ret float %1
|
|
}
|
|
|
|
define <2 x double> @test_neg_fma_v2f64(<2 x double> %a, <2 x double> %b,
|
|
; VSX-LABEL: test_neg_fma_v2f64:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xvnegdp 0, 34
|
|
; VSX-NEXT: xvmaddadp 36, 0, 35
|
|
; VSX-NEXT: vmr 2, 4
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_neg_fma_v2f64:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fneg 0, 2
|
|
; NO-VSX-NEXT: fneg 1, 1
|
|
; NO-VSX-NEXT: fmadd 1, 1, 3, 5
|
|
; NO-VSX-NEXT: fmadd 2, 0, 4, 6
|
|
; NO-VSX-NEXT: blr
|
|
<2 x double> %c) {
|
|
entry:
|
|
%0 = fsub contract reassoc <2 x double> <double -0.0, double -0.0>, %a
|
|
%1 = call contract reassoc <2 x double> @llvm.fma.v2f64(<2 x double> %0,
|
|
<2 x double> %b,
|
|
<2 x double> %c)
|
|
ret <2 x double> %1
|
|
}
|
|
|
|
define <4 x float> @test_neg_fma_v4f32(<4 x float> %a, <4 x float> %b,
|
|
; VSX-LABEL: test_neg_fma_v4f32:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xvnegsp 0, 34
|
|
; VSX-NEXT: xvmaddasp 36, 0, 35
|
|
; VSX-NEXT: vmr 2, 4
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_neg_fma_v4f32:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: vspltisb 5, -1
|
|
; NO-VSX-NEXT: vslw 5, 5, 5
|
|
; NO-VSX-NEXT: vsubfp 2, 5, 2
|
|
; NO-VSX-NEXT: vmaddfp 2, 2, 3, 4
|
|
; NO-VSX-NEXT: blr
|
|
<4 x float> %c) {
|
|
entry:
|
|
%0 = fsub contract reassoc <4 x float> <float -0.0, float -0.0, float -0.0,
|
|
float -0.0>, %a
|
|
%1 = call contract reassoc <4 x float> @llvm.fma.v4f32(<4 x float> %0,
|
|
<4 x float> %b,
|
|
<4 x float> %c)
|
|
ret <4 x float> %1
|
|
}
|
|
|
|
define double @test_fast_mul_sub_f64(double %a, double %b, double %c) {
|
|
; VSX-LABEL: test_fast_mul_sub_f64:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsnmsubadp 1, 2, 3
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_fast_mul_sub_f64:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fnmsub 1, 2, 3, 1
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fmul reassoc nsz double %b, %c
|
|
%1 = fsub reassoc nsz double %a, %0
|
|
ret double %1
|
|
}
|
|
|
|
define double @test_fast_2mul_sub_f64(double %a, double %b, double %c,
|
|
; VSX-LABEL: test_fast_2mul_sub_f64:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsmuldp 0, 3, 4
|
|
; VSX-NEXT: xsmsubadp 0, 1, 2
|
|
; VSX-NEXT: fmr 1, 0
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_fast_2mul_sub_f64:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fmul 0, 3, 4
|
|
; NO-VSX-NEXT: fmsub 1, 1, 2, 0
|
|
; NO-VSX-NEXT: blr
|
|
double %d) {
|
|
entry:
|
|
%0 = fmul reassoc double %a, %b
|
|
%1 = fmul reassoc double %c, %d
|
|
%2 = fsub reassoc double %0, %1
|
|
ret double %2
|
|
}
|
|
|
|
define double @test_fast_neg_fma_f64(double %a, double %b, double %c) {
|
|
; VSX-LABEL: test_fast_neg_fma_f64:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsnmsubadp 3, 1, 2
|
|
; VSX-NEXT: fmr 1, 3
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_fast_neg_fma_f64:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fnmsub 1, 1, 2, 3
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fsub reassoc double -0.0, %a
|
|
%1 = call reassoc nsz double @llvm.fma.f64(double %0, double %b, double %c)
|
|
ret double %1
|
|
}
|
|
|
|
define float @test_fast_mul_sub_f32(float %a, float %b, float %c) {
|
|
; VSX-LABEL: test_fast_mul_sub_f32:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsnmsubasp 1, 2, 3
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_fast_mul_sub_f32:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fnmsubs 1, 2, 3, 1
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fmul reassoc float %b, %c
|
|
%1 = fsub reassoc nsz float %a, %0
|
|
ret float %1
|
|
}
|
|
|
|
define float @test_fast_2mul_sub_f32(float %a, float %b, float %c, float %d) {
|
|
; VSX-LABEL: test_fast_2mul_sub_f32:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsmulsp 0, 3, 4
|
|
; VSX-NEXT: xsmsubasp 0, 1, 2
|
|
; VSX-NEXT: fmr 1, 0
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_fast_2mul_sub_f32:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fmuls 0, 3, 4
|
|
; NO-VSX-NEXT: fmsubs 1, 1, 2, 0
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fmul reassoc float %a, %b
|
|
%1 = fmul reassoc float %c, %d
|
|
%2 = fsub reassoc nsz float %0, %1
|
|
ret float %2
|
|
}
|
|
|
|
define float @test_fast_neg_fma_f32(float %a, float %b, float %c) {
|
|
; VSX-LABEL: test_fast_neg_fma_f32:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xsnmsubasp 3, 1, 2
|
|
; VSX-NEXT: fmr 1, 3
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_fast_neg_fma_f32:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fnmsubs 1, 1, 2, 3
|
|
; NO-VSX-NEXT: blr
|
|
entry:
|
|
%0 = fsub reassoc float -0.0, %a
|
|
%1 = call reassoc nsz float @llvm.fma.f32(float %0, float %b, float %c)
|
|
ret float %1
|
|
}
|
|
|
|
define <2 x double> @test_fast_neg_fma_v2f64(<2 x double> %a, <2 x double> %b,
|
|
; VSX-LABEL: test_fast_neg_fma_v2f64:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xvnmsubadp 36, 34, 35
|
|
; VSX-NEXT: vmr 2, 4
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_fast_neg_fma_v2f64:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: fnmsub 1, 1, 3, 5
|
|
; NO-VSX-NEXT: fnmsub 2, 2, 4, 6
|
|
; NO-VSX-NEXT: blr
|
|
<2 x double> %c) {
|
|
entry:
|
|
%0 = fsub reassoc <2 x double> <double -0.0, double -0.0>, %a
|
|
%1 = call reassoc nsz <2 x double> @llvm.fma.v2f64(<2 x double> %0, <2 x double> %b,
|
|
<2 x double> %c)
|
|
ret <2 x double> %1
|
|
}
|
|
|
|
define <4 x float> @test_fast_neg_fma_v4f32(<4 x float> %a, <4 x float> %b,
|
|
; VSX-LABEL: test_fast_neg_fma_v4f32:
|
|
; VSX: # %bb.0: # %entry
|
|
; VSX-NEXT: xvnmsubasp 36, 34, 35
|
|
; VSX-NEXT: vmr 2, 4
|
|
; VSX-NEXT: blr
|
|
;
|
|
; NO-VSX-LABEL: test_fast_neg_fma_v4f32:
|
|
; NO-VSX: # %bb.0: # %entry
|
|
; NO-VSX-NEXT: vnmsubfp 2, 2, 3, 4
|
|
; NO-VSX-NEXT: blr
|
|
<4 x float> %c) {
|
|
entry:
|
|
%0 = fsub reassoc <4 x float> <float -0.0, float -0.0, float -0.0,
|
|
float -0.0>, %a
|
|
%1 = call reassoc nsz <4 x float> @llvm.fma.v4f32(<4 x float> %0, <4 x float> %b,
|
|
<4 x float> %c)
|
|
ret <4 x float> %1
|
|
}
|
|
|
|
declare float @llvm.fma.f32(float %a, float %b, float %c)
|
|
declare double @llvm.fma.f64(double %a, double %b, double %c)
|
|
declare <4 x float> @llvm.fma.v4f32(<4 x float> %a, <4 x float> %b,
|
|
<4 x float> %c)
|
|
declare <2 x double> @llvm.fma.v2f64(<2 x double> %a, <2 x double> %b,
|
|
<2 x double> %c)
|