[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