mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 07:06:06 +00:00
[RISCV] Add no NaN support to lowerFMAXIMUM_FMINIMUM.
Using the nonans FMF and the DAG.isKnownNeverNaN on the inputs. Reviewed By: fakepaper56 Differential Revision: https://reviews.llvm.org/D156748
This commit is contained in:
parent
6888de1187
commit
048458f94c
@ -4670,12 +4670,18 @@ static SDValue lowerFMAXIMUM_FMINIMUM(SDValue Op, SelectionDAG &DAG,
|
||||
// ensures that when one input is a nan, the other will also be a nan allowing
|
||||
// the nan to propagate. If both inputs are nan, this will swap the inputs
|
||||
// which is harmless.
|
||||
// FIXME: Handle nonans FMF and use isKnownNeverNaN.
|
||||
SDValue XIsNonNan = DAG.getSetCC(DL, XLenVT, X, X, ISD::SETOEQ);
|
||||
SDValue NewY = DAG.getSelect(DL, VT, XIsNonNan, Y, X);
|
||||
|
||||
SDValue YIsNonNan = DAG.getSetCC(DL, XLenVT, Y, Y, ISD::SETOEQ);
|
||||
SDValue NewX = DAG.getSelect(DL, VT, YIsNonNan, X, Y);
|
||||
SDValue NewY = Y;;
|
||||
if (!Op->getFlags().hasNoNaNs() && !DAG.isKnownNeverNaN(X)) {
|
||||
SDValue XIsNonNan = DAG.getSetCC(DL, XLenVT, X, X, ISD::SETOEQ);
|
||||
NewY = DAG.getSelect(DL, VT, XIsNonNan, Y, X);
|
||||
}
|
||||
|
||||
SDValue NewX = X;
|
||||
if (!Op->getFlags().hasNoNaNs() && !DAG.isKnownNeverNaN(Y)) {
|
||||
SDValue YIsNonNan = DAG.getSetCC(DL, XLenVT, Y, Y, ISD::SETOEQ);
|
||||
NewX = DAG.getSelect(DL, VT, YIsNonNan, X, Y);
|
||||
}
|
||||
|
||||
unsigned Opc =
|
||||
Op.getOpcode() == ISD::FMAXIMUM ? RISCVISD::FMAX : RISCVISD::FMIN;
|
||||
|
@ -159,6 +159,209 @@ define double @fmaximum_f64(double %a, double %b) nounwind {
|
||||
%1 = call double @llvm.maximum.f64(double %a, double %b)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
define double @fminimum_nnan_f64(double %a, double %b) nounwind {
|
||||
; CHECKIFD-LABEL: fminimum_nnan_f64:
|
||||
; CHECKIFD: # %bb.0:
|
||||
; CHECKIFD-NEXT: fmin.d fa0, fa0, fa1
|
||||
; CHECKIFD-NEXT: ret
|
||||
;
|
||||
; RV32IZFINXZDINX-LABEL: fminimum_nnan_f64:
|
||||
; RV32IZFINXZDINX: # %bb.0:
|
||||
; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
|
||||
; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2
|
||||
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
|
||||
; RV32IZFINXZDINX-NEXT: ret
|
||||
;
|
||||
; RV64IZFINXZDINX-LABEL: fminimum_nnan_f64:
|
||||
; RV64IZFINXZDINX: # %bb.0:
|
||||
; RV64IZFINXZDINX-NEXT: fmin.d a0, a0, a1
|
||||
; RV64IZFINXZDINX-NEXT: ret
|
||||
%1 = call nnan double @llvm.minimum.f64(double %a, double %b)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
define double @fmaximum_nnan_f64(double %a, double %b) nounwind {
|
||||
; CHECKIFD-LABEL: fmaximum_nnan_f64:
|
||||
; CHECKIFD: # %bb.0:
|
||||
; CHECKIFD-NEXT: feq.d a0, fa0, fa0
|
||||
; CHECKIFD-NEXT: fmv.d fa5, fa1
|
||||
; CHECKIFD-NEXT: beqz a0, .LBB3_3
|
||||
; CHECKIFD-NEXT: # %bb.1:
|
||||
; CHECKIFD-NEXT: feq.d a0, fa1, fa1
|
||||
; CHECKIFD-NEXT: beqz a0, .LBB3_4
|
||||
; CHECKIFD-NEXT: .LBB3_2:
|
||||
; CHECKIFD-NEXT: fmin.d fa0, fa0, fa5
|
||||
; CHECKIFD-NEXT: ret
|
||||
; CHECKIFD-NEXT: .LBB3_3:
|
||||
; CHECKIFD-NEXT: fmv.d fa5, fa0
|
||||
; CHECKIFD-NEXT: feq.d a0, fa1, fa1
|
||||
; CHECKIFD-NEXT: bnez a0, .LBB3_2
|
||||
; CHECKIFD-NEXT: .LBB3_4:
|
||||
; CHECKIFD-NEXT: fmin.d fa0, fa1, fa5
|
||||
; CHECKIFD-NEXT: ret
|
||||
;
|
||||
; RV32IZFINXZDINX-LABEL: fmaximum_nnan_f64:
|
||||
; RV32IZFINXZDINX: # %bb.0:
|
||||
; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
|
||||
; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: feq.d a6, a0, a0
|
||||
; RV32IZFINXZDINX-NEXT: mv a4, a2
|
||||
; RV32IZFINXZDINX-NEXT: bnez a6, .LBB3_2
|
||||
; RV32IZFINXZDINX-NEXT: # %bb.1:
|
||||
; RV32IZFINXZDINX-NEXT: mv a4, a0
|
||||
; RV32IZFINXZDINX-NEXT: .LBB3_2:
|
||||
; RV32IZFINXZDINX-NEXT: feq.d a6, a2, a2
|
||||
; RV32IZFINXZDINX-NEXT: bnez a6, .LBB3_4
|
||||
; RV32IZFINXZDINX-NEXT: # %bb.3:
|
||||
; RV32IZFINXZDINX-NEXT: mv a0, a2
|
||||
; RV32IZFINXZDINX-NEXT: .LBB3_4:
|
||||
; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a4
|
||||
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
|
||||
; RV32IZFINXZDINX-NEXT: ret
|
||||
;
|
||||
; RV64IZFINXZDINX-LABEL: fmaximum_nnan_f64:
|
||||
; RV64IZFINXZDINX: # %bb.0:
|
||||
; RV64IZFINXZDINX-NEXT: feq.d a3, a0, a0
|
||||
; RV64IZFINXZDINX-NEXT: mv a2, a1
|
||||
; RV64IZFINXZDINX-NEXT: beqz a3, .LBB3_3
|
||||
; RV64IZFINXZDINX-NEXT: # %bb.1:
|
||||
; RV64IZFINXZDINX-NEXT: feq.d a3, a1, a1
|
||||
; RV64IZFINXZDINX-NEXT: beqz a3, .LBB3_4
|
||||
; RV64IZFINXZDINX-NEXT: .LBB3_2:
|
||||
; RV64IZFINXZDINX-NEXT: fmin.d a0, a0, a2
|
||||
; RV64IZFINXZDINX-NEXT: ret
|
||||
; RV64IZFINXZDINX-NEXT: .LBB3_3:
|
||||
; RV64IZFINXZDINX-NEXT: mv a2, a0
|
||||
; RV64IZFINXZDINX-NEXT: feq.d a3, a1, a1
|
||||
; RV64IZFINXZDINX-NEXT: bnez a3, .LBB3_2
|
||||
; RV64IZFINXZDINX-NEXT: .LBB3_4:
|
||||
; RV64IZFINXZDINX-NEXT: fmin.d a0, a1, a2
|
||||
; RV64IZFINXZDINX-NEXT: ret
|
||||
%1 = call double @llvm.minimum.f64(double %a, double %b)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
define double @fminimum_nnan_op_f64(double %a, double %b) nounwind {
|
||||
; CHECKIFD-LABEL: fminimum_nnan_op_f64:
|
||||
; CHECKIFD: # %bb.0:
|
||||
; CHECKIFD-NEXT: feq.d a0, fa1, fa1
|
||||
; CHECKIFD-NEXT: bnez a0, .LBB4_2
|
||||
; CHECKIFD-NEXT: # %bb.1:
|
||||
; CHECKIFD-NEXT: fmin.d fa0, fa1, fa1
|
||||
; CHECKIFD-NEXT: ret
|
||||
; CHECKIFD-NEXT: .LBB4_2:
|
||||
; CHECKIFD-NEXT: fadd.d fa5, fa0, fa0
|
||||
; CHECKIFD-NEXT: fmin.d fa0, fa5, fa1
|
||||
; CHECKIFD-NEXT: ret
|
||||
;
|
||||
; RV32IZFINXZDINX-LABEL: fminimum_nnan_op_f64:
|
||||
; RV32IZFINXZDINX: # %bb.0:
|
||||
; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
|
||||
; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: feq.d a0, a2, a2
|
||||
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: bnez a0, .LBB4_2
|
||||
; RV32IZFINXZDINX-NEXT: # %bb.1:
|
||||
; RV32IZFINXZDINX-NEXT: mv a0, a2
|
||||
; RV32IZFINXZDINX-NEXT: j .LBB4_3
|
||||
; RV32IZFINXZDINX-NEXT: .LBB4_2:
|
||||
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: fadd.d a0, a0, a0
|
||||
; RV32IZFINXZDINX-NEXT: .LBB4_3:
|
||||
; RV32IZFINXZDINX-NEXT: fmin.d a0, a0, a2
|
||||
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
|
||||
; RV32IZFINXZDINX-NEXT: ret
|
||||
;
|
||||
; RV64IZFINXZDINX-LABEL: fminimum_nnan_op_f64:
|
||||
; RV64IZFINXZDINX: # %bb.0:
|
||||
; RV64IZFINXZDINX-NEXT: feq.d a2, a1, a1
|
||||
; RV64IZFINXZDINX-NEXT: bnez a2, .LBB4_2
|
||||
; RV64IZFINXZDINX-NEXT: # %bb.1:
|
||||
; RV64IZFINXZDINX-NEXT: fmin.d a0, a1, a1
|
||||
; RV64IZFINXZDINX-NEXT: ret
|
||||
; RV64IZFINXZDINX-NEXT: .LBB4_2:
|
||||
; RV64IZFINXZDINX-NEXT: fadd.d a0, a0, a0
|
||||
; RV64IZFINXZDINX-NEXT: fmin.d a0, a0, a1
|
||||
; RV64IZFINXZDINX-NEXT: ret
|
||||
%c = fadd nnan double %a, %a
|
||||
%1 = call double @llvm.minimum.f64(double %c, double %b)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
define double @fmaximum_nnan_op_f64(double %a, double %b) nounwind {
|
||||
; CHECKIFD-LABEL: fmaximum_nnan_op_f64:
|
||||
; CHECKIFD: # %bb.0:
|
||||
; CHECKIFD-NEXT: fadd.d fa5, fa0, fa1
|
||||
; CHECKIFD-NEXT: fsub.d fa4, fa0, fa1
|
||||
; CHECKIFD-NEXT: fmax.d fa0, fa5, fa4
|
||||
; CHECKIFD-NEXT: ret
|
||||
;
|
||||
; RV32IZFINXZDINX-LABEL: fmaximum_nnan_op_f64:
|
||||
; RV32IZFINXZDINX: # %bb.0:
|
||||
; RV32IZFINXZDINX-NEXT: addi sp, sp, -16
|
||||
; RV32IZFINXZDINX-NEXT: sw a2, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a3, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a2, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a3, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: fadd.d a4, a0, a2
|
||||
; RV32IZFINXZDINX-NEXT: fsub.d a0, a0, a2
|
||||
; RV32IZFINXZDINX-NEXT: fmax.d a0, a4, a0
|
||||
; RV32IZFINXZDINX-NEXT: sw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: sw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a0, 8(sp)
|
||||
; RV32IZFINXZDINX-NEXT: lw a1, 12(sp)
|
||||
; RV32IZFINXZDINX-NEXT: addi sp, sp, 16
|
||||
; RV32IZFINXZDINX-NEXT: ret
|
||||
;
|
||||
; RV64IZFINXZDINX-LABEL: fmaximum_nnan_op_f64:
|
||||
; RV64IZFINXZDINX: # %bb.0:
|
||||
; RV64IZFINXZDINX-NEXT: fadd.d a2, a0, a1
|
||||
; RV64IZFINXZDINX-NEXT: fsub.d a0, a0, a1
|
||||
; RV64IZFINXZDINX-NEXT: fmax.d a0, a2, a0
|
||||
; RV64IZFINXZDINX-NEXT: ret
|
||||
%c = fadd nnan double %a, %b
|
||||
%d = fsub nnan double %a, %b
|
||||
%1 = call double @llvm.maximum.f64(double %c, double %d)
|
||||
ret double %1
|
||||
}
|
||||
|
||||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
||||
; RV32IFD: {{.*}}
|
||||
; RV64IFD: {{.*}}
|
||||
|
@ -181,3 +181,162 @@ define float @fmaximum_f32(float %a, float %b) nounwind {
|
||||
%1 = call float @llvm.maximum.f32(float %a, float %b)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define float @fminimum_nnan_f32(float %a, float %b) nounwind {
|
||||
; RV32IF-LABEL: fminimum_nnan_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmin.s fa0, fa0, fa1
|
||||
; RV32IF-NEXT: ret
|
||||
;
|
||||
; RV32IZFINX-LABEL: fminimum_nnan_f32:
|
||||
; RV32IZFINX: # %bb.0:
|
||||
; RV32IZFINX-NEXT: fmin.s a0, a0, a1
|
||||
; RV32IZFINX-NEXT: ret
|
||||
;
|
||||
; RV64IF-LABEL: fminimum_nnan_f32:
|
||||
; RV64IF: # %bb.0:
|
||||
; RV64IF-NEXT: fmin.s fa0, fa0, fa1
|
||||
; RV64IF-NEXT: ret
|
||||
;
|
||||
; RV64IZFINX-LABEL: fminimum_nnan_f32:
|
||||
; RV64IZFINX: # %bb.0:
|
||||
; RV64IZFINX-NEXT: fmin.s a0, a0, a1
|
||||
; RV64IZFINX-NEXT: ret
|
||||
%1 = call nnan float @llvm.minimum.f32(float %a, float %b)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define float @fmaximum_nnan_f32(float %a, float %b) nounwind {
|
||||
; RV32IF-LABEL: fmaximum_nnan_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmax.s fa0, fa0, fa1
|
||||
; RV32IF-NEXT: ret
|
||||
;
|
||||
; RV32IZFINX-LABEL: fmaximum_nnan_f32:
|
||||
; RV32IZFINX: # %bb.0:
|
||||
; RV32IZFINX-NEXT: fmax.s a0, a0, a1
|
||||
; RV32IZFINX-NEXT: ret
|
||||
;
|
||||
; RV64IF-LABEL: fmaximum_nnan_f32:
|
||||
; RV64IF: # %bb.0:
|
||||
; RV64IF-NEXT: fmax.s fa0, fa0, fa1
|
||||
; RV64IF-NEXT: ret
|
||||
;
|
||||
; RV64IZFINX-LABEL: fmaximum_nnan_f32:
|
||||
; RV64IZFINX: # %bb.0:
|
||||
; RV64IZFINX-NEXT: fmax.s a0, a0, a1
|
||||
; RV64IZFINX-NEXT: ret
|
||||
%1 = call nnan float @llvm.maximum.f32(float %a, float %b)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define float @fminimum_nnan_attr_f32(float %a, float %b) nounwind "no-nans-fp-math"="true" {
|
||||
; RV32IF-LABEL: fminimum_nnan_attr_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fmin.s fa0, fa0, fa1
|
||||
; RV32IF-NEXT: ret
|
||||
;
|
||||
; RV32IZFINX-LABEL: fminimum_nnan_attr_f32:
|
||||
; RV32IZFINX: # %bb.0:
|
||||
; RV32IZFINX-NEXT: fmin.s a0, a0, a1
|
||||
; RV32IZFINX-NEXT: ret
|
||||
;
|
||||
; RV64IF-LABEL: fminimum_nnan_attr_f32:
|
||||
; RV64IF: # %bb.0:
|
||||
; RV64IF-NEXT: fmin.s fa0, fa0, fa1
|
||||
; RV64IF-NEXT: ret
|
||||
;
|
||||
; RV64IZFINX-LABEL: fminimum_nnan_attr_f32:
|
||||
; RV64IZFINX: # %bb.0:
|
||||
; RV64IZFINX-NEXT: fmin.s a0, a0, a1
|
||||
; RV64IZFINX-NEXT: ret
|
||||
%1 = call float @llvm.minimum.f32(float %a, float %b)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define float @fminimum_nnan_op_f32(float %a, float %b) nounwind {
|
||||
; RV32IF-LABEL: fminimum_nnan_op_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: feq.s a0, fa0, fa0
|
||||
; RV32IF-NEXT: bnez a0, .LBB5_2
|
||||
; RV32IF-NEXT: # %bb.1:
|
||||
; RV32IF-NEXT: fmin.s fa0, fa0, fa0
|
||||
; RV32IF-NEXT: ret
|
||||
; RV32IF-NEXT: .LBB5_2:
|
||||
; RV32IF-NEXT: fadd.s fa5, fa0, fa0
|
||||
; RV32IF-NEXT: fmin.s fa0, fa0, fa5
|
||||
; RV32IF-NEXT: ret
|
||||
;
|
||||
; RV32IZFINX-LABEL: fminimum_nnan_op_f32:
|
||||
; RV32IZFINX: # %bb.0:
|
||||
; RV32IZFINX-NEXT: feq.s a1, a0, a0
|
||||
; RV32IZFINX-NEXT: bnez a1, .LBB5_2
|
||||
; RV32IZFINX-NEXT: # %bb.1:
|
||||
; RV32IZFINX-NEXT: fmin.s a0, a0, a0
|
||||
; RV32IZFINX-NEXT: ret
|
||||
; RV32IZFINX-NEXT: .LBB5_2:
|
||||
; RV32IZFINX-NEXT: fadd.s a1, a0, a0
|
||||
; RV32IZFINX-NEXT: fmin.s a0, a0, a1
|
||||
; RV32IZFINX-NEXT: ret
|
||||
;
|
||||
; RV64IF-LABEL: fminimum_nnan_op_f32:
|
||||
; RV64IF: # %bb.0:
|
||||
; RV64IF-NEXT: feq.s a0, fa0, fa0
|
||||
; RV64IF-NEXT: bnez a0, .LBB5_2
|
||||
; RV64IF-NEXT: # %bb.1:
|
||||
; RV64IF-NEXT: fmin.s fa0, fa0, fa0
|
||||
; RV64IF-NEXT: ret
|
||||
; RV64IF-NEXT: .LBB5_2:
|
||||
; RV64IF-NEXT: fadd.s fa5, fa0, fa0
|
||||
; RV64IF-NEXT: fmin.s fa0, fa0, fa5
|
||||
; RV64IF-NEXT: ret
|
||||
;
|
||||
; RV64IZFINX-LABEL: fminimum_nnan_op_f32:
|
||||
; RV64IZFINX: # %bb.0:
|
||||
; RV64IZFINX-NEXT: feq.s a1, a0, a0
|
||||
; RV64IZFINX-NEXT: bnez a1, .LBB5_2
|
||||
; RV64IZFINX-NEXT: # %bb.1:
|
||||
; RV64IZFINX-NEXT: fmin.s a0, a0, a0
|
||||
; RV64IZFINX-NEXT: ret
|
||||
; RV64IZFINX-NEXT: .LBB5_2:
|
||||
; RV64IZFINX-NEXT: fadd.s a1, a0, a0
|
||||
; RV64IZFINX-NEXT: fmin.s a0, a0, a1
|
||||
; RV64IZFINX-NEXT: ret
|
||||
%c = fadd nnan float %a, %a
|
||||
%1 = call float @llvm.minimum.f32(float %a, float %c)
|
||||
ret float %1
|
||||
}
|
||||
|
||||
define float @fmaximum_nnan_op_f32(float %a, float %b) nounwind {
|
||||
; RV32IF-LABEL: fmaximum_nnan_op_f32:
|
||||
; RV32IF: # %bb.0:
|
||||
; RV32IF-NEXT: fadd.s fa5, fa0, fa1
|
||||
; RV32IF-NEXT: fsub.s fa4, fa0, fa1
|
||||
; RV32IF-NEXT: fmax.s fa0, fa5, fa4
|
||||
; RV32IF-NEXT: ret
|
||||
;
|
||||
; RV32IZFINX-LABEL: fmaximum_nnan_op_f32:
|
||||
; RV32IZFINX: # %bb.0:
|
||||
; RV32IZFINX-NEXT: fadd.s a2, a0, a1
|
||||
; RV32IZFINX-NEXT: fsub.s a0, a0, a1
|
||||
; RV32IZFINX-NEXT: fmax.s a0, a2, a0
|
||||
; RV32IZFINX-NEXT: ret
|
||||
;
|
||||
; RV64IF-LABEL: fmaximum_nnan_op_f32:
|
||||
; RV64IF: # %bb.0:
|
||||
; RV64IF-NEXT: fadd.s fa5, fa0, fa1
|
||||
; RV64IF-NEXT: fsub.s fa4, fa0, fa1
|
||||
; RV64IF-NEXT: fmax.s fa0, fa5, fa4
|
||||
; RV64IF-NEXT: ret
|
||||
;
|
||||
; RV64IZFINX-LABEL: fmaximum_nnan_op_f32:
|
||||
; RV64IZFINX: # %bb.0:
|
||||
; RV64IZFINX-NEXT: fadd.s a2, a0, a1
|
||||
; RV64IZFINX-NEXT: fsub.s a0, a0, a1
|
||||
; RV64IZFINX-NEXT: fmax.s a0, a2, a0
|
||||
; RV64IZFINX-NEXT: ret
|
||||
%c = fadd nnan float %a, %b
|
||||
%d = fsub nnan float %a, %b
|
||||
%1 = call float @llvm.maximum.f32(float %c, float %d)
|
||||
ret float %1
|
||||
}
|
||||
|
@ -99,3 +99,94 @@ define half @fmaximum_f16(half %a, half %b) nounwind {
|
||||
%1 = call half @llvm.maximum.f16(half %a, half %b)
|
||||
ret half %1
|
||||
}
|
||||
|
||||
define half @fminimum_nnan_f16(half %a, half %b) nounwind {
|
||||
; CHECKIZFH-LABEL: fminimum_nnan_f16:
|
||||
; CHECKIZFH: # %bb.0:
|
||||
; CHECKIZFH-NEXT: fmin.h fa0, fa0, fa1
|
||||
; CHECKIZFH-NEXT: ret
|
||||
;
|
||||
; CHECKIZHINX-LABEL: fminimum_nnan_f16:
|
||||
; CHECKIZHINX: # %bb.0:
|
||||
; CHECKIZHINX-NEXT: fmin.h a0, a0, a1
|
||||
; CHECKIZHINX-NEXT: ret
|
||||
%1 = call nnan half @llvm.minimum.f16(half %a, half %b)
|
||||
ret half %1
|
||||
}
|
||||
|
||||
define half @fmaximum_nnan_f16(half %a, half %b) nounwind {
|
||||
; CHECKIZFH-LABEL: fmaximum_nnan_f16:
|
||||
; CHECKIZFH: # %bb.0:
|
||||
; CHECKIZFH-NEXT: fmax.h fa0, fa0, fa1
|
||||
; CHECKIZFH-NEXT: ret
|
||||
;
|
||||
; CHECKIZHINX-LABEL: fmaximum_nnan_f16:
|
||||
; CHECKIZHINX: # %bb.0:
|
||||
; CHECKIZHINX-NEXT: fmax.h a0, a0, a1
|
||||
; CHECKIZHINX-NEXT: ret
|
||||
%1 = call nnan half @llvm.maximum.f16(half %a, half %b)
|
||||
ret half %1
|
||||
}
|
||||
|
||||
define half @fminimum_nnan_attr_f16(half %a, half %b) nounwind "no-nans-fp-math"="true" {
|
||||
; CHECKIZFH-LABEL: fminimum_nnan_attr_f16:
|
||||
; CHECKIZFH: # %bb.0:
|
||||
; CHECKIZFH-NEXT: fmin.h fa0, fa0, fa1
|
||||
; CHECKIZFH-NEXT: ret
|
||||
;
|
||||
; CHECKIZHINX-LABEL: fminimum_nnan_attr_f16:
|
||||
; CHECKIZHINX: # %bb.0:
|
||||
; CHECKIZHINX-NEXT: fmin.h a0, a0, a1
|
||||
; CHECKIZHINX-NEXT: ret
|
||||
%1 = call half @llvm.minimum.f16(half %a, half %b)
|
||||
ret half %1
|
||||
}
|
||||
|
||||
define half @fminimum_nnan_op_f16(half %a, half %b) nounwind {
|
||||
; CHECKIZFH-LABEL: fminimum_nnan_op_f16:
|
||||
; CHECKIZFH: # %bb.0:
|
||||
; CHECKIZFH-NEXT: feq.h a0, fa0, fa0
|
||||
; CHECKIZFH-NEXT: bnez a0, .LBB5_2
|
||||
; CHECKIZFH-NEXT: # %bb.1:
|
||||
; CHECKIZFH-NEXT: fmin.h fa0, fa0, fa0
|
||||
; CHECKIZFH-NEXT: ret
|
||||
; CHECKIZFH-NEXT: .LBB5_2:
|
||||
; CHECKIZFH-NEXT: fadd.h fa5, fa0, fa0
|
||||
; CHECKIZFH-NEXT: fmin.h fa0, fa0, fa5
|
||||
; CHECKIZFH-NEXT: ret
|
||||
;
|
||||
; CHECKIZHINX-LABEL: fminimum_nnan_op_f16:
|
||||
; CHECKIZHINX: # %bb.0:
|
||||
; CHECKIZHINX-NEXT: feq.h a1, a0, a0
|
||||
; CHECKIZHINX-NEXT: bnez a1, .LBB5_2
|
||||
; CHECKIZHINX-NEXT: # %bb.1:
|
||||
; CHECKIZHINX-NEXT: fmin.h a0, a0, a0
|
||||
; CHECKIZHINX-NEXT: ret
|
||||
; CHECKIZHINX-NEXT: .LBB5_2:
|
||||
; CHECKIZHINX-NEXT: fadd.h a1, a0, a0
|
||||
; CHECKIZHINX-NEXT: fmin.h a0, a0, a1
|
||||
; CHECKIZHINX-NEXT: ret
|
||||
%c = fadd nnan half %a, %a
|
||||
%1 = call half @llvm.minimum.f16(half %a, half %c)
|
||||
ret half %1
|
||||
}
|
||||
|
||||
define half @fmaximum_nnan_op_f16(half %a, half %b) nounwind {
|
||||
; CHECKIZFH-LABEL: fmaximum_nnan_op_f16:
|
||||
; CHECKIZFH: # %bb.0:
|
||||
; CHECKIZFH-NEXT: fadd.h fa5, fa0, fa1
|
||||
; CHECKIZFH-NEXT: fsub.h fa4, fa0, fa1
|
||||
; CHECKIZFH-NEXT: fmax.h fa0, fa5, fa4
|
||||
; CHECKIZFH-NEXT: ret
|
||||
;
|
||||
; CHECKIZHINX-LABEL: fmaximum_nnan_op_f16:
|
||||
; CHECKIZHINX: # %bb.0:
|
||||
; CHECKIZHINX-NEXT: fadd.h a2, a0, a1
|
||||
; CHECKIZHINX-NEXT: fsub.h a0, a0, a1
|
||||
; CHECKIZHINX-NEXT: fmax.h a0, a2, a0
|
||||
; CHECKIZHINX-NEXT: ret
|
||||
%c = fadd nnan half %a, %b
|
||||
%d = fsub nnan half %a, %b
|
||||
%1 = call half @llvm.maximum.f16(half %c, half %d)
|
||||
ret half %1
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user