From 5f22decefac061c6e1e01804d46669a8c3ebc06c Mon Sep 17 00:00:00 2001 From: YunQiang Su Date: Sat, 28 Feb 2026 10:56:02 +0800 Subject: [PATCH] Clang: Deprecate float support from __builtin_elementwise_max (#180885) Now we have __builtin_elementwise_maxnum __builtin_elementwise_maximum __builtin_elementwise_maximumnum --- clang/docs/LanguageExtensions.rst | 8 ++++---- clang/docs/ReleaseNotes.rst | 3 +++ .../include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/Sema/SemaChecking.cpp | 14 +++++++++++++- clang/test/Sema/builtins-elementwise-math.c | 17 +++++++++++++++++ .../test/SemaCXX/builtins-elementwise-math.cpp | 8 ++++++-- libclc/clc/lib/generic/math/clc_fdim.inc | 2 +- 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 72cbf0610a2b..a3e487f91072 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -839,13 +839,13 @@ of different sizes and signs is forbidden in binary and ternary builtins. T __builtin_elementwise_copysign(T x, T y) return the magnitude of x with the sign of y. floating point types T __builtin_elementwise_fmod(T x, T y) return the floating-point remainder of (x/y) whose sign floating point types matches the sign of x. - T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger integer and floating point types - For floating point types, follows semantics of maxNum + T __builtin_elementwise_max(T x, T y) return x or y, whichever is larger integer + For floating point types, follows semantics of maxNum floating point types (deprecated) in IEEE 754-2008. See `LangRef `_ for the comparison. - T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller integer and floating point types - For floating point types, follows semantics of minNum + T __builtin_elementwise_min(T x, T y) return x or y, whichever is smaller integer + For floating point types, follows semantics of minNum floating point types (deprecated) in IEEE 754-2008. See `LangRef `_ for the comparison. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5068ccd5f682..eae19edc5e07 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -155,6 +155,9 @@ Non-comprehensive list of changes in this release extends bit-reversal support to all standard integers type, including ``_BitInt`` +- Deprecated float types support from ``__builtin_elementwise_max`` and + ``__builtin_elementwise_min``. + New Compiler Flags ------------------ - New option ``-fms-anonymous-structs`` / ``-fno-ms-anonymous-structs`` added diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 8a3b9de19ad3..a0a74f52f8aa 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6297,6 +6297,8 @@ def warn_unavailable_def : Warning< def warn_deprecated_builtin : Warning< "builtin %0 is deprecated; use %1 instead">, InGroup; +def warn_deprecated_builtin_no_suggestion : Warning<"builtin %0 is deprecated">, + InGroup; def err_unavailable : Error<"%0 is unavailable">; def err_property_method_unavailable : Error<"property access is using %0 method which is unavailable">; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 45dce52179f8..a49e3883a35a 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -3567,10 +3567,22 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, return ExprError(); break; case Builtin::BI__builtin_elementwise_min: - case Builtin::BI__builtin_elementwise_max: + case Builtin::BI__builtin_elementwise_max: { if (BuiltinElementwiseMath(TheCall)) return ExprError(); + Expr *Arg0 = TheCall->getArg(0); + Expr *Arg1 = TheCall->getArg(1); + QualType Ty0 = Arg0->getType(); + QualType Ty1 = Arg1->getType(); + const VectorType *VecTy0 = Ty0->getAs(); + const VectorType *VecTy1 = Ty1->getAs(); + if (Ty0->isFloatingType() || Ty1->isFloatingType() || + (VecTy0 && VecTy0->getElementType()->isFloatingType()) || + (VecTy1 && VecTy1->getElementType()->isFloatingType())) + Diag(TheCall->getBeginLoc(), diag::warn_deprecated_builtin_no_suggestion) + << Context.BuiltinInfo.getQuotedName(BuiltinID); break; + } case Builtin::BI__builtin_elementwise_popcount: case Builtin::BI__builtin_elementwise_bitreverse: if (PrepareBuiltinElementwiseMathOneArgCall( diff --git a/clang/test/Sema/builtins-elementwise-math.c b/clang/test/Sema/builtins-elementwise-math.c index 47f78d658c92..53cccc6e855f 100644 --- a/clang/test/Sema/builtins-elementwise-math.c +++ b/clang/test/Sema/builtins-elementwise-math.c @@ -238,6 +238,14 @@ void test_builtin_elementwise_max(int i, short s, double d, float4 v, int3 iv, u _Complex float c1, c2; c1 = __builtin_elementwise_max(c1, c2); // expected-error@-1 {{1st argument must be a vector, integer or floating-point type (was '_Complex float')}} + + double dr; + dr = __builtin_elementwise_max(d, 0.0); + // expected-warning@-1 {{builtin '__builtin_elementwise_max' is deprecated}} + + float4 vr; + vr = __builtin_elementwise_max(v, v); + // expected-warning@-1 {{builtin '__builtin_elementwise_max' is deprecated}} } void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, unsigned3 uv, int *p) { @@ -298,6 +306,14 @@ void test_builtin_elementwise_min(int i, short s, double d, float4 v, int3 iv, u _Complex float c1, c2; c1 = __builtin_elementwise_min(c1, c2); // expected-error@-1 {{1st argument must be a vector, integer or floating-point type (was '_Complex float')}} + + double dr; + dr = __builtin_elementwise_min(d, 0.0); + // expected-warning@-1 {{builtin '__builtin_elementwise_min' is deprecated}} + + float4 vr; + vr = __builtin_elementwise_min(v, v); + // expected-warning@-1 {{builtin '__builtin_elementwise_min' is deprecated}} } void test_builtin_elementwise_maximum(int i, short s, float f, double d, float4 fv, double4 dv, int3 iv, unsigned3 uv, int *p) { @@ -1379,6 +1395,7 @@ typedef struct { float3 foo(float3 a,const struct_float3* hi) { float3 b = __builtin_elementwise_max((float3)(0.0f), a); + // expected-warning@-1 {{builtin '__builtin_elementwise_max' is deprecated}} return __builtin_elementwise_pow(b, hi->b.yyy); } diff --git a/clang/test/SemaCXX/builtins-elementwise-math.cpp b/clang/test/SemaCXX/builtins-elementwise-math.cpp index 7482e5043aa3..2042334980d2 100644 --- a/clang/test/SemaCXX/builtins-elementwise-math.cpp +++ b/clang/test/SemaCXX/builtins-elementwise-math.cpp @@ -12,8 +12,6 @@ struct false_type { template struct is_const : false_type {}; template struct is_const : true_type {}; -// expected-no-diagnostics - void test_builtin_elementwise_abs() { const int a = 2; int b = 1; @@ -64,16 +62,22 @@ void test_builtin_elementwise_max_fp() { const float a = 2.0f; float b = 1.0f; static_assert(!is_const::value); + // expected-warning@-1 {{builtin '__builtin_elementwise_max' is deprecated}} static_assert(!is_const::value); + // expected-warning@-1 {{builtin '__builtin_elementwise_max' is deprecated}} static_assert(!is_const::value); + // expected-warning@-1 {{builtin '__builtin_elementwise_max' is deprecated}} } void test_builtin_elementwise_min_fp() { const float a = 2.0f; float b = 1.0f; static_assert(!is_const::value); + // expected-warning@-1 {{builtin '__builtin_elementwise_min' is deprecated}} static_assert(!is_const::value); + // expected-warning@-1 {{builtin '__builtin_elementwise_min' is deprecated}} static_assert(!is_const::value); + // expected-warning@-1 {{builtin '__builtin_elementwise_min' is deprecated}} } void test_builtin_elementwise_maximum() { diff --git a/libclc/clc/lib/generic/math/clc_fdim.inc b/libclc/clc/lib/generic/math/clc_fdim.inc index d34ee8c39a9d..0a8463a71f7e 100644 --- a/libclc/clc/lib/generic/math/clc_fdim.inc +++ b/libclc/clc/lib/generic/math/clc_fdim.inc @@ -8,7 +8,7 @@ _CLC_OVERLOAD _CLC_DEF __CLC_GENTYPE __clc_fdim(__CLC_GENTYPE x, __CLC_GENTYPE y) { - return __clc_select(__builtin_elementwise_max(x - y, __CLC_FP_LIT(0.0)), + return __clc_select(__builtin_elementwise_maxnum(x - y, __CLC_FP_LIT(0.0)), __CLC_GENTYPE_NAN, __CLC_CONVERT_BIT_INTN(__clc_isnan(x) || __clc_isnan(y))); }