Skip to content

Commit 7e8ff2a

Browse files
authored
[RISCV][GISel] Optimize +0.0 to use fcvt.d.w for s64 on rv32 (#153978)
Resolve the TODO: on RV32, when constructing the double-precision constant `+0.0` for `s64`, `BuildPairF64Pseudo` can be optimized to use the `fcvt.d.w` instruction to generate the result directly.
1 parent 58de8f2 commit 7e8ff2a

File tree

3 files changed

+24
-45
lines changed

3 files changed

+24
-45
lines changed

llvm/lib/Target/RISCV/GISel/RISCVInstructionSelector.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,6 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
736736
}
737737
case TargetOpcode::G_FCONSTANT: {
738738
// TODO: Use constant pool for complex constants.
739-
// TODO: Optimize +0.0 to use fcvt.d.w for s64 on rv32.
740739
Register DstReg = MI.getOperand(0).getReg();
741740
const APFloat &FPimm = MI.getOperand(1).getFPImm()->getValueAPF();
742741
APInt Imm = FPimm.bitcastToAPInt();
@@ -753,8 +752,22 @@ bool RISCVInstructionSelector::select(MachineInstr &MI) {
753752
if (!FMV.constrainAllUses(TII, TRI, RBI))
754753
return false;
755754
} else {
755+
// s64 on rv32
756756
assert(Size == 64 && !Subtarget->is64Bit() &&
757757
"Unexpected size or subtarget");
758+
759+
if (Imm.isNonNegative() && Imm.isZero()) {
760+
// Optimize +0.0 to use fcvt.d.w
761+
MachineInstrBuilder FCVT =
762+
MIB.buildInstr(RISCV::FCVT_D_W, {DstReg}, {Register(RISCV::X0)})
763+
.addImm(RISCVFPRndMode::RNE);
764+
if (!FCVT.constrainAllUses(TII, TRI, RBI))
765+
return false;
766+
767+
MI.eraseFromParent();
768+
return true;
769+
}
770+
758771
// Split into two pieces and build through the stack.
759772
Register GPRRegHigh = MRI->createVirtualRegister(&RISCV::GPRRegClass);
760773
Register GPRRegLow = MRI->createVirtualRegister(&RISCV::GPRRegClass);

llvm/test/CodeGen/RISCV/GlobalISel/double-arith.ll

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,9 @@ define double @fmadd_d(double %a, double %b, double %c) nounwind {
395395
define double @fmsub_d(double %a, double %b, double %c) nounwind {
396396
; RV32IFD-LABEL: fmsub_d:
397397
; RV32IFD: # %bb.0:
398-
; RV32IFD-NEXT: addi sp, sp, -16
399-
; RV32IFD-NEXT: sw zero, 8(sp)
400-
; RV32IFD-NEXT: sw zero, 12(sp)
401-
; RV32IFD-NEXT: fld fa5, 8(sp)
398+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
402399
; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
403400
; RV32IFD-NEXT: fmsub.d fa0, fa0, fa1, fa5
404-
; RV32IFD-NEXT: addi sp, sp, 16
405401
; RV32IFD-NEXT: ret
406402
;
407403
; RV64IFD-LABEL: fmsub_d:
@@ -478,14 +474,10 @@ define double @fmsub_d(double %a, double %b, double %c) nounwind {
478474
define double @fnmadd_d(double %a, double %b, double %c) nounwind {
479475
; RV32IFD-LABEL: fnmadd_d:
480476
; RV32IFD: # %bb.0:
481-
; RV32IFD-NEXT: addi sp, sp, -16
482-
; RV32IFD-NEXT: sw zero, 8(sp)
483-
; RV32IFD-NEXT: sw zero, 12(sp)
484-
; RV32IFD-NEXT: fld fa5, 8(sp)
477+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
485478
; RV32IFD-NEXT: fadd.d fa4, fa0, fa5
486479
; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
487480
; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa1, fa5
488-
; RV32IFD-NEXT: addi sp, sp, 16
489481
; RV32IFD-NEXT: ret
490482
;
491483
; RV64IFD-LABEL: fnmadd_d:
@@ -590,14 +582,10 @@ define double @fnmadd_d(double %a, double %b, double %c) nounwind {
590582
define double @fnmadd_d_2(double %a, double %b, double %c) nounwind {
591583
; RV32IFD-LABEL: fnmadd_d_2:
592584
; RV32IFD: # %bb.0:
593-
; RV32IFD-NEXT: addi sp, sp, -16
594-
; RV32IFD-NEXT: sw zero, 8(sp)
595-
; RV32IFD-NEXT: sw zero, 12(sp)
596-
; RV32IFD-NEXT: fld fa5, 8(sp)
585+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
597586
; RV32IFD-NEXT: fadd.d fa4, fa1, fa5
598587
; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
599588
; RV32IFD-NEXT: fnmadd.d fa0, fa4, fa0, fa5
600-
; RV32IFD-NEXT: addi sp, sp, 16
601589
; RV32IFD-NEXT: ret
602590
;
603591
; RV64IFD-LABEL: fnmadd_d_2:
@@ -772,13 +760,9 @@ define double @fnmadd_nsz(double %a, double %b, double %c) nounwind {
772760
define double @fnmsub_d(double %a, double %b, double %c) nounwind {
773761
; RV32IFD-LABEL: fnmsub_d:
774762
; RV32IFD: # %bb.0:
775-
; RV32IFD-NEXT: addi sp, sp, -16
776-
; RV32IFD-NEXT: sw zero, 8(sp)
777-
; RV32IFD-NEXT: sw zero, 12(sp)
778-
; RV32IFD-NEXT: fld fa5, 8(sp)
763+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
779764
; RV32IFD-NEXT: fadd.d fa5, fa0, fa5
780765
; RV32IFD-NEXT: fnmsub.d fa0, fa5, fa1, fa2
781-
; RV32IFD-NEXT: addi sp, sp, 16
782766
; RV32IFD-NEXT: ret
783767
;
784768
; RV64IFD-LABEL: fnmsub_d:
@@ -851,13 +835,9 @@ define double @fnmsub_d(double %a, double %b, double %c) nounwind {
851835
define double @fnmsub_d_2(double %a, double %b, double %c) nounwind {
852836
; RV32IFD-LABEL: fnmsub_d_2:
853837
; RV32IFD: # %bb.0:
854-
; RV32IFD-NEXT: addi sp, sp, -16
855-
; RV32IFD-NEXT: sw zero, 8(sp)
856-
; RV32IFD-NEXT: sw zero, 12(sp)
857-
; RV32IFD-NEXT: fld fa5, 8(sp)
838+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
858839
; RV32IFD-NEXT: fadd.d fa5, fa1, fa5
859840
; RV32IFD-NEXT: fnmsub.d fa0, fa5, fa0, fa2
860-
; RV32IFD-NEXT: addi sp, sp, 16
861841
; RV32IFD-NEXT: ret
862842
;
863843
; RV64IFD-LABEL: fnmsub_d_2:
@@ -976,14 +956,10 @@ define double @fmadd_d_contract(double %a, double %b, double %c) nounwind {
976956
define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
977957
; RV32IFD-LABEL: fmsub_d_contract:
978958
; RV32IFD: # %bb.0:
979-
; RV32IFD-NEXT: addi sp, sp, -16
980-
; RV32IFD-NEXT: sw zero, 8(sp)
981-
; RV32IFD-NEXT: sw zero, 12(sp)
982-
; RV32IFD-NEXT: fld fa5, 8(sp)
959+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
983960
; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
984961
; RV32IFD-NEXT: fmul.d fa4, fa0, fa1
985962
; RV32IFD-NEXT: fsub.d fa0, fa4, fa5
986-
; RV32IFD-NEXT: addi sp, sp, 16
987963
; RV32IFD-NEXT: ret
988964
;
989965
; RV64IFD-LABEL: fmsub_d_contract:
@@ -1069,17 +1045,13 @@ define double @fmsub_d_contract(double %a, double %b, double %c) nounwind {
10691045
define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
10701046
; RV32IFD-LABEL: fnmadd_d_contract:
10711047
; RV32IFD: # %bb.0:
1072-
; RV32IFD-NEXT: addi sp, sp, -16
1073-
; RV32IFD-NEXT: sw zero, 8(sp)
1074-
; RV32IFD-NEXT: sw zero, 12(sp)
1075-
; RV32IFD-NEXT: fld fa5, 8(sp)
1048+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
10761049
; RV32IFD-NEXT: fadd.d fa4, fa0, fa5
10771050
; RV32IFD-NEXT: fadd.d fa3, fa1, fa5
10781051
; RV32IFD-NEXT: fadd.d fa5, fa2, fa5
10791052
; RV32IFD-NEXT: fmul.d fa4, fa4, fa3
10801053
; RV32IFD-NEXT: fneg.d fa4, fa4
10811054
; RV32IFD-NEXT: fsub.d fa0, fa4, fa5
1082-
; RV32IFD-NEXT: addi sp, sp, 16
10831055
; RV32IFD-NEXT: ret
10841056
;
10851057
; RV64IFD-LABEL: fnmadd_d_contract:
@@ -1204,14 +1176,10 @@ define double @fnmadd_d_contract(double %a, double %b, double %c) nounwind {
12041176
define double @fnmsub_d_contract(double %a, double %b, double %c) nounwind {
12051177
; RV32IFD-LABEL: fnmsub_d_contract:
12061178
; RV32IFD: # %bb.0:
1207-
; RV32IFD-NEXT: addi sp, sp, -16
1208-
; RV32IFD-NEXT: sw zero, 8(sp)
1209-
; RV32IFD-NEXT: sw zero, 12(sp)
1210-
; RV32IFD-NEXT: fld fa5, 8(sp)
1179+
; RV32IFD-NEXT: fcvt.d.w fa5, zero
12111180
; RV32IFD-NEXT: fadd.d fa4, fa0, fa5
12121181
; RV32IFD-NEXT: fadd.d fa5, fa1, fa5
12131182
; RV32IFD-NEXT: fnmsub.d fa0, fa4, fa5, fa2
1214-
; RV32IFD-NEXT: addi sp, sp, 16
12151183
; RV32IFD-NEXT: ret
12161184
;
12171185
; RV64IFD-LABEL: fnmsub_d_contract:

llvm/test/CodeGen/RISCV/GlobalISel/instruction-select/fp-constant.mir

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,8 @@ body: |
164164
; RV32-LABEL: name: double_positive_zero
165165
; RV32: liveins: $x10
166166
; RV32-NEXT: {{ $}}
167-
; RV32-NEXT: [[COPY:%[0-9]+]]:gpr = COPY $x0
168-
; RV32-NEXT: [[COPY1:%[0-9]+]]:gpr = COPY $x0
169-
; RV32-NEXT: [[BuildPairF64Pseudo:%[0-9]+]]:fpr64 = BuildPairF64Pseudo [[COPY1]], [[COPY]]
170-
; RV32-NEXT: $f10_d = COPY [[BuildPairF64Pseudo]]
167+
; RV32-NEXT: [[FCVT_D_W:%[0-9]+]]:fpr64 = FCVT_D_W $x0, 0
168+
; RV32-NEXT: $f10_d = COPY [[FCVT_D_W]]
171169
; RV32-NEXT: PseudoRET implicit $f10_d
172170
;
173171
; RV64-LABEL: name: double_positive_zero

0 commit comments

Comments
 (0)