@@ -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,
@@ -5964,6 +5969,9 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
5964
5969
case ISD::FMINNUM:
5965
5970
case ISD::FMAXNUM:
5966
5971
return lowerFMINNUM_FMAXNUM(Op, DAG);
5972
+ case ISD::FMINIMUM:
5973
+ case ISD::FMAXIMUM:
5974
+ return lowerFMINIMUM_FMAXIMUM(Op, DAG);
5967
5975
case ISD::FLDEXP:
5968
5976
case ISD::STRICT_FLDEXP:
5969
5977
return lowerFLDEXP(Op, DAG);
@@ -5985,8 +5993,6 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
5985
5993
case ISD::FMUL:
5986
5994
case ISD::FMINNUM_IEEE:
5987
5995
case ISD::FMAXNUM_IEEE:
5988
- case ISD::FMINIMUM:
5989
- case ISD::FMAXIMUM:
5990
5996
case ISD::FMINIMUMNUM:
5991
5997
case ISD::FMAXIMUMNUM:
5992
5998
case ISD::UADDSAT:
@@ -6841,6 +6847,34 @@ SDValue SITargetLowering::lowerFMINNUM_FMAXNUM(SDValue Op,
6841
6847
return Op;
6842
6848
}
6843
6849
6850
+ SDValue SITargetLowering::lowerFMINIMUM_FMAXIMUM(SDValue Op,
6851
+ SelectionDAG &DAG) const {
6852
+ EVT VT = Op.getValueType();
6853
+ if (VT.isVector())
6854
+ return splitBinaryVectorOp(Op, DAG);
6855
+
6856
+ assert(!Subtarget->hasIEEEMinMax() && !Subtarget->hasMinimum3Maximum3F16() &&
6857
+ Subtarget->hasMinimum3Maximum3PKF16() && VT == MVT::f16 &&
6858
+ "should not need to widen f16 minimum/maximum to v2f16");
6859
+
6860
+ // Widen f16 operation to v2f16
6861
+
6862
+ // fminimum f16:x, f16:y ->
6863
+ // extract_vector_elt (fminimum (v2f16 (scalar_to_vector x))
6864
+ // (v2f16 (scalar_to_vector y))), 0
6865
+ SDLoc SL(Op);
6866
+ SDValue WideSrc0 =
6867
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, SL, MVT::v2f16, Op.getOperand(0));
6868
+ SDValue WideSrc1 =
6869
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, SL, MVT::v2f16, Op.getOperand(1));
6870
+
6871
+ SDValue Widened =
6872
+ DAG.getNode(Op.getOpcode(), SL, MVT::v2f16, WideSrc0, WideSrc1);
6873
+
6874
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::f16, Widened,
6875
+ DAG.getConstant(0, SL, MVT::i32));
6876
+ }
6877
+
6844
6878
SDValue SITargetLowering::lowerFLDEXP(SDValue Op, SelectionDAG &DAG) const {
6845
6879
bool IsStrict = Op.getOpcode() == ISD::STRICT_FLDEXP;
6846
6880
EVT VT = Op.getValueType();
0 commit comments