@@ -860,8 +860,13 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM,
860
860
if (Subtarget->hasMinimum3Maximum3F32())
861
861
setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f32, Legal);
862
862
863
- if (Subtarget->hasMinimum3Maximum3PKF16())
863
+ if (Subtarget->hasMinimum3Maximum3PKF16()) {
864
864
setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::v2f16, Legal);
865
+
866
+ // If only the vector form is available, we need to widen to a vector.
867
+ if (!Subtarget->hasMinimum3Maximum3F16())
868
+ setOperationAction({ISD::FMAXIMUM, ISD::FMINIMUM}, MVT::f16, Custom);
869
+ }
865
870
}
866
871
867
872
setOperationAction(ISD::INTRINSIC_WO_CHAIN,
@@ -5842,6 +5847,9 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
5842
5847
case ISD::FMINNUM:
5843
5848
case ISD::FMAXNUM:
5844
5849
return lowerFMINNUM_FMAXNUM(Op, DAG);
5850
+ case ISD::FMINIMUM:
5851
+ case ISD::FMAXIMUM:
5852
+ return lowerFMINIMUM_FMAXIMUM(Op, DAG);
5845
5853
case ISD::FLDEXP:
5846
5854
case ISD::STRICT_FLDEXP:
5847
5855
return lowerFLDEXP(Op, DAG);
@@ -5863,8 +5871,6 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
5863
5871
case ISD::FMUL:
5864
5872
case ISD::FMINNUM_IEEE:
5865
5873
case ISD::FMAXNUM_IEEE:
5866
- case ISD::FMINIMUM:
5867
- case ISD::FMAXIMUM:
5868
5874
case ISD::UADDSAT:
5869
5875
case ISD::USUBSAT:
5870
5876
case ISD::SADDSAT:
@@ -6718,6 +6724,34 @@ SDValue SITargetLowering::lowerFMINNUM_FMAXNUM(SDValue Op,
6718
6724
return Op;
6719
6725
}
6720
6726
6727
+ SDValue SITargetLowering::lowerFMINIMUM_FMAXIMUM(SDValue Op,
6728
+ SelectionDAG &DAG) const {
6729
+ EVT VT = Op.getValueType();
6730
+ if (VT.isVector())
6731
+ return splitBinaryVectorOp(Op, DAG);
6732
+
6733
+ assert(!Subtarget->hasIEEEMinMax() && !Subtarget->hasMinimum3Maximum3F16() &&
6734
+ Subtarget->hasMinimum3Maximum3PKF16() && VT == MVT::f16 &&
6735
+ "should not need to widen f16 minimum/maximum to v2f16");
6736
+
6737
+ // Widen f16 operation to v2f16
6738
+
6739
+ // fminimum f16:x, f16:y ->
6740
+ // extract_vector_elt (fminimum (v2f16 (scalar_to_vector x))
6741
+ // (v2f16 (scalar_to_vector y))), 0
6742
+ SDLoc SL(Op);
6743
+ SDValue WideSrc0 =
6744
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, SL, MVT::v2f16, Op.getOperand(0));
6745
+ SDValue WideSrc1 =
6746
+ DAG.getNode(ISD::SCALAR_TO_VECTOR, SL, MVT::v2f16, Op.getOperand(1));
6747
+
6748
+ SDValue Widened =
6749
+ DAG.getNode(Op.getOpcode(), SL, MVT::v2f16, WideSrc0, WideSrc1);
6750
+
6751
+ return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, SL, MVT::f16, Widened,
6752
+ DAG.getConstant(0, SL, MVT::i32));
6753
+ }
6754
+
6721
6755
SDValue SITargetLowering::lowerFLDEXP(SDValue Op, SelectionDAG &DAG) const {
6722
6756
bool IsStrict = Op.getOpcode() == ISD::STRICT_FLDEXP;
6723
6757
EVT VT = Op.getValueType();
0 commit comments