ngzhian created this revision.
Herald added subscribers: ecnelises, sunfish, hiraditya, jgravelle-google, 
sbc100, dschuff.
ngzhian requested review of this revision.
Herald added subscribers: llvm-commits, cfe-commits, aheejin.
Herald added projects: clang, LLVM.

Add i32x4.relaxed_trunc_f32x4_s, i32x4.relaxed_trunc_f32x4_u,
i32x4.relaxed_trunc_f64x2_s_zero, i32x4.relaxed_trunc_f64x2_u_zero.

These are only exposed as builtins, and require user opt-in.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D112186

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/WebAssemblyISD.def
  llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
  llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll

Index: llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
===================================================================
--- llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
+++ llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
@@ -466,6 +466,40 @@
   ret <4 x i32> %a
 }
 
+; CHECK-LABEL: relaxed_trunc_s_v4i32:
+; NO-CHECK-NOT: f32x4
+; CHECK-NEXT: .functype relaxed_trunc_s_v4i32 (v128) -> (v128){{$}}
+; CHECK-NEXT: i32x4.relaxed_trunc_f32x4_s $push[[R:[0-9]+]]=, $0
+; CHECK-NEXT: return $pop[[R]]
+declare <4 x i32> @llvm.wasm.relaxed.trunc.signed.v4i32.v4f32(<4 x float>)
+define <4 x i32> @relaxed_trunc_s_v4i32(<4 x float> %x) {
+  %a = call <4 x i32> @llvm.wasm.relaxed.trunc.signed.v4i32.v4f32(<4 x float> %x)
+  ret <4 x i32> %a
+}
+
+; CHECK-LABEL: relaxed_trunc_u_v4i32:
+; NO-CHECK-NOT: f32x4
+; CHECK-NEXT: .functype relaxed_trunc_u_v4i32 (v128) -> (v128){{$}}
+; CHECK-NEXT: i32x4.relaxed_trunc_f32x4_u $push[[R:[0-9]+]]=, $0
+; CHECK-NEXT: return $pop[[R]]
+declare <4 x i32> @llvm.wasm.relaxed.trunc.unsigned.v4i32.v4f32(<4 x float>)
+define <4 x i32> @relaxed_trunc_u_v4i32(<4 x float> %x) {
+  %a = call <4 x i32> @llvm.wasm.relaxed.trunc.unsigned.v4i32.v4f32(<4 x float> %x)
+  ret <4 x i32> %a
+}
+
+; CHECK-LABEL: relaxed_trunc_zero_s_v4i32:
+; CHECK-NEXT: .functype relaxed_trunc_zero_s_v4i32 (v128) -> (v128){{$}}
+; CHECK-NEXT: i32x4.relaxed_trunc_zero_f64x2_s $push[[R:[0-9]+]]=, $0{{$}}
+; CHECK-NEXT: return $pop[[R]]{{$}}
+declare <2 x i32> @llvm.wasm.relaxed.trunc.zero.signed.v2i32.v2f64(<2 x double>)
+define <4 x i32> @relaxed_trunc_zero_s_v4i32(<2 x double> %x) {
+  %v = call <2 x i32> @llvm.wasm.relaxed.trunc.zero.signed.v2i32.v2f64(<2 x double> %x)
+  %a = shufflevector <2 x i32> %v, <2 x i32> <i32 0, i32 0>,
+           <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  ret <4 x i32> %a
+}
+
 ; CHECK-LABEL: trunc_sat_zero_s_v4i32:
 ; CHECK-NEXT: .functype trunc_sat_zero_s_v4i32 (v128) -> (v128){{$}}
 ; CHECK-NEXT: i32x4.trunc_sat_zero_f64x2_s $push[[R:[0-9]+]]=, $0{{$}}
Index: llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -1392,3 +1392,20 @@
 
 defm "" : SIMD_RELAXED_FMINMAX<F32x4, 0xb4, 0xe2>;
 defm "" : SIMD_RELAXED_FMINMAX<F64x2, 0xd4, 0xee>;
+
+//===----------------------------------------------------------------------===//
+// Relaxed floating-point to int conversions
+//===----------------------------------------------------------------------===//
+
+multiclass SIMD_RELAXED_CONVERT<Vec vec, Vec arg, SDPatternOperator op, string name, bits<32> simdop> {
+  defm op#_#vec :
+    RELAXED_I<(outs V128:$dst), (ins V128:$vec), (outs), (ins),
+              [(set (vec.vt V128:$dst), (vec.vt (op (arg.vt V128:$vec))))],
+              vec.prefix#"."#name#"\t$dst, $vec", vec.prefix#"."#name, simdop>;
+}
+
+defm "" : SIMD_RELAXED_CONVERT<I32x4, F32x4, int_wasm_relaxed_trunc_signed, "relaxed_trunc_f32x4_s", 0xa5>;
+defm "" : SIMD_RELAXED_CONVERT<I32x4, F32x4, int_wasm_relaxed_trunc_unsigned, "relaxed_trunc_f32x4_u", 0xa6>;
+
+defm "" : SIMD_RELAXED_CONVERT<I32x4, F64x2, int_wasm_relaxed_trunc_zero_signed, "relaxed_trunc_f64x2_s_zero", 0xc5>;
+defm "" : SIMD_RELAXED_CONVERT<I32x4, F64x2, int_wasm_relaxed_trunc_zero_unsigned, "relaxed_trunc_f64x2_u_zero", 0xc6>;
Index: llvm/lib/Target/WebAssembly/WebAssemblyISD.def
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISD.def
+++ llvm/lib/Target/WebAssembly/WebAssemblyISD.def
@@ -50,3 +50,7 @@
 HANDLE_MEM_NODETYPE(GLOBAL_SET)
 HANDLE_MEM_NODETYPE(TABLE_GET)
 HANDLE_MEM_NODETYPE(TABLE_SET)
+
+// Relaxed SIMD proposal.
+HANDLE_NODETYPE(RELAXED_TRUNC_ZERO_S)
+HANDLE_NODETYPE(RELAXED_TRUNC_ZERO_U)
Index: llvm/include/llvm/IR/IntrinsicsWebAssembly.td
===================================================================
--- llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -214,6 +214,27 @@
             [LLVMMatchType<0>, LLVMMatchType<0>],
             [IntrNoMem, IntrSpeculatable]>;
 
+def int_wasm_relaxed_trunc_signed:
+  Intrinsic<[llvm_anyvector_ty],
+            [llvm_anyvector_ty],
+            [IntrNoMem, IntrSpeculatable]>;
+
+def int_wasm_relaxed_trunc_unsigned:
+  Intrinsic<[llvm_anyvector_ty],
+            [llvm_anyvector_ty],
+            [IntrNoMem, IntrSpeculatable]>;
+
+def int_wasm_relaxed_trunc_zero_signed:
+  Intrinsic<[llvm_anyvector_ty],
+            [llvm_anyvector_ty],
+            [IntrNoMem, IntrSpeculatable]>;
+
+def int_wasm_relaxed_trunc_zero_unsigned:
+  Intrinsic<[llvm_anyvector_ty],
+            [llvm_anyvector_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
@@ -765,3 +765,34 @@
   // WEBASSEMBLY-SAME: <2 x double> %a, <2 x double> %b)
   // WEBASSEMBLY-NEXT: ret
 }
+
+i32x4 relaxed_trunc_s_i32x4_f32x4(f32x4 f) {
+  return __builtin_wasm_relaxed_trunc_s_i32x4_f32x4(f);
+  // WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.trunc.signed.v4i32.v4f32(<4 x float> %f)
+  // WEBASSEMBLY-NEXT: ret
+}
+
+i32x4 relaxed_trunc_u_i32x4_f32x4(f32x4 f) {
+  return __builtin_wasm_relaxed_trunc_u_i32x4_f32x4(f);
+  // WEBASSEMBLY: call <4 x i32> @llvm.wasm.relaxed.trunc.unsigned.v4i32.v4f32(<4 x float> %f)
+  // WEBASSEMBLY-NEXT: ret
+}
+
+i32x4 relaxed_trunc_zero_s_i32x4_f64x2(f64x2 x) {
+  return __builtin_wasm_relaxed_trunc_zero_s_i32x4_f64x2(x);
+  // WEBASSEMBLY: %0 = tail call <2 x i32> @llvm.wasm.relaxed.trunc.zero.signed.v2i32.v2f64(<2 x double> %x)
+  // WEBASSEMBLY: %1 = shufflevector <2 x i32> %0, <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  // WEBASSEMBLY: ret <4 x i32> %1
+}
+
+u32x4 relaxed_trunc_zero_u_i32x4_f64x2(f64x2 x) {
+  return __builtin_wasm_relaxed_trunc_zero_u_i32x4_f64x2(x);
+  // WEBASSEMBLY: %0 = tail call <2 x i32> @llvm.wasm.relaxed.trunc.zero.unsigned.v2i32.v2f64(<2 x double> %x)
+  // WEBASSEMBLY: %1 = shufflevector <2 x i32> %0, <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
+  // WEBASSEMBLY: ret <4 x i32> %1
+}
+
+
+/* i32x4 trunc_saturate_u_i32x4_f32x4(f32x4 f) { */
+/*   return __builtin_wasm_trunc_saturate_u_i32x4_f32x4(f); */
+/* } */
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -18247,7 +18247,9 @@
     return Builder.CreateCall(Callee, {Low, High});
   }
   case WebAssembly::BI__builtin_wasm_trunc_sat_zero_s_f64x2_i32x4:
