Skip to content

Commit

Permalink
[RISCV] Optimize lowering of floating-point -0.0
Browse files Browse the repository at this point in the history
This idea has come up in several reviews -- D115978 and D105902 -- so I
can't take any credit for the idea. Instead of using a constant pool to
lower -0.0, we can emit a sequence of two instructions:

    fmv.[hwd].x freg, zero
    fsgnjn.[hsd] freg, freg, freg

This is only done when the floating-point type is legal.

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D117687
  • Loading branch information
frasercrmck committed Jan 20, 2022
1 parent 770353c commit 5a12024
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 201 deletions.
2 changes: 0 additions & 2 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Expand Up @@ -1305,8 +1305,6 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
return false;
if (VT == MVT::f64 && !Subtarget.hasStdExtD())
return false;
if (Imm.isNegZero())
return false;
return Imm.isZero();
}

Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoD.td
Expand Up @@ -285,6 +285,8 @@ let Predicates = [HasStdExtD, IsRV32] in {

/// Float constants
def : Pat<(f64 (fpimm0)), (FCVT_D_W (i32 X0))>;
def : Pat<(f64 (fpimmneg0)), (FSGNJN_D (FCVT_D_W (i32 X0)),
(FCVT_D_W (i32 X0)))>;

// double->[u]int. Round-to-zero must be used.
def : Pat<(i32 (any_fp_to_sint FPR64:$rs1)), (FCVT_W_D FPR64:$rs1, 0b001)>;
Expand All @@ -309,6 +311,8 @@ let Predicates = [HasStdExtD, IsRV64] in {

/// Float constants
def : Pat<(f64 (fpimm0)), (FMV_D_X (i64 X0))>;
def : Pat<(f64 (fpimmneg0)), (FSGNJN_D (FMV_D_X (i64 X0)),
(FMV_D_X (i64 X0)))>;

// Moves (no conversion)
def : Pat<(bitconvert (i64 GPR:$rs1)), (FMV_D_X GPR:$rs1)>;
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/RISCV/RISCVInstrInfoF.td
Expand Up @@ -320,7 +320,8 @@ def PseudoQuietFLT_S : PseudoQuietFCMP<FPR32>;
//===----------------------------------------------------------------------===//

/// Floating point constants
def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
def fpimm0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(+0.0); }]>;
def fpimmneg0 : PatLeaf<(fpimm), [{ return N->isExactlyValue(-0.0); }]>;

/// Generic pattern classes
class PatSetCC<RegisterClass Ty, SDPatternOperator OpNode, CondCode Cond, RVInst Inst>
Expand All @@ -336,6 +337,7 @@ let Predicates = [HasStdExtF] in {

/// Float constants
def : Pat<(f32 (fpimm0)), (FMV_W_X X0)>;
def : Pat<(f32 (fpimmneg0)), (FSGNJN_S (FMV_W_X X0), (FMV_W_X X0))>;

/// Float conversion operations

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td
Expand Up @@ -201,6 +201,7 @@ let Predicates = [HasStdExtZfh] in {

/// Float constants
def : Pat<(f16 (fpimm0)), (FMV_H_X X0)>;
def : Pat<(f16 (fpimmneg0)), (FSGNJN_H (FMV_H_X X0), (FMV_H_X X0))>;

/// Float conversion operations

Expand Down
24 changes: 12 additions & 12 deletions llvm/test/CodeGen/RISCV/fp-imm.ll
Expand Up @@ -34,26 +34,26 @@ define float @f32_positive_zero(float *%pf) nounwind {
define float @f32_negative_zero(float *%pf) nounwind {
; RV32F-LABEL: f32_negative_zero:
; RV32F: # %bb.0:
; RV32F-NEXT: lui a0, %hi(.LCPI1_0)
; RV32F-NEXT: flw fa0, %lo(.LCPI1_0)(a0)
; RV32F-NEXT: fmv.w.x ft0, zero
; RV32F-NEXT: fneg.s fa0, ft0
; RV32F-NEXT: ret
;
; RV32D-LABEL: f32_negative_zero:
; RV32D: # %bb.0:
; RV32D-NEXT: lui a0, %hi(.LCPI1_0)
; RV32D-NEXT: flw fa0, %lo(.LCPI1_0)(a0)
; RV32D-NEXT: fmv.w.x ft0, zero
; RV32D-NEXT: fneg.s fa0, ft0
; RV32D-NEXT: ret
;
; RV64F-LABEL: f32_negative_zero:
; RV64F: # %bb.0:
; RV64F-NEXT: lui a0, %hi(.LCPI1_0)
; RV64F-NEXT: flw fa0, %lo(.LCPI1_0)(a0)
; RV64F-NEXT: fmv.w.x ft0, zero
; RV64F-NEXT: fneg.s fa0, ft0
; RV64F-NEXT: ret
;
; RV64D-LABEL: f32_negative_zero:
; RV64D: # %bb.0:
; RV64D-NEXT: lui a0, %hi(.LCPI1_0)
; RV64D-NEXT: flw fa0, %lo(.LCPI1_0)(a0)
; RV64D-NEXT: fmv.w.x ft0, zero
; RV64D-NEXT: fneg.s fa0, ft0
; RV64D-NEXT: ret
ret float -0.0
}
Expand Down Expand Up @@ -91,8 +91,8 @@ define double @f64_negative_zero(double *%pd) nounwind {
;
; RV32D-LABEL: f64_negative_zero:
; RV32D: # %bb.0:
; RV32D-NEXT: lui a0, %hi(.LCPI3_0)
; RV32D-NEXT: fld fa0, %lo(.LCPI3_0)(a0)
; RV32D-NEXT: fcvt.d.w ft0, zero
; RV32D-NEXT: fneg.d fa0, ft0
; RV32D-NEXT: ret
;
; RV64F-LABEL: f64_negative_zero:
Expand All @@ -103,8 +103,8 @@ define double @f64_negative_zero(double *%pd) nounwind {
;
; RV64D-LABEL: f64_negative_zero:
; RV64D: # %bb.0:
; RV64D-NEXT: lui a0, %hi(.LCPI3_0)
; RV64D-NEXT: fld fa0, %lo(.LCPI3_0)(a0)
; RV64D-NEXT: fmv.d.x ft0, zero
; RV64D-NEXT: fneg.d fa0, ft0
; RV64D-NEXT: ret
ret double -0.0
}

0 comments on commit 5a12024

Please sign in to comment.