Skip to content

Commit c076638

Browse files
authored
[WebAssembly] Support BUILD_VECTOR with F16x8. (#108117)
Convert BUILD_VECTORS with FP16x8 to I16x8 since there's no FP16 scalar value to intialize v128.const.
1 parent 415288a commit c076638

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
212212
MVT::v2f64})
213213
setOperationAction(ISD::BUILD_VECTOR, T, Custom);
214214

215+
if (Subtarget->hasFP16())
216+
setOperationAction(ISD::BUILD_VECTOR, MVT::f16, Custom);
217+
215218
// We have custom shuffle lowering to expose the shuffle mask
216219
for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32, MVT::v2i64,
217220
MVT::v2f64})
@@ -2059,6 +2062,18 @@ static SDValue LowerConvertLow(SDValue Op, SelectionDAG &DAG) {
20592062

20602063
SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
20612064
SelectionDAG &DAG) const {
2065+
MVT VT = Op.getSimpleValueType();
2066+
if (VT == MVT::v8f16) {
2067+
// BUILD_VECTOR can't handle FP16 operands since Wasm doesn't have a scaler
2068+
// FP16 type, so cast them to I16s.
2069+
MVT IVT = VT.changeVectorElementType(MVT::i16);
2070+
SmallVector<SDValue, 8> NewOps;
2071+
for (unsigned I = 0, E = Op.getNumOperands(); I < E; ++I)
2072+
NewOps.push_back(DAG.getBitcast(MVT::i16, Op.getOperand(I)));
2073+
SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, SDLoc(), IVT, NewOps);
2074+
return DAG.getBitcast(VT, Res);
2075+
}
2076+
20622077
if (auto ConvertLow = LowerConvertLow(Op, DAG))
20632078
return ConvertLow;
20642079

llvm/test/CodeGen/WebAssembly/half-precision.ll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ define <8 x half> @splat_v8f16(float %x) {
2727
ret <8 x half> %v
2828
}
2929

30+
; CHECK-LABEL: const_splat_v8f16:
31+
; CHECK: v128.const $push0=, 20800, 0, 0, 0, 0, 0, 0, 20800
32+
; CHECK-NEXT: return $pop0
33+
define <8 x half> @const_splat_v8f16() {
34+
ret <8 x half> <half 42., half 0., half 0., half 0., half 0., half 0., half 0., half 42.>
35+
}
36+
3037
; CHECK-LABEL: extract_lane_v8f16:
3138
; CHECK: f16x8.extract_lane $push0=, $0, 1
3239
; CHECK-NEXT: return $pop0

0 commit comments

Comments
 (0)