[llvm] c30c065 - [RISCV] Fix crashes with Zfhmin+Zfa.

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 8 21:20:07 PDT 2024


Author: Craig Topper
Date: 2024-09-08T21:19:29-07:00
New Revision: c30c0659d6c0c9fd3bc6861cd1eb99a3fcaa1026

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

LOG: [RISCV] Fix crashes with Zfhmin+Zfa.

We were incorrectly making ISD::FMAXIMUM, ISD::FMINIMUM, and
ISD::FNEARBYINT legal with Zfhmin+Zfa when we really need Zfh+Zfa.

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVISelLowering.cpp
    llvm/test/CodeGen/RISCV/half-zfa.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 38dae970c9e051..23f2b0e96495e9 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -467,8 +467,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
       setOperationAction(FPRndMode, MVT::f16,
                          Subtarget.hasStdExtZfa() ? Legal : Custom);
       setOperationAction(ISD::IS_FPCLASS, MVT::f16, Custom);
+      setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f16,
+                         Subtarget.hasStdExtZfa() ? Legal : Custom);
     } else {
       setOperationAction(ZfhminZfbfminPromoteOps, MVT::f16, Promote);
+      setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f16, Promote);
       for (auto Op : {ISD::LROUND, ISD::LLROUND, ISD::LRINT, ISD::LLRINT,
                       ISD::STRICT_LROUND, ISD::STRICT_LLROUND,
                       ISD::STRICT_LRINT, ISD::STRICT_LLRINT})
@@ -487,8 +490,9 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     setOperationAction(ISD::SELECT, MVT::f16, Custom);
     setOperationAction(ISD::BR_CC, MVT::f16, Expand);
 
-    setOperationAction(ISD::FNEARBYINT, MVT::f16,
-                       Subtarget.hasStdExtZfa() ? Legal : Promote);
+    setOperationAction(
+        ISD::FNEARBYINT, MVT::f16,
+        Subtarget.hasStdExtZfh() && Subtarget.hasStdExtZfa() ? Legal : Promote);
     setOperationAction({ISD::FREM, ISD::FPOW, ISD::FPOWI,
                         ISD::FCOS, ISD::FSIN, ISD::FSINCOS, ISD::FEXP,
                         ISD::FEXP2, ISD::FEXP10, ISD::FLOG, ISD::FLOG2,
@@ -506,9 +510,6 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
     // We need to custom promote this.
     if (Subtarget.is64Bit())
       setOperationAction(ISD::FPOWI, MVT::i32, Custom);
-
-    setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f16,
-                       Subtarget.hasStdExtZfa() ? Legal : Custom);
   }
 
   if (Subtarget.hasStdExtFOrZfinx()) {

diff  --git a/llvm/test/CodeGen/RISCV/half-zfa.ll b/llvm/test/CodeGen/RISCV/half-zfa.ll
index 93ffcb8a1a05c2..e119695a27eba8 100644
--- a/llvm/test/CodeGen/RISCV/half-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/half-zfa.ll
@@ -3,6 +3,10 @@
 ; RUN:     | FileCheck %s
 ; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+zfa,+zfh < %s \
 ; RUN:     | FileCheck %s
+; RUN: llc -mtriple=riscv32 -target-abi ilp32f -mattr=+zfa,+zfhmin < %s \
+; RUN:     | FileCheck %s --check-prefix=ZFHMIN
+; RUN: llc -mtriple=riscv64 -target-abi lp64f -mattr=+zfa,+zfhmin < %s \
+; RUN:     | FileCheck %s --check-prefix=ZFHMIN
 
 declare half @llvm.minimum.f16(half, half)
 
@@ -11,6 +15,14 @@ define half @fminm_h(half %a, half %b) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fminm.h fa0, fa0, fa1
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fminm_h:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
+; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
+; ZFHMIN-NEXT:    fminm.s fa5, fa4, fa5
+; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; ZFHMIN-NEXT:    ret
   %1 = call half @llvm.minimum.f16(half %a, half %b)
   ret half %1
 }
@@ -22,6 +34,14 @@ define half @fmaxm_h(half %a, half %b) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fmaxm.h fa0, fa0, fa1
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fmaxm_h:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
+; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
+; ZFHMIN-NEXT:    fmaxm.s fa5, fa4, fa5
+; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; ZFHMIN-NEXT:    ret
   %1 = tail call half @llvm.maximum.f16(half %a, half %b)
   ret half %1
 }
