Skip to content

Commit 5a12024

Browse files
committed
[RISCV] Optimize lowering of floating-point -0.0
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
1 parent 770353c commit 5a12024

File tree

8 files changed

+279
-201
lines changed

8 files changed

+279
-201
lines changed

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,8 +1305,6 @@ bool RISCVTargetLowering::isFPImmLegal(const APFloat &Imm, EVT VT,
13051305
return false;
13061306
if (VT == MVT::f64 && !Subtarget.hasStdExtD())
13071307
return false;
1308-
if (Imm.isNegZero())
1309-
return false;
13101308
return Imm.isZero();
13111309
}
13121310

llvm/lib/Target/RISCV/RISCVInstrInfoD.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ let Predicates = [HasStdExtD, IsRV32] in {
285285

286286
/// Float constants
287287
def : Pat<(f64 (fpimm0)), (FCVT_D_W (i32 X0))>;
288+
def : Pat<(f64 (fpimmneg0)), (FSGNJN_D (FCVT_D_W (i32 X0)),
289+
(FCVT_D_W (i32 X0)))>;
288290

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

310312
/// Float constants
311313
def : Pat<(f64 (fpimm0)), (FMV_D_X (i64 X0))>;
314+
def : Pat<(f64 (fpimmneg0)), (FSGNJN_D (FMV_D_X (i64 X0)),
315+
(FMV_D_X (i64 X0)))>;
312316

313317
// Moves (no conversion)
314318
def : Pat<(bitconvert (i64 GPR:$rs1)), (FMV_D_X GPR:$rs1)>;

llvm/lib/Target/RISCV/RISCVInstrInfoF.td

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ def PseudoQuietFLT_S : PseudoQuietFCMP<FPR32>;
320320
//===----------------------------------------------------------------------===//
321321

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

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

337338
/// Float constants
338339
def : Pat<(f32 (fpimm0)), (FMV_W_X X0)>;
340+
def : Pat<(f32 (fpimmneg0)), (FSGNJN_S (FMV_W_X X0), (FMV_W_X X0))>;
339341

340342
/// Float conversion operations
341343

llvm/lib/Target/RISCV/RISCVInstrInfoZfh.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ let Predicates = [HasStdExtZfh] in {
201201

202202
/// Float constants
203203
def : Pat<(f16 (fpimm0)), (FMV_H_X X0)>;
204+
def : Pat<(f16 (fpimmneg0)), (FSGNJN_H (FMV_H_X X0), (FMV_H_X X0))>;
204205

205206
/// Float conversion operations
206207

llvm/test/CodeGen/RISCV/fp-imm.ll

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,26 +34,26 @@ define float @f32_positive_zero(float *%pf) nounwind {
3434
define float @f32_negative_zero(float *%pf) nounwind {
3535
; RV32F-LABEL: f32_negative_zero:
3636
; RV32F: # %bb.0:
37-
; RV32F-NEXT: lui a0, %hi(.LCPI1_0)
38-
; RV32F-NEXT: flw fa0, %lo(.LCPI1_0)(a0)
37+
; RV32F-NEXT: fmv.w.x ft0, zero
38+
; RV32F-NEXT: fneg.s fa0, ft0
3939
; RV32F-NEXT: ret
4040
;
4141
; RV32D-LABEL: f32_negative_zero:
4242
; RV32D: # %bb.0:
43-
; RV32D-NEXT: lui a0, %hi(.LCPI1_0)
44-
; RV32D-NEXT: flw fa0, %lo(.LCPI1_0)(a0)
43+
; RV32D-NEXT: fmv.w.x ft0, zero
44+
; RV32D-NEXT: fneg.s fa0, ft0
4545
; RV32D-NEXT: ret
4646
;
4747
; RV64F-LABEL: f32_negative_zero:
4848
; RV64F: # %bb.0:
49-
; RV64F-NEXT: lui a0, %hi(.LCPI1_0)
50-
; RV64F-NEXT: flw fa0, %lo(.LCPI1_0)(a0)
49+
; RV64F-NEXT: fmv.w.x ft0, zero
50+
; RV64F-NEXT: fneg.s fa0, ft0
5151
; RV64F-NEXT: ret
5252
;
5353
; RV64D-LABEL: f32_negative_zero:
5454
; RV64D: # %bb.0:
55-
; RV64D-NEXT: lui a0, %hi(.LCPI1_0)
56-
; RV64D-NEXT: flw fa0, %lo(.LCPI1_0)(a0)
55+
; RV64D-NEXT: fmv.w.x ft0, zero
56+
; RV64D-NEXT: fneg.s fa0, ft0
5757
; RV64D-NEXT: ret
5858
ret float -0.0
5959
}
@@ -91,8 +91,8 @@ define double @f64_negative_zero(double *%pd) nounwind {
9191
;
9292
; RV32D-LABEL: f64_negative_zero:
9393
; RV32D: # %bb.0:
94-
; RV32D-NEXT: lui a0, %hi(.LCPI3_0)
95-
; RV32D-NEXT: fld fa0, %lo(.LCPI3_0)(a0)
94+
; RV32D-NEXT: fcvt.d.w ft0, zero
95+
; RV32D-NEXT: fneg.d fa0, ft0
9696
; RV32D-NEXT: ret
9797
;
9898
; RV64F-LABEL: f64_negative_zero:
@@ -103,8 +103,8 @@ define double @f64_negative_zero(double *%pd) nounwind {
103103
;
104104
; RV64D-LABEL: f64_negative_zero:
105105
; RV64D: # %bb.0:
106-
; RV64D-NEXT: lui a0, %hi(.LCPI3_0)
107-
; RV64D-NEXT: fld fa0, %lo(.LCPI3_0)(a0)
106+
; RV64D-NEXT: fmv.d.x ft0, zero
107+
; RV64D-NEXT: fneg.d fa0, ft0
108108
; RV64D-NEXT: ret
109109
ret double -0.0
110110
}

0 commit comments

Comments
 (0)