|
19 | 19 |
|
20 | 20 | namespace llvm { |
21 | 21 |
|
22 | | -static const int StandardVectorWidth = 256; |
23 | | - |
24 | 22 | bool isPackedVectorType(EVT SomeVT) { |
25 | 23 | if (!SomeVT.isVector()) |
26 | 24 | return false; |
27 | 25 | return SomeVT.getVectorNumElements() > StandardVectorWidth; |
28 | 26 | } |
29 | 27 |
|
| 28 | +MVT getLegalVectorType(Packing P, MVT ElemVT) { |
| 29 | + return MVT::getVectorVT(ElemVT, P == Packing::Normal ? StandardVectorWidth |
| 30 | + : PackedVectorWidth); |
| 31 | +} |
| 32 | + |
| 33 | +Packing getTypePacking(EVT VT) { |
| 34 | + assert(VT.isVector()); |
| 35 | + return isPackedVectorType(VT) ? Packing::Dense : Packing::Normal; |
| 36 | +} |
| 37 | + |
| 38 | +bool isMaskType(EVT SomeVT) { |
| 39 | + if (!SomeVT.isVector()) |
| 40 | + return false; |
| 41 | + return SomeVT.getVectorElementType() == MVT::i1; |
| 42 | +} |
| 43 | + |
30 | 44 | /// \returns the VVP_* SDNode opcode corresponsing to \p OC. |
31 | 45 | Optional<unsigned> getVVPOpcode(unsigned Opcode) { |
32 | 46 | switch (Opcode) { |
@@ -121,11 +135,55 @@ SDValue VECustomDAG::getConstant(uint64_t Val, EVT VT, bool IsTarget, |
121 | 135 | return DAG.getConstant(Val, DL, VT, IsTarget, IsOpaque); |
122 | 136 | } |
123 | 137 |
|
| 138 | +SDValue VECustomDAG::getConstantMask(Packing Packing, bool AllTrue) const { |
| 139 | + auto MaskVT = getLegalVectorType(Packing, MVT::i1); |
| 140 | + |
| 141 | + // VEISelDAGtoDAG will replace this pattern with the constant-true VM. |
| 142 | + auto TrueVal = DAG.getConstant(-1, DL, MVT::i32); |
| 143 | + auto AVL = getConstant(MaskVT.getVectorNumElements(), MVT::i32); |
| 144 | + auto Res = getNode(VEISD::VEC_BROADCAST, MaskVT, {TrueVal, AVL}); |
| 145 | + if (AllTrue) |
| 146 | + return Res; |
| 147 | + |
| 148 | + return DAG.getNOT(DL, Res, Res.getValueType()); |
| 149 | +} |
| 150 | + |
| 151 | +SDValue VECustomDAG::getMaskBroadcast(EVT ResultVT, SDValue Scalar, |
| 152 | + SDValue AVL) const { |
| 153 | + // Constant mask splat. |
| 154 | + if (auto BcConst = dyn_cast<ConstantSDNode>(Scalar)) |
| 155 | + return getConstantMask(getTypePacking(ResultVT), |
| 156 | + BcConst->getSExtValue() != 0); |
| 157 | + |
| 158 | + // Expand the broadcast to a vector comparison. |
| 159 | + auto ScalarBoolVT = Scalar.getSimpleValueType(); |
| 160 | + assert(ScalarBoolVT == MVT::i32); |
| 161 | + |
| 162 | + // Cast to i32 ty. |
| 163 | + SDValue CmpElem = DAG.getSExtOrTrunc(Scalar, DL, MVT::i32); |
| 164 | + unsigned ElemCount = ResultVT.getVectorNumElements(); |
| 165 | + MVT CmpVecTy = MVT::getVectorVT(ScalarBoolVT, ElemCount); |
| 166 | + |
| 167 | + // Broadcast to vector. |
| 168 | + SDValue BCVec = |
| 169 | + DAG.getNode(VEISD::VEC_BROADCAST, DL, CmpVecTy, {CmpElem, AVL}); |
| 170 | + SDValue ZeroVec = |
| 171 | + getBroadcast(CmpVecTy, {DAG.getConstant(0, DL, ScalarBoolVT)}, AVL); |
| 172 | + |
| 173 | + MVT BoolVecTy = MVT::getVectorVT(MVT::i1, ElemCount); |
| 174 | + |
| 175 | + // Broadcast(Data) != Broadcast(0) |
| 176 | + // TODO: Use a VVP operation for this. |
| 177 | + return DAG.getSetCC(DL, BoolVecTy, BCVec, ZeroVec, ISD::CondCode::SETNE); |
| 178 | +} |
| 179 | + |
124 | 180 | SDValue VECustomDAG::getBroadcast(EVT ResultVT, SDValue Scalar, |
125 | 181 | SDValue AVL) const { |
126 | 182 | assert(ResultVT.isVector()); |
127 | 183 | auto ScaVT = Scalar.getValueType(); |
128 | | - assert(ScaVT != MVT::i1 && "TODO: Mask broadcasts"); |
| 184 | + |
| 185 | + if (isMaskType(ResultVT)) |
| 186 | + return getMaskBroadcast(ResultVT, Scalar, AVL); |
129 | 187 |
|
130 | 188 | if (isPackedVectorType(ResultVT)) { |
131 | 189 | // v512x packed mode broadcast |
|
0 commit comments