-  case WebAssembly::BI__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4: {
+  case WebAssembly::BI__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4:
+  case WebAssembly::BI__builtin_wasm_relaxed_trunc_zero_s_i32x4_f64x2:
+  case WebAssembly::BI__builtin_wasm_relaxed_trunc_zero_u_i32x4_f64x2: {
     Value *Vec = EmitScalarExpr(E->getArg(0));
     unsigned IntNo;
     switch (BuiltinID) {
@@ -18257,6 +18259,12 @@
     case WebAssembly::BI__builtin_wasm_trunc_sat_zero_u_f64x2_i32x4:
       IntNo = Intrinsic::fptoui_sat;
       break;
+    case WebAssembly::BI__builtin_wasm_relaxed_trunc_zero_s_i32x4_f64x2:
+      IntNo = Intrinsic::wasm_relaxed_trunc_zero_signed;
+      break;
+    case WebAssembly::BI__builtin_wasm_relaxed_trunc_zero_u_i32x4_f64x2:
+      IntNo = Intrinsic::wasm_relaxed_trunc_zero_unsigned;
+      break;
     default:
       llvm_unreachable("unexpected builtin ID");
     }
@@ -18347,6 +18355,26 @@
     Function *Callee = CGM.getIntrinsic(IntNo, LHS->getType());
     return Builder.CreateCall(Callee, {LHS, RHS});
   }
+  case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_i32x4_f32x4:
+  case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_i32x4_f32x4: {
+    Value *Vec = EmitScalarExpr(E->getArg(0));
+    unsigned IntNo;
+    switch (BuiltinID) {
+    case WebAssembly::BI__builtin_wasm_relaxed_trunc_s_i32x4_f32x4:
+      IntNo = Intrinsic::wasm_relaxed_trunc_signed;
+      break;
+    case WebAssembly::BI__builtin_wasm_relaxed_trunc_u_i32x4_f32x4:
+      IntNo = Intrinsic::wasm_relaxed_trunc_unsigned;
+      break;
+    default:
+      llvm_unreachable("unexpected builtin ID");
+    }
+    llvm::Type *SrcT = Vec->getType();
+    llvm::Type *TruncT =
+        SrcT->getWithNewType(llvm::IntegerType::get(getLLVMContext(), 32));
+    Function *Callee = CGM.getIntrinsic(IntNo, {TruncT, SrcT});
+    return Builder.CreateCall(Callee, {Vec});
+  }
   default:
     return nullptr;
   }
Index: clang/include/clang/Basic/BuiltinsWebAssembly.def
===================================================================
--- clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -179,5 +179,10 @@
 TARGET_BUILTIN(__builtin_wasm_relaxed_min_f64x2, "V2dV2dV2d", "nc", "relaxed-simd")
 TARGET_BUILTIN(__builtin_wasm_relaxed_max_f64x2, "V2dV2dV2d", "nc", "relaxed-simd")
 
+TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_s_i32x4_f32x4, "V4iV4f", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_u_i32x4_f32x4, "V4iV4f", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_zero_s_i32x4_f64x2, "V4iV2d", "nc", "relaxed-simd")
+TARGET_BUILTIN(__builtin_wasm_relaxed_trunc_zero_u_i32x4_f64x2, "V4UiV2d", "nc", "relaxed-simd")
+
 #undef BUILTIN
 #undef TARGET_BUILTIN
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to