[clang] 1e9c39a - [WebAssembly] Use functions instead of macros for const SIMD intrinsics

Thomas Lively via cfe-commits cfe-commits at lists.llvm.org
Fri May 7 11:50:26 PDT 2021


Author: Thomas Lively
Date: 2021-05-07T11:50:19-07:00
New Revision: 1e9c39a3f982fe2f50cd19c74be8b64dfba4baad

URL: https://github.com/llvm/llvm-project/commit/1e9c39a3f982fe2f50cd19c74be8b64dfba4baad
DIFF: https://github.com/llvm/llvm-project/commit/1e9c39a3f982fe2f50cd19c74be8b64dfba4baad.diff

LOG: [WebAssembly] Use functions instead of macros for const SIMD intrinsics

To improve hygiene, consistency, and usability, it would be good to replace all
the macro intrinsics in wasm_simd128.h with functions. The reason for using
macros in the first place was to enforce the use of constants for some arguments
using `_Static_assert` with `__builtin_constant_p`. This commit switches to
using functions and uses the `__diagnose_if__` attribute rather than
`_Static_assert` to enforce constantness.

The remaining macro intrinsics cannot be made into functions until the builtin
functions they are implemented with can be replaced with normal code patterns
because the builtin functions themselves require that their arguments are
constants.

This commit also fixes a bug with the const_splat intrinsics in which the f32x4
and f64x2 variants were incorrectly producing integer vectors.

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

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/wasm_simd128.h b/clang/lib/Headers/wasm_simd128.h
index cd11f096dd956..fe087d2442a16 100644
--- a/clang/lib/Headers/wasm_simd128.h
+++ b/clang/lib/Headers/wasm_simd128.h
@@ -48,8 +48,9 @@ typedef unsigned int __u32x2
   __attribute__((__always_inline__, __nodebug__, __target__("simd128"),        \
                  __min_vector_width__(128)))
 
