[llvm] [SelectionDAG] Fold constant min/max vector reductions (PR #209190)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 13 07:51:38 PDT 2026


================
@@ -7802,19 +7806,28 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode, const SDLoc &DL,
     if (Opcode == ISD::BITCAST)
       return SDValue();
 
-    // Constant fold VECREDUCE_ADD with a BUILD_VECTOR of integer constants.
-    if (Opcode == ISD::VECREDUCE_ADD && ISD::isBuildVectorOfConstantSDNodes(N1.getNode())) {
+    // Constant fold integer vector reductions with constant BUILD_VECTORs.
+    if ((Opcode == ISD::VECREDUCE_ADD || Opcode == ISD::VECREDUCE_SMAX ||
+         Opcode == ISD::VECREDUCE_SMIN || Opcode == ISD::VECREDUCE_UMAX ||
+         Opcode == ISD::VECREDUCE_UMIN) &&
+        ISD::isBuildVectorOfConstantSDNodes(N1.getNode())) {
       unsigned EltBits = N1.getValueType().getScalarSizeInBits();
-      APInt Acc = APInt::getZero(EltBits);
+      std::optional<APInt> Acc;
+      unsigned BaseOpcode = ISD::getVecReduceBaseOpcode(Opcode);
       for (SDValue Elt : N1->op_values()) {
         if (Elt.getOpcode() == ISD::POISON)
           return getPOISON(VT);
         if (Elt.isUndef() || cast<ConstantSDNode>(Elt)->isOpaque())
           return SDValue();
-        Acc += cast<ConstantSDNode>(Elt)->getAPIntValue().trunc(EltBits);
+        APInt Value = cast<ConstantSDNode>(Elt)->getAPIntValue().trunc(EltBits);
+        Acc = Acc ? FoldValue(BaseOpcode, *Acc, Value) : Value;
+        if (!Acc)
----------------
mygitljf wrote:

No. BaseOpcode is derived from the explicitly handled reduction opcodes, and FoldValue supports all of them. I'll replace this fallback with an assert.

https://github.com/llvm/llvm-project/pull/209190


More information about the llvm-commits mailing list