@@ -4118,6 +4118,56 @@ static SDValue getWideningInterleave(SDValue EvenV, SDValue OddV,
4118
4118
return Interleaved;
4119
4119
}
4120
4120
4121
+ // If we have a vector of bits that we want to reverse, we can use a vbrev on a
4122
+ // larger element type, e.g. v32i1 can be reversed with a v1i32 bitreverse.
4123
+ static SDValue lowerBitreverseShuffle(ShuffleVectorSDNode *SVN,
4124
+ SelectionDAG &DAG,
4125
+ const RISCVSubtarget &Subtarget) {
4126
+ SDLoc DL(SVN);
4127
+ MVT VT = SVN->getSimpleValueType(0);
4128
+ SDValue V = SVN->getOperand(0);
4129
+ unsigned NumElts = VT.getVectorNumElements();
4130
+
4131
+ assert(VT.getVectorElementType() == MVT::i1);
4132
+
4133
+ if (!ShuffleVectorInst::isReverseMask(SVN->getMask()) ||
4134
+ !SVN->getOperand(1).isUndef())
4135
+ return SDValue();
4136
+
4137
+ unsigned ViaEltSize = std::max((uint64_t)8, PowerOf2Ceil(NumElts));
4138
+ MVT ViaVT = MVT::getVectorVT(MVT::getIntegerVT(ViaEltSize), 1);
4139
+ MVT ViaBitVT = MVT::getVectorVT(MVT::i1, ViaVT.getScalarSizeInBits());
4140
+
4141
+ // If we don't have zvbb or the larger element type > ELEN, the operation will
4142
+ // be illegal.
4143
+ if (!Subtarget.getTargetLowering()->isOperationLegalOrCustom(ISD::BITREVERSE,
4144
+ ViaVT))
4145
+ return SDValue();
4146
+
4147
+ // If the bit vector doesn't fit exactly into the larger element type, we need
4148
+ // to insert it into the larger vector and then shift up the reversed bits
4149
+ // afterwards to get rid of the gap introduced.
4150
+ if (ViaEltSize > NumElts)
4151
+ V = DAG.getNode(ISD::INSERT_SUBVECTOR, DL, ViaBitVT, DAG.getUNDEF(ViaBitVT),
4152
+ V, DAG.getVectorIdxConstant(0, DL));
4153
+
4154
+ SDValue Res =
4155
+ DAG.getNode(ISD::BITREVERSE, DL, ViaVT, DAG.getBitcast(ViaVT, V));
4156
+
4157
+ // Shift up the reversed bits if the vector didn't exactly fit into the larger
4158
+ // element type.
4159
+ if (ViaEltSize > NumElts)
4160
+ Res = DAG.getNode(ISD::SRL, DL, ViaVT, Res,
4161
+ DAG.getConstant(ViaEltSize - NumElts, DL, ViaVT));
4162
+
4163
+ Res = DAG.getBitcast(ViaBitVT, Res);
4164
+
4165
+ if (ViaEltSize > NumElts)
4166
+ Res = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DL, VT, Res,
4167
+ DAG.getVectorIdxConstant(0, DL));
4168
+ return Res;
4169
+ }
4170
+
4121
4171
static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
4122
4172
const RISCVSubtarget &Subtarget) {
4123
4173
SDValue V1 = Op.getOperand(0);
@@ -4128,8 +4178,11 @@ static SDValue lowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG,
4128
4178
unsigned NumElts = VT.getVectorNumElements();
4129
4179
ShuffleVectorSDNode *SVN = cast<ShuffleVectorSDNode>(Op.getNode());
4130
4180
4131
- // Promote i1 shuffle to i8 shuffle.
4132
4181
if (VT.getVectorElementType() == MVT::i1) {
4182
+ if (SDValue V = lowerBitreverseShuffle(SVN, DAG, Subtarget))
4183
+ return V;
4184
+
4185
+ // Promote i1 shuffle to i8 shuffle.
4133
4186
MVT WidenVT = MVT::getVectorVT(MVT::i8, VT.getVectorElementCount());
4134
4187
V1 = DAG.getNode(ISD::ZERO_EXTEND, DL, WidenVT, V1);
4135
4188
V2 = V2.isUndef() ? DAG.getUNDEF(WidenVT)
0 commit comments