[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