================
@@ -28825,6 +28817,48 @@ static SDValue performCTPOPCombine(SDNode *N,
return DAG.getNegative(NegPopCount, DL, VT);
}
+static unsigned getReductionForOpcode(unsigned Op) {
+ switch (Op) {
+ case ISD::SMIN:
+ return ISD::VECREDUCE_SMIN;
+ case ISD::SMAX:
+ return ISD::VECREDUCE_SMAX;
+ case ISD::UMIN:
+ return ISD::VECREDUCE_UMIN;
+ case ISD::UMAX:
+ return ISD::VECREDUCE_UMAX;
+ default:
+ llvm_unreachable("unimplemented mapping");
+ }
+}
+
+static SDValue performMINMAXCombine(SDNode *N, SelectionDAG &DAG,
+ const AArch64TargetLowering &TLI) {
+ using namespace llvm::SDPatternMatch;
+ if (SDValue V = trySQDMULHCombine(N, DAG))
+ return V;
+
+ unsigned ReductionOpcode = getReductionForOpcode(N->getOpcode());
+ if (!TLI.isOperationLegalOrCustom(ReductionOpcode, MVT::v2i64))
+ return SDValue();
+
+ // Fold `min/max(vec[0], vec[1])` to `vecreduce_min/max(vec)` for v2i64.
+
+ APInt Idx;
+ SDValue Vec;
+ if (!sd_match(N->getOperand(0),
+ m_OneUse(m_ExtractElt(m_SpecificVT(MVT::v2i64, m_Value(Vec)),
+ m_ConstInt(Idx)))))
+ return SDValue();
+
+ if (!sd_match(
+ N->getOperand(1),
+ m_OneUse(m_ExtractElt(m_Specific(Vec), m_SpecificInt(1 - Idx)))))
+ return SDValue();
+
+ return DAG.getNode(ReductionOpcode, SDLoc(N), MVT::i64, Vec);
----------------
paulwalker-arm wrote:
```suggestion
return DAG.getNode(ReductionOpcode, SDLoc(N), N->getValueType(0), Vec);
```
This is just me being cautious because the result of an extract_elt can be
bigger than its operand's element type. While in this context that makes the
reduction results undefined, the DAG is still strictly speaking correct. Given
reductions have the same "non-matching types" property, we may as well follow
the same path.
https://github.com/llvm/llvm-project/pull/181162
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits