Skip to content

Commit

Permalink
[WebAssembly] Support BUILD_VECTOR with F16x8. (#108117)
Browse files Browse the repository at this point in the history
Convert BUILD_VECTORS with FP16x8 to I16x8 since there's no FP16 scalar
value to intialize v128.const.
  • Loading branch information
brendandahl authored Sep 11, 2024
1 parent 415288a commit c076638
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
15 changes: 15 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ WebAssemblyTargetLowering::WebAssemblyTargetLowering(
MVT::v2f64})
setOperationAction(ISD::BUILD_VECTOR, T, Custom);

if (Subtarget->hasFP16())
setOperationAction(ISD::BUILD_VECTOR, MVT::f16, Custom);

// We have custom shuffle lowering to expose the shuffle mask
for (auto T : {MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v4f32, MVT::v2i64,
MVT::v2f64})
Expand Down Expand Up @@ -2059,6 +2062,18 @@ static SDValue LowerConvertLow(SDValue Op, SelectionDAG &DAG) {

SDValue WebAssemblyTargetLowering::LowerBUILD_VECTOR(SDValue Op,
SelectionDAG &DAG) const {
MVT VT = Op.getSimpleValueType();
if (VT == MVT::v8f16) {
// BUILD_VECTOR can't handle FP16 operands since Wasm doesn't have a scaler
// FP16 type, so cast them to I16s.
MVT IVT = VT.changeVectorElementType(MVT::i16);
SmallVector<SDValue, 8> NewOps;
for (unsigned I = 0, E = Op.getNumOperands(); I < E; ++I)
NewOps.push_back(DAG.getBitcast(MVT::i16, Op.getOperand(I)));
SDValue Res = DAG.getNode(ISD::BUILD_VECTOR, SDLoc(), IVT, NewOps);
return DAG.getBitcast(VT, Res);
}

if (auto ConvertLow = LowerConvertLow(Op, DAG))
return ConvertLow;

Expand Down
7 changes: 7 additions & 0 deletions llvm/test/CodeGen/WebAssembly/half-precision.ll
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ define <8 x half> @splat_v8f16(float %x) {
ret <8 x half> %v
}

; CHECK-LABEL: const_splat_v8f16:
; CHECK: v128.const $push0=, 20800, 0, 0, 0, 0, 0, 0, 20800
; CHECK-NEXT: return $pop0
define <8 x half> @const_splat_v8f16() {
ret <8 x half> <half 42., half 0., half 0., half 0., half 0., half 0., half 0., half 42.>
}

; CHECK-LABEL: extract_lane_v8f16:
; CHECK: f16x8.extract_lane $push0=, $0, 1
; CHECK-NEXT: return $pop0
Expand Down

0 comments on commit c076638

Please sign in to comment.