@@ -31,6 +51,13 @@ define half @fround_h_1(half %a) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fround.h fa0, fa0, rmm
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fround_h_1:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; ZFHMIN-NEXT:    fround.s fa5, fa5, rmm
+; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; ZFHMIN-NEXT:    ret
   %call = tail call half @llvm.round.f16(half %a) nounwind readnone
   ret half %call
 }
@@ -43,6 +70,13 @@ define half @fround_h_2(half %a) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fround.h fa0, fa0, rdn
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fround_h_2:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; ZFHMIN-NEXT:    fround.s fa5, fa5, rdn
+; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; ZFHMIN-NEXT:    ret
   %call = tail call half @llvm.floor.f16(half %a) nounwind readnone
   ret half %call
 }
@@ -55,6 +89,13 @@ define half @fround_h_3(half %a) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fround.h fa0, fa0, rup
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fround_h_3:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; ZFHMIN-NEXT:    fround.s fa5, fa5, rup
+; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; ZFHMIN-NEXT:    ret
   %call = tail call half @llvm.ceil.f16(half %a) nounwind readnone
   ret half %call
 }
@@ -67,6 +108,13 @@ define half @fround_h_4(half %a) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fround.h fa0, fa0, rtz
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fround_h_4:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; ZFHMIN-NEXT:    fround.s fa5, fa5, rtz
+; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; ZFHMIN-NEXT:    ret
   %call = tail call half @llvm.trunc.f16(half %a) nounwind readnone
   ret half %call
 }
@@ -79,6 +127,13 @@ define half @fround_h_5(half %a) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fround.h fa0, fa0
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fround_h_5:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; ZFHMIN-NEXT:    fround.s fa5, fa5
+; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; ZFHMIN-NEXT:    ret
   %call = tail call half @llvm.nearbyint.f16(half %a) nounwind readnone
   ret half %call
 }
@@ -91,6 +146,13 @@ define half @froundnx_h(half %a) nounwind {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    froundnx.h fa0, fa0
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: froundnx_h:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa0
+; ZFHMIN-NEXT:    froundnx.s fa5, fa5
+; ZFHMIN-NEXT:    fcvt.h.s fa0, fa5
+; ZFHMIN-NEXT:    ret
   %call = tail call half @llvm.rint.f16(half %a) nounwind readnone
   ret half %call
 }
@@ -104,6 +166,13 @@ define i32 @fcmp_olt_q(half %a, half %b) nounwind strictfp {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fltq.h a0, fa0, fa1
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fcmp_olt_q:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
+; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
+; ZFHMIN-NEXT:    fltq.s a0, fa4, fa5
+; ZFHMIN-NEXT:    ret
   %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") strictfp
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -114,6 +183,13 @@ define i32 @fcmp_ole_q(half %a, half %b) nounwind strictfp {
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    fleq.h a0, fa0, fa1
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fcmp_ole_q:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
+; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
+; ZFHMIN-NEXT:    fleq.s a0, fa4, fa5
+; ZFHMIN-NEXT:    ret
   %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") strictfp
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -126,6 +202,15 @@ define i32 @fcmp_one_q(half %a, half %b) nounwind strictfp {
 ; CHECK-NEXT:    fltq.h a1, fa1, fa0
 ; CHECK-NEXT:    or a0, a1, a0
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fcmp_one_q:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
+; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
+; ZFHMIN-NEXT:    fltq.s a0, fa4, fa5
+; ZFHMIN-NEXT:    fltq.s a1, fa5, fa4
+; ZFHMIN-NEXT:    or a0, a1, a0
+; ZFHMIN-NEXT:    ret
   %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") strictfp
   %2 = zext i1 %1 to i32
   ret i32 %2
@@ -139,6 +224,16 @@ define i32 @fcmp_ueq_q(half %a, half %b) nounwind strictfp {
 ; CHECK-NEXT:    or a0, a1, a0
 ; CHECK-NEXT:    xori a0, a0, 1
 ; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: fcmp_ueq_q:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    fcvt.s.h fa5, fa1
+; ZFHMIN-NEXT:    fcvt.s.h fa4, fa0
+; ZFHMIN-NEXT:    fltq.s a0, fa4, fa5
+; ZFHMIN-NEXT:    fltq.s a1, fa5, fa4
+; ZFHMIN-NEXT:    or a0, a1, a0
+; ZFHMIN-NEXT:    xori a0, a0, 1
+; ZFHMIN-NEXT:    ret
   %1 = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") strictfp
   %2 = zext i1 %1 to i32
   ret i32 %2


        


More information about the llvm-commits mailing list