getValue(I.getArgOperand(0))));
return;
}
- case Intrinsic::minnum: {
- auto VT = getValue(I.getArgOperand(0)).getValueType();
- unsigned Opc =
- I.hasNoNaNs() && TLI.isOperationLegalOrCustom(ISD::FMINIMUM, VT)
- ? ISD::FMINIMUM
- : ISD::FMINNUM;
- setValue(&I, DAG.getNode(Opc, sdl, VT,
+ case Intrinsic::minnum:
+ setValue(&I, DAG.getNode(ISD::FMINNUM, sdl,
+ getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
getValue(I.getArgOperand(1))));
return;
- }
- case Intrinsic::maxnum: {
- auto VT = getValue(I.getArgOperand(0)).getValueType();
- unsigned Opc =
- I.hasNoNaNs() && TLI.isOperationLegalOrCustom(ISD::FMAXIMUM, VT)
- ? ISD::FMAXIMUM
- : ISD::FMAXNUM;
- setValue(&I, DAG.getNode(Opc, sdl, VT,
+ case Intrinsic::maxnum:
+ setValue(&I, DAG.getNode(ISD::FMAXNUM, sdl,
+ getValue(I.getArgOperand(0)).getValueType(),
getValue(I.getArgOperand(0)),
getValue(I.getArgOperand(1))));
return;
- }
case Intrinsic::minimum:
setValue(&I, DAG.getNode(ISD::FMINIMUM, sdl,
getValue(I.getArgOperand(0)).getValueType(),
return DAG.getNode(NewOp, dl, VT, Quiet0, Quiet1, Node->getFlags());
}
+ // If the target has FMINIMUM/FMAXIMUM but not FMINNUM/FMAXNUM use that
+ // instead if there are no NaNs.
+ if (Node->getFlags().hasNoNaNs()) {
+ unsigned IEEE2018Op =
+ Node->getOpcode() == ISD::FMINNUM ? ISD::FMINIMUM : ISD::FMAXIMUM;
+ if (isOperationLegalOrCustom(IEEE2018Op, VT)) {
+ return DAG.getNode(IEEE2018Op, dl, VT, Node->getOperand(0),
+ Node->getOperand(1), Node->getFlags());
+ }
+ }
+
return SDValue();
}
ret float %a
}
+; CHECK-LABEL: fminnum32_intrinsic:
+; CHECK: f32.min $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
+; CHECK-NEXT: return $pop0{{$}}
+declare float @llvm.minnum.f32(float, float)
+define float @fminnum32_intrinsic(float %x, float %y) {
+ %a = call nnan float @llvm.minnum.f32(float %x, float %y)
+ ret float %a
+}
+
; CHECK-LABEL: fmax32_intrinsic:
; CHECK: f32.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
; CHECK-NEXT: return $pop0{{$}}
ret float %a
}
+; CHECK-LABEL: fmaxnum32_intrinsic:
+; CHECK: f32.max $push0=, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
+; CHECK-NEXT: return $pop0{{$}}
+declare float @llvm.maxnum.f32(float, float)
+define float @fmaxnum32_intrinsic(float %x, float %y) {
+ %a = call nnan float @llvm.maxnum.f32(float %x, float %y)
+ ret float %a
+}
+
; CHECK-LABEL: fma32:
; CHECK: {{^}} f32.call $push[[LR:[0-9]+]]=, fmaf, $pop{{[0-9]+}}, $pop{{[0-9]+}}, $pop{{[0-9]+}}{{$}}
; CHECK-NEXT: return $pop[[LR]]{{$}}
ret <4 x float> %a
}
+; CHECK-LABEL: minnum_intrinsic_v4f32:
+; NO-SIMD128-NOT: f32x4
+; SIMD128-NEXT: .functype minnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
+; SIMD128-NEXT: f32x4.min $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x float> @llvm.minnum.v4f32(<4 x float>, <4 x float>)
+define <4 x float> @minnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
+ %a = call nnan <4 x float> @llvm.minnum.v4f32(<4 x float> %x, <4 x float> %y)
+ ret <4 x float> %a
+}
+
; CHECK-LABEL: max_intrinsic_v4f32:
; NO-SIMD128-NOT: f32x4
; SIMD128-NEXT: .functype max_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
ret <4 x float> %a
}
+; CHECK-LABEL: maxnum_intrinsic_v4f32:
+; NO-SIMD128-NOT: f32x4
+; SIMD128-NEXT: .functype maxnum_intrinsic_v4f32 (v128, v128) -> (v128){{$}}
+; SIMD128-NEXT: f32x4.max $push[[R:[0-9]+]]=, $0, $1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x float> @llvm.maxnum.v4f32(<4 x float>, <4 x float>)
+define <4 x float> @maxnum_intrinsic_v4f32(<4 x float> %x, <4 x float> %y) {
+ %a = call nnan <4 x float> @llvm.maxnum.v4f32(<4 x float> %x, <4 x float> %y)
+ ret <4 x float> %a
+}
+
; CHECK-LABEL: min_const_intrinsic_v4f32:
; NO-SIMD128-NOT: f32x4
; SIMD128-NEXT: .functype min_const_intrinsic_v4f32 () -> (v128){{$}}