[llvm] AArch64: Add FCANONICALIZE and FMINNUM_IEEE support (PR #104429)

YunQiang Su via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 15 20:11:55 PDT 2024


https://github.com/wzssyqa updated https://github.com/llvm/llvm-project/pull/104429

>From 3340528b5b520cbae86781cfeb48370354e90238 Mon Sep 17 00:00:00 2001
From: YunQiang Su <yunqiang at isrc.iscas.ac.cn>
Date: Thu, 15 Aug 2024 16:40:00 +0800
Subject: [PATCH] AArch64: Add FCANONICALIZE and FMINNUM_IEEE support

FMINNM/FMAXNM instructions of AArch64 follow IEEE754-2008.
We can use them to canonicalize a floating point number.
And FMINNUM_IEEE/FMAXNUM_IEEE is used by something like expanding
FMINIMUMNUM/FMAXIMUMNUM, so let's define them.

update combine_andor_with_cmps.ll
---
 .../Target/AArch64/AArch64ISelLowering.cpp    | 43 ++++++++++++++-----
 llvm/lib/Target/AArch64/AArch64InstrInfo.td   | 12 ++++++
 .../AArch64/combine_andor_with_cmps.ll        |  8 ++--
 3 files changed, 48 insertions(+), 15 deletions(-)

diff --git a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
index 97fb2c5f552731..b34d1eaf8828e2 100644
--- a/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64ISelLowering.cpp
@@ -860,17 +860,38 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,
   setOperationAction(ISD::FP_ROUND, MVT::v4bf16, Custom);
 
   // AArch64 has implementations of a lot of rounding-like FP operations.
-  for (auto Op :
-       {ISD::FFLOOR,          ISD::FNEARBYINT,      ISD::FCEIL,
-        ISD::FRINT,           ISD::FTRUNC,          ISD::FROUND,
-        ISD::FROUNDEVEN,      ISD::FMINNUM,         ISD::FMAXNUM,
-        ISD::FMINIMUM,        ISD::FMAXIMUM,        ISD::LROUND,
-        ISD::LLROUND,         ISD::LRINT,           ISD::LLRINT,
-        ISD::STRICT_FFLOOR,   ISD::STRICT_FCEIL,    ISD::STRICT_FNEARBYINT,
-        ISD::STRICT_FRINT,    ISD::STRICT_FTRUNC,   ISD::STRICT_FROUNDEVEN,
-        ISD::STRICT_FROUND,   ISD::STRICT_FMINNUM,  ISD::STRICT_FMAXNUM,
-        ISD::STRICT_FMINIMUM, ISD::STRICT_FMAXIMUM, ISD::STRICT_LROUND,
-        ISD::STRICT_LLROUND,  ISD::STRICT_LRINT,    ISD::STRICT_LLRINT}) {
+  for (auto Op : {ISD::FFLOOR,
+                  ISD::FNEARBYINT,
+                  ISD::FCEIL,
+                  ISD::FRINT,
+                  ISD::FTRUNC,
+                  ISD::FROUND,
+                  ISD::FROUNDEVEN,
+                  ISD::FMINNUM,
+                  ISD::FMAXNUM,
+                  ISD::FMINNUM_IEEE,
+                  ISD::FMAXNUM_IEEE,
+                  ISD::FMINIMUM,
+                  ISD::FMAXIMUM,
+                  ISD::LROUND,
+                  ISD::LLROUND,
+                  ISD::LRINT,
+                  ISD::LLRINT,
+                  ISD::STRICT_FFLOOR,
+                  ISD::STRICT_FCEIL,
+                  ISD::STRICT_FNEARBYINT,
+                  ISD::STRICT_FRINT,
+                  ISD::STRICT_FTRUNC,
+                  ISD::STRICT_FROUNDEVEN,
+                  ISD::STRICT_FROUND,
+                  ISD::STRICT_FMINNUM,
+                  ISD::STRICT_FMAXNUM,
+                  ISD::STRICT_FMINIMUM,
+                  ISD::STRICT_FMAXIMUM,
+                  ISD::STRICT_LROUND,
+                  ISD::STRICT_LLROUND,
+                  ISD::STRICT_LRINT,
+                  ISD::STRICT_LLRINT}) {
     for (MVT Ty : {MVT::f32, MVT::f64})
       setOperationAction(Op, Ty, Legal);
     if (Subtarget->hasFullFP16())
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
index 403453a4ee0a92..0714913b23f4ee 100644
--- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td
@@ -5051,6 +5051,18 @@ def : Pat<(v1f64 (fmaxnum (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
 def : Pat<(v1f64 (fminnum (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),
           (FMINNMDrr FPR64:$Rn, FPR64:$Rm)>;
 
+def : Pat<(fminnum_ieee (f64 FPR64:$a), (f64 FPR64:$b)),
+          (FMINNMDrr FPR64:$a, FPR64:$b)>;
+def : Pat<(fminnum_ieee (f32 FPR32:$a), (f32 FPR32:$b)),
+          (FMINNMSrr FPR32:$a, FPR32:$b)>;
+def : Pat<(fmaxnum_ieee (f64 FPR64:$a), (f64 FPR64:$b)),
+          (FMAXNMDrr FPR64:$a, FPR64:$b)>;
+def : Pat<(fmaxnum_ieee (f32 FPR32:$a), (f32 FPR32:$b)),
+          (FMAXNMSrr FPR32:$a, FPR32:$b)>;
+def : Pat<(f32 (fcanonicalize f32:$a)),
+          (FMINNMSrr   f32:$a, f32:$a)>;
+def : Pat<(f64 (fcanonicalize f64:$a)),
+          (FMINNMDrr   f64:$a, f64:$a)>;
 //===----------------------------------------------------------------------===//
 // Floating point three operand instructions.
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/CodeGen/AArch64/combine_andor_with_cmps.ll b/llvm/test/CodeGen/AArch64/combine_andor_with_cmps.ll
index 783683cf7e8442..a718f6c2055afd 100644
--- a/llvm/test/CodeGen/AArch64/combine_andor_with_cmps.ll
+++ b/llvm/test/CodeGen/AArch64/combine_andor_with_cmps.ll
@@ -41,8 +41,8 @@ define i1 @test3(float %arg1, float %arg2, float %arg3) {
 ; CHECK-NEXT:    fadd s0, s0, s3
 ; CHECK-NEXT:    fmov s3, #2.00000000
 ; CHECK-NEXT:    fadd s1, s1, s3
-; CHECK-NEXT:    fcmp s1, s2
-; CHECK-NEXT:    fccmp s0, s2, #0, lt
+; CHECK-NEXT:    fmaxnm s0, s0, s1
+; CHECK-NEXT:    fcmp s0, s2
 ; CHECK-NEXT:    cset w0, lt
 ; CHECK-NEXT:    ret
   %add1 = fadd nnan float %arg1, 1.0
@@ -60,8 +60,8 @@ define i1 @test4(float %arg1, float %arg2, float %arg3) {
 ; CHECK-NEXT:    fadd s0, s0, s3
 ; CHECK-NEXT:    fmov s3, #2.00000000
 ; CHECK-NEXT:    fadd s1, s1, s3
-; CHECK-NEXT:    fcmp s1, s2
-; CHECK-NEXT:    fccmp s0, s2, #4, gt
+; CHECK-NEXT:    fminnm s0, s0, s1
+; CHECK-NEXT:    fcmp s0, s2
 ; CHECK-NEXT:    cset w0, gt
 ; CHECK-NEXT:    ret
   %add1 = fadd nnan float %arg1, 1.0



More information about the llvm-commits mailing list