Skip to content

Commit

Permalink
[RISCV] Select +0.0 immediate using fmv.{w,d}.x / fcvt.d.w
Browse files Browse the repository at this point in the history
Floating point positive zero can be selected using fmv.w.x / fmv.d.x /
fcvt.d.w and the zero source register.

Differential Revision: https://reviews.llvm.org/D75729
  • Loading branch information
rofirrim committed Mar 20, 2020
1 parent ebb04e9 commit 3c24aee
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 108 deletions.
11 changes: 11 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Expand Up @@ -336,6 +336,17 @@ bool RISCVTargetLowering::isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const {
return Subtarget.is64Bit() && SrcVT == MVT::i32 && DstVT == MVT::i64;
}

bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const {
if (VT == MVT::f32 && !Subtarget.hasStdExtF())
return false;
if (VT == MVT::f64 && !Subtarget.hasStdExtD())
return false;
if (Imm.isNegZero())
return false;
return Imm.isZero();
}

bool RISCVTargetLowering::hasBitPreservingFPLogic(EVT VT) const {
return (VT == MVT::f32 && Subtarget.hasStdExtF()) ||
(VT == MVT::f64 && Subtarget.hasStdExtD());
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.h
Expand Up @@ -74,6 +74,8 @@ class RISCVTargetLowering : public TargetLowering {
bool isTruncateFree(EVT SrcVT, EVT DstVT) const override;
bool isZExtFree(SDValue Val, EVT VT2) const override;
bool isSExtCheaperThanZExt(EVT SrcVT, EVT DstVT) const override;
bool isFPImmLegal(const APFloat &Imm, EVT VT,
bool ForCodeSize) const override;

bool hasBitPreservingFPLogic(EVT VT) const override;

Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoD.td
Expand Up @@ -339,6 +339,10 @@ def SplitF64Pseudo
} // Predicates = [HasStdExtD]

let Predicates = [HasStdExtD, IsRV32] in {

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

// double->[u]int. Round-to-zero must be used.
def : Pat<(fp_to_sint FPR64:$rs1), (FCVT_W_D FPR64:$rs1, 0b001)>;
def : Pat<(fp_to_uint FPR64:$rs1), (FCVT_WU_D FPR64:$rs1, 0b001)>;
Expand All @@ -349,6 +353,10 @@ def : Pat<(uint_to_fp GPR:$rs1), (FCVT_D_WU GPR:$rs1)>;
} // Predicates = [HasStdExtD, IsRV32]

let Predicates = [HasStdExtD, IsRV64] in {

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

def : Pat<(bitconvert GPR:$rs1), (FMV_D_X GPR:$rs1)>;
def : Pat<(bitconvert FPR64:$rs1), (FMV_X_D FPR64:$rs1)>;

Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Target/RISCV/RISCVInstrInfoF.td
Expand Up @@ -286,6 +286,9 @@ def PseudoFSW : PseudoStore<"fsw", FPR32>;
// Pseudo-instructions and codegen patterns
//===----------------------------------------------------------------------===//

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

/// Generic pattern classes
class PatFpr32Fpr32<SDPatternOperator OpNode, RVInstR Inst>
: Pat<(OpNode FPR32:$rs1, FPR32:$rs2), (Inst $rs1, $rs2)>;
Expand All @@ -295,6 +298,9 @@ class PatFpr32Fpr32DynFrm<SDPatternOperator OpNode, RVInstRFrm Inst>

let Predicates = [HasStdExtF] in {

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

/// Float conversion operations

// Moves (no conversion)
Expand Down
56 changes: 22 additions & 34 deletions llvm/test/CodeGen/RISCV/double-arith.ll
Expand Up @@ -460,9 +460,7 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind {
; RV32IFD-NEXT: sw a4, 8(sp)
; RV32IFD-NEXT: sw a5, 12(sp)
; RV32IFD-NEXT: fld ft2, 8(sp)
; RV32IFD-NEXT: lui a0, %hi(.LCPI15_0)
; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI15_0)
; RV32IFD-NEXT: fld ft3, 0(a0)
; RV32IFD-NEXT: fcvt.d.w ft3, zero
; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
; RV32IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2
; RV32IFD-NEXT: fsd ft0, 8(sp)
Expand All @@ -473,14 +471,12 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind {
;
; RV64IFD-LABEL: fmsub_d:
; RV64IFD: # %bb.0:
; RV64IFD-NEXT: lui a3, %hi(.LCPI15_0)
; RV64IFD-NEXT: addi a3, a3, %lo(.LCPI15_0)
; RV64IFD-NEXT: fld ft0, 0(a3)
; RV64IFD-NEXT: fmv.d.x ft1, a1
; RV64IFD-NEXT: fmv.d.x ft2, a0
; RV64IFD-NEXT: fmv.d.x ft3, a2
; RV64IFD-NEXT: fadd.d ft0, ft3, ft0
; RV64IFD-NEXT: fmsub.d ft0, ft2, ft1, ft0
; RV64IFD-NEXT: fmv.d.x ft0, a1
; RV64IFD-NEXT: fmv.d.x ft1, a0
; RV64IFD-NEXT: fmv.d.x ft2, a2
; RV64IFD-NEXT: fmv.d.x ft3, zero
; RV64IFD-NEXT: fadd.d ft2, ft2, ft3
; RV64IFD-NEXT: fmsub.d ft0, ft1, ft0, ft2
; RV64IFD-NEXT: fmv.x.d a0, ft0
; RV64IFD-NEXT: ret
%c_ = fadd double 0.0, %c ; avoid negation using xor
Expand All @@ -502,9 +498,7 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind {
; RV32IFD-NEXT: sw a0, 8(sp)
; RV32IFD-NEXT: sw a1, 12(sp)
; RV32IFD-NEXT: fld ft2, 8(sp)
; RV32IFD-NEXT: lui a0, %hi(.LCPI16_0)
; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI16_0)
; RV32IFD-NEXT: fld ft3, 0(a0)
; RV32IFD-NEXT: fcvt.d.w ft3, zero
; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
; RV32IFD-NEXT: fadd.d ft1, ft1, ft3
; RV32IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1
Expand All @@ -516,15 +510,13 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind {
;
; RV64IFD-LABEL: fnmadd_d:
; RV64IFD: # %bb.0:
; RV64IFD-NEXT: lui a3, %hi(.LCPI16_0)
; RV64IFD-NEXT: addi a3, a3, %lo(.LCPI16_0)
; RV64IFD-NEXT: fld ft0, 0(a3)
; RV64IFD-NEXT: fmv.d.x ft1, a1
; RV64IFD-NEXT: fmv.d.x ft2, a2
; RV64IFD-NEXT: fmv.d.x ft3, a0
; RV64IFD-NEXT: fadd.d ft3, ft3, ft0
; RV64IFD-NEXT: fadd.d ft0, ft2, ft0
; RV64IFD-NEXT: fnmadd.d ft0, ft3, ft1, ft0
; RV64IFD-NEXT: fmv.d.x ft0, a1
; RV64IFD-NEXT: fmv.d.x ft1, a2
; RV64IFD-NEXT: fmv.d.x ft2, a0
; RV64IFD-NEXT: fmv.d.x ft3, zero
; RV64IFD-NEXT: fadd.d ft2, ft2, ft3
; RV64IFD-NEXT: fadd.d ft1, ft1, ft3
; RV64IFD-NEXT: fnmadd.d ft0, ft2, ft0, ft1
; RV64IFD-NEXT: fmv.x.d a0, ft0
; RV64IFD-NEXT: ret
%a_ = fadd double 0.0, %a
Expand All @@ -548,9 +540,7 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
; RV32IFD-NEXT: sw a0, 8(sp)
; RV32IFD-NEXT: sw a1, 12(sp)
; RV32IFD-NEXT: fld ft2, 8(sp)
; RV32IFD-NEXT: lui a0, %hi(.LCPI17_0)
; RV32IFD-NEXT: addi a0, a0, %lo(.LCPI17_0)
; RV32IFD-NEXT: fld ft3, 0(a0)
; RV32IFD-NEXT: fcvt.d.w ft3, zero
; RV32IFD-NEXT: fadd.d ft2, ft2, ft3
; RV32IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0
; RV32IFD-NEXT: fsd ft0, 8(sp)
Expand All @@ -561,14 +551,12 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
;
; RV64IFD-LABEL: fnmsub_d:
; RV64IFD: # %bb.0:
; RV64IFD-NEXT: lui a3, %hi(.LCPI17_0)
; RV64IFD-NEXT: addi a3, a3, %lo(.LCPI17_0)
; RV64IFD-NEXT: fld ft0, 0(a3)
; RV64IFD-NEXT: fmv.d.x ft1, a2
; RV64IFD-NEXT: fmv.d.x ft2, a1
; RV64IFD-NEXT: fmv.d.x ft3, a0
; RV64IFD-NEXT: fadd.d ft0, ft3, ft0
; RV64IFD-NEXT: fnmsub.d ft0, ft0, ft2, ft1
; RV64IFD-NEXT: fmv.d.x ft0, a2
; RV64IFD-NEXT: fmv.d.x ft1, a1
; RV64IFD-NEXT: fmv.d.x ft2, a0
; RV64IFD-NEXT: fmv.d.x ft3, zero
; RV64IFD-NEXT: fadd.d ft2, ft2, ft3
; RV64IFD-NEXT: fnmsub.d ft0, ft2, ft1, ft0
; RV64IFD-NEXT: fmv.x.d a0, ft0
; RV64IFD-NEXT: ret
%a_ = fadd double 0.0, %a
Expand Down
88 changes: 38 additions & 50 deletions llvm/test/CodeGen/RISCV/float-arith.ll
Expand Up @@ -339,27 +339,23 @@ define float @fmadd_s(float %a, float %b, float %c) nounwind {
define float @fmsub_s(float %a, float %b, float %c) nounwind {
; RV32IF-LABEL: fmsub_s:
; RV32IF: # %bb.0:
; RV32IF-NEXT: lui a3, %hi(.LCPI15_0)
; RV32IF-NEXT: addi a3, a3, %lo(.LCPI15_0)
; RV32IF-NEXT: flw ft0, 0(a3)
; RV32IF-NEXT: fmv.w.x ft1, a1
; RV32IF-NEXT: fmv.w.x ft2, a0
; RV32IF-NEXT: fmv.w.x ft3, a2
; RV32IF-NEXT: fadd.s ft0, ft3, ft0
; RV32IF-NEXT: fmsub.s ft0, ft2, ft1, ft0
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a0
; RV32IF-NEXT: fmv.w.x ft2, a2
; RV32IF-NEXT: fmv.w.x ft3, zero
; RV32IF-NEXT: fadd.s ft2, ft2, ft3
; RV32IF-NEXT: fmsub.s ft0, ft1, ft0, ft2
; RV32IF-NEXT: fmv.x.w a0, ft0
; RV32IF-NEXT: ret
;
; RV64IF-LABEL: fmsub_s:
; RV64IF: # %bb.0:
; RV64IF-NEXT: lui a3, %hi(.LCPI15_0)
; RV64IF-NEXT: addi a3, a3, %lo(.LCPI15_0)
; RV64IF-NEXT: flw ft0, 0(a3)
; RV64IF-NEXT: fmv.w.x ft1, a1
; RV64IF-NEXT: fmv.w.x ft2, a0
; RV64IF-NEXT: fmv.w.x ft3, a2
; RV64IF-NEXT: fadd.s ft0, ft3, ft0
; RV64IF-NEXT: fmsub.s ft0, ft2, ft1, ft0
; RV64IF-NEXT: fmv.w.x ft0, a1
; RV64IF-NEXT: fmv.w.x ft1, a0
; RV64IF-NEXT: fmv.w.x ft2, a2
; RV64IF-NEXT: fmv.w.x ft3, zero
; RV64IF-NEXT: fadd.s ft2, ft2, ft3
; RV64IF-NEXT: fmsub.s ft0, ft1, ft0, ft2
; RV64IF-NEXT: fmv.x.w a0, ft0
; RV64IF-NEXT: ret
%c_ = fadd float 0.0, %c ; avoid negation using xor
Expand All @@ -371,29 +367,25 @@ define float @fmsub_s(float %a, float %b, float %c) nounwind {
define float @fnmadd_s(float %a, float %b, float %c) nounwind {
; RV32IF-LABEL: fnmadd_s:
; RV32IF: # %bb.0:
; RV32IF-NEXT: lui a3, %hi(.LCPI16_0)
; RV32IF-NEXT: addi a3, a3, %lo(.LCPI16_0)
; RV32IF-NEXT: flw ft0, 0(a3)
; RV32IF-NEXT: fmv.w.x ft1, a1
; RV32IF-NEXT: fmv.w.x ft2, a2
; RV32IF-NEXT: fmv.w.x ft3, a0
; RV32IF-NEXT: fadd.s ft3, ft3, ft0
; RV32IF-NEXT: fadd.s ft0, ft2, ft0
; RV32IF-NEXT: fnmadd.s ft0, ft3, ft1, ft0
; RV32IF-NEXT: fmv.w.x ft0, a1
; RV32IF-NEXT: fmv.w.x ft1, a2
; RV32IF-NEXT: fmv.w.x ft2, a0
; RV32IF-NEXT: fmv.w.x ft3, zero
; RV32IF-NEXT: fadd.s ft2, ft2, ft3
; RV32IF-NEXT: fadd.s ft1, ft1, ft3
; RV32IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1
; RV32IF-NEXT: fmv.x.w a0, ft0
; RV32IF-NEXT: ret
;
; RV64IF-LABEL: fnmadd_s:
; RV64IF: # %bb.0:
; RV64IF-NEXT: lui a3, %hi(.LCPI16_0)
; RV64IF-NEXT: addi a3, a3, %lo(.LCPI16_0)
; RV64IF-NEXT: flw ft0, 0(a3)
; RV64IF-NEXT: fmv.w.x ft1, a1
; RV64IF-NEXT: fmv.w.x ft2, a2
; RV64IF-NEXT: fmv.w.x ft3, a0
; RV64IF-NEXT: fadd.s ft3, ft3, ft0
; RV64IF-NEXT: fadd.s ft0, ft2, ft0
; RV64IF-NEXT: fnmadd.s ft0, ft3, ft1, ft0
; RV64IF-NEXT: fmv.w.x ft0, a1
; RV64IF-NEXT: fmv.w.x ft1, a2
; RV64IF-NEXT: fmv.w.x ft2, a0
; RV64IF-NEXT: fmv.w.x ft3, zero
; RV64IF-NEXT: fadd.s ft2, ft2, ft3
; RV64IF-NEXT: fadd.s ft1, ft1, ft3
; RV64IF-NEXT: fnmadd.s ft0, ft2, ft0, ft1
; RV64IF-NEXT: fmv.x.w a0, ft0
; RV64IF-NEXT: ret
%a_ = fadd float 0.0, %a
Expand All @@ -407,27 +399,23 @@ define float @fnmadd_s(float %a, float %b, float %c) nounwind {
define float @fnmsub_s(float %a, float %b, float %c) nounwind {
; RV32IF-LABEL: fnmsub_s:
; RV32IF: # %bb.0:
; RV32IF-NEXT: lui a3, %hi(.LCPI17_0)
; RV32IF-NEXT: addi a3, a3, %lo(.LCPI17_0)
; RV32IF-NEXT: flw ft0, 0(a3)
; RV32IF-NEXT: fmv.w.x ft1, a2
; RV32IF-NEXT: fmv.w.x ft2, a1
; RV32IF-NEXT: fmv.w.x ft3, a0
; RV32IF-NEXT: fadd.s ft0, ft3, ft0
; RV32IF-NEXT: fnmsub.s ft0, ft0, ft2, ft1
; RV32IF-NEXT: fmv.w.x ft0, a2
; RV32IF-NEXT: fmv.w.x ft1, a1
; RV32IF-NEXT: fmv.w.x ft2, a0
; RV32IF-NEXT: fmv.w.x ft3, zero
; RV32IF-NEXT: fadd.s ft2, ft2, ft3
; RV32IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0
; RV32IF-NEXT: fmv.x.w a0, ft0
; RV32IF-NEXT: ret
;
; RV64IF-LABEL: fnmsub_s:
; RV64IF: # %bb.0:
; RV64IF-NEXT: lui a3, %hi(.LCPI17_0)
; RV64IF-NEXT: addi a3, a3, %lo(.LCPI17_0)
; RV64IF-NEXT: flw ft0, 0(a3)
; RV64IF-NEXT: fmv.w.x ft1, a2
; RV64IF-NEXT: fmv.w.x ft2, a1
; RV64IF-NEXT: fmv.w.x ft3, a0
; RV64IF-NEXT: fadd.s ft0, ft3, ft0
; RV64IF-NEXT: fnmsub.s ft0, ft0, ft2, ft1
; RV64IF-NEXT: fmv.w.x ft0, a2
; RV64IF-NEXT: fmv.w.x ft1, a1
; RV64IF-NEXT: fmv.w.x ft2, a0
; RV64IF-NEXT: fmv.w.x ft3, zero
; RV64IF-NEXT: fadd.s ft2, ft2, ft3
; RV64IF-NEXT: fnmsub.s ft0, ft2, ft1, ft0
; RV64IF-NEXT: fmv.x.w a0, ft0
; RV64IF-NEXT: ret
%a_ = fadd float 0.0, %a
Expand Down
8 changes: 2 additions & 6 deletions llvm/test/CodeGen/RISCV/float-br-fcmp.ll
Expand Up @@ -720,10 +720,8 @@ define i32 @br_fcmp_store_load_stack_slot(float %a, float %b) nounwind {
; RV32IF-NEXT: sw ra, 12(sp)
; RV32IF-NEXT: mv a0, zero
; RV32IF-NEXT: call dummy
; RV32IF-NEXT: lui a1, %hi(.LCPI17_0)
; RV32IF-NEXT: addi a1, a1, %lo(.LCPI17_0)
; RV32IF-NEXT: flw ft1, 0(a1)
; RV32IF-NEXT: fmv.w.x ft0, a0
; RV32IF-NEXT: fmv.w.x ft1, zero
; RV32IF-NEXT: fsw ft1, 8(sp)
; RV32IF-NEXT: feq.s a0, ft0, ft1
; RV32IF-NEXT: beqz a0, .LBB17_3
Expand All @@ -747,9 +745,7 @@ define i32 @br_fcmp_store_load_stack_slot(float %a, float %b) nounwind {
; RV64IF-NEXT: addi sp, sp, -32
; RV64IF-NEXT: sd ra, 24(sp)
; RV64IF-NEXT: sd s0, 16(sp)
; RV64IF-NEXT: lui a0, %hi(.LCPI17_0)
; RV64IF-NEXT: addi a0, a0, %lo(.LCPI17_0)
; RV64IF-NEXT: flw ft0, 0(a0)
; RV64IF-NEXT: fmv.w.x ft0, zero
; RV64IF-NEXT: fsw ft0, 12(sp)
; RV64IF-NEXT: fmv.x.w s0, ft0
; RV64IF-NEXT: mv a0, s0
Expand Down
24 changes: 6 additions & 18 deletions llvm/test/CodeGen/RISCV/fp-imm.ll
Expand Up @@ -11,30 +11,22 @@
define float @f32_positive_zero(float *%pf) nounwind {
; RV32F-LABEL: f32_positive_zero:
; RV32F: # %bb.0:
; RV32F-NEXT: lui a0, %hi(.LCPI0_0)
; RV32F-NEXT: addi a0, a0, %lo(.LCPI0_0)
; RV32F-NEXT: flw fa0, 0(a0)
; RV32F-NEXT: fmv.w.x fa0, zero
; RV32F-NEXT: ret
;
; RV32D-LABEL: f32_positive_zero:
; RV32D: # %bb.0:
; RV32D-NEXT: lui a0, %hi(.LCPI0_0)
; RV32D-NEXT: addi a0, a0, %lo(.LCPI0_0)
; RV32D-NEXT: flw fa0, 0(a0)
; RV32D-NEXT: fmv.w.x fa0, zero
; RV32D-NEXT: ret
;
; RV64F-LABEL: f32_positive_zero:
; RV64F: # %bb.0:
; RV64F-NEXT: lui a0, %hi(.LCPI0_0)
; RV64F-NEXT: addi a0, a0, %lo(.LCPI0_0)
; RV64F-NEXT: flw fa0, 0(a0)
; RV64F-NEXT: fmv.w.x fa0, zero
; RV64F-NEXT: ret
;
; RV64D-LABEL: f32_positive_zero:
; RV64D: # %bb.0:
; RV64D-NEXT: lui a0, %hi(.LCPI0_0)
; RV64D-NEXT: addi a0, a0, %lo(.LCPI0_0)
; RV64D-NEXT: flw fa0, 0(a0)
; RV64D-NEXT: fmv.w.x fa0, zero
; RV64D-NEXT: ret
ret float 0.0
}
Expand Down Expand Up @@ -79,9 +71,7 @@ define double @f64_positive_zero(double *%pd) nounwind {
;
; RV32D-LABEL: f64_positive_zero:
; RV32D: # %bb.0:
; RV32D-NEXT: lui a0, %hi(.LCPI2_0)
; RV32D-NEXT: addi a0, a0, %lo(.LCPI2_0)
; RV32D-NEXT: fld fa0, 0(a0)
; RV32D-NEXT: fcvt.d.w fa0, zero
; RV32D-NEXT: ret
;
; RV64F-LABEL: f64_positive_zero:
Expand All @@ -91,9 +81,7 @@ define double @f64_positive_zero(double *%pd) nounwind {
;
; RV64D-LABEL: f64_positive_zero:
; RV64D: # %bb.0:
; RV64D-NEXT: lui a0, %hi(.LCPI2_0)
; RV64D-NEXT: addi a0, a0, %lo(.LCPI2_0)
; RV64D-NEXT: fld fa0, 0(a0)
; RV64D-NEXT: fmv.d.x fa0, zero
; RV64D-NEXT: ret
ret double 0.0
}
Expand Down

0 comments on commit 3c24aee

Please sign in to comment.