[PATCH] D117898: [Clang] Add elementwise saturated add/sub builtins
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
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
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
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
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
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
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
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
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
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
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
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 =