@@ -11106,6 +11106,31 @@ void RISCVTargetLowering::ReplaceNodeResults(SDNode *N,
11106
11106
}
11107
11107
}
11108
11108
11109
+ /// Given an integer binary operator, return the generic ISD::VECREDUCE_OP
11110
+ /// which corresponds to it.
11111
+ static unsigned getVecReduceOpcode(unsigned Opc) {
11112
+ switch (Opc) {
11113
+ default:
11114
+ llvm_unreachable("Unhandled binary to transfrom reduction");
11115
+ case ISD::ADD:
11116
+ return ISD::VECREDUCE_ADD;
11117
+ case ISD::UMAX:
11118
+ return ISD::VECREDUCE_UMAX;
11119
+ case ISD::SMAX:
11120
+ return ISD::VECREDUCE_SMAX;
11121
+ case ISD::UMIN:
11122
+ return ISD::VECREDUCE_UMIN;
11123
+ case ISD::SMIN:
11124
+ return ISD::VECREDUCE_SMIN;
11125
+ case ISD::AND:
11126
+ return ISD::VECREDUCE_AND;
11127
+ case ISD::OR:
11128
+ return ISD::VECREDUCE_OR;
11129
+ case ISD::XOR:
11130
+ return ISD::VECREDUCE_XOR;
11131
+ }
11132
+ };
11133
+
11109
11134
/// Perform two related transforms whose purpose is to incrementally recognize
11110
11135
/// an explode_vector followed by scalar reduction as a vector reduction node.
11111
11136
/// This exists to recover from a deficiency in SLP which can't handle
@@ -11124,8 +11149,15 @@ combineBinOpOfExtractToReduceTree(SDNode *N, SelectionDAG &DAG,
11124
11149
11125
11150
const SDLoc DL(N);
11126
11151
const EVT VT = N->getValueType(0);
11127
- [[maybe_unused]] const unsigned Opc = N->getOpcode();
11128
- assert(Opc == ISD::ADD && "extend this to other reduction types");
11152
+
11153
+ // TODO: Handle floating point here.
11154
+ if (!VT.isInteger())
11155
+ return SDValue();
11156
+
11157
+ const unsigned Opc = N->getOpcode();
11158
+ const unsigned ReduceOpc = getVecReduceOpcode(Opc);
11159
+ assert(Opc == ISD::getVecReduceBaseOpcode(ReduceOpc) &&
11160
+ "Inconsistent mappings");
11129
11161
const SDValue LHS = N->getOperand(0);
11130
11162
const SDValue RHS = N->getOperand(1);
11131
11163
@@ -11155,13 +11187,13 @@ combineBinOpOfExtractToReduceTree(SDNode *N, SelectionDAG &DAG,
11155
11187
EVT ReduceVT = EVT::getVectorVT(*DAG.getContext(), VT, 2);
11156
11188
SDValue Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ReduceVT, SrcVec,
11157
11189
DAG.getVectorIdxConstant(0, DL));
11158
- return DAG.getNode(ISD::VECREDUCE_ADD , DL, VT, Vec);
11190
+ return DAG.getNode(ReduceOpc , DL, VT, Vec);
11159
11191
}
11160
11192
11161
11193
// Match (binop (reduce (extract_subvector V, 0),
11162
11194
// (extract_vector_elt V, sizeof(SubVec))))
11163
11195
// into a reduction of one more element from the original vector V.
11164
- if (LHS.getOpcode() != ISD::VECREDUCE_ADD )
11196
+ if (LHS.getOpcode() != ReduceOpc )
11165
11197
return SDValue();
11166
11198
11167
11199
SDValue ReduceVec = LHS.getOperand(0);
@@ -11177,7 +11209,7 @@ combineBinOpOfExtractToReduceTree(SDNode *N, SelectionDAG &DAG,
11177
11209
EVT ReduceVT = EVT::getVectorVT(*DAG.getContext(), VT, Idx + 1);
11178
11210
SDValue Vec = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, ReduceVT, SrcVec,
11179
11211
DAG.getVectorIdxConstant(0, DL));
11180
- return DAG.getNode(ISD::VECREDUCE_ADD , DL, VT, Vec);
11212
+ return DAG.getNode(ReduceOpc , DL, VT, Vec);
11181
11213
}
11182
11214
}
11183
11215
@@ -11685,6 +11717,8 @@ static SDValue performANDCombine(SDNode *N,
11685
11717
11686
11718
if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
11687
11719
return V;
11720
+ if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
11721
+ return V;
11688
11722
11689
11723
if (DCI.isAfterLegalizeDAG())
11690
11724
if (SDValue V = combineDeMorganOfBoolean(N, DAG))
@@ -11737,6 +11771,8 @@ static SDValue performORCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI,
11737
11771
11738
11772
if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
11739
11773
return V;
11774
+ if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
11775
+ return V;
11740
11776
11741
11777
if (DCI.isAfterLegalizeDAG())
11742
11778
if (SDValue V = combineDeMorganOfBoolean(N, DAG))
@@ -11788,6 +11824,9 @@ static SDValue performXORCombine(SDNode *N, SelectionDAG &DAG,
11788
11824
11789
11825
if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
11790
11826
return V;
11827
+ if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
11828
+ return V;
11829
+
11791
11830
// fold (xor (select cond, 0, y), x) ->
11792
11831
// (select cond, x, (xor x, y))
11793
11832
return combineSelectAndUseCommutative(N, DAG, /*AllOnes*/ false, Subtarget);
@@ -13993,8 +14032,13 @@ SDValue RISCVTargetLowering::PerformDAGCombine(SDNode *N,
13993
14032
case ISD::SMAX:
13994
14033
case ISD::SMIN:
13995
14034
case ISD::FMAXNUM:
13996
- case ISD::FMINNUM:
13997
- return combineBinOpToReduce(N, DAG, Subtarget);
14035
+ case ISD::FMINNUM: {
14036
+ if (SDValue V = combineBinOpToReduce(N, DAG, Subtarget))
14037
+ return V;
14038
+ if (SDValue V = combineBinOpOfExtractToReduceTree(N, DAG, Subtarget))
14039
+ return V;
14040
+ return SDValue();
14041
+ }
13998
14042
case ISD::SETCC:
13999
14043
return performSETCCCombine(N, DAG, Subtarget);
14000
14044
case ISD::SIGN_EXTEND_INREG:
0 commit comments