@@ -61,8 +61,6 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
61
61
addRegisterClass (MVT::v8i16, &WebAssembly::V128RegClass);
62
62
addRegisterClass (MVT::v4i32, &WebAssembly::V128RegClass);
63
63
addRegisterClass (MVT::v4f32, &WebAssembly::V128RegClass);
64
- }
65
- if (Subtarget->hasUnimplementedSIMD128 ()) {
66
64
addRegisterClass (MVT::v2i64, &WebAssembly::V128RegClass);
67
65
addRegisterClass (MVT::v2f64, &WebAssembly::V128RegClass);
68
66
}
@@ -116,10 +114,8 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
116
114
for (auto T : {MVT::i32, MVT::i64})
117
115
setOperationAction (Op, T, Expand);
118
116
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 })
120
118
setOperationAction (Op, T, Expand);
121
- if (Subtarget->hasUnimplementedSIMD128 ())
122
- setOperationAction (Op, MVT::v2i64, Expand);
123
119
}
124
120
125
121
// SIMD-specific configuration
@@ -130,83 +126,63 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
130
126
setOperationAction (Op, T, Legal);
131
127
132
128
// 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})
134
131
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);
138
132
139
133
// 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})
141
136
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);
145
137
146
138
// 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 })
149
141
setOperationAction (Op, T, Custom);
150
- if (Subtarget->hasUnimplementedSIMD128 ())
151
- setOperationAction (Op, MVT::v2i64, Custom);
152
- }
153
142
154
143
// 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})
157
147
setOperationAction (Op, T, Custom);
158
- if (Subtarget->hasUnimplementedSIMD128 ())
159
- for (auto T : {MVT::v2i64, MVT::v2f64})
160
- setOperationAction (Op, T, Custom);
161
- }
162
148
163
149
// There is no i64x2.mul instruction
150
+ // TODO: Actually, there is now. Implement it.
164
151
setOperationAction (ISD::MUL, MVT::v2i64, Expand);
165
152
166
153
// 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})
169
157
setOperationAction (Op, T, Expand);
170
- if (Subtarget->hasUnimplementedSIMD128 ())
171
- for (auto T : {MVT::v2i64, MVT::v2f64})
172
- setOperationAction (Op, T, Expand);
173
- }
174
158
175
159
// Expand integer operations supported for scalars but not SIMD
176
160
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 })
179
163
setOperationAction (Op, T, Expand);
180
- if (Subtarget->hasUnimplementedSIMD128 ())
181
- setOperationAction (Op, MVT::v2i64, Expand);
182
- }
183
164
184
165
// 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);
190
169
191
170
// Expand float operations supported for scalars but not SIMD
192
171
for (auto Op : {ISD::FCEIL, ISD::FFLOOR, ISD::FTRUNC, ISD::FNEARBYINT,
193
172
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);
199
176
200
177
// 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);
210
186
}
211
187
212
188
// As a special case, these operators use the type to mean the type to
@@ -1270,39 +1246,42 @@ WebAssemblyTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
1270
1246
SelectionDAG &DAG) const {
1271
1247
SDLoc DL (Op);
1272
1248
// 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.
1278
1255
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 ));
1306
1285
}
1307
1286
1308
1287
SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR (SDValue Op,
@@ -1502,7 +1481,6 @@ SDValue WebAssemblyTargetLowering::LowerSETCC(SDValue Op,
1502
1481
// expanding all i64x2 SETCC nodes, but that seems to expand f64x2 SETCC nodes
1503
1482
// (which return i64x2 results) as well. So instead we manually unroll i64x2
1504
1483
// comparisons here.
1505
- assert (Subtarget->hasUnimplementedSIMD128 ());
1506
1484
assert (Op->getOperand (0 )->getSimpleValueType (0 ) == MVT::v2i64);
1507
1485
SmallVector<SDValue, 2 > LHS, RHS;
1508
1486
DAG.ExtractVectorElements (Op->getOperand (0 ), LHS);
0 commit comments