-#define __REQUIRE_CONSTANT(e)                                                  \
-  _Static_assert(__builtin_constant_p(e), "Expected constant")
+#define __REQUIRE_CONSTANT(c)                                                  \
+  __attribute__((__diagnose_if__(!__builtin_constant_p(c),                     \
+                                 #c " must be constant", "error")))
 
 static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_load(const void *__mem) {
   // UB-free unaligned access copied from xmmintrin.h
@@ -246,88 +247,90 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_make(double __c0,
   return (v128_t)(__f64x2){__c0, __c1};
 }
 
-#define wasm_i8x16_const(__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7, __c8, \
-                         __c9, __c10, __c11, __c12, __c13, __c14, __c15)       \
-  __extension__({                                                              \
-    __REQUIRE_CONSTANT(__c0);                                                  \
-    __REQUIRE_CONSTANT(__c1);                                                  \
-    __REQUIRE_CONSTANT(__c2);                                                  \
-    __REQUIRE_CONSTANT(__c3);                                                  \
-    __REQUIRE_CONSTANT(__c4);                                                  \
-    __REQUIRE_CONSTANT(__c5);                                                  \
-    __REQUIRE_CONSTANT(__c6);                                                  \
-    __REQUIRE_CONSTANT(__c7);                                                  \
-    __REQUIRE_CONSTANT(__c8);                                                  \
-    __REQUIRE_CONSTANT(__c9);                                                  \
-    __REQUIRE_CONSTANT(__c10);                                                 \
-    __REQUIRE_CONSTANT(__c11);                                                 \
-    __REQUIRE_CONSTANT(__c12);                                                 \
-    __REQUIRE_CONSTANT(__c13);                                                 \
-    __REQUIRE_CONSTANT(__c14);                                                 \
-    __REQUIRE_CONSTANT(__c15);                                                 \
-    (v128_t)(__i8x16){__c0, __c1, __c2,  __c3,  __c4,  __c5,  __c6,  __c7,     \
-                      __c8, __c9, __c10, __c11, __c12, __c13, __c14, __c15};   \
-  })
-
-#define wasm_i16x8_const(__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7)       \
-  __extension__({                                                              \
-    __REQUIRE_CONSTANT(__c0);                                                  \
-    __REQUIRE_CONSTANT(__c1);                                                  \
-    __REQUIRE_CONSTANT(__c2);                                                  \
-    __REQUIRE_CONSTANT(__c3);                                                  \
-    __REQUIRE_CONSTANT(__c4);                                                  \
-    __REQUIRE_CONSTANT(__c5);                                                  \
-    __REQUIRE_CONSTANT(__c6);                                                  \
-    __REQUIRE_CONSTANT(__c7);                                                  \
-    (v128_t)(__i16x8){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7};         \
-  })
-
-#define wasm_i32x4_const(__c0, __c1, __c2, __c3)                               \
-  __extension__({                                                              \
-    __REQUIRE_CONSTANT(__c0);                                                  \
-    __REQUIRE_CONSTANT(__c1);                                                  \
-    __REQUIRE_CONSTANT(__c2);                                                  \
-    __REQUIRE_CONSTANT(__c3);                                                  \
-    (v128_t)(__i32x4){__c0, __c1, __c2, __c3};                                 \
-  })
-
-#define wasm_i64x2_const(__c0, __c1)                                           \
-  __extension__({                                                              \
-    __REQUIRE_CONSTANT(__c0);                                                  \
-    __REQUIRE_CONSTANT(__c1);                                                  \
-    (v128_t)(__i64x2){__c0, __c1};                                             \
-  })
-
-#define wasm_f32x4_const(__c0, __c1, __c2, __c3)                               \
-  __extension__({                                                              \
-    __REQUIRE_CONSTANT(__c0);                                                  \
-    __REQUIRE_CONSTANT(__c1);                                                  \
-    __REQUIRE_CONSTANT(__c2);                                                  \
-    __REQUIRE_CONSTANT(__c3);                                                  \
-    (v128_t)(__f32x4){__c0, __c1, __c2, __c3};                                 \
-  })
-
-#define wasm_f64x2_const(__c0, __c1)                                           \
-  __extension__({                                                              \
-    __REQUIRE_CONSTANT(__c0);                                                  \
-    __REQUIRE_CONSTANT(__c1);                                                  \
-    (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_const(int8_t __c0, int8_t __c1, int8_t __c2, int8_t __c3,
+                 int8_t __c4, int8_t __c5, int8_t __c6, int8_t __c7,
+                 int8_t __c8, int8_t __c9, int8_t __c10, int8_t __c11,
+                 int8_t __c12, int8_t __c13, int8_t __c14, int8_t __c15)
+    __REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
+        __REQUIRE_CONSTANT(__c3) __REQUIRE_CONSTANT(__c4)
+            __REQUIRE_CONSTANT(__c5) __REQUIRE_CONSTANT(__c6)
+                __REQUIRE_CONSTANT(__c7) __REQUIRE_CONSTANT(__c8)
+                    __REQUIRE_CONSTANT(__c9) __REQUIRE_CONSTANT(__c10)
+                        __REQUIRE_CONSTANT(__c11) __REQUIRE_CONSTANT(__c12)
+                            __REQUIRE_CONSTANT(__c13) __REQUIRE_CONSTANT(__c14)
+                                __REQUIRE_CONSTANT(__c15) {
+  return (v128_t)(__i8x16){__c0,  __c1,  __c2,  __c3, __c4,  __c5,
+                           __c6,  __c7,  __c8,  __c9, __c10, __c11,
+                           __c12, __c13, __c14, __c15};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS
+wasm_i16x8_const(int16_t __c0, int16_t __c1, int16_t __c2, int16_t __c3,
+                 int16_t __c4, int16_t __c5, int16_t __c6, int16_t __c7)
+    __REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
+        __REQUIRE_CONSTANT(__c3) __REQUIRE_CONSTANT(__c4)
+            __REQUIRE_CONSTANT(__c5) __REQUIRE_CONSTANT(__c6)
+                __REQUIRE_CONSTANT(__c7) {
+  return (v128_t)(__i16x8){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS
+wasm_i32x4_const(int32_t __c0, int32_t __c1, int32_t __c2, int32_t __c3)
+    __REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
+        __REQUIRE_CONSTANT(__c3) {
+  return (v128_t)(__i32x4){__c0, __c1, __c2, __c3};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_const(int64_t __c0,
+                                                             int64_t __c1)
+    __REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) {
+  return (v128_t)(__i64x2){__c0, __c1};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS
+wasm_f32x4_const(float __c0, float __c1, float __c2, float __c3)
+    __REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
+        __REQUIRE_CONSTANT(__c3) {
+  return (v128_t)(__f32x4){__c0, __c1, __c2, __c3};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_const(double __c0,
+                                                             double __c1)
+    __REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) {
+  return (v128_t)(__f64x2){__c0, __c1};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_const_splat(int8_t __c)
+    __REQUIRE_CONSTANT(__c) {
+  return (v128_t)(__i8x16){__c, __c, __c, __c, __c, __c, __c, __c,
+                           __c, __c, __c, __c, __c, __c, __c, __c};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_const_splat(int16_t __c)
+    __REQUIRE_CONSTANT(__c) {
+  return (v128_t)(__i16x8){__c, __c, __c, __c, __c, __c, __c, __c};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_const_splat(int32_t __c)
+    __REQUIRE_CONSTANT(__c) {
+  return (v128_t)(__i32x4){__c, __c, __c, __c};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_const_splat(int64_t __c)
+    __REQUIRE_CONSTANT(__c) {
+  return (v128_t)(__i64x2){__c, __c};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_const_splat(float __c)
+    __REQUIRE_CONSTANT(__c) {
+  return (v128_t)(__f32x4){__c, __c, __c, __c};
+}
+
+static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_const_splat(double __c)
+    __REQUIRE_CONSTANT(__c) {
+  return (v128_t)(__f64x2){__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,

diff  --git a/clang/test/Headers/wasm.c b/clang/test/Headers/wasm.c
index 409da99d43a70..8b87eb2c0e2ec 100644
--- a/clang/test/Headers/wasm.c
+++ b/clang/test/Headers/wasm.c
@@ -420,7 +420,7 @@ v128_t test_i64x2_const_splat() {
 
 // CHECK-LABEL: @test_f32x4_const_splat(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    ret <4 x i32> <i32 42, i32 42, i32 42, i32 42>
+// CHECK-NEXT:    ret <4 x i32> <i32 1109917696, i32 1109917696, i32 1109917696, i32 1109917696>
 //
 v128_t test_f32x4_const_splat() {
   return wasm_f32x4_const_splat(42);
@@ -428,7 +428,7 @@ v128_t test_f32x4_const_splat() {
 
 // CHECK-LABEL: @test_f64x2_const_splat(
 // CHECK-NEXT:  entry:
-// CHECK-NEXT:    ret <4 x i32> <i32 42, i32 0, i32 42, i32 0>
+// CHECK-NEXT:    ret <4 x i32> <i32 0, i32 1078263808, i32 0, i32 1078263808>
 //
 v128_t test_f64x2_const_splat() {
   return wasm_f64x2_const_splat(42);


        


More information about the cfe-commits mailing list