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