tlively created this revision.
tlively added a reviewer: aheejin.
Herald added subscribers: wingo, ecnelises, sunfish, hiraditya,
jgravelle-google, sbc100, dschuff.
tlively requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.
As proposed in https://github.com/WebAssembly/simd/pull/383.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D95012
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
@@ -742,4 +742,22 @@
# CHECK: prefetch.nt 16 # encoding: [0xfd,0xc6,0x01,0x00,0x10]
prefetch.nt 16
+ # CHECK: f64x2.convert_low_i32x4_s # encoding: [0xfd,0x53]
+ f64x2.convert_low_i32x4_s
+
+ # CHECK: f64x2.convert_low_i32x4_u # encoding: [0xfd,0x54]
+ f64x2.convert_low_i32x4_u
+
+ # CHECK: i32x4.trunc_sat_zero_f64x2_s # encoding: [0xfd,0x55]
+ i32x4.trunc_sat_zero_f64x2_s
+
+ # CHECK: i32x4.trunc_sat_zero_f64x2_u # encoding: [0xfd,0x56]
+ i32x4.trunc_sat_zero_f64x2_u
+
+ # CHECK: f32x4.demote_zero_f64x2 # encoding: [0xfd,0x57]
+ f32x4.demote_zero_f64x2
+
+ # CHECK: f64x2.promote_low_f32x4 # encoding: [0xfd,0x69]
+ f64x2.promote_low_f32x4
+
end_function
Index: llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
+++ llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
@@ -566,6 +566,26 @@
ret <4 x i32> %a
}
+; CHECK-LABEL: trunc_sat_zero_signed_v4i32:
+; SIMD128-NEXT: .functype trunc_sat_zero_signed_v4i32 (v128) -> (v128){{$}}
+; SIMD128-NEXT: i32x4.trunc_sat_zero_f64x2_s $push[[R:[0-9]+]]=, $0{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double>)
+define <4 x i32> @trunc_sat_zero_signed_v4i32(<2 x double> %a) {
+ %v = call <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double> %a)
+ ret <4 x i32> %v
+}
+
+; CHECK-LABEL: trunc_sat_zero_unsigned_v4i32:
+; SIMD128-NEXT: .functype trunc_sat_zero_unsigned_v4i32 (v128) -> (v128){{$}}
+; SIMD128-NEXT: i32x4.trunc_sat_zero_f64x2_u $push[[R:[0-9]+]]=, $0{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double>)
+define <4 x i32> @trunc_sat_zero_unsigned_v4i32(<2 x double> %a) {
+ %v = call <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double> %a)
+ ret <4 x i32> %v
+}
+
; ==============================================================================
; 2 x i64
; ==============================================================================
@@ -820,6 +840,16 @@
ret <4 x float> %v
}
+; CHECK-LABEL: demote_zero_v4f32:
+; SIMD128-NEXT: .functype demote_zero_v4f32 (v128) -> (v128){{$}}
+; SIMD128-NEXT: f32x4.demote_zero_f64x2 $push[[R:[0-9]+]]=, $0{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <4 x float> @llvm.wasm.demote.zero(<2 x double>)
+define <4 x float> @demote_zero_v4f32(<2 x double> %a) {
+ %v = call <4 x float> @llvm.wasm.demote.zero(<2 x double> %a)
+ ret <4 x float> %v
+}
+
; ==============================================================================
; 2 x f64
; ==============================================================================
@@ -918,3 +948,33 @@
)
ret <2 x double> %v
}
+
+; CHECK-LABEL: convert_low_signed_v2f64:
+; SIMD128-NEXT: .functype convert_low_signed_v2f64 (v128) -> (v128){{$}}
+; SIMD128-NEXT: f64x2.convert_low_i32x4_s $push[[R:[0-9]+]]=, $0{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <2 x double> @llvm.wasm.convert.low.signed(<4 x i32>)
+define <2 x double> @convert_low_signed_v2f64(<4 x i32> %a) {
+ %v = call <2 x double> @llvm.wasm.convert.low.signed(<4 x i32> %a)
+ ret <2 x double> %v
+}
+
+; CHECK-LABEL: convert_low_unsigned_v2f64:
+; SIMD128-NEXT: .functype convert_low_unsigned_v2f64 (v128) -> (v128){{$}}
+; SIMD128-NEXT: f64x2.convert_low_i32x4_u $push[[R:[0-9]+]]=, $0{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32>)
+define <2 x double> @convert_low_unsigned_v2f64(<4 x i32> %a) {
+ %v = call <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32> %a)
+ ret <2 x double> %v
+}
+
+; CHECK-LABEL: promote_low_v2f64:
+; SIMD128-NEXT: .functype promote_low_v2f64 (v128) -> (v128){{$}}
+; SIMD128-NEXT: f64x2.promote_low_f32x4 $push[[R:[0-9]+]]=, $0{{$}}
+; SIMD128-NEXT: return $pop[[R]]{{$}}
+declare <2 x double> @llvm.wasm.promote.low(<4 x float>)
+define <2 x double> @promote_low_v2f64(<4 x float> %a) {
+ %v = call <2 x double> @llvm.wasm.promote.low(<4 x float> %a)
+ ret <2 x double> %v
+}
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -1257,6 +1257,20 @@
"extadd_pairwise_i16x8_u", 0xa6>;
+// Prototype f64x2 conversions
+defm "" : SIMDConvert<F64x2, I32x4, int_wasm_convert_low_signed,
+ "convert_low_i32x4_s", 0x53>;
+defm "" : SIMDConvert<F64x2, I32x4, int_wasm_convert_low_unsigned,
+ "convert_low_i32x4_u", 0x54>;
+defm "" : SIMDConvert<I32x4, F64x2, int_wasm_trunc_saturate_zero_signed,
+ "trunc_sat_zero_f64x2_s", 0x55>;
+defm "" : SIMDConvert<I32x4, F64x2, int_wasm_trunc_saturate_zero_unsigned,
+ "trunc_sat_zero_f64x2_u", 0x56>;
+defm "" : SIMDConvert<F32x4, F64x2, int_wasm_demote_zero,
+ "demote_zero_f64x2", 0x57>;
+defm "" : SIMDConvert<F64x2, F32x4, int_wasm_promote_low,
+ "promote_low_f32x4", 0x69>;
+
//===----------------------------------------------------------------------===//
// 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
@@ -325,6 +325,26 @@
ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
"", [SDNPMemOperand]>;
+// TODO: Remove these if possible if they are merged to the spec.
+def int_wasm_convert_low_signed :
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_convert_low_unsigned :
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_trunc_saturate_zero_signed :
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_trunc_saturate_zero_unsigned :
+ Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_demote_zero :
+ Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+def int_wasm_promote_low :
+ Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty],
+ [IntrNoMem, IntrSpeculatable]>;
+
//===----------------------------------------------------------------------===//
// 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,42 @@
// 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)
+ // WEBASSEMBLY: ret
+}
+
+f64x2 convert_low_u_i32x4_f64x2(u32x4 x) {
+ return __builtin_wasm_convert_low_u_i32x4_f64x2(x);
+ // WEBASSEMBLY: call <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32> %x)
+ // WEBASSEMBLY: ret
+}
+
+i32x4 trunc_saturate_zero_s_f64x2_i32x4(f64x2 x) {
+ return __builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4(x);
+ // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double> %x)
+ // WEBASSEMBLY: ret
+}
+
+u32x4 trunc_saturate_zero_u_f64x2_i32x4(f64x2 x) {
+ return __builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4(x);
+ // WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double> %x)
+ // WEBASSEMBLY: ret
+}
+
+f32x4 wasm_demote_zero_f64x2_f32x4(f64x2 x) {
+ return __builtin_wasm_demote_zero_f64x2_f32x4(x);
+ // WEBASSEMBLY: call <4 x float> @llvm.wasm.demote.zero(<2 x double> %x)
+ // WEBASSEMBLY: ret
+}
+
+f64x2 wasm_promote_low_f32x4_f64x2(f32x4 x) {
+ return __builtin_wasm_promote_low_f32x4_f64x2(x);
+ // WEBASSEMBLY: call <2 x double> @llvm.wasm.promote.low(<4 x float> %x)
+ // WEBASSEMBLY: ret
+}
+
i32x4 load32_zero(int *p) {
return __builtin_wasm_load32_zero(p);
// WEBASSEMBLY: call <4 x i32> @llvm.wasm.load32.zero(i32* %p)
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -17101,6 +17101,46 @@
Function *Callee = CGM.getIntrinsic(IntNo);
return Builder.CreateCall(Callee, Vec);
}
+ 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));
+ unsigned IntNo;
+ switch (BuiltinID) {
+ case WebAssembly::BI__builtin_wasm_convert_low_s_i32x4_f64x2:
+ IntNo = Intrinsic::wasm_convert_low_signed;
+ break;
+ case WebAssembly::BI__builtin_wasm_convert_low_u_i32x4_f64x2:
+ IntNo = Intrinsic::wasm_convert_low_unsigned;
+ break;
+ }
+ Function *Callee = CGM.getIntrinsic(IntNo);
+ return Builder.CreateCall(Callee, Vec);
+ }
+ case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4:
+ case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4: {
+ Value *Vec = EmitScalarExpr(E->getArg(0));
+ unsigned IntNo;
+ switch (BuiltinID) {
+ case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4:
+ IntNo = Intrinsic::wasm_trunc_saturate_zero_signed;
+ break;
+ case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4:
+ IntNo = Intrinsic::wasm_trunc_saturate_zero_unsigned;
+ break;
+ }
+ Function *Callee = CGM.getIntrinsic(IntNo);
+ return Builder.CreateCall(Callee, Vec);
+ }
+ case WebAssembly::BI__builtin_wasm_demote_zero_f64x2_f32x4: {
+ Value *Vec = EmitScalarExpr(E->getArg(0));
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_demote_zero);
+ return Builder.CreateCall(Callee, Vec);
+ }
+ case WebAssembly::BI__builtin_wasm_promote_low_f32x4_f64x2: {
+ Value *Vec = EmitScalarExpr(E->getArg(0));
+ Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_promote_low);
+ return Builder.CreateCall(Callee, Vec);
+ }
case WebAssembly::BI__builtin_wasm_load32_zero: {
Value *Ptr = EmitScalarExpr(E->getArg(0));
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_load32_zero);
Index: clang/include/clang/Basic/BuiltinsWebAssembly.def
===================================================================
--- clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -206,6 +206,13 @@
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_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")
+TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4, "V4UiV2d", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_demote_zero_f64x2_f32x4, "V4fV2d", "nc", "simd128")
+TARGET_BUILTIN(__builtin_wasm_promote_low_f32x4_f64x2, "V2dV4f", "nc", "simd128")
+
TARGET_BUILTIN(__builtin_wasm_load32_zero, "V4ii*", "n", "simd128")
TARGET_BUILTIN(__builtin_wasm_load64_zero, "V2LLiLLi*", "n", "simd128")
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits