[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-02-08 Thread Simon Pilgrim via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc00db9715975: [Clang] Add elementwise saturated add/sub 
builtins (authored by RKSimon).

Changed prior to commit:
  https://reviews.llvm.org/D117898?vs=406264=406756#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -21,6 +21,22 @@
   static_assert(!is_const::value);
 }
 
+void test_builtin_elementwise_add_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
+void test_builtin_elementwise_sub_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
 void test_builtin_elementwise_max() {
   const int a = 2;
   int b = 1;
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -33,6 +33,122 @@
   // 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 

[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-02-07 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:549
+ T __builtin_elementwise_add_sat(T x, T y) return the sum of x and y, clamped 
to the range of signed or integer types
+   values representable by the bit 
width of the arguments.
+ T __builtin_elementwise_sub_sat(T x, T y) return the difference of x and y, 
clamped to the range ofinteger types

RKSimon wrote:
> aaron.ballman wrote:
> > aaron.ballman wrote:
> > > craig.topper wrote:
> > > > Not sure if I'm reading this right due to the columns, but is 
> > > > "unsigned" missing after the "signed or"
> > > This reads strangely to me as well. "..., clamped to the range of signed 
> > > or integer types unsigned values representable by.."
> > This still seems unaddressed.
> I rephrased it - what did you have in mind?
I think what's been throwing me off is "range of integer types signed or 
unsigned values", but I don't think signed or unsigned really matters here, so 
I tried to reword it a bit. Does this work for you?

`return the sum of x and y, clamped to the range of representable values for 
the integer type.`

(Similar below for difference).



Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-02-07 Thread Simon Pilgrim via Phabricator via cfe-commits
RKSimon added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:549
+ T __builtin_elementwise_add_sat(T x, T y) return the sum of x and y, clamped 
to the range of signed or integer types
+   values representable by the bit 
width of the arguments.
+ T __builtin_elementwise_sub_sat(T x, T y) return the difference of x and y, 
clamped to the range ofinteger types

aaron.ballman wrote:
> aaron.ballman wrote:
> > craig.topper wrote:
> > > Not sure if I'm reading this right due to the columns, but is "unsigned" 
> > > missing after the "signed or"
> > This reads strangely to me as well. "..., clamped to the range of signed or 
> > integer types unsigned values representable by.."
> This still seems unaddressed.
I rephrased it - what did you have in mind?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-02-07 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

Aside from some nits, this LGTM.




Comment at: clang/docs/LanguageExtensions.rst:549
+ T __builtin_elementwise_add_sat(T x, T y) return the sum of x and y, clamped 
to the range of signed or integer types
+   values representable by the bit 
width of the arguments.
+ T __builtin_elementwise_sub_sat(T x, T y) return the difference of x and y, 
clamped to the range ofinteger types

aaron.ballman wrote:
> craig.topper wrote:
> > Not sure if I'm reading this right due to the columns, but is "unsigned" 
> > missing after the "signed or"
> This reads strangely to me as well. "..., clamped to the range of signed or 
> integer types unsigned values representable by.."
This still seems unaddressed.



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:3157-3184
+  case Builtin::BI__builtin_elementwise_add_sat: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Result;
+assert(Op0->getType()->isIntOrIntVectorTy() && "integer type expected");
+QualType Ty = E->getArg(0)->getType();
+if (auto *VecTy = Ty->getAs())

aaron.ballman wrote:
> Almost all of this logic is shared (except for picking the intrinsic), should 
> it be combined?
Same with this one.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-02-06 Thread Simon Pilgrim via Phabricator via cfe-commits
RKSimon updated this revision to Diff 406264.
RKSimon added a comment.

rebase, simplify description in documentation and add _BitInt test coverage


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -21,6 +21,22 @@
   static_assert(!is_const::value);
 }
 
+void test_builtin_elementwise_add_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
+void test_builtin_elementwise_sub_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
 void test_builtin_elementwise_max() {
   const int a = 2;
   int b = 1;
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -33,6 +33,122 @@
   // 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 

[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-01-28 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:549
+ T __builtin_elementwise_add_sat(T x, T y) return the sum of x and y, clamped 
to the range of signed or integer types
+   values representable by the bit 
width of the arguments.
+ T __builtin_elementwise_sub_sat(T x, T y) return the difference of x and y, 
clamped to the range ofinteger types

craig.topper wrote:
> Not sure if I'm reading this right due to the columns, but is "unsigned" 
> missing after the "signed or"
This reads strangely to me as well. "..., clamped to the range of signed or 
integer types unsigned values representable by.."



Comment at: clang/lib/CodeGen/CGBuiltin.cpp:3157-3184
+  case Builtin::BI__builtin_elementwise_add_sat: {
+Value *Op0 = EmitScalarExpr(E->getArg(0));
+Value *Op1 = EmitScalarExpr(E->getArg(1));
+Value *Result;
+assert(Op0->getType()->isIntOrIntVectorTy() && "integer type expected");
+QualType Ty = E->getArg(0)->getType();
+if (auto *VecTy = Ty->getAs())

Almost all of this logic is shared (except for picking the intrinsic), should 
it be combined?



Comment at: clang/test/CodeGen/builtins-elementwise-math.c:117
+  // CHECK-NEXT: call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[VU1]], <4 x 
i32> [[VU2]])
+  vu1 = __builtin_elementwise_sub_sat(vu1, vu2);
+

fhahn wrote:
> It might be good to have tests where one argument is signed and the other 
> unsigned as well. Those appear to be missing for other builtins as well 
> unfortunately.
I think it'd be good to have some codegen tests for `_BitInt` to make sure the 
behavior is correct.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-01-28 Thread Simon Pilgrim via Phabricator via cfe-commits
RKSimon updated this revision to Diff 404013.
RKSimon added a comment.

rebase and add signed/unsigned integer mismatch tests


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -21,6 +21,22 @@
   static_assert(!is_const::value);
 }
 
+void test_builtin_elementwise_add_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
+void test_builtin_elementwise_sub_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
 void test_builtin_elementwise_max() {
   const int a = 2;
   int b = 1;
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -33,6 +33,122 @@
   // 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 

[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-01-28 Thread Florian Hahn via Phabricator via cfe-commits
fhahn added inline comments.



Comment at: clang/test/CodeGen/builtins-elementwise-math.c:117
+  // CHECK-NEXT: call <4 x i32> @llvm.usub.sat.v4i32(<4 x i32> [[VU1]], <4 x 
i32> [[VU2]])
+  vu1 = __builtin_elementwise_sub_sat(vu1, vu2);
+

It might be good to have tests where one argument is signed and the other 
unsigned as well. Those appear to be missing for other builtins as well 
unfortunately.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-01-27 Thread Simon Pilgrim via Phabricator via cfe-commits
RKSimon added a comment.

ping?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-01-23 Thread Simon Pilgrim via Phabricator via cfe-commits
RKSimon updated this revision to Diff 402313.
RKSimon added a comment.

address feedback


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -21,6 +21,22 @@
   static_assert(!is_const::value);
 }
 
+void test_builtin_elementwise_add_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
+void test_builtin_elementwise_sub_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
 void test_builtin_elementwise_max() {
   const int a = 2;
   int b = 1;
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -32,6 +32,116 @@
   // 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, 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))}}
+
+  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, 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))}}
+
+  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 = 

