diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2022-02-08 11:21:46 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2022-02-08 11:22:01 +0000 |
commit | c00db971597557e952901eac4be131157d1d5eb9 (patch) | |
tree | 451f4ab434c80bc5106616f30e8e27c78b25d2ba /clang/test/Sema/builtins-elementwise-math.c | |
parent | 95b8a3e52050d68ca5e8f6f8d1b810f6c23b4cea (diff) | |
download | llvm-c00db971597557e952901eac4be131157d1d5eb9.zip llvm-c00db971597557e952901eac4be131157d1d5eb9.tar.gz llvm-c00db971597557e952901eac4be131157d1d5eb9.tar.bz2 |
[Clang] Add elementwise saturated add/sub builtins
This patch implements `__builtin_elementwise_add_sat` and `__builtin_elementwise_sub_sat` builtins.
These map to the add/sub saturated math intrinsics described here:
https://llvm.org/docs/LangRef.html#saturation-arithmetic-intrinsics
With this in place we should then be able to replace the x86 SSE adds/subs intrinsics with these generic variants - it looks like other targets should be able to use these as well (arm/aarch64/webassembly all have similar examples in cgbuiltin).
Differential Revision: https://reviews.llvm.org/D117898
Diffstat (limited to 'clang/test/Sema/builtins-elementwise-math.c')
-rw-r--r-- | clang/test/Sema/builtins-elementwise-math.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/clang/test/Sema/builtins-elementwise-math.c b/clang/test/Sema/builtins-elementwise-math.c index f2da7a0..273cddd 100644 --- a/clang/test/Sema/builtins-elementwise-math.c +++ b/clang/test/Sema/builtins-elementwise-math.c @@ -33,6 +33,122 @@ void test_builtin_elementwise_abs(int i, double d, float4 v, int3 iv, unsigned u // expected-error@-1 {{1st argument must be a signed integer or floating point type (was 'unsigned4' (vector of 4 'unsigned int' values))}} } +void test_builtin_elementwise_add_sat(int i, short s, double d, float4 v, int3 iv, unsigned3 uv, int *p) { + i = __builtin_elementwise_add_sat(p, d); + // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}} + + struct Foo foo = __builtin_elementwise_add_sat(i, i); + // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}} + + i = __builtin_elementwise_add_sat(i); + // expected-error@-1 {{too few arguments to function call, expected 2, have 1}} + + i = __builtin_elementwise_add_sat(); + // expected-error@-1 {{too few arguments to function call, expected 2, have 0}} + + i = __builtin_elementwise_add_sat(i, i, i); + // expected-error@-1 {{too many arguments to function call, expected 2, have 3}} + + i = __builtin_elementwise_add_sat(v, iv); + // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'int3' (vector of 3 'int' values))}} + + i = __builtin_elementwise_add_sat(uv, iv); + // expected-error@-1 {{arguments are of different types ('unsigned3' (vector of 3 'unsigned int' values) vs 'int3' (vector of 3 'int' values))}} + + v = __builtin_elementwise_add_sat(v, v); + // expected-error@-1 {{1st argument must be a vector of integers (was 'float4' (vector of 4 'float' values))}} + + s = __builtin_elementwise_add_sat(i, s); + + enum e { one, + two }; + i = __builtin_elementwise_add_sat(one, two); + + enum f { three }; + enum f x = __builtin_elementwise_add_sat(one, three); + + _BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}} + ext = __builtin_elementwise_add_sat(ext, ext); + + const int ci; + i = __builtin_elementwise_add_sat(ci, i); + i = __builtin_elementwise_add_sat(i, ci); + i = __builtin_elementwise_add_sat(ci, ci); + + i = __builtin_elementwise_add_sat(i, int_as_one); // ok (attributes don't match)? + i = __builtin_elementwise_add_sat(i, b); // ok (sugar doesn't match)? + + int A[10]; + A = __builtin_elementwise_add_sat(A, A); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'int *')}} + + int(ii); + int j; + j = __builtin_elementwise_add_sat(i, j); + + _Complex float c1, c2; + c1 = __builtin_elementwise_add_sat(c1, c2); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was '_Complex float')}} +} + +void test_builtin_elementwise_sub_sat(int i, short s, double d, float4 v, int3 iv, unsigned3 uv, int *p) { + i = __builtin_elementwise_sub_sat(p, d); + // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}} + + struct Foo foo = __builtin_elementwise_sub_sat(i, i); + // expected-error@-1 {{initializing 'struct Foo' with an expression of incompatible type 'int'}} + + i = __builtin_elementwise_sub_sat(i); + // expected-error@-1 {{too few arguments to function call, expected 2, have 1}} + + i = __builtin_elementwise_sub_sat(); + // expected-error@-1 {{too few arguments to function call, expected 2, have 0}} + + i = __builtin_elementwise_sub_sat(i, i, i); + // expected-error@-1 {{too many arguments to function call, expected 2, have 3}} + + i = __builtin_elementwise_sub_sat(v, iv); + // expected-error@-1 {{arguments are of different types ('float4' (vector of 4 'float' values) vs 'int3' (vector of 3 'int' values))}} + + i = __builtin_elementwise_sub_sat(uv, iv); + // expected-error@-1 {{arguments are of different types ('unsigned3' (vector of 3 'unsigned int' values) vs 'int3' (vector of 3 'int' values))}} + + v = __builtin_elementwise_sub_sat(v, v); + // expected-error@-1 {{1st argument must be a vector of integers (was 'float4' (vector of 4 'float' values))}} + + s = __builtin_elementwise_sub_sat(i, s); + + enum e { one, + two }; + i = __builtin_elementwise_sub_sat(one, two); + + enum f { three }; + enum f x = __builtin_elementwise_sub_sat(one, three); + + _BitInt(32) ext; // expected-warning {{'_BitInt' in C17 and earlier is a Clang extension}} + ext = __builtin_elementwise_sub_sat(ext, ext); + + const int ci; + i = __builtin_elementwise_sub_sat(ci, i); + i = __builtin_elementwise_sub_sat(i, ci); + i = __builtin_elementwise_sub_sat(ci, ci); + + i = __builtin_elementwise_sub_sat(i, int_as_one); // ok (attributes don't match)? + i = __builtin_elementwise_sub_sat(i, b); // ok (sugar doesn't match)? + + int A[10]; + A = __builtin_elementwise_sub_sat(A, A); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'int *')}} + + int(ii); + int j; + j = __builtin_elementwise_sub_sat(i, j); + + _Complex float c1, c2; + c1 = __builtin_elementwise_sub_sat(c1, c2); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was '_Complex float')}} +} + void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, unsigned3 uv, int *p) { i = __builtin_elementwise_max(p, d); // expected-error@-1 {{arguments are of different types ('int *' vs 'double')}} |