diff --git a/llvm/lib/Target/PowerPC/PPCInstrVSX.td b/llvm/lib/Target/PowerPC/PPCInstrVSX.td --- a/llvm/lib/Target/PowerPC/PPCInstrVSX.td +++ b/llvm/lib/Target/PowerPC/PPCInstrVSX.td @@ -1011,6 +1011,14 @@ (f64 (EXTRACT_SUBREG $S, sub_64))>; } +// Additional patterns for VSX f32 fabs and fnabs +def : Pat<(f32 (fabs f32:$S)), + (f32 (COPY_TO_REGCLASS (XSABSDP + (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; +def : Pat<(f32 (fneg (fabs f32:$S))), + (f32 (COPY_TO_REGCLASS (XSNABSDP + (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; + // Additional fnmsub patterns: -a*b + c == -(a*b - c) def : Pat<(fma (fneg f64:$A), f64:$B, f64:$C), (XSNMSUBADP $C, $A, $B)>; @@ -1578,6 +1586,13 @@ AltVSXFMARel; } + // Additional pattern for VSX f32 fneg + // XSNMSUBASP was firstly introduced in POWER ISA v2.07, while XSNEGDP exists + // in v2.06. Put this here to keep fnmsub in P7 targets. + def : Pat<(f32 (fneg f32:$S)), + (f32 (COPY_TO_REGCLASS (XSNEGDP + (COPY_TO_REGCLASS $S, VSFRC)), VSSRC))>; + // Additional xsnmsubasp patterns: -a*b + c == -(a*b - c) def : Pat<(fma (fneg f32:$A), f32:$B, f32:$C), (XSNMSUBASP $C, $A, $B)>; diff --git a/llvm/test/CodeGen/PowerPC/float-logic-ops.ll b/llvm/test/CodeGen/PowerPC/float-logic-ops.ll --- a/llvm/test/CodeGen/PowerPC/float-logic-ops.ll +++ b/llvm/test/CodeGen/PowerPC/float-logic-ops.ll @@ -5,7 +5,7 @@ define float @absf(float %a) { ; CHECK-LABEL: absf: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: fabs f1, f1 +; CHECK-NEXT: xsabsdp f1, f1 ; CHECK-NEXT: blr entry: %conv = bitcast float %a to i32 @@ -80,7 +80,7 @@ define float @negf(float %a) { ; CHECK-LABEL: negf: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: fneg f1, f1 +; CHECK-NEXT: xsnegdp f1, f1 ; CHECK-NEXT: blr entry: %conv = bitcast float %a to i32 @@ -127,7 +127,7 @@ define float @nabsf(float %a) { ; CHECK-LABEL: nabsf: ; CHECK: # %bb.0: # %entry -; CHECK-NEXT: fnabs f1, f1 +; CHECK-NEXT: xsnabsdp f1, f1 ; CHECK-NEXT: blr entry: %conv = bitcast float %a to i32 diff --git a/llvm/test/CodeGen/PowerPC/fma.ll b/llvm/test/CodeGen/PowerPC/fma.ll --- a/llvm/test/CodeGen/PowerPC/fma.ll +++ b/llvm/test/CodeGen/PowerPC/fma.ll @@ -198,6 +198,9 @@ ret float %F ; CHECK-P8-LABEL: test_XSNMADDASP: ; CHECK-P8: xsnmaddasp + +; CHECK-VSX-LABEL: test_XSNMADDASP: +; CHECK-VSX: fnmadds } define float @test_XSNMSUBASP(float %A, float %B, float %C) { @@ -208,4 +211,7 @@ ret float %F ; CHECK-P8-LABEL: test_XSNMSUBASP: ; CHECK-P8: xsnmsubasp + +; CHECK-VSX-LABEL: test_XSNMSUBASP: +; CHECK-VSX: fnmsubs } diff --git a/llvm/test/CodeGen/PowerPC/fmf-propagation.ll b/llvm/test/CodeGen/PowerPC/fmf-propagation.ll --- a/llvm/test/CodeGen/PowerPC/fmf-propagation.ll +++ b/llvm/test/CodeGen/PowerPC/fmf-propagation.ll @@ -280,8 +280,8 @@ define float @sqrt_afn_ieee(float %x) #0 { ; FMF-LABEL: sqrt_afn_ieee: ; FMF: # %bb.0: +; FMF-NEXT: xsabsdp 0, 1 ; FMF-NEXT: addis 3, 2, .LCPI10_2@toc@ha -; FMF-NEXT: fabs 0, 1 ; FMF-NEXT: lfs 2, .LCPI10_2@toc@l(3) ; FMF-NEXT: fcmpu 0, 0, 2 ; FMF-NEXT: xxlxor 0, 0, 0 @@ -303,8 +303,8 @@ ; ; GLOBAL-LABEL: sqrt_afn_ieee: ; GLOBAL: # %bb.0: +; GLOBAL-NEXT: xsabsdp 0, 1 ; GLOBAL-NEXT: addis 3, 2, .LCPI10_2@toc@ha -; GLOBAL-NEXT: fabs 0, 1 ; GLOBAL-NEXT: lfs 2, .LCPI10_2@toc@l(3) ; GLOBAL-NEXT: fcmpu 0, 0, 2 ; GLOBAL-NEXT: xxlxor 0, 0, 0 @@ -418,8 +418,8 @@ define float @sqrt_fast_ieee(float %x) #0 { ; FMF-LABEL: sqrt_fast_ieee: ; FMF: # %bb.0: +; FMF-NEXT: xsabsdp 0, 1 ; FMF-NEXT: addis 3, 2, .LCPI14_2@toc@ha -; FMF-NEXT: fabs 0, 1 ; FMF-NEXT: lfs 2, .LCPI14_2@toc@l(3) ; FMF-NEXT: fcmpu 0, 0, 2 ; FMF-NEXT: xxlxor 0, 0, 0 @@ -440,8 +440,8 @@ ; ; GLOBAL-LABEL: sqrt_fast_ieee: ; GLOBAL: # %bb.0: +; GLOBAL-NEXT: xsabsdp 0, 1 ; GLOBAL-NEXT: addis 3, 2, .LCPI14_2@toc@ha -; GLOBAL-NEXT: fabs 0, 1 ; GLOBAL-NEXT: lfs 2, .LCPI14_2@toc@l(3) ; GLOBAL-NEXT: fcmpu 0, 0, 2 ; GLOBAL-NEXT: xxlxor 0, 0, 0 diff --git a/llvm/test/CodeGen/PowerPC/fsub-fneg.ll b/llvm/test/CodeGen/PowerPC/fsub-fneg.ll --- a/llvm/test/CodeGen/PowerPC/fsub-fneg.ll +++ b/llvm/test/CodeGen/PowerPC/fsub-fneg.ll @@ -8,9 +8,9 @@ define double @neg_ext_op1_extra_use(float %x, double %y) nounwind { ; CHECK-LABEL: neg_ext_op1_extra_use: ; CHECK: # %bb.0: -; CHECK-NEXT: xsadddp 0, 2, 1 -; CHECK-NEXT: fneg 1, 1 -; CHECK-NEXT: xsdivdp 1, 1, 0 +; CHECK-NEXT: xsnegdp 0, 1 +; CHECK-NEXT: xsadddp 1, 2, 1 +; CHECK-NEXT: xsdivdp 1, 0, 1 ; CHECK-NEXT: blr %t1 = fsub float -0.0, %x %t2 = fpext float %t1 to double