@@ -11113,6 +11113,31 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
11113
11113
}
11114
11114
}
11115
11115
11116
+ /// Given an integer binary operator, return the generic ISD::VECREDUCE_OP
11117
+ /// which corresponds to it.
11118
+ static unsigned getVecReduceOpcode(unsigned Opc) {
11119
+ switch (Opc) {
11120
+ default:
11121
+ llvm_unreachable("Unhandled binary to transfrom reduction");
11122
+ case ISD::ADD:
11123
+ return ISD::VECREDUCE_ADD;
11124
+ case ISD::UMAX:
11125
+ return ISD::VECREDUCE_UMAX;
11126
+ case ISD::SMAX:
11127
+ return ISD::VECREDUCE_SMAX;
11128
+ case ISD::UMIN:
11129
+ return ISD::VECREDUCE_UMIN;
11130
+ case ISD::SMIN:
11131
+ return ISD::VECREDUCE_SMIN;
11132
+ case ISD::AND:
11133
+ return ISD::VECREDUCE_AND;
11134
+ case ISD::OR:
11135
+ return ISD::VECREDUCE_OR;
11136
+ case ISD::XOR:
11137
+ return ISD::VECREDUCE_XOR;
11138
+ }
11139
+ }
11140
+
11116
11141
/// Perform two related transforms whose purpose is to incrementally recognize
11117
11142
/// an explode_vector followed by scalar reduction as a vector reduction node.
11118
11143
/// This exists to recover from a deficiency in SLP which can't handle
@@ -11136,8 +11161,15 @@ combineBinOpOfExtractToReduceTree(SDNode *N, SelectionDAG &DAG,
11136
11161
11137
11162
const SDLoc DL(N);
11138
11163
const EVT VT = N->getValueType(0);
11139
- [[maybe_unused]] const unsigned Opc = N->getOpcode();
11140
- assert(Opc == ISD::ADD && "extend this to other reduction types");
11164
+
11165
+ // TODO: Handle floating point here.
11166
+ if (!VT.isInteger())
11167
+ return SDValue();
11168
+
11169
+ const unsigned Opc = N->getOpcode();
11170
+ const unsigned ReduceOpc = getVecReduceOpcode(Opc);
11171
+ assert(Opc == ISD::getVecReduceBaseOpcode(ReduceOpc) &&
11172
+ "Inconsistent mappings");
11141
11173
const SDValue LHS = N->getOperand(0);
11142
11174
const SDValue RHS = N->getOperand(1);
11143
11175
@@ -11167,13 +11199,13 @@ combineBinOpOfExtractToReduceTree(SDNode *N, SelectionDAG &DAG,
11167
11199
EVT ReduceVT = EVT::getVectorVT(*DAG.getContext(), VT, 2);
11168
11200
SDValue Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ReduceVT, SrcVec,
11169
11201
DAG.getVectorIdxConstant(0, DL));
11170
- return DAG.getNode(ISD::VECREDUCE_ADD , DL, VT, Vec);
11202
+ return DAG.getNode(ReduceOpc , DL, VT, Vec);
11171
11203
}
11172
11204
11173
11205
// Match (binop (reduce (extract_subvector V, 0),
11174
11206
// (extract_vector_elt V, sizeof(SubVec))))
11175
11207
// into a reduction of one more element from the original vector V.
11176
- if (LHS.getOpcode() != ISD::VECREDUCE_ADD )
11208
+ if (LHS.getOpcode() != ReduceOpc )
11177
11209
return SDValue();
11178
11210
11179
11211
SDValue ReduceVec = LHS.getOperand(0);
@@ -11189,7 +11221,7 @@ combineBinOpOfExtractToReduceTree(SDNode *N, SelectionDAG &DAG,
11189
11221
EVT ReduceVT = EVT::getVectorVT(*DAG.getContext(), VT, Idx + 1);
11190
11222
SDValue Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ReduceVT, SrcVec,
11191
11223
DAG.getVectorIdxConstant(0, DL));
11192
- return DAG.getNode(ISD::VECREDUCE_ADD , DL, VT, Vec);
11224
+ return DAG.getNode(ReduceOpc , DL, VT, Vec);
11193
11225
}
11194
11226
}
11195
11227
@@ -11697,6 +11729,8 @@ static SDValue performANDCombine(SDNode *N,
11697
11729
11698
11730
if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
11699
11731
return V;
11732
+ if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
11733
+ return V;
11700
11734
11701
11735
if (DCI.isAfterLegalizeDAG())
11702
11736
if (SDValue V = combineDeMorganOfBoolean(N, DAG))
@@ -11749,6 +11783,8 @@ static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
11749
11783
11750
11784
if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
11751
11785
return V;
11786
+ if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
11787
+ return V;
11752
11788
11753
11789
if (DCI.isAfterLegalizeDAG())
11754
11790
if (SDValue V = combineDeMorganOfBoolean(N, DAG))
@@ -11800,6 +11836,9 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
11800
11836
11801
11837
if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
11802
11838
return V;
11839
+ if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
11840
+ return V;
11841
+
11803
11842
// fold (xor (select cond, 0, y), x) ->
11804
11843
// (select cond, x, (xor x, y))
11805
11844
return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false, Subtarget);
@@ -14005,8 +14044,13 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
14005
14044
case ISD::SMAX:
14006
14045
case ISD::SMIN:
14007
14046
case ISD::FMAXNUM:
14008
- case ISD::FMINNUM:
14009
- return combineBinOpToReduce(N, DAG, Subtarget);
14047
+ case ISD::FMINNUM: {
14048
+ if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
14049
+ return V;
14050
+ if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
14051
+ return V;
14052
+ return SDValue();
14053
+ }
14010
14054
case ISD::SETCC:
14011
14055
return performSETCCCombine(N, DAG, Subtarget);
14012
14056
case ISD::SIGN_EXTEND_INREG:
0 commit comments