Skip to content

[WebAssembly] Implement prototype f16x8.extract_lane instruction. #93272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/Basic/BuiltinsWebAssembly.def
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ TARGET_BUILTIN(__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4, "V4fV8UsV8UsV4f"
TARGET_BUILTIN(__builtin_wasm_loadf16_f32, "fh*", "nU", "half-precision")
TARGET_BUILTIN(__builtin_wasm_storef16_f32, "vfh*", "n", "half-precision")
TARGET_BUILTIN(__builtin_wasm_splat_f16x8, "V8hf", "nc", "half-precision")
TARGET_BUILTIN(__builtin_wasm_extract_lane_f16x8, "fV8hi", "nc", "half-precision")

// Reference Types builtins
// Some builtins are custom type-checked - see 't' as part of the third argument,
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21235,6 +21235,12 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_splat_f16x8);
return Builder.CreateCall(Callee, {Val});
}
case WebAssembly::BI__builtin_wasm_extract_lane_f16x8: {
Value *Vector = EmitScalarExpr(E->getArg(0));
Value *Index = EmitScalarExpr(E->getArg(1));
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_extract_lane_f16x8);
return Builder.CreateCall(Callee, {Vector, Index});
}
case WebAssembly::BI__builtin_wasm_table_get: {
assert(E->getArg(0)->getType()->isArrayType());
Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CodeGen/builtins-wasm.c
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,12 @@ f16x8 splat_f16x8(float a) {
// WEBASSEMBLY-NEXT: ret <8 x half> %0
return __builtin_wasm_splat_f16x8(a);
}

float extract_lane_f16x8(f16x8 a, int i) {
// WEBASSEMBLY: %0 = tail call float @llvm.wasm.extract.lane.f16x8(<8 x half> %a, i32 %i)
// WEBASSEMBLY-NEXT: ret float %0
return __builtin_wasm_extract_lane_f16x8(a, i);
}
__externref_t externref_null() {
return __builtin_wasm_ref_null_extern();
// WEBASSEMBLY: tail call ptr addrspace(10) @llvm.wasm.ref.null.extern()
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/IntrinsicsWebAssembly.td
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,10 @@ def int_wasm_splat_f16x8:
DefaultAttrsIntrinsic<[llvm_v8f16_ty],
[llvm_float_ty],
[IntrNoMem, IntrSpeculatable]>;
def int_wasm_extract_lane_f16x8:
DefaultAttrsIntrinsic<[llvm_float_ty],
[llvm_v8f16_ty, llvm_i32_ty],
[IntrNoMem, IntrSpeculatable]>;


//===----------------------------------------------------------------------===//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ inline bool isArgument(unsigned Opc) {
case WebAssembly::ARGUMENT_v4i32_S:
case WebAssembly::ARGUMENT_v2i64:
case WebAssembly::ARGUMENT_v2i64_S:
case WebAssembly::ARGUMENT_v8f16:
case WebAssembly::ARGUMENT_v8f16_S:
case WebAssembly::ARGUMENT_v4f32:
case WebAssembly::ARGUMENT_v4f32_S:
case WebAssembly::ARGUMENT_v2f64:
Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ MVT WebAssemblyAsmPrinter::getRegType(unsigned RegNo) const {
const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
const TargetRegisterClass *TRC = MRI->getRegClass(RegNo);
for (MVT T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64, MVT::v16i8, MVT::v8i16,
MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64})
MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64, MVT::v8f16})
if (TRI->isTypeLegalForClass(*TRC, T))
return T;
LLVM_DEBUG(errs() << "Unknown type for register number: " << RegNo);
Expand Down Expand Up @@ -662,6 +662,8 @@ void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) {
case WebAssembly::ARGUMENT_v4f32_S:
case WebAssembly::ARGUMENT_v2f64:
case WebAssembly::ARGUMENT_v2f64_S:
case WebAssembly::ARGUMENT_v8f16:
case WebAssembly::ARGUMENT_v8f16_S:
// These represent values which are live into the function entry, so there's
// no instruction to emit.
break;
Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ defm "" : ARGUMENT<V128, v4i32>;
defm "" : ARGUMENT<V128, v2i64>;
defm "" : ARGUMENT<V128, v4f32>;
defm "" : ARGUMENT<V128, v2f64>;
defm "" : ARGUMENT<V128, v8f16>;

// Constrained immediate argument types. Allow any value from the minimum signed
// value to the maximum unsigned value for the lane size.
Expand Down Expand Up @@ -659,6 +660,14 @@ def : Pat<
(and (vector_extract (v8i16 V128:$vec), (i32 LaneIdx8:$idx)), (i32 0xffff)),
(EXTRACT_LANE_I16x8_u $vec, imm:$idx)>;

defm EXTRACT_LANE_F16x8 :
HALF_PRECISION_I<(outs F32:$dst), (ins V128:$vec, vec_i8imm_op:$idx),
(outs), (ins vec_i8imm_op:$idx),
[(set (f32 F32:$dst), (int_wasm_extract_lane_f16x8
(v8f16 V128:$vec), (i32 LaneIdx16:$idx)))],
"f16x8.extract_lane\t$dst, $vec, $idx",
"f16x8.extract_lane\t$idx", 0x121>;

// Replace lane value: replace_lane
multiclass ReplaceLane<Vec vec, bits<32> simdop> {
defm REPLACE_LANE_#vec :
Expand Down
8 changes: 8 additions & 0 deletions llvm/test/CodeGen/WebAssembly/half-precision.ll
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,11 @@ define <8 x half> @splat_v8f16(float %x) {
%v = call <8 x half> @llvm.wasm.splat.f16x8(float %x)
ret <8 x half> %v
}

; CHECK-LABEL: extract_lane_v8f16:
; CHECK: f16x8.extract_lane $push0=, $0, 1
; CHECK-NEXT: return $pop0
define float @extract_lane_v8f16(<8 x half> %v) {
%r = call float @llvm.wasm.extract.lane.f16x8(<8 x half> %v, i32 1)
ret float %r
}
3 changes: 3 additions & 0 deletions llvm/test/MC/WebAssembly/simd-encodings.s
Original file line number Diff line number Diff line change
Expand Up @@ -848,4 +848,7 @@ main:
# CHECK: f16x8.splat # encoding: [0xfd,0xa0,0x02]
f16x8.splat

# CHECK: f16x8.extract_lane 1 # encoding: [0xfd,0xa1,0x02,0x01]
f16x8.extract_lane 1

end_function
Loading