@@ -61,8 +61,6 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
6161 addRegisterClass (MVT::v8i16, &WebAssembly::V128RegClass);
6262 addRegisterClass (MVT::v4i32, &WebAssembly::V128RegClass);
6363 addRegisterClass (MVT::v4f32, &WebAssembly::V128RegClass);
64- }
65- if (Subtarget->hasUnimplementedSIMD128 ()) {
6664 addRegisterClass (MVT::v2i64, &WebAssembly::V128RegClass);
6765 addRegisterClass (MVT::v2f64, &WebAssembly::V128RegClass);
6866 }
@@ -116,10 +114,8 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
116114 for (auto T : {MVT::i32 , MVT::i64 })
117115 setOperationAction (Op, T, Expand);
118116 if (Subtarget->hasSIMD128 ())
119- for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
117+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 })
120118 setOperationAction (Op, T, Expand);
121- if (Subtarget->hasUnimplementedSIMD128 ())
122- setOperationAction (Op, MVT::v2i64, Expand);
123119 }
124120
125121 // SIMD-specific configuration
@@ -130,83 +126,63 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
130126 setOperationAction (Op, T, Legal);
131127
132128 // Custom lower BUILD_VECTORs to minimize number of replace_lanes
133- for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32})
129+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32, MVT::v2i64,
130+ MVT::v2f64})
134131 setOperationAction (ISD::BUILD_VECTOR, T, Custom);
135- if (Subtarget->hasUnimplementedSIMD128 ())
136- for (auto T : {MVT::v2i64, MVT::v2f64})
137- setOperationAction (ISD::BUILD_VECTOR, T, Custom);
138132
139133 // We have custom shuffle lowering to expose the shuffle mask
140- for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32})
134+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32, MVT::v2i64,
135+ MVT::v2f64})
141136 setOperationAction (ISD::VECTOR_SHUFFLE, T, Custom);
142- if (Subtarget->hasUnimplementedSIMD128 ())
143- for (auto T: {MVT::v2i64, MVT::v2f64})
144- setOperationAction (ISD::VECTOR_SHUFFLE, T, Custom);
145137
146138 // Custom lowering since wasm shifts must have a scalar shift amount
147- for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL}) {
148- for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
139+ for (auto Op : {ISD::SHL, ISD::SRA, ISD::SRL})
140+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 })
149141 setOperationAction (Op, T, Custom);
150- if (Subtarget->hasUnimplementedSIMD128 ())
151- setOperationAction (Op, MVT::v2i64, Custom);
152- }
153142
154143 // Custom lower lane accesses to expand out variable indices
155- for (auto Op : {ISD::EXTRACT_VECTOR_ELT, ISD::INSERT_VECTOR_ELT}) {
156- for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32})
144+ for (auto Op : {ISD::EXTRACT_VECTOR_ELT, ISD::INSERT_VECTOR_ELT})
145+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32, MVT::v2i64,
146+ MVT::v2f64})
157147 setOperationAction (Op, T, Custom);
158- if (Subtarget->hasUnimplementedSIMD128 ())
159- for (auto T : {MVT::v2i64, MVT::v2f64})
160- setOperationAction (Op, T, Custom);
161- }
162148
163149 // There is no i64x2.mul instruction
150+ // TODO: Actually, there is now. Implement it.
164151 setOperationAction (ISD::MUL, MVT::v2i64, Expand);
165152
166153 // There are no vector select instructions
167- for (auto Op : {ISD::VSELECT, ISD::SELECT_CC, ISD::SELECT}) {
168- for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32})
154+ for (auto Op : {ISD::VSELECT, ISD::SELECT_CC, ISD::SELECT})
155+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32, MVT::v2i64,
156+ MVT::v2f64})
169157 setOperationAction (Op, T, Expand);
170- if (Subtarget->hasUnimplementedSIMD128 ())
171- for (auto T : {MVT::v2i64, MVT::v2f64})
172- setOperationAction (Op, T, Expand);
173- }
174158
175159 // Expand integer operations supported for scalars but not SIMD
176160 for (auto Op : {ISD::CTLZ, ISD::CTTZ, ISD::CTPOP, ISD::SDIV, ISD::UDIV,
177- ISD::SREM, ISD::UREM, ISD::ROTL, ISD::ROTR}) {
178- for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
161+ ISD::SREM, ISD::UREM, ISD::ROTL, ISD::ROTR})
162+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64 })
179163 setOperationAction (Op, T, Expand);
180- if (Subtarget->hasUnimplementedSIMD128 ())
181- setOperationAction (Op, MVT::v2i64, Expand);
182- }
183164
184165 // But we do have integer min and max operations
185- if (Subtarget->hasUnimplementedSIMD128 ()) {
186- for (auto Op : {ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX})
187- for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
188- setOperationAction (Op, T, Legal);
189- }
166+ for (auto Op : {ISD::SMIN, ISD::SMAX, ISD::UMIN, ISD::UMAX})
167+ for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32})
168+ setOperationAction (Op, T, Legal);
190169
191170 // Expand float operations supported for scalars but not SIMD
192171 for (auto Op : {ISD::FCEIL, ISD::FFLOOR, ISD::FTRUNC, ISD::FNEARBYINT,
193172 ISD::FCOPYSIGN, ISD::FLOG, ISD::FLOG2, ISD::FLOG10,
194- ISD::FEXP, ISD::FEXP2, ISD::FRINT}) {
195- setOperationAction (Op, MVT::v4f32, Expand);
196- if (Subtarget->hasUnimplementedSIMD128 ())
197- setOperationAction (Op, MVT::v2f64, Expand);
198- }
173+ ISD::FEXP, ISD::FEXP2, ISD::FRINT})
174+ for (auto T : {MVT::v4f32, MVT::v2f64})
175+ setOperationAction (Op, T, Expand);
199176
200177 // Expand operations not supported for i64x2 vectors
201- if (Subtarget->hasUnimplementedSIMD128 ())
202- for (unsigned CC = 0 ; CC < ISD::SETCC_INVALID; ++CC)
203- setCondCodeAction (static_cast <ISD::CondCode>(CC), MVT::v2i64, Custom);
204-
205- // Expand additional SIMD ops that V8 hasn't implemented yet
206- if (!Subtarget->hasUnimplementedSIMD128 ()) {
207- setOperationAction (ISD::FSQRT, MVT::v4f32, Expand);
208- setOperationAction (ISD::FDIV, MVT::v4f32, Expand);
209- }
178+ for (unsigned CC = 0 ; CC < ISD::SETCC_INVALID; ++CC)
179+ setCondCodeAction (static_cast <ISD::CondCode>(CC), MVT::v2i64, Custom);
180+
181+ // 64x2 conversions are not in the spec
182+ for (auto Op :
183+ {ISD::SINT_TO_FP, ISD::UINT_TO_FP, ISD::FP_TO_SINT, ISD::FP_TO_UINT})
184+ for (auto T : {MVT::v2i64, MVT::v2f64})
185+ setOperationAction (Op, T, Expand);
210186 }
211187
212188 // As a special case, these operators use the type to mean the type to
@@ -1270,39 +1246,42 @@ WebAssemblyTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
12701246 SelectionDAG &DAG) const {
12711247 SDLoc DL (Op);
12721248 // If sign extension operations are disabled, allow sext_inreg only if operand
1273- // is a vector extract. SIMD does not depend on sign extension operations, but
1274- // allowing sext_inreg in this context lets us have simple patterns to select
1275- // extract_lane_s instructions. Expanding sext_inreg everywhere would be
1276- // simpler in this file, but would necessitate large and brittle patterns to
1277- // undo the expansion and select extract_lane_s instructions.
1249+ // is a vector extract of an i8 or i16 lane. SIMD does not depend on sign
1250+ // extension operations, but allowing sext_inreg in this context lets us have
1251+ // simple patterns to select extract_lane_s instructions. Expanding sext_inreg
1252+ // everywhere would be simpler in this file, but would necessitate large and
1253+ // brittle patterns to undo the expansion and select extract_lane_s
1254+ // instructions.
12781255 assert (!Subtarget->hasSignExt () && Subtarget->hasSIMD128 ());
1279- if (Op.getOperand (0 ).getOpcode () == ISD::EXTRACT_VECTOR_ELT) {
1280- const SDValue &Extract = Op.getOperand (0 );
1281- MVT VecT = Extract.getOperand (0 ).getSimpleValueType ();
1282- MVT ExtractedLaneT = static_cast <VTSDNode *>(Op.getOperand (1 ).getNode ())
1283- ->getVT ()
1284- .getSimpleVT ();
1285- MVT ExtractedVecT =
1286- MVT::getVectorVT (ExtractedLaneT, 128 / ExtractedLaneT.getSizeInBits ());
1287- if (ExtractedVecT == VecT)
1288- return Op;
1289- // Bitcast vector to appropriate type to ensure ISel pattern coverage
1290- const SDValue &Index = Extract.getOperand (1 );
1291- unsigned IndexVal =
1292- static_cast <ConstantSDNode *>(Index.getNode ())->getZExtValue ();
1293- unsigned Scale =
1294- ExtractedVecT.getVectorNumElements () / VecT.getVectorNumElements ();
1295- assert (Scale > 1 );
1296- SDValue NewIndex =
1297- DAG.getConstant (IndexVal * Scale, DL, Index.getValueType ());
1298- SDValue NewExtract = DAG.getNode (
1299- ISD::EXTRACT_VECTOR_ELT, DL, Extract.getValueType (),
1300- DAG.getBitcast (ExtractedVecT, Extract.getOperand (0 )), NewIndex);
1301- return DAG.getNode (ISD::SIGN_EXTEND_INREG, DL, Op.getValueType (),
1302- NewExtract, Op.getOperand (1 ));
1303- }
1304- // Otherwise expand
1305- return SDValue ();
1256+ if (Op.getOperand (0 ).getOpcode () != ISD::EXTRACT_VECTOR_ELT)
1257+ return SDValue ();
1258+
1259+ const SDValue &Extract = Op.getOperand (0 );
1260+ MVT VecT = Extract.getOperand (0 ).getSimpleValueType ();
1261+ if (VecT.getVectorElementType ().getSizeInBits () > 32 )
1262+ return SDValue ();
1263+ MVT ExtractedLaneT = static_cast <VTSDNode *>(Op.getOperand (1 ).getNode ())
1264+ ->getVT ()
1265+ .getSimpleVT ();
1266+ MVT ExtractedVecT =
1267+ MVT::getVectorVT (ExtractedLaneT, 128 / ExtractedLaneT.getSizeInBits ());
1268+ if (ExtractedVecT == VecT)
1269+ return Op;
1270+
1271+ // Bitcast vector to appropriate type to ensure ISel pattern coverage
1272+ const SDValue &Index = Extract.getOperand (1 );
1273+ unsigned IndexVal =
1274+ static_cast <ConstantSDNode *>(Index.getNode ())->getZExtValue ();
1275+ unsigned Scale =
1276+ ExtractedVecT.getVectorNumElements () / VecT.getVectorNumElements ();
1277+ assert (Scale > 1 );
1278+ SDValue NewIndex =
1279+ DAG.getConstant (IndexVal * Scale, DL, Index.getValueType ());
1280+ SDValue NewExtract = DAG.getNode (
1281+ ISD::EXTRACT_VECTOR_ELT, DL, Extract.getValueType (),
1282+ DAG.getBitcast (ExtractedVecT, Extract.getOperand (0 )), NewIndex);
1283+ return DAG.getNode (ISD::SIGN_EXTEND_INREG, DL, Op.getValueType (), NewExtract,
1284+ Op.getOperand (1 ));
13061285}
13071286
13081287SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR (SDValue Op,
@@ -1502,7 +1481,6 @@ SDValue WebAssemblyTargetLowering::LowerSETCC(SDValue Op,
15021481 // expanding all i64x2 SETCC nodes, but that seems to expand f64x2 SETCC nodes
15031482 // (which return i64x2 results) as well. So instead we manually unroll i64x2
15041483 // comparisons here.
1505- assert (Subtarget->hasUnimplementedSIMD128 ());
15061484 assert (Op->getOperand (0 )->getSimpleValueType (0 ) == MVT::v2i64);
15071485 SmallVector<SDValue, 2 > LHS, RHS;
15081486 DAG.ExtractVectorElements (Op->getOperand (0 ), LHS);
0 commit comments