@@ -869,8 +869,13 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM,
869
869
if (Subtarget->hasMinimum3Maximum3F32())
870
870
setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f32, Legal);
871
871
872
- if (Subtarget->hasMinimum3Maximum3PKF16())
872
+ if (Subtarget->hasMinimum3Maximum3PKF16()) {
873
873
setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::v2f16, Legal);
874
+
875
+ // If only the vector form is available, we need to widen to a vector.
876
+ if (!Subtarget->hasMinimum3Maximum3F16())
877
+ setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f16, Custom);
878
+ }
874
879
}
875
880
876
881
setOperationAction(ISD::INTRINSIC_WO_CHAIN,
@@ -5963,6 +5968,9 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
5963
5968
case ISD::FMINNUM:
5964
5969
case ISD::FMAXNUM:
5965
5970
return lowerFMINNUM_FMAXNUM(Op, DAG);
5971
+ case ISD::FMINIMUM:
5972
+ case ISD::FMAXIMUM:
5973
+ return lowerFMINIMUM_FMAXIMUM(Op, DAG);
5966
5974
case ISD::FLDEXP:
5967
5975
case ISD::STRICT_FLDEXP:
5968
5976
return lowerFLDEXP(Op, DAG);
@@ -5984,8 +5992,6 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
5984
5992
case ISD::FMUL:
5985
5993
case ISD::FMINNUM_IEEE:
5986
5994
case ISD::FMAXNUM_IEEE:
5987
- case ISD::FMINIMUM:
5988
- case ISD::FMAXIMUM:
5989
5995
case ISD::FMINIMUMNUM:
5990
5996
case ISD::FMAXIMUMNUM:
5991
5997
case ISD::UADDSAT:
@@ -6840,6 +6846,34 @@ SDValue SITargetLowering::lowerFMINNUM_FMAXNUM(SDValue Op,
6840
6846
return Op;
6841
6847
}
6842
6848
6849
+ SDValue SITargetLowering::lowerFMINIMUM_FMAXIMUM(SDValue Op,
6850
+ SelectionDAG &DAG) const {
6851
+ EVT VT = Op.getValueType();
6852
+ if (VT.isVector())
6853
+ return splitBinaryVectorOp(Op, DAG);
6854
+
6855
+ assert(!Subtarget->hasIEEEMinMax() && !Subtarget->hasMinimum3Maximum3F16() &&
6856
+ Subtarget->hasMinimum3Maximum3PKF16() && VT == MVT::f16 &&
6857
+ "should not need to widen f16 minimum/maximum to v2f16");
6858
+
6859
+ // Widen f16 operation to v2f16
6860
+
6861
+ // fminimum f16:x, f16:y ->
6862
+ // extract_vector_elt (fminimum (v2f16 (scalar_to_vector x))
6863
+ // (v2f16 (scalar_to_vector y))), 0
6864
+ SDLoc SL(Op);
6865
+ SDValue WideSrc0 =
6866
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, SL, MVT::v2f16, Op.getOperand(0));
6867
+ SDValue WideSrc1 =
6868
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, SL, MVT::v2f16, Op.getOperand(1));
6869
+
6870
+ SDValue Widened =
6871
+ DAG.getNode(Op.getOpcode(), SL, MVT::v2f16, WideSrc0, WideSrc1);
6872
+
6873
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::f16, Widened,
6874
+ DAG.getConstant(0, SL, MVT::i32));
6875
+ }
6876
+
6843
6877
SDValue SITargetLowering::lowerFLDEXP(SDValue Op, SelectionDAG &DAG) const {
6844
6878
bool IsStrict = Op.getOpcode() == ISD::STRICT_FLDEXP;
6845
6879
EVT VT = Op.getValueType();
0 commit comments