This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG4b68b64dcc5b: [WebAssembly] Prototype i8x16 to i32x4
widening instructions (authored by tlively).
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D95557/new/
https://reviews.llvm.org/D95557
Files:
clang/include/clang/Basic/BuiltinsWebAssembly.def
clang/lib/CodeGen/CGBuiltin.cpp
clang/test/CodeGen/builtins-wasm.c
llvm/include/llvm/IR/IntrinsicsWebAssembly.td
llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
llvm/test/MC/WebAssembly/simd-encodings.s
Index: llvm/test/MC/WebAssembly/simd-encodings.s
===================================================================
--- llvm/test/MC/WebAssembly/simd-encodings.s
+++ llvm/test/MC/WebAssembly/simd-encodings.s
@@ -760,4 +760,10 @@
# CHECK: f64x2.promote_low_f32x4 # encoding: [0xfd,0x69]
f64x2.promote_low_f32x4
+ # CHECK: i32x4.widen_i8x16_s 3 # encoding: [0xfd,0x67,0x03]
+ i32x4.widen_i8x16_s 3
+
+ # CHECK: i32x4.widen_i8x16_u 3 # encoding: [0xfd,0x68,0x03]
+ i32x4.widen_i8x16_u 3
+
end_function
Index: llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
+++ llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
@@ -586,6 +586,27 @@
ret <4 x i32> %v
}
+
+; CHECK-LABEL: widen_signed_v4i32:
+; SIMD128-NEXT: .functype widen_signed_v4i32 (v128) -> (v128){{$}}
+; SIMD128-NEXT: i32x4.widen_i8x16_s $push[[R:[0-9]+]]=, $0, 1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x i32> @llvm.wasm.widen.signed(<16 x i8>, i32 immarg)
+define <4 x i32> @widen_signed_v4i32(<16 x i8> %x) {
+ %v = call <4 x i32> @llvm.wasm.widen.signed(<16 x i8> %x, i32 1)
+ ret <4 x i32> %v
+}
+
+; CHECK-LABEL: widen_unsigned_v4i32:
+; SIMD128-NEXT: .functype widen_unsigned_v4i32 (v128) -> (v128){{$}}
+; SIMD128-NEXT: i32x4.widen_i8x16_u $push[[R:[0-9]+]]=, $0, 1{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x i32> @llvm.wasm.widen.unsigned(<16 x i8>, i32 immarg)
+define <4 x i32> @widen_unsigned_v4i32(<16 x i8> %x) {
+ %v = call <4 x i32> @llvm.wasm.widen.unsigned(<16 x i8> %x, i32 1)
+ ret <4 x i32> %v
+}
+
; ==============================================================================
; 2 x i64
; ==============================================================================
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -1256,7 +1256,6 @@
defm "" : SIMDConvert<I32x4, I16x8, int_wasm_extadd_pairwise_unsigned,
"extadd_pairwise_i16x8_u", 0xa6>;
-
// Prototype f64x2 conversions
defm "" : SIMDConvert<F64x2, I32x4, int_wasm_convert_low_signed,
"convert_low_i32x4_s", 0x53>;
@@ -1271,6 +1270,25 @@
defm "" : SIMDConvert<F64x2, F32x4, int_wasm_promote_low,
"promote_low_f32x4", 0x69>;
+// Prototype i8x16 to i32x4 widening
+defm WIDEN_I8x16_TO_I32x4_S :
+ SIMD_I<(outs V128:$dst), (ins V128:$vec, vec_i8imm_op:$idx),
+ (outs), (ins vec_i8imm_op:$idx),
+ [(set (I32x4.vt V128:$dst),
+ (I32x4.vt (int_wasm_widen_signed
+ (I8x16.vt V128:$vec), (i32 timm:$idx))))],
+ "i32x4.widen_i8x16_s\t$dst, $vec, $idx",
+ "i32x4.widen_i8x16_s\t$idx", 0x67>;
+defm WIDEN_I8x16_TO_I32x4_U :
+ SIMD_I<(outs V128:$dst), (ins V128:$vec, vec_i8imm_op:$idx),
+ (outs), (ins vec_i8imm_op:$idx),
+ [(set (I32x4.vt V128:$dst),
+ (I32x4.vt (int_wasm_widen_unsigned
+ (I8x16.vt V128:$vec), (i32 timm:$idx))))],
+ "i32x4.widen_i8x16_u\t$dst, $vec, $idx",
+ "i32x4.widen_i8x16_u\t$idx", 0x68>;
+
+
//===----------------------------------------------------------------------===//
// Quasi-Fused Multiply- Add and Subtract (QFMA/QFMS)
//===----------------------------------------------------------------------===//
Index: llvm/include/llvm/IR/IntrinsicsWebAssembly.td
===================================================================
--- llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -348,6 +348,14 @@
Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty],
[IntrNoMem, IntrSpeculatable]>;
+// TODO: Remove these if possible if they are merged to the spec.
+def int_wasm_widen_signed :
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>;
+def int_wasm_widen_unsigned :
+ Intrinsic<[llvm_v4i32_ty], [llvm_v16i8_ty, llvm_i32_ty],
+ [IntrNoMem, IntrSpeculatable, ImmArg<ArgIndex<1>>]>;
+
//===----------------------------------------------------------------------===//
// Thread-local storage intrinsics
//===----------------------------------------------------------------------===//
Index: clang/test/CodeGen/builtins-wasm.c
===================================================================
--- clang/test/CodeGen/builtins-wasm.c
+++ clang/test/CodeGen/builtins-wasm.c
@@ -976,6 +976,18 @@
// WEBASSEMBLY: ret
}
+i32x4 widen_s_i8x16_i32x4(i8x16 x) {
+ return __builtin_wasm_widen_s_i8x16_i32x4(x, 3);
+ // WEBASSEMBLY: call <4 x i32> @llvm.wasm.widen.signed(<16 x i8> %x, i32 3)
+ // WEBASSEMBLY: ret
+}
+
+u32x4 widen_u_i8x16_i32x4(u8x16 x) {
+ return __builtin_wasm_widen_u_i8x16_i32x4(x, 3);
+ // WEBASSEMBLY: call <4 x i32> @llvm.wasm.widen.unsigned(<16 x i8> %x, i32 3)
+ // WEBASSEMBLY: ret
+}
+
f64x2 convert_low_s_i32x4_f64x2(i32x4 x) {
return __builtin_wasm_convert_low_s_i32x4_f64x2(x);
// WEBASSEMBLY: call <2 x double> @llvm.wasm.convert.low.signed(<4 x i32> %x)
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -17220,6 +17220,24 @@
Function *Callee = CGM.getIntrinsic(IntNo);
return Builder.CreateCall(Callee, Vec);
}
+ case WebAssembly::BI__builtin_wasm_widen_s_i8x16_i32x4:
+ case WebAssembly::BI__builtin_wasm_widen_u_i8x16_i32x4: {
+ Value *Vec = EmitScalarExpr(E->getArg(0));
+ llvm::APSInt SubVecConst =
+ *E->getArg(1)->getIntegerConstantExpr(getContext());
+ Value *SubVec = llvm::ConstantInt::get(getLLVMContext(), SubVecConst);
+ unsigned IntNo;
+ switch (BuiltinID) {
+ case WebAssembly::BI__builtin_wasm_widen_s_i8x16_i32x4:
+ IntNo = Intrinsic::wasm_widen_signed;
+ break;
+ case WebAssembly::BI__builtin_wasm_widen_u_i8x16_i32x4:
+ IntNo = Intrinsic::wasm_widen_unsigned;
+ break;
+ }
+ Function *Callee = CGM.getIntrinsic(IntNo);
+ return Builder.CreateCall(Callee, {Vec, SubVec});
+ }
case WebAssembly::BI__builtin_wasm_convert_low_s_i32x4_f64x2:
case WebAssembly::BI__builtin_wasm_convert_low_u_i32x4_f64x2: {
Value *Vec = EmitScalarExpr(E->getArg(0));
Index: clang/include/clang/Basic/BuiltinsWebAssembly.def
===================================================================
--- clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -206,6 +206,9 @@
TARGET_BUILTIN(__builtin_wasm_widen_low_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_widen_high_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_widen_s_i8x16_i32x4, "V4iV16ScIi", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_widen_u_i8x16_i32x4, "V4UiV16UcIi", "nc", "simd128")
+
TARGET_BUILTIN(__builtin_wasm_convert_low_s_i32x4_f64x2, "V2dV4i", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_convert_low_u_i32x4_f64x2, "V2dV4Ui", "nc", "simd128")
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4, "V4iV2d", "nc", "simd128")
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits