Skip to content

Commit 11802ec

Browse files
committed
[WebAssembly] Prototype new f64x2 conversions
As proposed in WebAssembly/simd#383. Differential Revision: https://reviews.llvm.org/D95012
1 parent f5d8eb0 commit 11802ec

File tree

7 files changed

+195
-0
lines changed

7 files changed

+195
-0
lines changed

clang/include/clang/Basic/BuiltinsWebAssembly.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,13 @@ TARGET_BUILTIN(__builtin_wasm_widen_high_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd1
206206
TARGET_BUILTIN(__builtin_wasm_widen_low_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128")
207207
TARGET_BUILTIN(__builtin_wasm_widen_high_u_i32x4_i64x2, "V2LLUiV4Ui", "nc", "simd128")
208208

209+
TARGET_BUILTIN(__builtin_wasm_convert_low_s_i32x4_f64x2, "V2dV4i", "nc", "simd128")
210+
TARGET_BUILTIN(__builtin_wasm_convert_low_u_i32x4_f64x2, "V2dV4Ui", "nc", "simd128")
211+
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4, "V4iV2d", "nc", "simd128")
212+
TARGET_BUILTIN(__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4, "V4UiV2d", "nc", "simd128")
213+
TARGET_BUILTIN(__builtin_wasm_demote_zero_f64x2_f32x4, "V4fV2d", "nc", "simd128")
214+
TARGET_BUILTIN(__builtin_wasm_promote_low_f32x4_f64x2, "V2dV4f", "nc", "simd128")
215+
209216
TARGET_BUILTIN(__builtin_wasm_load32_zero, "V4ii*", "n", "simd128")
210217
TARGET_BUILTIN(__builtin_wasm_load64_zero, "V2LLiLLi*", "n", "simd128")
211218

clang/lib/CodeGen/CGBuiltin.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17220,6 +17220,46 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
1722017220
Function *Callee = CGM.getIntrinsic(IntNo);
1722117221
return Builder.CreateCall(Callee, Vec);
1722217222
}
17223+
case WebAssembly::BI__builtin_wasm_convert_low_s_i32x4_f64x2:
17224+
case WebAssembly::BI__builtin_wasm_convert_low_u_i32x4_f64x2: {
17225+
Value *Vec = EmitScalarExpr(E->getArg(0));
17226+
unsigned IntNo;
17227+
switch (BuiltinID) {
17228+
case WebAssembly::BI__builtin_wasm_convert_low_s_i32x4_f64x2:
17229+
IntNo = Intrinsic::wasm_convert_low_signed;
17230+
break;
17231+
case WebAssembly::BI__builtin_wasm_convert_low_u_i32x4_f64x2:
17232+
IntNo = Intrinsic::wasm_convert_low_unsigned;
17233+
break;
17234+
}
17235+
Function *Callee = CGM.getIntrinsic(IntNo);
17236+
return Builder.CreateCall(Callee, Vec);
17237+
}
17238+
case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4:
17239+
case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4: {
17240+
Value *Vec = EmitScalarExpr(E->getArg(0));
17241+
unsigned IntNo;
17242+
switch (BuiltinID) {
17243+
case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4:
17244+
IntNo = Intrinsic::wasm_trunc_saturate_zero_signed;
17245+
break;
17246+
case WebAssembly::BI__builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4:
17247+
IntNo = Intrinsic::wasm_trunc_saturate_zero_unsigned;
17248+
break;
17249+
}
17250+
Function *Callee = CGM.getIntrinsic(IntNo);
17251+
return Builder.CreateCall(Callee, Vec);
17252+
}
17253+
case WebAssembly::BI__builtin_wasm_demote_zero_f64x2_f32x4: {
17254+
Value *Vec = EmitScalarExpr(E->getArg(0));
17255+
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_demote_zero);
17256+
return Builder.CreateCall(Callee, Vec);
17257+
}
17258+
case WebAssembly::BI__builtin_wasm_promote_low_f32x4_f64x2: {
17259+
Value *Vec = EmitScalarExpr(E->getArg(0));
17260+
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_promote_low);
17261+
return Builder.CreateCall(Callee, Vec);
17262+
}
1722317263
case WebAssembly::BI__builtin_wasm_load32_zero: {
1722417264
Value *Ptr = EmitScalarExpr(E->getArg(0));
1722517265
Function *Callee = CGM.getIntrinsic(Intrinsic::wasm_load32_zero);

clang/test/CodeGen/builtins-wasm.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -976,6 +976,42 @@ u64x2 widen_high_u_i32x4_i64x2(u32x4 x) {
976976
// WEBASSEMBLY: ret
977977
}
978978

979+
f64x2 convert_low_s_i32x4_f64x2(i32x4 x) {
980+
return __builtin_wasm_convert_low_s_i32x4_f64x2(x);
981+
// WEBASSEMBLY: call <2 x double> @llvm.wasm.convert.low.signed(<4 x i32> %x)
982+
// WEBASSEMBLY: ret
983+
}
984+
985+
f64x2 convert_low_u_i32x4_f64x2(u32x4 x) {
986+
return __builtin_wasm_convert_low_u_i32x4_f64x2(x);
987+
// WEBASSEMBLY: call <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32> %x)
988+
// WEBASSEMBLY: ret
989+
}
990+
991+
i32x4 trunc_saturate_zero_s_f64x2_i32x4(f64x2 x) {
992+
return __builtin_wasm_trunc_saturate_zero_s_f64x2_i32x4(x);
993+
// WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double> %x)
994+
// WEBASSEMBLY: ret
995+
}
996+
997+
u32x4 trunc_saturate_zero_u_f64x2_i32x4(f64x2 x) {
998+
return __builtin_wasm_trunc_saturate_zero_u_f64x2_i32x4(x);
999+
// WEBASSEMBLY: call <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double> %x)
1000+
// WEBASSEMBLY: ret
1001+
}
1002+
1003+
f32x4 wasm_demote_zero_f64x2_f32x4(f64x2 x) {
1004+
return __builtin_wasm_demote_zero_f64x2_f32x4(x);
1005+
// WEBASSEMBLY: call <4 x float> @llvm.wasm.demote.zero(<2 x double> %x)
1006+
// WEBASSEMBLY: ret
1007+
}
1008+
1009+
f64x2 wasm_promote_low_f32x4_f64x2(f32x4 x) {
1010+
return __builtin_wasm_promote_low_f32x4_f64x2(x);
1011+
// WEBASSEMBLY: call <2 x double> @llvm.wasm.promote.low(<4 x float> %x)
1012+
// WEBASSEMBLY: ret
1013+
}
1014+
9791015
i32x4 load32_zero(int *p) {
9801016
return __builtin_wasm_load32_zero(p);
9811017
// WEBASSEMBLY: call <4 x i32> @llvm.wasm.load32.zero(i32* %p)

llvm/include/llvm/IR/IntrinsicsWebAssembly.td

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,26 @@ def int_wasm_prefetch_nt :
328328
ReadOnly<ArgIndex<0>>, NoCapture<ArgIndex<0>>],
329329
"", [SDNPMemOperand]>;
330330

331+
// TODO: Remove these if possible if they are merged to the spec.
332+
def int_wasm_convert_low_signed :
333+
Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
334+
[IntrNoMem, IntrSpeculatable]>;
335+
def int_wasm_convert_low_unsigned :
336+
Intrinsic<[llvm_v2f64_ty], [llvm_v4i32_ty],
337+
[IntrNoMem, IntrSpeculatable]>;
338+
def int_wasm_trunc_saturate_zero_signed :
339+
Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
340+
[IntrNoMem, IntrSpeculatable]>;
341+
def int_wasm_trunc_saturate_zero_unsigned :
342+
Intrinsic<[llvm_v4i32_ty], [llvm_v2f64_ty],
343+
[IntrNoMem, IntrSpeculatable]>;
344+
def int_wasm_demote_zero :
345+
Intrinsic<[llvm_v4f32_ty], [llvm_v2f64_ty],
346+
[IntrNoMem, IntrSpeculatable]>;
347+
def int_wasm_promote_low :
348+
Intrinsic<[llvm_v2f64_ty], [llvm_v4f32_ty],
349+
[IntrNoMem, IntrSpeculatable]>;
350+
331351
//===----------------------------------------------------------------------===//
332352
// Thread-local storage intrinsics
333353
//===----------------------------------------------------------------------===//

llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,20 @@ defm "" : SIMDConvert<I32x4, I16x8, int_wasm_extadd_pairwise_unsigned,
12571257
"extadd_pairwise_i16x8_u", 0xa6>;
12581258

12591259

1260+
// Prototype f64x2 conversions
1261+
defm "" : SIMDConvert<F64x2, I32x4, int_wasm_convert_low_signed,
1262+
"convert_low_i32x4_s", 0x53>;
1263+
defm "" : SIMDConvert<F64x2, I32x4, int_wasm_convert_low_unsigned,
1264+
"convert_low_i32x4_u", 0x54>;
1265+
defm "" : SIMDConvert<I32x4, F64x2, int_wasm_trunc_saturate_zero_signed,
1266+
"trunc_sat_zero_f64x2_s", 0x55>;
1267+
defm "" : SIMDConvert<I32x4, F64x2, int_wasm_trunc_saturate_zero_unsigned,
1268+
"trunc_sat_zero_f64x2_u", 0x56>;
1269+
defm "" : SIMDConvert<F32x4, F64x2, int_wasm_demote_zero,
1270+
"demote_zero_f64x2", 0x57>;
1271+
defm "" : SIMDConvert<F64x2, F32x4, int_wasm_promote_low,
1272+
"promote_low_f32x4", 0x69>;
1273+
12601274
//===----------------------------------------------------------------------===//
12611275
// Quasi-Fused Multiply- Add and Subtract (QFMA/QFMS)
12621276
//===----------------------------------------------------------------------===//

llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,26 @@ define <4 x i32> @trunc_sat_u_v4i32(<4 x float> %x) {
566566
ret <4 x i32> %a
567567
}
568568

569+
; CHECK-LABEL: trunc_sat_zero_signed_v4i32:
570+
; SIMD128-NEXT: .functype trunc_sat_zero_signed_v4i32 (v128) -> (v128){{$}}
571+
; SIMD128-NEXT: i32x4.trunc_sat_zero_f64x2_s $push[[R:[0-9]+]]=, $0{{$}}
572+
; SIMD128-NEXT: return $pop[[R]]{{$}}
573+
declare <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double>)
574+
define <4 x i32> @trunc_sat_zero_signed_v4i32(<2 x double> %a) {
575+
%v = call <4 x i32> @llvm.wasm.trunc.saturate.zero.signed(<2 x double> %a)
576+
ret <4 x i32> %v
577+
}
578+
579+
; CHECK-LABEL: trunc_sat_zero_unsigned_v4i32:
580+
; SIMD128-NEXT: .functype trunc_sat_zero_unsigned_v4i32 (v128) -> (v128){{$}}
581+
; SIMD128-NEXT: i32x4.trunc_sat_zero_f64x2_u $push[[R:[0-9]+]]=, $0{{$}}
582+
; SIMD128-NEXT: return $pop[[R]]{{$}}
583+
declare <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double>)
584+
define <4 x i32> @trunc_sat_zero_unsigned_v4i32(<2 x double> %a) {
585+
%v = call <4 x i32> @llvm.wasm.trunc.saturate.zero.unsigned(<2 x double> %a)
586+
ret <4 x i32> %v
587+
}
588+
569589
; ==============================================================================
570590
; 2 x i64
571591
; ==============================================================================
@@ -820,6 +840,16 @@ define <4 x float> @qfms_v4f32(<4 x float> %a, <4 x float> %b, <4 x float> %c) {
820840
ret <4 x float> %v
821841
}
822842

