diff options
| author | Koakuma <koachan@protonmail.com> | 2025-05-06 02:02:28 +0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-05 21:02:28 +0200 |
| commit | 6bedda90a969faab95a7b28e2315ce902a10a3d5 (patch) | |
| tree | 170e7a4224e98d248a5a1a68a3c0182c6cf01204 | |
| parent | bea9bea3c994035f2bc07a6a92efe4d77bdcb071 (diff) | |
[SPARC] Use op-then-neg instructions when we have VIS3 (#135717)users/koachan/spr/main.sparc-use-op-then-neg-instructions-when-we-have-vis3
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.cpp | 6 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcISelLowering.h | 2 | ||||
| -rw-r--r-- | llvm/lib/Target/Sparc/SparcInstrVIS.td | 8 | ||||
| -rw-r--r-- | llvm/test/CodeGen/SPARC/float-vis3.ll | 131 |
4 files changed, 147 insertions, 0 deletions
diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index 0b98327d5343..d9762c884994 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -3605,6 +3605,12 @@ bool SparcTargetLowering::useLoadStackGuardNode(const Module &M) const { return true; } +bool SparcTargetLowering::isFNegFree(EVT VT) const { + if (Subtarget->isVIS3()) + return VT == MVT::f32 || VT == MVT::f64; + return false; +} + bool SparcTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const { return Subtarget->isVIS() && (VT == MVT::f32 || VT == MVT::f64) && diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h index deb66854a1e7..33403e807db0 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/llvm/lib/Target/Sparc/SparcISelLowering.h @@ -207,6 +207,8 @@ namespace llvm { return VT != MVT::f128; } + bool isFNegFree(EVT VT) const override; + bool isFPImmLegal(const APFloat &Imm, EVT VT, bool ForCodeSize) const override; diff --git a/llvm/lib/Target/Sparc/SparcInstrVIS.td b/llvm/lib/Target/Sparc/SparcInstrVIS.td index d411daedf1b2..047a56696af8 100644 --- a/llvm/lib/Target/Sparc/SparcInstrVIS.td +++ b/llvm/lib/Target/Sparc/SparcInstrVIS.td @@ -321,4 +321,12 @@ def : Pat<(i64 (sext (i32 (bitconvert f32:$src)))), (MOVSTOSW $src)>; def : Pat<(f32 (bitconvert i32:$src)), (MOVWTOS $src)>; def : Pat<(i64 (bitconvert f64:$src)), (MOVDTOX $src)>; def : Pat<(f64 (bitconvert i64:$src)), (MOVXTOD $src)>; + +// OP-then-neg FP operations. +// TODO handle equivalent patterns like `rs1*-rs2`. +def : Pat<(f32 (fneg (fadd f32:$rs1, f32:$rs2))), (FNADDS $rs1, $rs2)>; +def : Pat<(f64 (fneg (fadd f64:$rs1, f64:$rs2))), (FNADDD $rs1, $rs2)>; +def : Pat<(f32 (fneg (fmul f32:$rs1, f32:$rs2))), (FNMULS $rs1, $rs2)>; +def : Pat<(f64 (fneg (fmul f64:$rs1, f64:$rs2))), (FNMULD $rs1, $rs2)>; +def : Pat<(f64 (fneg (fmul (fpextend f32:$rs1), (fpextend f32:$rs2)))), (FNSMULD $rs1, $rs2)>; } // Predicates = [HasVIS3] diff --git a/llvm/test/CodeGen/SPARC/float-vis3.ll b/llvm/test/CodeGen/SPARC/float-vis3.ll new file mode 100644 index 000000000000..2352eb0e9733 --- /dev/null +++ b/llvm/test/CodeGen/SPARC/float-vis3.ll @@ -0,0 +1,131 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -mtriple=sparc64 -mattr=+vis3 < %s | FileCheck %s + +define float @fnadds(float %a, float %b) nounwind { +; CHECK-LABEL: fnadds: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: retl +; CHECK-NEXT: fnadds %f1, %f3, %f0 +entry: + %add = fadd float %a, %b + %fneg = fneg float %add + ret float %fneg +} + +define double @fnaddd(double %a, double %b) nounwind { +; CHECK-LABEL: fnaddd: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: retl +; CHECK-NEXT: fnaddd %f0, %f2, %f0 +entry: + %add = fadd double %a, %b + %fneg = fneg double %add + ret double %fneg +} + +define float @fnmuls(float %a, float %b) nounwind { +; CHECK-LABEL: fnmuls: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: retl +; CHECK-NEXT: fnmuls %f1, %f3, %f0 +entry: + %mul = fmul float %a, %b + %fneg = fneg float %mul + ret float %fneg +} + +define double @fnmuld(double %a, double %b) nounwind { +; CHECK-LABEL: fnmuld: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: retl +; CHECK-NEXT: fnmuld %f0, %f2, %f0 +entry: + %mul = fmul double %a, %b + %fneg = fneg double %mul + ret double %fneg +} + +define double @fnsmuld(float %a, float %b) nounwind { +; CHECK-LABEL: fnsmuld: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: retl +; CHECK-NEXT: fnsmuld %f1, %f3, %f0 +entry: + %da = fpext float %a to double + %db = fpext float %b to double + %mul = fmul double %da, %db + %fneg = fneg double %mul + ret double %fneg +} + +define <4 x float> @vec_fnadds(<4 x float> %a, <4 x float> %b) nounwind { +; CHECK-LABEL: vec_fnadds: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: fnadds %f1, %f9, %f0 +; CHECK-NEXT: fnadds %f3, %f11, %f1 +; CHECK-NEXT: fnadds %f5, %f13, %f2 +; CHECK-NEXT: retl +; CHECK-NEXT: fnadds %f7, %f15, %f3 +entry: + %add = fadd <4 x float> %a, %b + %fneg = fneg <4 x float> %add + ret <4 x float> %fneg +} + +define <4 x double> @vec_fnaddd(<4 x double> %a, <4 x double> %b) nounwind { +; CHECK-LABEL: vec_fnaddd: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: fnaddd %f0, %f8, %f0 +; CHECK-NEXT: fnaddd %f2, %f10, %f2 +; CHECK-NEXT: fnaddd %f4, %f12, %f4 +; CHECK-NEXT: retl +; CHECK-NEXT: fnaddd %f6, %f14, %f6 +entry: + %add = fadd <4 x double> %a, %b + %fneg = fneg <4 x double> %add + ret <4 x double> %fneg +} + +define <4 x float> @vec_fnmuls(<4 x float> %a, <4 x float> %b) nounwind { +; CHECK-LABEL: vec_fnmuls: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: fnmuls %f1, %f9, %f0 +; CHECK-NEXT: fnmuls %f3, %f11, %f1 +; CHECK-NEXT: fnmuls %f5, %f13, %f2 +; CHECK-NEXT: retl +; CHECK-NEXT: fnmuls %f7, %f15, %f3 +entry: + %mul = fmul <4 x float> %a, %b + %fneg = fneg <4 x float> %mul + ret <4 x float> %fneg +} + +define <4 x double> @vec_fnmuld(<4 x double> %a, <4 x double> %b) nounwind { +; CHECK-LABEL: vec_fnmuld: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: fnmuld %f0, %f8, %f0 +; CHECK-NEXT: fnmuld %f2, %f10, %f2 +; CHECK-NEXT: fnmuld %f4, %f12, %f4 +; CHECK-NEXT: retl +; CHECK-NEXT: fnmuld %f6, %f14, %f6 +entry: + %mul = fmul <4 x double> %a, %b + %fneg = fneg <4 x double> %mul + ret <4 x double> %fneg +} + +define <4 x double> @vec_fnsmuld(<4 x float> %a, <4 x float> %b) nounwind { +; CHECK-LABEL: vec_fnsmuld: +; CHECK: ! %bb.0: ! %entry +; CHECK-NEXT: fnsmuld %f1, %f9, %f0 +; CHECK-NEXT: fnsmuld %f3, %f11, %f2 +; CHECK-NEXT: fnsmuld %f5, %f13, %f4 +; CHECK-NEXT: retl +; CHECK-NEXT: fnsmuld %f7, %f15, %f6 +entry: + %da = fpext <4 x float> %a to <4 x double> + %db = fpext <4 x float> %b to <4 x double> + %mul = fmul <4 x double> %da, %db + %fneg = fneg <4 x double> %mul + ret <4 x double> %fneg +} |
