diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp --- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp @@ -4670,12 +4670,18 @@ // 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; diff --git a/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll b/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll --- a/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll +++ b/llvm/test/CodeGen/RISCV/double-maximum-minimum.ll @@ -159,6 +159,209 @@ %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: {{.*}} diff --git a/llvm/test/CodeGen/RISCV/float-maximum-minimum.ll b/llvm/test/CodeGen/RISCV/float-maximum-minimum.ll --- a/llvm/test/CodeGen/RISCV/float-maximum-minimum.ll +++ b/llvm/test/CodeGen/RISCV/float-maximum-minimum.ll @@ -181,3 +181,162 @@ %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 +} diff --git a/llvm/test/CodeGen/RISCV/half-maximum-minimum.ll b/llvm/test/CodeGen/RISCV/half-maximum-minimum.ll --- a/llvm/test/CodeGen/RISCV/half-maximum-minimum.ll +++ b/llvm/test/CodeGen/RISCV/half-maximum-minimum.ll @@ -99,3 +99,94 @@ %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 +}