https://github.com/llvm-beanz updated https://github.com/llvm/llvm-project/pull/87270
>From c4dd0ba015dd51eea423d5d52d4afa9b2e92d514 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Mon, 1 Apr 2024 13:24:00 -0500 Subject: [PATCH 1/2] [HLSL] Implement floating literal suffixes This change implements the HLSL floating literal suffixes for half and double literals. The PR for the HLSL language specification for this behavior is https://github.com/microsoft/hlsl-specs/pull/175. The TL;DR is that the `h` suffix on floating literals means `half`, and the `l` suffix means `double`. The expected behavior and diagnostics are different if native half is supported. When native half is not enabled half is 32-bit so implicit conversions to float do not lose precision and do not warn. In all cases `half` and `float` are distinct types. Resolves #85712 ../clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl --- clang/lib/Sema/SemaExpr.cpp | 5 +- clang/test/SemaHLSL/literal_suffixes.hlsl | 59 +++++++++++++++++++ .../SemaHLSL/literal_suffixes_no_16bit.hlsl | 59 +++++++++++++++++++ 3 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaHLSL/literal_suffixes.hlsl create mode 100644 clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6b2eb245d58263..cf3410fc51d125 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4117,7 +4117,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } else if (Literal.isFloatingLiteral()) { QualType Ty; if (Literal.isHalf){ - if (getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts())) + if (getLangOpts().HLSL || + getOpenCLOptions().isAvailableOption("cl_khr_fp16", getLangOpts())) Ty = Context.HalfTy; else { Diag(Tok.getLocation(), diag::err_half_const_requires_fp16); @@ -4125,6 +4126,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } } else if (Literal.isFloat) Ty = Context.FloatTy; + else if (getLangOpts().HLSL && Literal.isLong) + Ty = Context.DoubleTy; else if (Literal.isLong) Ty = Context.LongDoubleTy; else if (Literal.isFloat16) diff --git a/clang/test/SemaHLSL/literal_suffixes.hlsl b/clang/test/SemaHLSL/literal_suffixes.hlsl new file mode 100644 index 00000000000000..25a4d3b5103c48 --- /dev/null +++ b/clang/test/SemaHLSL/literal_suffixes.hlsl @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-library -fnative-half-type -Wconversion -verify %s + +void literal_assignments() { + half h; + + h = 2.0h; // No conversion, no diagnostic expected. + + // Literal conversions that don't lose precision also don't cause diagnostics. + // Conversion from double (no diagnostic expected) + h = 2.0l; + h = 2.0; + h = 2.0f; + + // Literal assignments with conversions that lose precision produce + // diagnostics under `-Wconversion`. + + // Lose precision on assignment. + h = 3.1415926535897932384626433h; // No diagnostic expected because this isn't a conversion. + + // Lose precision on assignment converting float to half. + h = 3.1415926535897932384626433f; // expected-warning {{implicit conversion loses floating-point precision: 'float' to 'half'}} + + // Lose precision on assignment converting float to half. + h = 3.1415926535897932384626433f * 2.0f; // expected-warning {{implicit conversion loses floating-point precision: 'float' to 'half'}} + + // Lose precision on assignment converting double to half. + h = 3.1415926535897932384626433l; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'half'}} + + // Lose precision on assignment converting double to half. + h = 3.1415926535897932384626433l * 2.0l; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'half'}} + + // Literal assinments of values out of the representable range produce + // warnings. + + h = 66000.h; // expected-warning {{magnitude of floating-point constant too large for type 'half'; maximum is 65504}} + h = -66000.h; // expected-warning {{magnitude of floating-point constant too large for type 'half'; maximum is 65504}} + + // The `h` suffix is invalid on integer literals. + h = 66000h; // expected-error {{invalid suffix 'h' on integer constant}} +} + +template <typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template <typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +// The no-suffix behavior is currently wrong. The behavior in DXC is complicated +// and undocumented. We have a language change planned to address this, and an +// issue tracking: https://github.com/llvm/llvm-project/issues/85714. +_Static_assert(is_same<double, __decltype(1.0)>::value, "1.0f literal is double (should be float)"); + +_Static_assert(is_same<half, __decltype(1.0h)>::value, "1.0h literal is half"); +_Static_assert(is_same<float, __decltype(1.0f)>::value, "1.0f literal is float"); +_Static_assert(is_same<double, __decltype(1.0l)>::value, "1.0l literal is double"); diff --git a/clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl b/clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl new file mode 100644 index 00000000000000..73e57041329e88 --- /dev/null +++ b/clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.2-library -Wconversion -verify %s + +void literal_assignments() { + half h; + + h = 2.0h; // No conversion, no diagnostic expected. + + // Literal conversions that don't lose precision also don't cause diagnostics. + // Conversion from double (no diagnostic expected) + h = 2.0l; + h = 2.0; + h = 2.0f; + + // Literal assignments with conversions that lose precision produce + // diagnostics under `-Wconversion`. + + // Lose precision on assignment. + h = 3.1415926535897932384626433h; // No diagnostic expected because this isn't a conversion. + + // Lose precision on assignment converting float to half. + h = 3.1415926535897932384626433f; // No diagnostic expected because half and float are the same size. + + // Lose precision on assignment converting float to half. + h = 3.1415926535897932384626433f * 2.0f; // No diagnostic expected because half and float are the same size. + + // Lose precision on assignment converting double to half. + h = 3.1415926535897932384626433l; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'half'}} + + // Lose precision on assignment converting double to half. + h = 3.1415926535897932384626433l * 2.0l; // expected-warning {{implicit conversion loses floating-point precision: 'double' to 'half'}} + + // Literal assinments of values out of the representable range produce + // warnings. + + h = 66000.h; // No diagnostic expected because half is 32-bit. + h = -66000.h; // No diagnostic expected because half is 32-bit. + + // The `h` suffix is invalid on integer literals. + h = 66000h; // expected-error {{invalid suffix 'h' on integer constant}} +} + +template <typename T, typename U> +struct is_same { + static const bool value = false; +}; + +template <typename T> +struct is_same<T, T> { + static const bool value = true; +}; + +// The no-suffix behavior is currently wrong. The behavior in DXC is complicated +// and undocumented. We have a language change planned to address this, and an +// issue tracking: https://github.com/llvm/llvm-project/issues/85714. +_Static_assert(is_same<double, __decltype(1.0)>::value, "1.0f literal is double (should be float)"); + +_Static_assert(is_same<half, __decltype(1.0h)>::value, "1.0h literal is half"); +_Static_assert(is_same<float, __decltype(1.0f)>::value, "1.0f literal is float"); +_Static_assert(is_same<double, __decltype(1.0l)>::value, "1.0l literal is double"); >From 8c4f2bac33e283c3074c054a670bd41227f5a143 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Fri, 5 Apr 2024 09:42:05 -0500 Subject: [PATCH 2/2] Updates based on feedback --- clang/lib/Sema/SemaExpr.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index cf3410fc51d125..ffe7e44e2387f4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4126,10 +4126,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { } } else if (Literal.isFloat) Ty = Context.FloatTy; - else if (getLangOpts().HLSL && Literal.isLong) - Ty = Context.DoubleTy; else if (Literal.isLong) - Ty = Context.LongDoubleTy; + Ty = !getLangOpts().HLSL ? Context.LongDoubleTy : Context.DoubleTy; else if (Literal.isFloat16) Ty = Context.Float16Ty; else if (Literal.isFloat128) _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits