aboutsummaryrefslogtreecommitdiff
path: root/clang/test/Sema/builtins-elementwise-math.c
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2022-02-08 11:21:46 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2022-02-08 11:22:01 +0000
commitc00db971597557e952901eac4be131157d1d5eb9 (patch)
tree451f4ab434c80bc5106616f30e8e27c78b25d2ba /clang/test/Sema/builtins-elementwise-math.c
parent95b8a3e52050d68ca5e8f6f8d1b810f6c23b4cea (diff)
downloadllvm-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.c116
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')}}