Skip to content

Commit 3f51097

Browse files
tlivelynikic
authored andcommitted
Update WebAssembly SIMD opcodes (#56)
* [WebAssembly] Enable recently implemented SIMD operations Summary: Moves a batch of instructions from unimplemented-simd128 to simd128 because they have recently become available in V8. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, cfe-commits, llvm-commits Tags: #clang, #llvm Differential Revision: https://reviews.llvm.org/D73926 * [WebAssembly] Simplify extract_vector lowering Summary: Removes patterns that were not doing useful work, changes the default extract instructions to be the unsigned versions now that they are enabled by default, fixes PR44988, and adds tests for sext_inreg lowering. Reviewers: aheejin Reviewed By: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D75005 * [WebAssembly] Renumber SIMD opcodes Summary: As described in WebAssembly/simd#209. This is the final reorganization of the SIMD opcode space before standardization. It has been landed in concert with corresponding changes in other projects in the WebAssembly SIMD ecosystem. Reviewers: aheejin Subscribers: dschuff, sbc100, jgravelle-google, hiraditya, sunfish, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D79224
1 parent b485511 commit 3f51097

18 files changed

+611
-875
lines changed

clang/include/clang/Basic/BuiltinsWebAssembly.def

+15-17
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,20 @@ TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc", "nontrappi
7373
TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16cV16cV16c", "nc", "unimplemented-simd128")
7474

7575
TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc", "simd128")
76-
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "unimplemented-simd128")
76+
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "simd128")
7777
TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i16x8, "iV8sIi", "nc", "simd128")
78-
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc", "unimplemented-simd128")
78+
TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc", "simd128")
7979
TARGET_BUILTIN(__builtin_wasm_extract_lane_i32x4, "iV4iIi", "nc", "simd128")
80-
TARGET_BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc", "unimplemented-simd128")
80+
TARGET_BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc", "simd128")
8181
TARGET_BUILTIN(__builtin_wasm_extract_lane_f32x4, "fV4fIi", "nc", "simd128")
82-
TARGET_BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc", "unimplemented-simd128")
82+
TARGET_BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc", "simd128")
8383

8484
TARGET_BUILTIN(__builtin_wasm_replace_lane_i8x16, "V16cV16cIii", "nc", "simd128")
8585
TARGET_BUILTIN(__builtin_wasm_replace_lane_i16x8, "V8sV8sIii", "nc", "simd128")
8686
TARGET_BUILTIN(__builtin_wasm_replace_lane_i32x4, "V4iV4iIii", "nc", "simd128")
87-
TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "unimplemented-simd128")
87+
TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "simd128")
8888
TARGET_BUILTIN(__builtin_wasm_replace_lane_f32x4, "V4fV4fIif", "nc", "simd128")
89-
TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "unimplemented-simd128")
89+
TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "simd128")
9090

9191
TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128")
9292
TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128")
@@ -98,8 +98,8 @@ TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd1
9898
TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128")
9999
TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128")
100100

101-
TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16cV16cV16c", "nc", "unimplemented-simd128")
102-
TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8sV8sV8s", "nc", "unimplemented-simd128")
101+
TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16cV16cV16c", "nc", "simd128")
102+
TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8sV8sV8s", "nc", "simd128")
103103

104104
TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128")
105105

@@ -113,27 +113,25 @@ TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128")
113113
TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128")
114114

115115
TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128")
116-
TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "unimplemented-simd128")
116+
TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "simd128")
117117

118118
TARGET_BUILTIN(__builtin_wasm_min_f32x4, "V4fV4fV4f", "nc", "simd128")
119119
TARGET_BUILTIN(__builtin_wasm_max_f32x4, "V4fV4fV4f", "nc", "simd128")
120-
TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
121-
TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128")
120+
TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "simd128")
121+
TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "simd128")
122122

123123
TARGET_BUILTIN(__builtin_wasm_dot_s_i32x4_i16x8, "V4iV8sV8s", "nc", "simd128")
124124

