[llvm] 1e15346 - MIPS: Add fcanonicalize for pre-R6 (#104554)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 27 02:13:49 PDT 2024
Author: YunQiang Su
Date: 2024-08-27T17:13:46+08:00
New Revision: 1e153461c66bf517097168790cdcb9418af6b623
URL: https://github.com/llvm/llvm-project/commit/1e153461c66bf517097168790cdcb9418af6b623
DIFF: https://github.com/llvm/llvm-project/commit/1e153461c66bf517097168790cdcb9418af6b623.diff
LOG: MIPS: Add fcanonicalize for pre-R6 (#104554)
MIPSr6 has max.s/max.d/min.s/min.d instructions, which can be used as
fcanonicalize.
For pre-R6, we have no instructions that can fcanonicalize an float, so
let's use `fadd Y,X,X` to quiet it if it is NaN.
IEEE754-2008 requires that the result of general-computational and
quiet-computational operation shouldn't be signal NaN.
Added:
llvm/test/CodeGen/Mips/fp-fcanonicalize.ll
Modified:
llvm/lib/Target/Mips/MipsISelLowering.cpp
llvm/lib/Target/Mips/MipsISelLowering.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 31b86b32008903..fa57a3fa9b1557 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -370,6 +370,9 @@ MipsTargetLowering::MipsTargetLowering(const MipsTargetMachine &TM,
setOperationAction(ISD::FMAXNUM_IEEE, MVT::f64, Legal);
setOperationAction(ISD::FMINNUM, MVT::f64, Expand);
setOperationAction(ISD::FMAXNUM, MVT::f64, Expand);
+ } else {
+ setOperationAction(ISD::FCANONICALIZE, MVT::f32, Custom);
+ setOperationAction(ISD::FCANONICALIZE, MVT::f64, Custom);
}
if (Subtarget.isGP64bit()) {
@@ -1251,6 +1254,8 @@ LowerOperation(SDValue Op, SelectionDAG &DAG) const
case ISD::VAARG: return lowerVAARG(Op, DAG);
case ISD::FCOPYSIGN: return lowerFCOPYSIGN(Op, DAG);
case ISD::FABS: return lowerFABS(Op, DAG);
+ case ISD::FCANONICALIZE:
+ return lowerFCANONICALIZE(Op, DAG);
case ISD::FRAMEADDR: return lowerFRAMEADDR(Op, DAG);
case ISD::RETURNADDR: return lowerRETURNADDR(Op, DAG);
case ISD::EH_RETURN: return lowerEH_RETURN(Op, DAG);
@@ -2520,6 +2525,20 @@ SDValue MipsTargetLowering::lowerFABS(SDValue Op, SelectionDAG &DAG) const {
return lowerFABS32(Op, DAG, Subtarget.hasExtractInsert());
}
+SDValue MipsTargetLowering::lowerFCANONICALIZE(SDValue Op,
+ SelectionDAG &DAG) const {
+ SDLoc DL(Op);
+ EVT VT = Op.getValueType();
+ SDValue Operand = Op.getOperand(0);
+ SDNodeFlags Flags = Op->getFlags();
+
+ if (Flags.hasNoNaNs() || DAG.isKnownNeverNaN(Operand))
+ return Operand;
+
+ SDValue Quiet = DAG.getNode(ISD::FADD, DL, VT, Operand, Operand);
+ return DAG.getSelectCC(DL, Operand, Operand, Quiet, Operand, ISD::SETUO);
+}
+
SDValue MipsTargetLowering::
lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
// check the depth
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.h b/llvm/lib/Target/Mips/MipsISelLowering.h
index 84ad40d6bbbe26..2b18b299180926 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.h
+++ b/llvm/lib/Target/Mips/MipsISelLowering.h
@@ -550,6 +550,7 @@ class TargetRegisterClass;
bool HasExtractInsert) const;
SDValue lowerFABS64(SDValue Op, SelectionDAG &DAG,
bool HasExtractInsert) const;
+ SDValue lowerFCANONICALIZE(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
SDValue lowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
diff --git a/llvm/test/CodeGen/Mips/fp-fcanonicalize.ll b/llvm/test/CodeGen/Mips/fp-fcanonicalize.ll
new file mode 100644
index 00000000000000..1faf6dd0891a29
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/fp-fcanonicalize.ll
@@ -0,0 +1,97 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc --mtriple=mipsisa32r6 < %s | FileCheck %s --check-prefix=MIPS32R6
+; RUN: llc --mtriple=mips < %s | FileCheck %s --check-prefix=MIPS32R2
+; RUN: llc --mtriple=mips64 < %s | FileCheck %s --check-prefix=MIPS64R2
+
+declare float @llvm.fcanonicalize.f32(float)
+declare double @llvm.fcanonicalize.f64(double)
+
+define float @fcanonicalize_float(float %x) {
+; MIPS32R6-LABEL: fcanonicalize_float:
+; MIPS32R6: # %bb.0:
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: min.s $f0, $f12, $f12
+;
+; MIPS32R2-LABEL: fcanonicalize_float:
+; MIPS32R2: # %bb.0:
+; MIPS32R2-NEXT: mov.s $f0, $f12
+; MIPS32R2-NEXT: add.s $f1, $f12, $f12
+; MIPS32R2-NEXT: c.un.s $f12, $f12
+; MIPS32R2-NEXT: jr $ra
+; MIPS32R2-NEXT: movt.s $f0, $f1, $fcc0
+;
+; MIPS64R2-LABEL: fcanonicalize_float:
+; MIPS64R2: # %bb.0:
+; MIPS64R2-NEXT: mov.s $f0, $f12
+; MIPS64R2-NEXT: add.s $f1, $f12, $f12
+; MIPS64R2-NEXT: c.un.s $f12, $f12
+; MIPS64R2-NEXT: jr $ra
+; MIPS64R2-NEXT: movt.s $f0, $f1, $fcc0
+ %z = call float @llvm.canonicalize.f32(float %x)
+ ret float %z
+}
+
+define float @fcanonicalize_float_nnan(float %x) {
+; MIPS32R6-LABEL: fcanonicalize_float_nnan:
+; MIPS32R6: # %bb.0:
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: min.s $f0, $f12, $f12
+;
+; MIPS32R2-LABEL: fcanonicalize_float_nnan:
+; MIPS32R2: # %bb.0:
+; MIPS32R2-NEXT: jr $ra
+; MIPS32R2-NEXT: mov.s $f0, $f12
+;
+; MIPS64R2-LABEL: fcanonicalize_float_nnan:
+; MIPS64R2: # %bb.0:
+; MIPS64R2-NEXT: jr $ra
+; MIPS64R2-NEXT: mov.s $f0, $f12
+ %z = call nnan float @llvm.canonicalize.f32(float %x)
+ ret float %z
+}
+
+
+define double @fcanonicalize_double(double %x) {
+; MIPS32R6-LABEL: fcanonicalize_double:
+; MIPS32R6: # %bb.0:
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: min.d $f0, $f12, $f12
+;
+; MIPS32R2-LABEL: fcanonicalize_double:
+; MIPS32R2: # %bb.0:
+; MIPS32R2-NEXT: mov.d $f0, $f12
+; MIPS32R2-NEXT: add.d $f2, $f12, $f12
+; MIPS32R2-NEXT: c.un.d $f12, $f12
+; MIPS32R2-NEXT: jr $ra
+; MIPS32R2-NEXT: movt.d $f0, $f2, $fcc0
+;
+; MIPS64R2-LABEL: fcanonicalize_double:
+; MIPS64R2: # %bb.0:
+; MIPS64R2-NEXT: mov.d $f0, $f12
+; MIPS64R2-NEXT: add.d $f1, $f12, $f12
+; MIPS64R2-NEXT: c.un.d $f12, $f12
+; MIPS64R2-NEXT: jr $ra
+; MIPS64R2-NEXT: movt.d $f0, $f1, $fcc0
+ %z = call double @llvm.canonicalize.f64(double %x)
+ ret double %z
+}
+
+define double @fcanonicalize_double_nnan(double %x) {
+; MIPS32R6-LABEL: fcanonicalize_double_nnan:
+; MIPS32R6: # %bb.0:
+; MIPS32R6-NEXT: jr $ra
+; MIPS32R6-NEXT: min.d $f0, $f12, $f12
+;
+; MIPS32R2-LABEL: fcanonicalize_double_nnan:
+; MIPS32R2: # %bb.0:
+; MIPS32R2-NEXT: jr $ra
+; MIPS32R2-NEXT: mov.d $f0, $f12
+;
+; MIPS64R2-LABEL: fcanonicalize_double_nnan:
+; MIPS64R2: # %bb.0:
+; MIPS64R2-NEXT: jr $ra
+; MIPS64R2-NEXT: mov.d $f0, $f12
+ %z = call nnan double @llvm.canonicalize.f64(double %x)
+ ret double %z
+}
+
More information about the llvm-commits
mailing list