[llvm] [RISCV] Fix incorrect use of Zfa fli instruction for negative minimum value. (PR #70411)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 26 21:24:04 PDT 2023


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/70411

isSmallestNormalized() only considers the magnitude, not the sign.

>From a5d64f8dd8ac1c33db345eff1a089b4d8bfe0088 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 26 Oct 2023 21:15:37 -0700
Subject: [PATCH 1/2] [RISCV] Add test cases showing fli being used for
 negative min normalized value.

We only use fli for the positive normalized value.
---
 llvm/test/CodeGen/RISCV/double-zfa.ll   |  9 +++++++++
 llvm/test/CodeGen/RISCV/float-zfa.ll    |  9 +++++++++
 llvm/test/CodeGen/RISCV/half-zfa-fli.ll | 16 ++++++++++++++++
 3 files changed, 34 insertions(+)

diff --git a/llvm/test/CodeGen/RISCV/double-zfa.ll b/llvm/test/CodeGen/RISCV/double-zfa.ll
index 904dd9f2ccbef91..9f244f0daacf55d 100644
--- a/llvm/test/CodeGen/RISCV/double-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/double-zfa.ll
@@ -152,6 +152,15 @@ define double @loadfpimm17() {
   ret double -2.0
 }
 
+; Ensure fli isn't incorrecty used for negative min normal value.
+define double @loadfpimm18() {
+; CHECK-LABEL: loadfpimm18:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fli.d fa0, min
+; CHECK-NEXT:    ret
+  ret double 0x8010000000000000
+}
+
 declare double @llvm.minimum.f64(double, double)
 
 define double @fminm_d(double %a, double %b) nounwind {
diff --git a/llvm/test/CodeGen/RISCV/float-zfa.ll b/llvm/test/CodeGen/RISCV/float-zfa.ll
index baa45e00b565fb5..ec982a78dfe767e 100644
--- a/llvm/test/CodeGen/RISCV/float-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/float-zfa.ll
@@ -106,6 +106,15 @@ define float @loadfpimm12() {
   ret float -2.0
 }
 
+; Ensure fli isn't incorrecty used for negative min normal value.
+define float @loadfpimm13() {
+; CHECK-LABEL: loadfpimm13:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fli.s fa0, min
+; CHECK-NEXT:    ret
+  ret float 0xb810000000000000
+}
+
 declare float @llvm.minimum.f32(float, float)
 
 define float @fminm_s(float %a, float %b) nounwind {
diff --git a/llvm/test/CodeGen/RISCV/half-zfa-fli.ll b/llvm/test/CodeGen/RISCV/half-zfa-fli.ll
index 2805a8e582b34b9..73a77660eb3bdcb 100644
--- a/llvm/test/CodeGen/RISCV/half-zfa-fli.ll
+++ b/llvm/test/CodeGen/RISCV/half-zfa-fli.ll
@@ -211,3 +211,19 @@ define half @loadfpimm14() {
 ; ZFHMIN-NEXT:    ret
   ret half -2.0
 }
+
+; Ensure fli isn't incorrecty used for negative min normal value.
+define half @loadfpimm15() {
+; CHECK-LABEL: loadfpimm15:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    fli.h fa0, min
+; CHECK-NEXT:    ret
+;
+; ZFHMIN-LABEL: loadfpimm15:
+; ZFHMIN:       # %bb.0:
+; ZFHMIN-NEXT:    lui a0, %hi(.LCPI14_0)
+; ZFHMIN-NEXT:    flh fa0, %lo(.LCPI14_0)(a0)
+; ZFHMIN-NEXT:    ret
+  ret half 0xH8400
+}
+

>From 9cd33f674c16cdf5101757868a86a8f09e642f95 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 26 Oct 2023 21:22:06 -0700
Subject: [PATCH 2/2] [RISCV] Fix incorrect use of Zfa fli instruction for
 negative minimum value.

isSmallestNormalized() only considers the magnitude, not the sign.
---
 llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp | 2 +-
 llvm/test/CodeGen/RISCV/double-zfa.ll                | 3 ++-
 llvm/test/CodeGen/RISCV/float-zfa.ll                 | 3 ++-
 llvm/test/CodeGen/RISCV/half-zfa-fli.ll              | 3 ++-
 4 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
index 7919189d198c8d1..ed8ae4a7a4550d4 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.cpp
@@ -251,7 +251,7 @@ int RISCVLoadFPImm::getLoadFPImm(APFloat FPImm) {
          "Unexpected semantics");
 
   // Handle the minimum normalized value which is different for each type.
-  if (FPImm.isSmallestNormalized())
+  if (FPImm.isSmallestNormalized() && !FPImm.isNegative())
     return 1;
 
   // Convert to single precision to use its lookup table.
diff --git a/llvm/test/CodeGen/RISCV/double-zfa.ll b/llvm/test/CodeGen/RISCV/double-zfa.ll
index 9f244f0daacf55d..162f33dd5ac9dd2 100644
--- a/llvm/test/CodeGen/RISCV/double-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/double-zfa.ll
@@ -156,7 +156,8 @@ define double @loadfpimm17() {
 define double @loadfpimm18() {
 ; CHECK-LABEL: loadfpimm18:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fli.d fa0, min
+; CHECK-NEXT:    lui a0, %hi(.LCPI16_0)
+; CHECK-NEXT:    fld fa0, %lo(.LCPI16_0)(a0)
 ; CHECK-NEXT:    ret
   ret double 0x8010000000000000
 }
diff --git a/llvm/test/CodeGen/RISCV/float-zfa.ll b/llvm/test/CodeGen/RISCV/float-zfa.ll
index ec982a78dfe767e..6f9e5ec035224df 100644
--- a/llvm/test/CodeGen/RISCV/float-zfa.ll
+++ b/llvm/test/CodeGen/RISCV/float-zfa.ll
@@ -110,7 +110,8 @@ define float @loadfpimm12() {
 define float @loadfpimm13() {
 ; CHECK-LABEL: loadfpimm13:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fli.s fa0, min
+; CHECK-NEXT:    lui a0, 526336
+; CHECK-NEXT:    fmv.w.x fa0, a0
 ; CHECK-NEXT:    ret
   ret float 0xb810000000000000
 }
diff --git a/llvm/test/CodeGen/RISCV/half-zfa-fli.ll b/llvm/test/CodeGen/RISCV/half-zfa-fli.ll
index 73a77660eb3bdcb..577b774c27a0b36 100644
--- a/llvm/test/CodeGen/RISCV/half-zfa-fli.ll
+++ b/llvm/test/CodeGen/RISCV/half-zfa-fli.ll
@@ -216,7 +216,8 @@ define half @loadfpimm14() {
 define half @loadfpimm15() {
 ; CHECK-LABEL: loadfpimm15:
 ; CHECK:       # %bb.0:
-; CHECK-NEXT:    fli.h fa0, min
+; CHECK-NEXT:    lui a0, %hi(.LCPI14_0)
+; CHECK-NEXT:    flh fa0, %lo(.LCPI14_0)(a0)
 ; CHECK-NEXT:    ret
 ;
 ; ZFHMIN-LABEL: loadfpimm15:



More information about the llvm-commits mailing list