Skip to content

Commit 1e9c39a

Browse files
committed
[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
1 parent 7246049 commit 1e9c39a

File tree

2 files changed

+89
-86
lines changed

2 files changed

+89
-86
lines changed

clang/lib/Headers/wasm_simd128.h

Lines changed: 87 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ typedef unsigned int __u32x2
4848
__attribute__((__always_inline__, __nodebug__, __target__("simd128"), \
4949
__min_vector_width__(128)))
5050

51-
#define __REQUIRE_CONSTANT(e) \
52-
_Static_assert(__builtin_constant_p(e), "Expected constant")
51+
#define __REQUIRE_CONSTANT(c) \
52+
__attribute__((__diagnose_if__(!__builtin_constant_p(c), \
53+
#c " must be constant", "error")))
5354

5455
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_v128_load(const void *__mem) {
5556
// UB-free unaligned access copied from xmmintrin.h
@@ -246,88 +247,90 @@ static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_make(double __c0,
246247
return (v128_t)(__f64x2){__c0, __c1};
247248
}
248249

249-
#define wasm_i8x16_const(__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7, __c8, \
250-
__c9, __c10, __c11, __c12, __c13, __c14, __c15) \
251-
__extension__({ \
252-
__REQUIRE_CONSTANT(__c0); \
253-
__REQUIRE_CONSTANT(__c1); \
254-
__REQUIRE_CONSTANT(__c2); \
255-
__REQUIRE_CONSTANT(__c3); \
256-
__REQUIRE_CONSTANT(__c4); \
257-
__REQUIRE_CONSTANT(__c5); \
258-
__REQUIRE_CONSTANT(__c6); \
259-
__REQUIRE_CONSTANT(__c7); \
260-
__REQUIRE_CONSTANT(__c8); \
261-
__REQUIRE_CONSTANT(__c9); \
262-
__REQUIRE_CONSTANT(__c10); \
263-
__REQUIRE_CONSTANT(__c11); \
264-
__REQUIRE_CONSTANT(__c12); \
265-
__REQUIRE_CONSTANT(__c13); \
266-
__REQUIRE_CONSTANT(__c14); \
267-
__REQUIRE_CONSTANT(__c15); \
268-
(v128_t)(__i8x16){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7, \
269-
__c8, __c9, __c10, __c11, __c12, __c13, __c14, __c15}; \
270-
})
271-
272-
#define wasm_i16x8_const(__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7) \
273-
__extension__({ \
274-
__REQUIRE_CONSTANT(__c0); \
275-
__REQUIRE_CONSTANT(__c1); \
276-
__REQUIRE_CONSTANT(__c2); \
277-
__REQUIRE_CONSTANT(__c3); \
278-
__REQUIRE_CONSTANT(__c4); \
279-
__REQUIRE_CONSTANT(__c5); \
280-
__REQUIRE_CONSTANT(__c6); \
281-
__REQUIRE_CONSTANT(__c7); \
282-
(v128_t)(__i16x8){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7}; \
283-
})
284-
285-
#define wasm_i32x4_const(__c0, __c1, __c2, __c3) \
286-
__extension__({ \
287-
__REQUIRE_CONSTANT(__c0); \
288-
__REQUIRE_CONSTANT(__c1); \
289-
__REQUIRE_CONSTANT(__c2); \
290-
__REQUIRE_CONSTANT(__c3); \
291-
(v128_t)(__i32x4){__c0, __c1, __c2, __c3}; \
292-
})
293-
294-
#define wasm_i64x2_const(__c0, __c1) \
295-
__extension__({ \
296-
__REQUIRE_CONSTANT(__c0); \
297-
__REQUIRE_CONSTANT(__c1); \
298-
(v128_t)(__i64x2){__c0, __c1}; \
299-
})
300-
301-
#define wasm_f32x4_const(__c0, __c1, __c2, __c3) \
302-
__extension__({ \
303-
__REQUIRE_CONSTANT(__c0); \
304-
__REQUIRE_CONSTANT(__c1); \
305-
__REQUIRE_CONSTANT(__c2); \
306-
__REQUIRE_CONSTANT(__c3); \
307-
(v128_t)(__f32x4){__c0, __c1, __c2, __c3}; \
308-
})
309-
310-
#define wasm_f64x2_const(__c0, __c1) \
311-
__extension__({ \
312-
__REQUIRE_CONSTANT(__c0); \
313-
__REQUIRE_CONSTANT(__c1); \
314-
(v128_t)(__f64x2){__c0, __c1}; \
315-
})
316-
317-
#define wasm_i8x16_const_splat(__c) \
318-
wasm_i8x16_const(__c, __c, __c, __c, __c, __c, __c, __c, __c, __c, __c, __c, \
319-
__c, __c, __c, __c)
320-
321-
#define wasm_i16x8_const_splat(__c) \
322-
wasm_i16x8_const(__c, __c, __c, __c, __c, __c, __c, __c)
323-
324-
#define wasm_i32x4_const_splat(__c) wasm_i32x4_const(__c, __c, __c, __c)
325-
326-
#define wasm_i64x2_const_splat(__c) wasm_i64x2_const(__c, __c)
327-
328-
#define wasm_f32x4_const_splat(__c) wasm_i32x4_const(__c, __c, __c, __c)
329-
330-
#define wasm_f64x2_const_splat(__c) wasm_i64x2_const(__c, __c)
250+
static __inline__ v128_t __DEFAULT_FN_ATTRS
251+
wasm_i8x16_const(int8_t __c0, int8_t __c1, int8_t __c2, int8_t __c3,
252+
int8_t __c4, int8_t __c5, int8_t __c6, int8_t __c7,
253+
int8_t __c8, int8_t __c9, int8_t __c10, int8_t __c11,
254+
int8_t __c12, int8_t __c13, int8_t __c14, int8_t __c15)
255+
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
256+
__REQUIRE_CONSTANT(__c3) __REQUIRE_CONSTANT(__c4)
257+
__REQUIRE_CONSTANT(__c5) __REQUIRE_CONSTANT(__c6)
258+
__REQUIRE_CONSTANT(__c7) __REQUIRE_CONSTANT(__c8)
259+
__REQUIRE_CONSTANT(__c9) __REQUIRE_CONSTANT(__c10)
260+
__REQUIRE_CONSTANT(__c11) __REQUIRE_CONSTANT(__c12)
261+
__REQUIRE_CONSTANT(__c13) __REQUIRE_CONSTANT(__c14)
262+
__REQUIRE_CONSTANT(__c15) {
263+
return (v128_t)(__i8x16){__c0, __c1, __c2, __c3, __c4, __c5,
264+
__c6, __c7, __c8, __c9, __c10, __c11,
265+
__c12, __c13, __c14, __c15};
266+
}
267+
268+
static __inline__ v128_t __DEFAULT_FN_ATTRS
269+
wasm_i16x8_const(int16_t __c0, int16_t __c1, int16_t __c2, int16_t __c3,
270+
int16_t __c4, int16_t __c5, int16_t __c6, int16_t __c7)
271+
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
272+
__REQUIRE_CONSTANT(__c3) __REQUIRE_CONSTANT(__c4)
273+
__REQUIRE_CONSTANT(__c5) __REQUIRE_CONSTANT(__c6)
274+
__REQUIRE_CONSTANT(__c7) {
275+
return (v128_t)(__i16x8){__c0, __c1, __c2, __c3, __c4, __c5, __c6, __c7};
276+
}
277+
278+
static __inline__ v128_t __DEFAULT_FN_ATTRS
279+
wasm_i32x4_const(int32_t __c0, int32_t __c1, int32_t __c2, int32_t __c3)
280+
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
281+
__REQUIRE_CONSTANT(__c3) {
282+
return (v128_t)(__i32x4){__c0, __c1, __c2, __c3};
283+
}
284+
285+
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_const(int64_t __c0,
286+
int64_t __c1)
287+
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) {
288+
return (v128_t)(__i64x2){__c0, __c1};
289+
}
290+
291+
static __inline__ v128_t __DEFAULT_FN_ATTRS
292+
wasm_f32x4_const(float __c0, float __c1, float __c2, float __c3)
293+
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) __REQUIRE_CONSTANT(__c2)
294+
__REQUIRE_CONSTANT(__c3) {
295+
return (v128_t)(__f32x4){__c0, __c1, __c2, __c3};
296+
}
297+
298+
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_const(double __c0,
299+
double __c1)
300+
__REQUIRE_CONSTANT(__c0) __REQUIRE_CONSTANT(__c1) {
301+
return (v128_t)(__f64x2){__c0, __c1};
302+
}
303+
304+
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_const_splat(int8_t __c)
305+
__REQUIRE_CONSTANT(__c) {
306+
return (v128_t)(__i8x16){__c, __c, __c, __c, __c, __c, __c, __c,
307+
__c, __c, __c, __c, __c, __c, __c, __c};
308+
}
309+
310+
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i16x8_const_splat(int16_t __c)
311+
__REQUIRE_CONSTANT(__c) {
312+
return (v128_t)(__i16x8){__c, __c, __c, __c, __c, __c, __c, __c};
313+
}
314+
315+
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i32x4_const_splat(int32_t __c)
316+
__REQUIRE_CONSTANT(__c) {
317+
return (v128_t)(__i32x4){__c, __c, __c, __c};
318+
}
319+
320+
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i64x2_const_splat(int64_t __c)
321+
__REQUIRE_CONSTANT(__c) {
322+
return (v128_t)(__i64x2){__c, __c};
323+
}
324+
325+
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f32x4_const_splat(float __c)
326+
__REQUIRE_CONSTANT(__c) {
327+
return (v128_t)(__f32x4){__c, __c, __c, __c};
328+
}
329+
330+
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_f64x2_const_splat(double __c)
331+
__REQUIRE_CONSTANT(__c) {
332+
return (v128_t)(__f64x2){__c, __c};
333+
}
331334

332335
static __inline__ v128_t __DEFAULT_FN_ATTRS wasm_i8x16_splat(int8_t __a) {
333336
return (v128_t)(__i8x16){__a, __a, __a, __a, __a, __a, __a, __a,

clang/test/Headers/wasm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -420,15 +420,15 @@ v128_t test_i64x2_const_splat() {
420420

421421
// CHECK-LABEL: @test_f32x4_const_splat(
422422
// CHECK-NEXT: entry:
423-
// CHECK-NEXT: ret <4 x i32> <i32 42, i32 42, i32 42, i32 42>
423+
// CHECK-NEXT: ret <4 x i32> <i32 1109917696, i32 1109917696, i32 1109917696, i32 1109917696>
424424
//
425425
v128_t test_f32x4_const_splat() {
426426
return wasm_f32x4_const_splat(42);
427427
}
428428

429429
// CHECK-LABEL: @test_f64x2_const_splat(
430430
// CHECK-NEXT: entry:
431-
// CHECK-NEXT: ret <4 x i32> <i32 42, i32 0, i32 42, i32 0>
431+
// CHECK-NEXT: ret <4 x i32> <i32 0, i32 1078263808, i32 0, i32 1078263808>
432432
//
433433
v128_t test_f64x2_const_splat() {
434434
return wasm_f64x2_const_splat(42);

0 commit comments

Comments
 (0)