[llvm] 0ce8ad6 - [SPARC] Use fzero/fzeros to materialize FP zeros when we have VIS

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 15 18:33:46 PDT 2025


Author: Koakuma
Date: 2025-04-16T08:33:42+07:00
New Revision: 0ce8ad68e44aaf50d1e2aa304fa8a1127e311e1d

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

LOG: [SPARC] Use fzero/fzeros to materialize FP zeros when we have VIS



Reviewers: rorth, brad0, s-barannikov

Reviewed By: s-barannikov

Pull Request: https://github.com/llvm/llvm-project/pull/135712

Added: 
    

Modified: 
    llvm/lib/Target/Sparc/SparcISelLowering.cpp
    llvm/lib/Target/Sparc/SparcISelLowering.h
    llvm/lib/Target/Sparc/SparcInstrVIS.td
    llvm/test/CodeGen/SPARC/float-constants.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
index 85b8750d40f46..bce8ddbd47586 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp
@@ -3560,6 +3560,12 @@ bool SparcTargetLowering::useLoadStackGuardNode(const Module &M) const {
   return true;
 }
 
+bool SparcTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
+                                       bool ForCodeSize) const {
+  return Subtarget->isVIS() && (VT == MVT::f32 || VT == MVT::f64) &&
+         Imm.isZero();
+}
+
 // Override to disable global variable loading on Linux.
 void SparcTargetLowering::insertSSPDeclarations(Module &M) const {
   if (!Subtarget->isTargetLinux())

diff  --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h
index 1bee5f4cfe84d..c09e465f5d05e 100644
--- a/llvm/lib/Target/Sparc/SparcISelLowering.h
+++ b/llvm/lib/Target/Sparc/SparcISelLowering.h
@@ -207,6 +207,9 @@ namespace llvm {
       return VT != MVT::f128;
     }
 
+    bool isFPImmLegal(const APFloat &Imm, EVT VT,
+                      bool ForCodeSize) const override;
+
     bool shouldInsertFencesForAtomic(const Instruction *I) const override {
       // FIXME: We insert fences for each atomics and generate
       // sub-optimal code for PSO/TSO. (Approximately nobody uses any

diff  --git a/llvm/lib/Target/Sparc/SparcInstrVIS.td b/llvm/lib/Target/Sparc/SparcInstrVIS.td
index 8ce8f37f34040..7be45fe9faf3f 100644
--- a/llvm/lib/Target/Sparc/SparcInstrVIS.td
+++ b/llvm/lib/Target/Sparc/SparcInstrVIS.td
@@ -45,10 +45,10 @@ class VISInst2<bits<9> opfval, string OpcStr, RegisterClass RC = DFPRegs>
         !strconcat(OpcStr, " $rs2, $rd")>;
 
 // For VIS Instructions with only rd operand.
-let Constraints = "$rd = $f", rs1 = 0, rs2 = 0 in
+let rs1 = 0, rs2 = 0 in
 class VISInstD<bits<9> opfval, string OpcStr, RegisterClass RC = DFPRegs>
        : VISInstFormat<opfval,
-        (outs RC:$rd), (ins RC:$f),
+        (outs RC:$rd), (ins),
         !strconcat(OpcStr, " $rd")>;
 
 // VIS 1 Instructions
@@ -277,3 +277,16 @@ def UMULXHI  : VISInst<0b000010110, "umulxhi", I64Regs>;
 def XMULX    : VISInst<0b100010101, "xmulx",   I64Regs>;
 def XMULXHI  : VISInst<0b100010110, "xmulxhi", I64Regs>;
 } // Predicates = [IsVIS3]
+
+// FP immediate patterns.
+def fpimm0 : FPImmLeaf<fAny, [{return Imm.isExactlyValue(+0.0);}]>;
+def fpnegimm0 : FPImmLeaf<fAny, [{return Imm.isExactlyValue(-0.0);}]>;
+
+// VIS instruction patterns.
+let Predicates = [HasVIS] in {
+// Zero immediate.
+def : Pat<(f64 fpimm0), (FZERO)>;
+def : Pat<(f32 fpimm0), (FZEROS)>;
+def : Pat<(f64 fpnegimm0), (FNEGD (FZERO))>;
+def : Pat<(f32 fpnegimm0), (FNEGS (FZEROS))>;
+} // Predicates = [HasVIS]

diff  --git a/llvm/test/CodeGen/SPARC/float-constants.ll b/llvm/test/CodeGen/SPARC/float-constants.ll
index b04ec68ed3d7e..440c75bfca9f9 100644
--- a/llvm/test/CodeGen/SPARC/float-constants.ll
+++ b/llvm/test/CodeGen/SPARC/float-constants.ll
@@ -1,6 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
 ; RUN: llc < %s -mtriple=sparc | FileCheck %s
 ; RUN: llc < %s -mtriple=sparcel | FileCheck %s --check-prefix=CHECK-LE
+; RUN: llc < %s -mtriple=sparcv9 -mattr=+vis | FileCheck %s --check-prefix=CHECK-VIS
 
 ;; Bitcast should not do a runtime conversion, but rather emit a
 ;; constant into integer registers directly.
@@ -17,6 +18,12 @@ define <2 x i32> @bitcast() nounwind {
 ; CHECK-LE-NEXT:    sethi 1049856, %o1
 ; CHECK-LE-NEXT:    retl
 ; CHECK-LE-NEXT:    mov %g0, %o0
+;
+; CHECK-VIS-LABEL: bitcast:
+; CHECK-VIS:       ! %bb.0:
+; CHECK-VIS-NEXT:    sethi 1049856, %o0
+; CHECK-VIS-NEXT:    retl
+; CHECK-VIS-NEXT:    mov %g0, %o1
   %1 = bitcast double 5.0 to <2 x i32>
   ret <2 x i32> %1
 }
@@ -43,6 +50,17 @@ define void @test_call() nounwind {
 ; CHECK-LE-NEXT:    mov %g0, %o0
 ; CHECK-LE-NEXT:    ret
 ; CHECK-LE-NEXT:    restore
+;
+; CHECK-VIS-LABEL: test_call:
+; CHECK-VIS:       ! %bb.0:
+; CHECK-VIS-NEXT:    save %sp, -176, %sp
+; CHECK-VIS-NEXT:    sethi %h44(.LCPI1_0), %i0
+; CHECK-VIS-NEXT:    add %i0, %m44(.LCPI1_0), %i0
+; CHECK-VIS-NEXT:    sllx %i0, 12, %i0
+; CHECK-VIS-NEXT:    call a
+; CHECK-VIS-NEXT:    ldd [%i0+%l44(.LCPI1_0)], %f0
+; CHECK-VIS-NEXT:    ret
+; CHECK-VIS-NEXT:    restore
   call void @a(double 5.0)
   ret void
 }
@@ -75,6 +93,103 @@ define double @test_intrins_call() nounwind {
 ; CHECK-LE-NEXT:    mov %o1, %o3
 ; CHECK-LE-NEXT:    ret
 ; CHECK-LE-NEXT:    restore
+;
+; CHECK-VIS-LABEL: test_intrins_call:
+; CHECK-VIS:       ! %bb.0:
+; CHECK-VIS-NEXT:    save %sp, -176, %sp
+; CHECK-VIS-NEXT:    sethi %h44(.LCPI2_0), %i0
+; CHECK-VIS-NEXT:    add %i0, %m44(.LCPI2_0), %i0
+; CHECK-VIS-NEXT:    sllx %i0, 12, %i0
+; CHECK-VIS-NEXT:    ldd [%i0+%l44(.LCPI2_0)], %f0
+; CHECK-VIS-NEXT:    fmovd %f0, %f2
+; CHECK-VIS-NEXT:    call pow
+; CHECK-VIS-NEXT:    nop
+; CHECK-VIS-NEXT:    ret
+; CHECK-VIS-NEXT:    restore
   %1 = call double @llvm.pow.f64(double 2.0, double 2.0)
   ret double %1
 }
+
+;; When we have VIS, f32/f64 zero constant should be materialized from fzero/fzeros.
+
+define double @pos_zero_double() nounwind {
+; CHECK-LABEL: pos_zero_double:
+; CHECK:       ! %bb.0:
+; CHECK-NEXT:    sethi %hi(.LCPI3_0), %o0
+; CHECK-NEXT:    retl
+; CHECK-NEXT:    ldd [%o0+%lo(.LCPI3_0)], %f0
+;
+; CHECK-LE-LABEL: pos_zero_double:
+; CHECK-LE:       ! %bb.0:
+; CHECK-LE-NEXT:    sethi %hi(.LCPI3_0), %o0
+; CHECK-LE-NEXT:    retl
+; CHECK-LE-NEXT:    ldd [%o0+%lo(.LCPI3_0)], %f0
+;
+; CHECK-VIS-LABEL: pos_zero_double:
+; CHECK-VIS:       ! %bb.0:
+; CHECK-VIS-NEXT:    retl
+; CHECK-VIS-NEXT:    fzero %f0
+  ret double +0.0
+}
+
+define double @neg_zero_double() nounwind {
+; CHECK-LABEL: neg_zero_double:
+; CHECK:       ! %bb.0:
+; CHECK-NEXT:    sethi %hi(.LCPI4_0), %o0
+; CHECK-NEXT:    retl
+; CHECK-NEXT:    ldd [%o0+%lo(.LCPI4_0)], %f0
+;
+; CHECK-LE-LABEL: neg_zero_double:
+; CHECK-LE:       ! %bb.0:
+; CHECK-LE-NEXT:    sethi %hi(.LCPI4_0), %o0
+; CHECK-LE-NEXT:    retl
+; CHECK-LE-NEXT:    ldd [%o0+%lo(.LCPI4_0)], %f0
+;
+; CHECK-VIS-LABEL: neg_zero_double:
+; CHECK-VIS:       ! %bb.0:
+; CHECK-VIS-NEXT:    fzero %f0
+; CHECK-VIS-NEXT:    retl
+; CHECK-VIS-NEXT:    fnegd %f0, %f0
+  ret double -0.0
+}
+
+define float @pos_zero_float() nounwind {
+; CHECK-LABEL: pos_zero_float:
+; CHECK:       ! %bb.0:
+; CHECK-NEXT:    sethi %hi(.LCPI5_0), %o0
+; CHECK-NEXT:    retl
+; CHECK-NEXT:    ld [%o0+%lo(.LCPI5_0)], %f0
+;
+; CHECK-LE-LABEL: pos_zero_float:
+; CHECK-LE:       ! %bb.0:
+; CHECK-LE-NEXT:    sethi %hi(.LCPI5_0), %o0
+; CHECK-LE-NEXT:    retl
+; CHECK-LE-NEXT:    ld [%o0+%lo(.LCPI5_0)], %f0
+;
+; CHECK-VIS-LABEL: pos_zero_float:
+; CHECK-VIS:       ! %bb.0:
+; CHECK-VIS-NEXT:    retl
+; CHECK-VIS-NEXT:    fzeros %f0
+  ret float +0.0
+}
+
+define float @neg_zero_float() nounwind {
+; CHECK-LABEL: neg_zero_float:
+; CHECK:       ! %bb.0:
+; CHECK-NEXT:    sethi %hi(.LCPI6_0), %o0
+; CHECK-NEXT:    retl
+; CHECK-NEXT:    ld [%o0+%lo(.LCPI6_0)], %f0
+;
+; CHECK-LE-LABEL: neg_zero_float:
+; CHECK-LE:       ! %bb.0:
+; CHECK-LE-NEXT:    sethi %hi(.LCPI6_0), %o0
+; CHECK-LE-NEXT:    retl
+; CHECK-LE-NEXT:    ld [%o0+%lo(.LCPI6_0)], %f0
+;
+; CHECK-VIS-LABEL: neg_zero_float:
+; CHECK-VIS:       ! %bb.0:
+; CHECK-VIS-NEXT:    fzeros %f0
+; CHECK-VIS-NEXT:    retl
+; CHECK-VIS-NEXT:    fnegs %f0, %f0
+  ret float -0.0
+}


        


More information about the llvm-commits mailing list