[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-01-21 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added inline comments.



Comment at: clang/docs/LanguageExtensions.rst:549
+ T __builtin_elementwise_add_sat(T x, T y) return the sum of x and y, clamped 
to the range of signed or integer types
+   values representable by the bit 
width of the arguments.
+ T __builtin_elementwise_sub_sat(T x, T y) return the difference of x and y, 
clamped to the range ofinteger types

Not sure if I'm reading this right due to the columns, but is "unsigned" 
missing after the "signed or"



Comment at: clang/include/clang/Basic/Builtins.def:656
 BUILTIN(__builtin_elementwise_roundeven, "v.", "nct")
+BUILTIN(__builtin_elementwise_sub_sat, "v.", "nct")
 BUILTIN(__builtin_elementwise_trunc, "v.", "nct")

I don't think these are in alphabetical order. ceil is after min. Looks more 
like they were grouped by similar operations.



Comment at: clang/lib/Sema/SemaChecking.cpp:2254
+
+   if (!EltTy->isIntegerType()) {
+  Diag(Arg->getBeginLoc(), diag::err_builtin_invalid_arg_type)

clang-format


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D117898/new/

https://reviews.llvm.org/D117898

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins

2022-01-21 Thread Simon Pilgrim via Phabricator via cfe-commits
RKSimon created this revision.
RKSimon added reviewers: fhahn, aaron.ballman, scanon, craig.topper.
Herald added subscribers: pengfei, sunfish, kristof.beyls, dschuff.
RKSimon requested review of this revision.
Herald added a subscriber: aheejin.
Herald added a project: clang.

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).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D117898

Files:
  clang/docs/LanguageExtensions.rst
  clang/include/clang/Basic/Builtins.def
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-elementwise-math.c
  clang/test/Sema/builtins-elementwise-math.c
  clang/test/SemaCXX/builtins-elementwise-math.cpp

Index: clang/test/SemaCXX/builtins-elementwise-math.cpp
===
--- clang/test/SemaCXX/builtins-elementwise-math.cpp
+++ clang/test/SemaCXX/builtins-elementwise-math.cpp
@@ -21,6 +21,22 @@
   static_assert(!is_const::value);
 }
 
+void test_builtin_elementwise_add_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
+void test_builtin_elementwise_sub_sat() {
+  const int a = 2;
+  int b = 1;
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+  static_assert(!is_const::value);
+}
+
 void test_builtin_elementwise_max() {
   const int a = 2;
   int b = 1;
Index: clang/test/Sema/builtins-elementwise-math.c
===
--- clang/test/Sema/builtins-elementwise-math.c
+++ clang/test/Sema/builtins-elementwise-math.c
@@ -32,6 +32,116 @@
   // 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, 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))}}
+
+  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, 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 =