[llvm] 4b68b64 - [WebAssembly] Prototype i8x16 to i32x4 widening instructions

Thomas Lively via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 28 10:59:43 PST 2021


Author: Thomas Lively
Date: 2021-01-28T10:59:32-08:00
New Revision: 4b68b64dcc5bcd6f29779b820791611c60438385

URL: https://github.com/llvm/llvm-project/commit/4b68b64dcc5bcd6f29779b820791611c60438385
DIFF: https://github.com/llvm/llvm-project/commit/4b68b64dcc5bcd6f29779b820791611c60438385.diff

LOG: [WebAssembly] Prototype i8x16 to i32x4 widening instructions

As proposed in https://github.com/WebAssembly/simd/pull/395 and matching the
opcodes used in V8:
https://chromium-review.googlesource.com/c/v8/v8/+/2617385/4/src/wasm/wasm-opcodes.h

Differential Revision: https://reviews.llvm.org/D95557

Added: 
    

Modified: 
    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

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def
index bb7d6d379e58..84f346bcb928 100644
--- a/clang/include/clang/Basic/BuiltinsWebAssembly.def
+++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def
@@ -206,6 +206,9 @@ TARGET_BUILTIN(__builtin_wasm_widen_high_s_i32x4_i64x2, "V2LLiV4i", "nc", "simd1
 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")

diff  --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 113541bd5024..973a20f2f58c 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -17220,6 +17220,24 @@ Value *CodeGenFunction::EmitWebAssemblyBuiltinExpr(unsigned BuiltinID,
     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));

diff  --git a/clang/test/CodeGen/builtins-wasm.c b/clang/test/CodeGen/builtins-wasm.c
index 61fc76cd1873..771764c85d6b 100644
--- a/clang/test/CodeGen/builtins-wasm.c
+++ b/clang/test/CodeGen/builtins-wasm.c
@@ -976,6 +976,18 @@ u64x2 widen_high_u_i32x4_i64x2(u32x4 x) {
   // 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)

diff  --git a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
index d306d0ccb90d..323b9a770c05 100644
--- a/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
+++ b/llvm/include/llvm/IR/IntrinsicsWebAssembly.td
@@ -348,6 +348,14 @@ def int_wasm_promote_low :
   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
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
index 9f3d0f4ab2c3..404cbcdf56b8 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrSIMD.td
@@ -1256,7 +1256,6 @@ defm "" : SIMDConvert<I32x4, I16x8, int_wasm_extadd_pairwise_signed,
 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<F32x4, F64x2, int_wasm_demote_zero,
 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)
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
index 59f31f09b7f4..f223615c57a1 100644
--- a/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
+++ b/llvm/test/CodeGen/WebAssembly/simd-intrinsics.ll
@@ -586,6 +586,27 @@ define <4 x i32> @trunc_sat_zero_unsigned_v4i32(<2 x double> %a) {
   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
 ; ==============================================================================

diff  --git a/llvm/test/MC/WebAssembly/simd-encodings.s b/llvm/test/MC/WebAssembly/simd-encodings.s
index 7a84548bd584..099c6489e703 100644
--- a/llvm/test/MC/WebAssembly/simd-encodings.s
+++ b/llvm/test/MC/WebAssembly/simd-encodings.s
@@ -760,4 +760,10 @@ main:
     # 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


        


More information about the llvm-commits mailing list