1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

[RISCV] Add patterns for checking isnan

Summary:
This patch addresses some weird assembly sequences we were seeing during
comparing floats. In particular, comparing a float to itself tells you whether
it is NaN or not, which we were doing correctly, but with an extra unneeded
`and` instruction.

This patch specialises the existing patterns to remove the `and` instructions
when both their operands are the same.

Reviewed By: luismarques, asb

Differential Revision: https://reviews.llvm.org/D78908
This commit is contained in:
Sam Elliott 2020-05-02 15:00:38 +01:00
parent 3dbabae7eb
commit ea67f31d92
4 changed files with 8 additions and 8 deletions

View File

@ -306,11 +306,15 @@ def : PatFpr64Fpr64<setole, FLE_D>;
def : Pat<(seto FPR64:$rs1, FPR64:$rs2),
(AND (FEQ_D FPR64:$rs1, FPR64:$rs1),
(FEQ_D FPR64:$rs2, FPR64:$rs2))>;
def : Pat<(seto FPR64:$rs1, FPR64:$rs1),
(FEQ_D $rs1, $rs1)>;
def : Pat<(setuo FPR64:$rs1, FPR64:$rs2),
(SLTIU (AND (FEQ_D FPR64:$rs1, FPR64:$rs1),
(FEQ_D FPR64:$rs2, FPR64:$rs2)),
1)>;
def : Pat<(setuo FPR64:$rs1, FPR64:$rs1),
(SLTIU (FEQ_D $rs1, $rs1), 1)>;
def Select_FPR64_Using_CC_GPR : SelectCC_rrirr<FPR64, GPR>;

View File

@ -366,11 +366,15 @@ def : PatFpr32Fpr32<setole, FLE_S>;
def : Pat<(seto FPR32:$rs1, FPR32:$rs2),
(AND (FEQ_S FPR32:$rs1, FPR32:$rs1),
(FEQ_S FPR32:$rs2, FPR32:$rs2))>;
def : Pat<(seto FPR32:$rs1, FPR32:$rs1),
(FEQ_S $rs1, $rs1)>;
def : Pat<(setuo FPR32:$rs1, FPR32:$rs2),
(SLTIU (AND (FEQ_S FPR32:$rs1, FPR32:$rs1),
(FEQ_S FPR32:$rs2, FPR32:$rs2)),
1)>;
def : Pat<(setuo FPR32:$rs1, FPR32:$rs1),
(SLTIU (FEQ_S $rs1, $rs1), 1)>;
def Select_FPR32_Using_CC_GPR : SelectCC_rrirr<FPR32, GPR>;

View File

@ -8,14 +8,12 @@ define zeroext i1 @double_is_nan(double %a) nounwind {
; RV32IFD-LABEL: double_is_nan:
; RV32IFD: # %bb.0:
; RV32IFD-NEXT: feq.d a0, fa0, fa0
; RV32IFD-NEXT: and a0, a0, a0
; RV32IFD-NEXT: seqz a0, a0
; RV32IFD-NEXT: ret
;
; RV64IFD-LABEL: double_is_nan:
; RV64IFD: # %bb.0:
; RV64IFD-NEXT: feq.d a0, fa0, fa0
; RV64IFD-NEXT: and a0, a0, a0
; RV64IFD-NEXT: seqz a0, a0
; RV64IFD-NEXT: ret
%1 = fcmp uno double %a, 0.000000e+00
@ -26,13 +24,11 @@ define zeroext i1 @double_not_nan(double %a) nounwind {
; RV32IFD-LABEL: double_not_nan:
; RV32IFD: # %bb.0:
; RV32IFD-NEXT: feq.d a0, fa0, fa0
; RV32IFD-NEXT: and a0, a0, a0
; RV32IFD-NEXT: ret
;
; RV64IFD-LABEL: double_not_nan:
; RV64IFD: # %bb.0:
; RV64IFD-NEXT: feq.d a0, fa0, fa0
; RV64IFD-NEXT: and a0, a0, a0
; RV64IFD-NEXT: ret
%1 = fcmp ord double %a, 0.000000e+00
ret i1 %1

View File

@ -8,14 +8,12 @@ define zeroext i1 @float_is_nan(float %a) nounwind {
; RV32IF-LABEL: float_is_nan:
; RV32IF: # %bb.0:
; RV32IF-NEXT: feq.s a0, fa0, fa0
; RV32IF-NEXT: and a0, a0, a0
; RV32IF-NEXT: seqz a0, a0
; RV32IF-NEXT: ret
;
; RV64IF-LABEL: float_is_nan:
; RV64IF: # %bb.0:
; RV64IF-NEXT: feq.s a0, fa0, fa0
; RV64IF-NEXT: and a0, a0, a0
; RV64IF-NEXT: seqz a0, a0
; RV64IF-NEXT: ret
%1 = fcmp uno float %a, 0.000000e+00
@ -26,13 +24,11 @@ define zeroext i1 @float_not_nan(float %a) nounwind {
; RV32IF-LABEL: float_not_nan:
; RV32IF: # %bb.0:
; RV32IF-NEXT: feq.s a0, fa0, fa0
; RV32IF-NEXT: and a0, a0, a0
; RV32IF-NEXT: ret
;
; RV64IF-LABEL: float_not_nan:
; RV64IF: # %bb.0:
; RV64IF-NEXT: feq.s a0, fa0, fa0
; RV64IF-NEXT: and a0, a0, a0
; RV64IF-NEXT: ret
%1 = fcmp ord float %a, 0.000000e+00
ret i1 %1