[llvm] f1447da - [SPARC] Use op-then-neg instructions when we have VIS3 (#138603)

via llvm-commits llvm-commits at lists.llvm.org
Mon May 5 15:36:33 PDT 2025


Author: Koakuma
Date: 2025-05-06T05:36:29+07:00
New Revision: f1447dab30547c73881619980ff054cf833d0ec9

URL: https://github.com/llvm/llvm-project/commit/f1447dab30547c73881619980ff054cf833d0ec9
DIFF: https://github.com/llvm/llvm-project/commit/f1447dab30547c73881619980ff054cf833d0ec9.diff

LOG:  [SPARC] Use op-then-neg instructions when we have VIS3 (#138603)

Added: 
    llvm/test/CodeGen/SPARC/float-vis3.ll

Modified: 
    llvm/lib/Target/Sparc/SparcISelLowering.cpp
    llvm/lib/Target/Sparc/SparcISelLowering.h
    llvm/lib/Target/Sparc/SparcInstrVIS.td

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 8e821c6506608..b83aecffe779c 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -3556,6 +3556,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 d7e4c48672a58..0d220f8c3d32e 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.h
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.h
@@ -164,6 +164,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 d411daedf1b2f..047a56696af84 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 0000000000000..2352eb0e97332
--- /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
+}


        


More information about the llvm-commits mailing list