Files
clang-p2996/llvm/test/CodeGen/PowerPC/fma-combine.ll
Amy Kwan ba627a32e1 [PowerPC] Update Refactored Load/Store Implementation, XForm VSX Patterns, and Tests
This patch includes the following updates to the load/store refactoring effort introduced in D93370:
 - Update various VSX patterns that use to "force" an XForm, to instead just XForm.
   This allows the ability for the patterns to compute the most optimal addressing
   mode (and to produce a DForm instruction when possible)
- Update pattern and test case for the LXVD2X/STXVD2X intrinsics
- Update LIT test cases that use to use the XForm instruction to use the DForm instruction

Differential Revision: https://reviews.llvm.org/D95115
2021-07-16 09:28:48 -05:00

350 lines
12 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -enable-no-signed-zeros-fp-math \
; RUN: -enable-unsafe-fp-math < %s | FileCheck -check-prefix=CHECK-FAST %s
; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu -enable-no-signed-zeros-fp-math \
; RUN: -enable-unsafe-fp-math -mattr=-vsx < %s | FileCheck -check-prefix=CHECK-FAST-NOVSX %s
; RUN: llc -mtriple=powerpc64le-unknown-linux-gnu < %s | FileCheck %s
define dso_local double @fma_combine1(double %a, double %b, double %c) {
; CHECK-FAST-LABEL: fma_combine1:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: xsnmaddadp 1, 3, 2
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: fma_combine1:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: fnmadd 1, 3, 2, 1
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: fma_combine1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xsnegdp 0, 3
; CHECK-NEXT: xsmuldp 0, 0, 2
; CHECK-NEXT: xssubdp 1, 0, 1
; CHECK-NEXT: blr
entry:
%fneg1 = fneg double %c
%mul = fmul double %fneg1, %b
%add = fsub double %mul, %a
ret double %add
}
define dso_local double @fma_combine2(double %a, double %b, double %c) {
; CHECK-FAST-LABEL: fma_combine2:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: xsnmaddadp 1, 2, 3
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: fma_combine2:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: fnmadd 1, 2, 3, 1
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: fma_combine2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xsnegdp 0, 3
; CHECK-NEXT: xsmuldp 0, 2, 0
; CHECK-NEXT: xssubdp 1, 0, 1
; CHECK-NEXT: blr
entry:
%fneg1 = fneg double %c
%mul = fmul double %b, %fneg1
%add = fsub double %mul, %a
ret double %add
}
@v = common dso_local local_unnamed_addr global double 0.000000e+00, align 8
@z = common dso_local local_unnamed_addr global double 0.000000e+00, align 8
define dso_local double @fma_combine_two_uses(double %a, double %b, double %c) {
; CHECK-FAST-LABEL: fma_combine_two_uses:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: xsnegdp 0, 1
; CHECK-FAST-NEXT: addis 3, 2, v@toc@ha
; CHECK-FAST-NEXT: addis 4, 2, z@toc@ha
; CHECK-FAST-NEXT: xsnmaddadp 1, 3, 2
; CHECK-FAST-NEXT: xsnegdp 2, 3
; CHECK-FAST-NEXT: stfd 0, v@toc@l(3)
; CHECK-FAST-NEXT: stfd 2, z@toc@l(4)
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: fma_combine_two_uses:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: fnmadd 0, 3, 2, 1
; CHECK-FAST-NOVSX-NEXT: fneg 2, 1
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, v@toc@ha
; CHECK-FAST-NOVSX-NEXT: addis 4, 2, z@toc@ha
; CHECK-FAST-NOVSX-NEXT: fneg 3, 3
; CHECK-FAST-NOVSX-NEXT: fmr 1, 0
; CHECK-FAST-NOVSX-NEXT: stfd 2, v@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: stfd 3, z@toc@l(4)
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: fma_combine_two_uses:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xsnegdp 3, 3
; CHECK-NEXT: addis 3, 2, v@toc@ha
; CHECK-NEXT: addis 4, 2, z@toc@ha
; CHECK-NEXT: xsmuldp 0, 3, 2
; CHECK-NEXT: stfd 3, z@toc@l(4)
; CHECK-NEXT: xsnegdp 2, 1
; CHECK-NEXT: xssubdp 0, 0, 1
; CHECK-NEXT: stfd 2, v@toc@l(3)
; CHECK-NEXT: fmr 1, 0
; CHECK-NEXT: blr
entry:
%fneg = fneg double %a
store double %fneg, double* @v, align 8
%fneg1 = fneg double %c
store double %fneg1, double* @z, align 8
%mul = fmul double %fneg1, %b
%add = fsub double %mul, %a
ret double %add
}
define dso_local double @fma_combine_one_use(double %a, double %b, double %c) {
; CHECK-FAST-LABEL: fma_combine_one_use:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: xsnegdp 0, 1
; CHECK-FAST-NEXT: addis 3, 2, v@toc@ha
; CHECK-FAST-NEXT: xsnmaddadp 1, 3, 2
; CHECK-FAST-NEXT: stfd 0, v@toc@l(3)
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: fma_combine_one_use:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: fnmadd 0, 3, 2, 1
; CHECK-FAST-NOVSX-NEXT: fneg 2, 1
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, v@toc@ha
; CHECK-FAST-NOVSX-NEXT: fmr 1, 0
; CHECK-FAST-NOVSX-NEXT: stfd 2, v@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: fma_combine_one_use:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xsnegdp 0, 3
; CHECK-NEXT: addis 3, 2, v@toc@ha
; CHECK-NEXT: xsmuldp 0, 0, 2
; CHECK-NEXT: xsnegdp 2, 1
; CHECK-NEXT: xssubdp 0, 0, 1
; CHECK-NEXT: stfd 2, v@toc@l(3)
; CHECK-NEXT: fmr 1, 0
; CHECK-NEXT: blr
entry:
%fneg = fneg double %a
store double %fneg, double* @v, align 8
%fneg1 = fneg double %c
%mul = fmul double %fneg1, %b
%add = fsub double %mul, %a
ret double %add
}
define dso_local float @fma_combine_no_ice() {
; CHECK-FAST-LABEL: fma_combine_no_ice:
; CHECK-FAST: # %bb.0:
; CHECK-FAST-NEXT: addis 3, 2, .LCPI4_0@toc@ha
; CHECK-FAST-NEXT: lfs 0, .LCPI4_0@toc@l(3)
; CHECK-FAST-NEXT: addis 3, 2, .LCPI4_1@toc@ha
; CHECK-FAST-NEXT: lfs 2, 0(3)
; CHECK-FAST-NEXT: lfs 3, .LCPI4_1@toc@l(3)
; CHECK-FAST-NEXT: addis 3, 2, .LCPI4_2@toc@ha
; CHECK-FAST-NEXT: lfs 1, .LCPI4_2@toc@l(3)
; CHECK-FAST-NEXT: xsmaddasp 3, 2, 0
; CHECK-FAST-NEXT: xsmaddasp 1, 2, 3
; CHECK-FAST-NEXT: xsnmsubasp 1, 3, 2
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: fma_combine_no_ice:
; CHECK-FAST-NOVSX: # %bb.0:
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI4_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 0, .LCPI4_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI4_1@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 1, 0(3)
; CHECK-FAST-NOVSX-NEXT: lfs 2, .LCPI4_1@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI4_2@toc@ha
; CHECK-FAST-NOVSX-NEXT: fmadds 0, 1, 2, 0
; CHECK-FAST-NOVSX-NEXT: lfs 2, .LCPI4_2@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: fmadds 2, 1, 0, 2
; CHECK-FAST-NOVSX-NEXT: fnmsubs 1, 0, 1, 2
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: fma_combine_no_ice:
; CHECK: # %bb.0:
; CHECK-NEXT: addis 3, 2, .LCPI4_0@toc@ha
; CHECK-NEXT: lfs 0, .LCPI4_0@toc@l(3)
; CHECK-NEXT: addis 3, 2, .LCPI4_1@toc@ha
; CHECK-NEXT: lfs 2, 0(3)
; CHECK-NEXT: lfs 3, .LCPI4_1@toc@l(3)
; CHECK-NEXT: addis 3, 2, .LCPI4_2@toc@ha
; CHECK-NEXT: lfs 1, .LCPI4_2@toc@l(3)
; CHECK-NEXT: fmr 4, 3
; CHECK-NEXT: xsmaddasp 3, 2, 0
; CHECK-NEXT: xsnmaddasp 4, 2, 0
; CHECK-NEXT: xsmaddasp 1, 2, 3
; CHECK-NEXT: xsmaddasp 1, 4, 2
; CHECK-NEXT: blr
%tmp = load float, float* undef, align 4
%tmp2 = load float, float* undef, align 4
%tmp3 = fmul contract reassoc float %tmp, 0x3FE372D780000000
%tmp4 = fadd contract reassoc float %tmp3, 1.000000e+00
%tmp5 = fmul contract reassoc float %tmp2, %tmp4
%tmp6 = load float, float* undef, align 4
%tmp7 = load float, float* undef, align 4
%tmp8 = fmul contract reassoc float %tmp7, 0x3FE372D780000000
%tmp9 = fsub contract reassoc nsz float -1.000000e+00, %tmp8
%tmp10 = fmul contract reassoc float %tmp9, %tmp6
%tmp11 = fadd contract reassoc float %tmp5, 5.000000e-01
%tmp12 = fadd contract reassoc float %tmp11, %tmp10
ret float %tmp12
}
; This would crash while trying getNegatedExpression().
define dso_local double @getNegatedExpression_crash(double %x, double %y) {
; CHECK-FAST-LABEL: getNegatedExpression_crash:
; CHECK-FAST: # %bb.0:
; CHECK-FAST-NEXT: addis 3, 2, .LCPI5_1@toc@ha
; CHECK-FAST-NEXT: lfs 3, .LCPI5_1@toc@l(3)
; CHECK-FAST-NEXT: addis 3, 2, .LCPI5_0@toc@ha
; CHECK-FAST-NEXT: lfs 4, .LCPI5_0@toc@l(3)
; CHECK-FAST-NEXT: xssubdp 0, 1, 3
; CHECK-FAST-NEXT: xsmaddadp 3, 1, 4
; CHECK-FAST-NEXT: xsmaddadp 0, 3, 2
; CHECK-FAST-NEXT: fmr 1, 0
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: getNegatedExpression_crash:
; CHECK-FAST-NOVSX: # %bb.0:
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI5_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: addis 4, 2, .LCPI5_1@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 0, .LCPI5_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: lfs 3, .LCPI5_1@toc@l(4)
; CHECK-FAST-NOVSX-NEXT: fmadd 3, 1, 3, 0
; CHECK-FAST-NOVSX-NEXT: fsub 0, 1, 0
; CHECK-FAST-NOVSX-NEXT: fmadd 1, 3, 2, 0
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: getNegatedExpression_crash:
; CHECK: # %bb.0:
; CHECK-NEXT: addis 3, 2, .LCPI5_1@toc@ha
; CHECK-NEXT: lfs 3, .LCPI5_1@toc@l(3)
; CHECK-NEXT: addis 3, 2, .LCPI5_0@toc@ha
; CHECK-NEXT: lfs 4, .LCPI5_0@toc@l(3)
; CHECK-NEXT: xssubdp 0, 1, 3
; CHECK-NEXT: xsmaddadp 3, 1, 4
; CHECK-NEXT: xsmaddadp 0, 3, 2
; CHECK-NEXT: fmr 1, 0
; CHECK-NEXT: blr
%neg = fneg reassoc double %x
%fma = call reassoc nsz double @llvm.fma.f64(double %neg, double 42.0, double -1.0)
%add = fadd reassoc nsz double %x, 1.0
%fma1 = call reassoc nsz double @llvm.fma.f64(double %fma, double %y, double %add)
ret double %fma1
}
define dso_local double @fma_flag_propagation(double %a) {
; CHECK-FAST-LABEL: fma_flag_propagation:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: xxlxor 1, 1, 1
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: fma_flag_propagation:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI6_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI6_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: fma_flag_propagation:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor 1, 1, 1
; CHECK-NEXT: blr
entry:
%0 = fneg double %a
%1 = call reassoc nnan double @llvm.fma.f64(double %0, double 1.0, double %a)
ret double %1
}
define dso_local double @neg_fma_flag_propagation(double %a) {
; CHECK-FAST-LABEL: neg_fma_flag_propagation:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: xxlxor 1, 1, 1
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: neg_fma_flag_propagation:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI7_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI7_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: neg_fma_flag_propagation:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xxlxor 1, 1, 1
; CHECK-NEXT: blr
entry:
%0 = call reassoc nnan double @llvm.fma.f64(double %a, double -1.0, double %a)
ret double %0
}
define <2 x double> @vec_neg_fma_flag_propagation(<2 x double> %a) {
; CHECK-FAST-LABEL: vec_neg_fma_flag_propagation:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: addis 3, 2, .LCPI8_0@toc@ha
; CHECK-FAST-NEXT: addi 3, 3, .LCPI8_0@toc@l
; CHECK-FAST-NEXT: lxvd2x 0, 0, 3
; CHECK-FAST-NEXT: xxswapd 0, 0
; CHECK-FAST-NEXT: xvmaddadp 34, 34, 0
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: vec_neg_fma_flag_propagation:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI8_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfs 1, .LCPI8_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: fmr 2, 1
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: vec_neg_fma_flag_propagation:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addis 3, 2, .LCPI8_0@toc@ha
; CHECK-NEXT: addi 3, 3, .LCPI8_0@toc@l
; CHECK-NEXT: lxvd2x 0, 0, 3
; CHECK-NEXT: xxswapd 0, 0
; CHECK-NEXT: xvmaddadp 34, 34, 0
; CHECK-NEXT: blr
entry:
%0 = call reassoc nnan <2 x double> @llvm.fma.v2f64(<2 x double> %a, <2 x double> <double -1.0, double -1.0>, <2 x double> %a)
ret <2 x double> %0
}
define dso_local double @fma_combine_const(double %a, double %b) {
; CHECK-FAST-LABEL: fma_combine_const:
; CHECK-FAST: # %bb.0: # %entry
; CHECK-FAST-NEXT: addis 3, 2, .LCPI9_0@toc@ha
; CHECK-FAST-NEXT: lfd 0, .LCPI9_0@toc@l(3)
; CHECK-FAST-NEXT: xsmaddadp 2, 1, 0
; CHECK-FAST-NEXT: fmr 1, 2
; CHECK-FAST-NEXT: blr
;
; CHECK-FAST-NOVSX-LABEL: fma_combine_const:
; CHECK-FAST-NOVSX: # %bb.0: # %entry
; CHECK-FAST-NOVSX-NEXT: addis 3, 2, .LCPI9_0@toc@ha
; CHECK-FAST-NOVSX-NEXT: lfd 0, .LCPI9_0@toc@l(3)
; CHECK-FAST-NOVSX-NEXT: fmadd 1, 1, 0, 2
; CHECK-FAST-NOVSX-NEXT: blr
;
; CHECK-LABEL: fma_combine_const:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addis 3, 2, .LCPI9_0@toc@ha
; CHECK-NEXT: lfd 0, .LCPI9_0@toc@l(3)
; CHECK-NEXT: addis 3, 2, .LCPI9_1@toc@ha
; CHECK-NEXT: lfd 3, .LCPI9_1@toc@l(3)
; CHECK-NEXT: xsmuldp 0, 1, 0
; CHECK-NEXT: fmr 1, 2
; CHECK-NEXT: xsmaddadp 1, 0, 3
; CHECK-NEXT: blr
entry:
%0 = fmul double %a, 1.1
%1 = call contract double @llvm.fma.f64(double %0, double 2.1, double %b)
ret double %1
}
declare double @llvm.fma.f64(double, double, double) nounwind readnone
declare <2 x double> @llvm.fma.v2f64(<2 x double>, <2 x double>, <2 x double>) nounwind readnone