[WebAssembly] Add SIMD const_splat intrinsics
authorThomas Lively <tlively@google.com>
Wed, 5 May 2021 20:46:45 +0000 (13:46 -0700)
committerThomas Lively <tlively@google.com>
Wed, 5 May 2021 20:46:45 +0000 (13:46 -0700)
These intrinsics do not correspond to their own underlying instruction, but are
a convenience for the common case of materializing a constant vector that has
the same value in each lane.

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

clang/lib/Headers/wasm_simd128.h
clang/test/Headers/wasm.c

index 2157125..e6fb049 100644 (file)
@@ -229,6 +229,11 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_make(int32_t __c0,
   return (v128_t)(__i32x4){__c0, __c1, __c2, __c3};
 }
 
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_make(int64_t __c0,
+                                                            int64_t __c1) {
+  return (v128_t)(__i64x2){__c0, __c1};
+}
+
 static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_make(float __c0,
                                                             float __c1,
                                                             float __c2,
@@ -236,11 +241,6 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_make(float __c0,
   return (v128_t)(__f32x4){__c0, __c1, __c2, __c3};
 }
 
-static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_make(int64_t __c0,
-                                                            int64_t __c1) {
-  return (v128_t)(__i64x2){__c0, __c1};
-}
-
 static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_make(double __c0,
                                                             double __c1) {
   return (v128_t)(__f64x2){__c0, __c1};
@@ -291,20 +291,20 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_make(double __c0,
     (v128_t)(__i32x4){__c0, __c1, __c2, __c3};                                 \
   })
 
-#define wasm_f32x4_const(__c0, __c1, __c2, __c3)                               \
+#define wasm_i64x2_const(__c0, __c1)                                           \
   __extension__({                                                              \
     __REQUIRE_CONSTANT(__c0);                                                  \
     __REQUIRE_CONSTANT(__c1);                                                  \
-    __REQUIRE_CONSTANT(__c2);                                                  \
-    __REQUIRE_CONSTANT(__c3);                                                  \
-    (v128_t)(__f32x4){__c0, __c1, __c2, __c3};                                 \
+    (v128_t)(__i64x2){__c0, __c1};                                             \
   })
 
-#define wasm_i64x2_const(__c0, __c1)                                           \
+#define wasm_f32x4_const(__c0, __c1, __c2, __c3)                               \
   __extension__({                                                              \
     __REQUIRE_CONSTANT(__c0);                                                  \
     __REQUIRE_CONSTANT(__c1);                                                  \
-    (v128_t)(__i64x2){__c0, __c1};                                             \
+    __REQUIRE_CONSTANT(__c2);                                                  \
+    __REQUIRE_CONSTANT(__c3);                                                  \
+    (v128_t)(__f32x4){__c0, __c1, __c2, __c3};                                 \
   })
 
 #define wasm_f64x2_const(__c0, __c1)                                           \
@@ -314,6 +314,21 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_make(double __c0,
     (v128_t)(__f64x2){__c0, __c1};                                             \
   })
 
+#define wasm_i8x16_const_splat(__c)                                            \
+  wasm_i8x16_const(__c, __c, __c, __c, __c, __c, __c, __c, __c, __c, __c, __c, \
+                   __c, __c, __c, __c)
+
+#define wasm_i16x8_const_splat(__c)                                            \
+  wasm_i16x8_const(__c, __c, __c, __c, __c, __c, __c, __c)
+
+#define wasm_i32x4_const_splat(__c) wasm_i32x4_const(__c, __c, __c, __c)
+
+#define wasm_i64x2_const_splat(__c) wasm_i64x2_const(__c, __c)
+
+#define wasm_f32x4_const_splat(__c) wasm_i32x4_const(__c, __c, __c, __c)
+
+#define wasm_f64x2_const_splat(__c) wasm_i64x2_const(__c, __c)
+
 static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_splat(int8_t __a) {
   return (v128_t)(__i8x16){__a, __a, __a, __a, __a, __a, __a, __a,
                            __a, __a, __a, __a, __a, __a, __a, __a};
index 30b15dd..f5076ae 100644 (file)
@@ -386,6 +386,54 @@ v128_t test_f64x2_const() {
   return wasm_f64x2_const(0, 1);
 }
 
+// CHECK-LABEL: @test_i8x16_const_splat(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> <i32 707406378, i32 707406378, i32 707406378, i32 707406378>
+//
+v128_t test_i8x16_const_splat() {
+  return wasm_i8x16_const_splat(42);
+}
+
+// CHECK-LABEL: @test_i16x8_const_splat(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> <i32 2752554, i32 2752554, i32 2752554, i32 2752554>
+//
+v128_t test_i16x8_const_splat() {
+  return wasm_i16x8_const_splat(42);
+}
+
+// CHECK-LABEL: @test_i32x4_const_splat(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> <i32 42, i32 42, i32 42, i32 42>
+//
+v128_t test_i32x4_const_splat() {
+  return wasm_i32x4_const_splat(42);
+}
+
+// CHECK-LABEL: @test_i64x2_const_splat(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> <i32 42, i32 0, i32 42, i32 0>
+//
+v128_t test_i64x2_const_splat() {
+  return wasm_i64x2_const_splat(42);
+}
+
+// CHECK-LABEL: @test_f32x4_const_splat(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> <i32 42, i32 42, i32 42, i32 42>
+//
+v128_t test_f32x4_const_splat() {
+  return wasm_f32x4_const_splat(42);
+}
+
+// CHECK-LABEL: @test_f64x2_const_splat(
+// CHECK-NEXT:  entry:
+// CHECK-NEXT:    ret <4 x i32> <i32 42, i32 0, i32 42, i32 0>
+//
+v128_t test_f64x2_const_splat() {
+  return wasm_f64x2_const_splat(42);
+}
+
 // CHECK-LABEL: @test_i8x16_splat(
 // CHECK-NEXT:  entry:
 // CHECK-NEXT:    [[VECINIT_I:%.*]] = insertelement <16 x i8> undef, i8 [[A:%.*]], i32 0