843+
; CHECK-LABEL: demote_zero_v4f32:
844+
; SIMD128-NEXT: .functype demote_zero_v4f32 (v128) -> (v128){{$}}
845+
; SIMD128-NEXT: f32x4.demote_zero_f64x2 $push[[R:[0-9]+]]=, $0{{$}}
846+
; SIMD128-NEXT: return $pop[[R]]{{$}}
847+
declare <4 x float> @llvm.wasm.demote.zero(<2 x double>)
848+
define <4 x float> @demote_zero_v4f32(<2 x double> %a) {
849+
%v = call <4 x float> @llvm.wasm.demote.zero(<2 x double> %a)
850+
ret <4 x float> %v
851+
}
852+
823853
; ==============================================================================
824854
; 2 x f64
825855
; ==============================================================================
@@ -918,3 +948,33 @@ define <2 x double> @qfms_v2f64(<2 x double> %a, <2 x double> %b, <2 x double> %
918948
)
919949
ret <2 x double> %v
920950
}
951+
952+
; CHECK-LABEL: convert_low_signed_v2f64:
953+
; SIMD128-NEXT: .functype convert_low_signed_v2f64 (v128) -> (v128){{$}}
954+
; SIMD128-NEXT: f64x2.convert_low_i32x4_s $push[[R:[0-9]+]]=, $0{{$}}
955+
; SIMD128-NEXT: return $pop[[R]]{{$}}
956+
declare <2 x double> @llvm.wasm.convert.low.signed(<4 x i32>)
957+
define <2 x double> @convert_low_signed_v2f64(<4 x i32> %a) {
958+
%v = call <2 x double> @llvm.wasm.convert.low.signed(<4 x i32> %a)
959+
ret <2 x double> %v
960+
}
961+
962+
; CHECK-LABEL: convert_low_unsigned_v2f64:
963+
; SIMD128-NEXT: .functype convert_low_unsigned_v2f64 (v128) -> (v128){{$}}
964+
; SIMD128-NEXT: f64x2.convert_low_i32x4_u $push[[R:[0-9]+]]=, $0{{$}}
965+
; SIMD128-NEXT: return $pop[[R]]{{$}}
966+
declare <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32>)
967+
define <2 x double> @convert_low_unsigned_v2f64(<4 x i32> %a) {
968+
%v = call <2 x double> @llvm.wasm.convert.low.unsigned(<4 x i32> %a)
969+
ret <2 x double> %v
970+
}
971+
972+
; CHECK-LABEL: promote_low_v2f64:
973+
; SIMD128-NEXT: .functype promote_low_v2f64 (v128) -> (v128){{$}}
974+
; SIMD128-NEXT: f64x2.promote_low_f32x4 $push[[R:[0-9]+]]=, $0{{$}}
975+
; SIMD128-NEXT: return $pop[[R]]{{$}}
976+
declare <2 x double> @llvm.wasm.promote.low(<4 x float>)
977+
define <2 x double> @promote_low_v2f64(<4 x float> %a) {
978+
%v = call <2 x double> @llvm.wasm.promote.low(<4 x float> %a)
979+
ret <2 x double> %v
980+
}

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,4 +742,22 @@ main:
742742
# CHECK: prefetch.nt 16 # encoding: [0xfd,0xc6,0x01,0x00,0x10]
743743
prefetch.nt 16
744744

745+
# CHECK: f64x2.convert_low_i32x4_s # encoding: [0xfd,0x53]
746+
f64x2.convert_low_i32x4_s
747+
748+
# CHECK: f64x2.convert_low_i32x4_u # encoding: [0xfd,0x54]
749+
f64x2.convert_low_i32x4_u
750+
751+
# CHECK: i32x4.trunc_sat_zero_f64x2_s # encoding: [0xfd,0x55]
752+
i32x4.trunc_sat_zero_f64x2_s
753+
754+
# CHECK: i32x4.trunc_sat_zero_f64x2_u # encoding: [0xfd,0x56]
755+
i32x4.trunc_sat_zero_f64x2_u
756+
757+
# CHECK: f32x4.demote_zero_f64x2 # encoding: [0xfd,0x57]
758+
f32x4.demote_zero_f64x2
759+
760+
# CHECK: f64x2.promote_low_f32x4 # encoding: [0xfd,0x69]
761+
f64x2.promote_low_f32x4
762+
745763
end_function

0 commit comments

Comments
 (0)