Skip to content

Commit 4ebe9bb

Browse files
authored
[WebAssembly] Implement prototype f16x8.extract_lane instruction. (#93272)
Specified at: https://github.com/WebAssembly/half-precision/blob/29a9b9462c9285d4ccc1a5dc39214ddfd1892658/proposals/half-precision/Overview.md Note: the current spec has f16x8.extract_lane as opcode 0x124, but this is incorrect and will be changed to 0x121 soon.
1 parent 89172e9 commit 4ebe9bb

File tree

9 files changed

+42
-1
lines changed

9 files changed

+42
-1
lines changed

clang/include/clang/Basic/BuiltinsWebAssembly.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ TARGET_BUILTIN(__builtin_wasm_relaxed_dot_bf16x8_add_f32_f32x4, "V4fV8UsV8UsV4f"
194194
TARGET_BUILTIN(__builtin_wasm_loadf16_f32, "fh*", "nU", "half-precision")
195195
TARGET_BUILTIN(__builtin_wasm_storef16_f32, "vfh*", "n", "half-precision")
196196
TARGET_BUILTIN(__builtin_wasm_splat_f16x8, "V8hf", "nc", "half-precision")
197+
TARGET_BUILTIN(__builtin_wasm_extract_lane_f16x8, "fV8hi", "nc", "half-precision")
197198

198199
// Reference Types builtins
199200
// Some builtins are custom type-checked - see 't' as part of the third argument,

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21235,6 +21235,12 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
2123521235
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_splat_f16x8);
2123621236
return Builder.CreateCall(Callee, {Val});
2123721237
}
21238+
case WebAssembly::BI__builtin_wasm_extract_lane_f16x8: {
21239+
Value *Vector = EmitScalarExpr(E->getArg(0));
21240+
Value *Index = EmitScalarExpr(E->getArg(1));
21241+
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_extract_lane_f16x8);
21242+
return Builder.CreateCall(Callee, {Vector, Index});
21243+
}
2123821244
case WebAssembly::BI__builtin_wasm_table_get: {
2123921245
assert(E->getArg(0)->getType()->isArrayType());
2124021246
Value *Table = EmitArrayToPointerDecay(E->getArg(0)).emitRawPointer(*this);

clang/test/CodeGen/builtins-wasm.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,12 @@ f16x8 splat_f16x8(float a) {
819819
// WEBASSEMBLY-NEXT: ret <8 x half> %0
820820
return __builtin_wasm_splat_f16x8(a);
821821
}
822+
823+
float extract_lane_f16x8(f16x8 a, int i) {
824+
// WEBASSEMBLY: %0 = tail call float @llvm.wasm.extract.lane.f16x8(<8 x half> %a, i32 %i)
825+
// WEBASSEMBLY-NEXT: ret float %0
826+
return __builtin_wasm_extract_lane_f16x8(a, i);
827+
}
822828
__externref_t externref_null() {
823829
return __builtin_wasm_ref_null_extern();
824830
// WEBASSEMBLY: tail call ptr addrspace(10) @llvm.wasm.ref.null.extern()

llvm/include/llvm/IR/IntrinsicsWebAssembly.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ def int_wasm_splat_f16x8:
341341
DefaultAttrsIntrinsic<[llvm_v8f16_ty],
342342
[llvm_float_ty],
343343
[IntrNoMem, IntrSpeculatable]>;
344+
def int_wasm_extract_lane_f16x8:
345+
DefaultAttrsIntrinsic<[llvm_float_ty],
346+
[llvm_v8f16_ty, llvm_i32_ty],
347+
[IntrNoMem, IntrSpeculatable]>;
344348

345349

346350
//===----------------------------------------------------------------------===//

llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,8 @@ inline bool isArgument(unsigned Opc) {
345345
case WebAssembly::ARGUMENT_v4i32_S:
346346
case WebAssembly::ARGUMENT_v2i64:
347347
case WebAssembly::ARGUMENT_v2i64_S:
348+
case WebAssembly::ARGUMENT_v8f16:
349+
case WebAssembly::ARGUMENT_v8f16_S:
348350
case WebAssembly::ARGUMENT_v4f32:
349351
case WebAssembly::ARGUMENT_v4f32_S:
350352
case WebAssembly::ARGUMENT_v2f64:

llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ MVT WebAssemblyAsmPrinter::getRegType(unsigned RegNo) const {
6262
const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo();
6363
const TargetRegisterClass *TRC = MRI->getRegClass(RegNo);
6464
for (MVT T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64, MVT::v16i8, MVT::v8i16,
65-
MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64})
65+
MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64, MVT::v8f16})
6666
if (TRI->isTypeLegalForClass(*TRC, T))
6767
return T;
6868
LLVM_DEBUG(errs() << "Unknown type for register number: " << RegNo);
@@ -662,6 +662,8 @@ void WebAssemblyAsmPrinter::emitInstruction(const MachineInstr *MI) {
662662
case WebAssembly::ARGUMENT_v4f32_S:
663663
case WebAssembly::ARGUMENT_v2f64:
664664
case WebAssembly::ARGUMENT_v2f64_S:
665+
case WebAssembly::ARGUMENT_v8f16:
666+
case WebAssembly::ARGUMENT_v8f16_S:
665667
// These represent values which are live into the function entry, so there's
666668
// no instruction to emit.
667669
break;

llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ defm "" : ARGUMENT<V128, v4i32>;
5252
defm "" : ARGUMENT<V128, v2i64>;
5353
defm "" : ARGUMENT<V128, v4f32>;
5454
defm "" : ARGUMENT<V128, v2f64>;
55+
defm "" : ARGUMENT<V128, v8f16>;
5556

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

663+
defm EXTRACT_LANE_F16x8 :
664+
HALF_PRECISION_I<(outs F32:$dst), (ins V128:$vec, vec_i8imm_op:$idx),
665+
(outs), (ins vec_i8imm_op:$idx),
666+
[(set (f32 F32:$dst), (int_wasm_extract_lane_f16x8
667+
(v8f16 V128:$vec), (i32 LaneIdx16:$idx)))],
668+
"f16x8.extract_lane\t$dst, $vec, $idx",
669+
"f16x8.extract_lane\t$idx", 0x121>;
670+
662671
// Replace lane value: replace_lane
663672
multiclass ReplaceLane<Vec vec, bits<32> simdop> {
664673
defm REPLACE_LANE_#vec :

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,11 @@ define <8 x half> @splat_v8f16(float %x) {
2727
%v = call <8 x half> @llvm.wasm.splat.f16x8(float %x)
2828
ret <8 x half> %v
2929
}
30+
31+
; CHECK-LABEL: extract_lane_v8f16:
32+
; CHECK: f16x8.extract_lane $push0=, $0, 1
33+
; CHECK-NEXT: return $pop0
34+
define float @extract_lane_v8f16(<8 x half> %v) {
35+
%r = call float @llvm.wasm.extract.lane.f16x8(<8 x half> %v, i32 1)
36+
ret float %r
37+
}

llvm/test/MC/WebAssembly/simd-encodings.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -848,4 +848,7 @@ main:
848848
# CHECK: f16x8.splat # encoding: [0xfd,0xa0,0x02]
849849
f16x8.splat
850850

851+
# CHECK: f16x8.extract_lane 1 # encoding: [0xfd,0xa1,0x02,0x01]
852+
f16x8.extract_lane 1
853+
851854
end_function

0 commit comments

Comments
 (0)