@@ -13199,6 +13199,33 @@ SDValue SITargetLowering::performFPMed3ImmCombine(SelectionDAG &DAG,
13199
13199
return SDValue();
13200
13200
}
13201
13201
13202
+ /// \return true if the subtarget supports minimum3 and maximum3 with the given
13203
+ /// base min/max opcode \p Opc for type \p VT.
13204
+ static bool supportsMin3Max3(const GCNSubtarget &Subtarget, unsigned Opc,
13205
+ EVT VT) {
13206
+ switch (Opc) {
13207
+ case ISD::FMINNUM:
13208
+ case ISD::FMAXNUM:
13209
+ case ISD::FMINNUM_IEEE:
13210
+ case ISD::FMAXNUM_IEEE:
13211
+ case AMDGPUISD::FMIN_LEGACY:
13212
+ case AMDGPUISD::FMAX_LEGACY:
13213
+ return (VT == MVT::f32) || (VT == MVT::f16 && Subtarget.hasMin3Max3_16());
13214
+ case ISD::FMINIMUM:
13215
+ case ISD::FMAXIMUM:
13216
+ return (VT == MVT::f32 || VT == MVT::f16) && Subtarget.hasIEEEMinMax3();
13217
+ case ISD::SMAX:
13218
+ case ISD::SMIN:
13219
+ case ISD::UMAX:
13220
+ case ISD::UMIN:
13221
+ return (VT == MVT::i32) || (VT == MVT::i16 && Subtarget.hasMin3Max3_16());
13222
+ default:
13223
+ return false;
13224
+ }
13225
+
13226
+ llvm_unreachable("not a min/max opcode");
13227
+ }
13228
+
13202
13229
SDValue SITargetLowering::performMinMaxCombine(SDNode *N,
13203
13230
DAGCombinerInfo &DCI) const {
13204
13231
SelectionDAG &DAG = DCI.DAG;
@@ -13211,10 +13238,7 @@ SDValue SITargetLowering::performMinMaxCombine(SDNode *N,
13211
13238
// Only do this if the inner op has one use since this will just increases
13212
13239
// register pressure for no benefit.
13213
13240
13214
- if (Opc != AMDGPUISD::FMIN_LEGACY && Opc != AMDGPUISD::FMAX_LEGACY &&
13215
- !VT.isVector() &&
13216
- (VT == MVT::i32 || VT == MVT::f32 ||
13217
- ((VT == MVT::f16 || VT == MVT::i16) && Subtarget->hasMin3Max3_16()))) {
13241
+ if (supportsMin3Max3(*Subtarget, Opc, VT)) {
13218
13242
// max(max(a, b), c) -> max3(a, b, c)
13219
13243
// min(min(a, b), c) -> min3(a, b, c)
13220
13244
if (Op0.getOpcode() == Opc && Op0.hasOneUse()) {
0 commit comments