125-
TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "unimplemented-simd128")
126-
TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "unimplemented-simd128")
125+
TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "simd128")
126+
TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "simd128")
127127

128-
TARGET_BUILTIN(__builtin_wasm_qfma_f32x4, "V4fV4fV4fV4f", "nc", "simd128")
129-
TARGET_BUILTIN(__builtin_wasm_qfms_f32x4, "V4fV4fV4fV4f", "nc", "simd128")
128+
TARGET_BUILTIN(__builtin_wasm_qfma_f32x4, "V4fV4fV4fV4f", "nc", "unimplemented-simd128")
129+
TARGET_BUILTIN(__builtin_wasm_qfms_f32x4, "V4fV4fV4fV4f", "nc", "unimplemented-simd128")
130130
TARGET_BUILTIN(__builtin_wasm_qfma_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-simd128")
131131
TARGET_BUILTIN(__builtin_wasm_qfms_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-simd128")
132132

133133
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128")
134134
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128")
135-
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128")
136-
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128")
137135

138136
TARGET_BUILTIN(__builtin_wasm_narrow_s_i8x16_i16x8, "V16cV8sV8s", "nc", "simd128")
139137
TARGET_BUILTIN(__builtin_wasm_narrow_u_i8x16_i16x8, "V16cV8sV8s", "nc", "simd128")

clang/lib/CodeGen/CGBuiltin.cpp

+2-4
Original file line numberDiff line numberDiff line change
@@ -14462,8 +14462,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
1446214462
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32_f64:
1446314463
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f32:
1446414464
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64_f64:
14465-
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32x4_f32x4:
14466-
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i64x2_f64x2: {
14465+
case WebAssembly::BI__builtin_wasm_trunc_saturate_s_i32x4_f32x4: {
1446714466
Value *Src = EmitScalarExpr(E->getArg(0));
1446814467
llvm::Type *ResT = ConvertType(E->getType());
1446914468
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_saturate_signed,
@@ -14474,8 +14473,7 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
1447414473
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32_f64:
1447514474
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f32:
1447614475
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64_f64:
14477-
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32x4_f32x4:
14478-
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i64x2_f64x2: {
14476+
case WebAssembly::BI__builtin_wasm_trunc_saturate_u_i32x4_f32x4: {
1447914477
Value *Src = EmitScalarExpr(E->getArg(0));
1448014478
llvm::Type *ResT = ConvertType(E->getType());
1448114479
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_trunc_saturate_unsigned,

clang/test/CodeGen/builtins-wasm.c

-12
Original file line numberDiff line numberDiff line change
@@ -519,18 +519,6 @@ i32x4 trunc_saturate_u_i32x4_f32x4(f32x4 f) {
519519
// WEBASSEMBLY-NEXT: ret
520520
}
521521

522-
i64x2 trunc_saturate_s_i64x2_f64x2(f64x2 f) {
523-
return __builtin_wasm_trunc_saturate_s_i64x2_f64x2(f);
524-
// WEBASSEMBLY: call <2 x i64> @llvm.wasm.trunc.saturate.signed.v2i64.v2f64(<2 x double> %f)
525-
// WEBASSEMBLY-NEXT: ret
526-
}
527-
528-
i64x2 trunc_saturate_u_i64x2_f64x2(f64x2 f) {
529-
return __builtin_wasm_trunc_saturate_u_i64x2_f64x2(f);
530-
// WEBASSEMBLY: call <2 x i64> @llvm.wasm.trunc.saturate.unsigned.v2i64.v2f64(<2 x double> %f)
531-
// WEBASSEMBLY-NEXT: ret
532-
}
533-
534522
i8x16 narrow_s_i8x16_i16x8(i16x8 low, i16x8 high) {
535523
return __builtin_wasm_narrow_s_i8x16_i16x8(low, high);
536524
// WEBASSEMBLY: call <16 x i8> @llvm.wasm.narrow.signed.v16i8.v8i16(

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

+65-87
Original file line numberDiff line numberDiff line change
@@ -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

13081287
SDValue 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

Comments
 (0)