https://github.com/llvm-beanz created https://github.com/llvm/llvm-project/pull/91015
This implements the HLSL 202x conforming literals feature. The feature proposal is available here: https://github.com/microsoft/hlsl-specs/blob/main/proposals/0017-conform ing-literals.md The language specification for this behavior is available in (poorly rendered) HTML or PDF: https://microsoft.github.io/hlsl-specs/specs/hlsl.html#Lex.Literal.Float https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf The main implementation details are: 1) Unsuffixed floating literals are `float`. 2) The integer `ll` suffix specifies `int64_t (aka long)` which is 64-bit because HLSL has no defined `long` keyword or `long long` type. Resolves #85714 >From 4511cd525a671e8c7ceec9ffc653b351d9b1a4d8 Mon Sep 17 00:00:00 2001 From: Chris Bieneman <chris.biene...@me.com> Date: Wed, 1 May 2024 14:10:58 -0500 Subject: [PATCH] [HLSL] Implement 202x conforming literals This implements the HLSL 202x conforming literals feature. The feature proposal is available here: https://github.com/microsoft/hlsl-specs/blob/main/proposals/0017-conform ing-literals.md The language specification for this behavior is available in (poorly rendered) HTML or PDF: https://microsoft.github.io/hlsl-specs/specs/hlsl.html#Lex.Literal.Float https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf The main implementation details are: 1) Unsuffixed floating literals are `float`. 2) The integer `ll` suffix specifies `int64_t (aka long)` which is 64-bit because HLSL has no defined `long` keyword or `long long` type. Resolves #85714 --- clang/lib/Sema/SemaExpr.cpp | 11 ++ clang/test/AST/HLSL/vector-constructors.hlsl | 135 ++++++++---------- .../CodeGenHLSL/builtins/ScalarSwizzles.hlsl | 17 ++- .../Arithmetic}/literal_suffixes.hlsl | 5 +- .../Arithmetic/literal_suffixes_202x.hlsl | 115 +++++++++++++++ .../literal_suffixes_no_16bit.hlsl | 5 +- .../Types/BuiltinVector/ScalarSwizzles.hlsl | 13 +- 7 files changed, 215 insertions(+), 86 deletions(-) rename clang/test/SemaHLSL/{ => Types/Arithmetic}/literal_suffixes.hlsl (87%) create mode 100644 clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes_202x.hlsl rename clang/test/SemaHLSL/{ => Types/Arithmetic}/literal_suffixes_no_16bit.hlsl (86%) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 7190e50b156f7b..5b42cf65cf80ff 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -4103,6 +4103,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { Ty = Context.Float16Ty; else if (Literal.isFloat128) Ty = Context.Float128Ty; + else if (getLangOpts().HLSL) + Ty = Context.FloatTy; else Ty = Context.DoubleTy; @@ -4173,6 +4175,15 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) { // be an unsigned int. bool AllowUnsigned = Literal.isUnsigned || Literal.getRadix() != 10; + // HLSL doesn't really have `long` or `long long`. We support the `ll` + // suffix for portability of code with C++, but both `l` and `ll` are + // 64-bit integer types, and we want the type of `1l` and `1ll` to be the + // same. + if (getLangOpts().HLSL && !Literal.isLong && Literal.isLongLong) { + Literal.isLong = true; + Literal.isLongLong = false; + } + // Check from smallest to largest, picking the smallest type we can. unsigned Width = 0; diff --git a/clang/test/AST/HLSL/vector-constructors.hlsl b/clang/test/AST/HLSL/vector-constructors.hlsl index 7861d5209b5d3e..5e0900bb623693 100644 --- a/clang/test/AST/HLSL/vector-constructors.hlsl +++ b/clang/test/AST/HLSL/vector-constructors.hlsl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -ast-dump -o - %s | FileCheck %s typedef float float2 __attribute__((ext_vector_type(2))); typedef float float3 __attribute__((ext_vector_type(3))); @@ -11,41 +11,36 @@ void entry() { // For the float2 vector, we just expect a conversion from constructor // parameters to an initialization list -// CHECK: VarDecl 0x{{[0-9a-fA-F]+}} <col:3, col:32> col:10 used Vec2 'float2':'float __attribute__((ext_vector_type(2)))' cinit -// CHECK-NEXT: CXXFunctionalCastExpr 0x{{[0-9a-fA-F]+}} <col:17, col:32> 'float2':'float __attribute__((ext_vector_type(2)))' functional cast to float2 <NoOp> -// CHECK-NEXT: InitListExpr 0x{{[0-9a-fA-F]+}} <col:24, col:29> 'float2':'float __attribute__((ext_vector_type(2)))' -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float' <FloatingCast> -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:24> 'double' 1.000000e+00 -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:29> 'float' <FloatingCast> -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:29> 'double' 2.000000e+00 +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} used Vec2 'float2':'float __attribute__((ext_vector_type(2)))' cinit +// CHECK-NEXT: CXXFunctionalCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' functional cast to float2 <NoOp> +// CHECK-NEXT: InitListExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 1.000000e+00 +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 2.000000e+00 // For the float 3 things get fun... // Here we expect accesses to the vec2 to provide the first and second // components using ArraySubscriptExpr -// CHECK: VarDecl 0x{{[0-9a-fA-F]+}} <col:3, col:33> col:10 Vec3 'float3':'float __attribute__((ext_vector_type(3)))' cinit -// CHECK-NEXT: CXXFunctionalCastExpr 0x{{[0-9a-fA-F]+}} <col:17, col:33> 'float3':'float __attribute__((ext_vector_type(3)))' functional cast to float3 <NoOp> -// CHECK-NEXT: InitListExpr 0x{{[0-9a-fA-F]+}} <col:24, col:30> 'float3':'float __attribute__((ext_vector_type(3)))' +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} col:10 Vec3 'float3':'float __attribute__((ext_vector_type(3)))' cinit +// CHECK-NEXT: CXXFunctionalCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float3':'float __attribute__((ext_vector_type(3)))' functional cast to float3 <NoOp> +// CHECK-NEXT: InitListExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float3':'float __attribute__((ext_vector_type(3)))' // CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24, <invalid sloc>> 'float' <LValueToRValue> // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9a-fA-F]+}} <col:24, <invalid sloc>> 'float' lvalue -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float2':'float __attribute__((ext_vector_type(2)))' lvalue Var 0x{{[0-9a-fA-F]+}} 'Vec2' 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' lvalue Var 0x{{[0-9a-fA-F]+}} 'Vec2' 'float2':'float __attribute__((ext_vector_type(2)))' // CHECK-NEXT: IntegerLiteral 0x{{[0-9a-fA-F]+}} <<invalid sloc>> 'int' 0 // CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24, <invalid sloc>> 'float' <LValueToRValue> // CHECK-NEXT: ArraySubscriptExpr 0x{{[0-9a-fA-F]+}} <col:24, <invalid sloc>> 'float' lvalue -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float2':'float __attribute__((ext_vector_type(2)))' lvalue Var 0x{{[0-9a-fA-F]+}} 'Vec2' 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' lvalue Var 0x{{[0-9a-fA-F]+}} 'Vec2' 'float2':'float __attribute__((ext_vector_type(2)))' // CHECK-NEXT: IntegerLiteral 0x{{[0-9a-fA-F]+}} <<invalid sloc>> 'int' 1 -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:30> 'float' <FloatingCast> -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:30> 'double' 3.000000e+00 - -// CHECK: VarDecl 0x{{[0-9a-fA-F]+}} <col:3, col:38> col:10 Vec3b 'float3':'float __attribute__((ext_vector_type(3)))' cinit -// CHECK-NEXT: CXXFunctionalCastExpr 0x{{[0-9a-fA-F]+}} <col:18, col:38> 'float3':'float __attribute__((ext_vector_type(3)))' functional cast to float3 <NoOp> -// CHECK-NEXT: InitListExpr 0x{{[0-9a-fA-F]+}} <col:25, col:35> 'float3':'float __attribute__((ext_vector_type(3)))' -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:25> 'float' <FloatingCast> -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:25> 'double' 1.000000e+00 -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:30> 'float' <FloatingCast> -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:30> 'double' 2.000000e+00 -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:35> 'float' <FloatingCast> -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:35> 'double' 3.000000e+00 +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 3.000000e+00 + +// CHECK: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} col:10 Vec3b 'float3':'float __attribute__((ext_vector_type(3)))' cinit +// CHECK-NEXT: CXXFunctionalCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float3':'float __attribute__((ext_vector_type(3)))' functional cast to float3 <NoOp> +// CHECK-NEXT: InitListExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float3':'float __attribute__((ext_vector_type(3)))' + +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 1.000000e+00 +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 2.000000e+00 +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 3.000000e+00 // The tests above verify pretty explictily that the Initialization lists are // being constructed as expected. The next tests are bit sparser for brevity. @@ -53,91 +48,85 @@ void entry() { float f = 1.0f, g = 2.0f; float2 foo0 = float2(f, g); // Non-literal -// CHECK: DeclStmt 0x{{[0-9a-fA-F]+}} <line:54:3, col:29> -// CHECK-NEXT: VarDecl +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} foo0 'float2' // CHECK-NEXT: CXXFunctionalCastExpr // CHECK-NEXT: InitListExpr -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float' <LValueToRValue> -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float' lvalue Var 0x{{[0-9a-fA-F]+}} 'f' 'float' -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:27> 'float' <LValueToRValue> -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:27> 'float' lvalue Var 0x{{[0-9a-fA-F]+}} 'g' 'float' +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <LValueToRValue> +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' lvalue Var 0x{{[0-9a-fA-F]+}} 'f' 'float' +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <LValueToRValue> +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' lvalue Var 0x{{[0-9a-fA-F]+}} 'g' 'float' int i = 1, j = 2; float2 foo1 = float2(1, 2); // Integer literals -// CHECK: DeclStmt 0x{{[0-9a-fA-F]+}} <line:66:3, col:29> -// CHECK-NEXT: VarDecl +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} foo1 'float2' // CHECK-NEXT: CXXFunctionalCastExpr // CHECK-NEXT: InitListExpr -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float' <IntegralToFloating> -// CHECK-NEXT: IntegerLiteral 0x{{[0-9a-fA-F]+}} <col:24> 'int' 1 -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:27> 'float' <IntegralToFloating> -// CHECK-NEXT: IntegerLiteral 0x{{[0-9a-fA-F]+}} <col:27> 'int' 2 +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <IntegralToFloating> +// CHECK-NEXT: IntegerLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'int' 1 +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <IntegralToFloating> +// CHECK-NEXT: IntegerLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'int' 2 float2 foo2 = float2(i, j); // Integer non-literal -// CHECK: DeclStmt 0x{{[0-9a-fA-F]+}} <line:77:3, col:29> -// CHECK-NEXT: VarDecl +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} foo2 'float2' // CHECK-NEXT: CXXFunctionalCastExpr // CHECK-NEXT: InitListExpr -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float' <IntegralToFloating> -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24> 'int' <LValueToRValue> -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:24> 'int' lvalue Var 0x{{[0-9a-fA-F]+}} 'i' 'int' -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:27> 'float' <IntegralToFloating> -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:27> 'int' <LValueToRValue> -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:27> 'int' lvalue Var 0x{{[0-9a-fA-F]+}} 'j' 'int' +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <IntegralToFloating> +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'int' <LValueToRValue> +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'int' lvalue Var 0x{{[0-9a-fA-F]+}} 'i' 'int' +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <IntegralToFloating> +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'int' <LValueToRValue> +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'int' lvalue Var 0x{{[0-9a-fA-F]+}} 'j' 'int' struct S { float f; } s; float2 foo4 = float2(s.f, s.f); -// CHECK: DeclStmt 0x{{[0-9a-fA-F]+}} <line:91:3, col:33> -// CHECK-NEXT: VarDecl +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} foo4 'float2' // CHECK-NEXT: CXXFunctionalCastExpr // CHECK-NEXT: InitListExpr -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24, col:26> 'float' <LValueToRValue> -// CHECK-NEXT: MemberExpr 0x{{[0-9a-fA-F]+}} <col:24, col:26> 'float' lvalue .f 0x{{[0-9a-fA-F]+}} -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:24> 'struct S':'S' lvalue Var 0x{{[0-9a-fA-F]+}} 's' 'struct S':'S' -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:29, col:31> 'float' <LValueToRValue> -// CHECK-NEXT: MemberExpr 0x{{[0-9a-fA-F]+}} <col:29, col:31> 'float' lvalue .f 0x{{[0-9a-fA-F]+}} -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:29> 'struct S':'S' lvalue Var 0x{{[0-9a-fA-F]+}} 's' 'struct S':'S' +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <LValueToRValue> +// CHECK-NEXT: MemberExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' lvalue .f 0x{{[0-9a-fA-F]+}} +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'struct S':'S' lvalue Var 0x{{[0-9a-fA-F]+}} 's' 'struct S':'S' +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <LValueToRValue> +// CHECK-NEXT: MemberExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' lvalue .f 0x{{[0-9a-fA-F]+}} +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'struct S':'S' lvalue Var 0x{{[0-9a-fA-F]+}} 's' 'struct S':'S' struct T { operator float() const { return 1.0f; } } t; float2 foo5 = float2(t, t); // user-defined cast operator -// CHECK: DeclStmt 0x{{[0-9a-fA-F]+}} <line:107:3, col:29> -// CHECK-NEXT: VarDecl +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} foo5 'float2' // CHECK-NEXT: CXXFunctionalCastExpr // CHECK-NEXT: InitListExpr -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float' <UserDefinedConversion> -// CHECK-NEXT: CXXMemberCallExpr 0x{{[0-9a-fA-F]+}} <col:24> 'float' -// CHECK-NEXT: MemberExpr 0x{{[0-9a-fA-F]+}} <col:24> '<bound member function type>' .operator float 0x{{[0-9a-fA-F]+}} -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:24> 'const T' lvalue <NoOp> -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:24> 'struct T':'T' lvalue Var 0x{{[0-9a-fA-F]+}} 't' 'struct T':'T' -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:27> 'float' <UserDefinedConversion> -// CHECK-NEXT: CXXMemberCallExpr 0x{{[0-9a-fA-F]+}} <col:27> 'float' -// CHECK-NEXT: MemberExpr 0x{{[0-9a-fA-F]+}} <col:27> '<bound member function type>' .operator float 0x{{[0-9a-fA-F]+}} -// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} <col:27> 'const T' lvalue <NoOp> -// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} <col:27> 'struct T':'T' lvalue Var 0x{{[0-9a-fA-F]+}} 't' 'struct T':'T' +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <UserDefinedConversion> +// CHECK-NEXT: CXXMemberCallExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' +// CHECK-NEXT: MemberExpr 0x{{[0-9a-fA-F]+}} {{.*}} '<bound member function type>' .operator float 0x{{[0-9a-fA-F]+}} +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'const T' lvalue <NoOp> +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'struct T':'T' lvalue Var 0x{{[0-9a-fA-F]+}} 't' 'struct T':'T' +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' <UserDefinedConversion> +// CHECK-NEXT: CXXMemberCallExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'float' +// CHECK-NEXT: MemberExpr 0x{{[0-9a-fA-F]+}} {{.*}} '<bound member function type>' .operator float 0x{{[0-9a-fA-F]+}} +// CHECK-NEXT: ImplicitCastExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'const T' lvalue <NoOp> +// CHECK-NEXT: DeclRefExpr 0x{{[0-9a-fA-F]+}} {{.*}} 'struct T':'T' lvalue Var 0x{{[0-9a-fA-F]+}} 't' 'struct T':'T' typedef float2 second_level_of_typedefs; second_level_of_typedefs foo6 = float2(1.0f, 2.0f); -// CHECK: DeclStmt 0x{{[0-9a-fA-F]+}} <line:125:3, col:53> -// CHECK-NEXT: VarDecl + +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} foo6 'second_level_of_typedefs' // CHECK-NEXT: CXXFunctionalCastExpr // CHECK-NEXT: InitListExpr -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:42> 'float' 1.000000e+00 -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:48> 'float' 2.000000e+00 +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 1.000000e+00 +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 2.000000e+00 float2 foo7 = second_level_of_typedefs(1.0f, 2.0f); -// CHECK: DeclStmt 0x{{[0-9a-fA-F]+}} <line:134:3, col:53> -// CHECK-NEXT: VarDecl +// CHECK-LABEL: VarDecl 0x{{[0-9a-fA-F]+}} {{.*}} foo7 'float2' // CHECK-NEXT: CXXFunctionalCastExpr // CHECK-NEXT: InitListExpr -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:42> 'float' 1.000000e+00 -// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} <col:48> 'float' 2.000000e+00 +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 1.000000e+00 +// CHECK-NEXT: FloatingLiteral 0x{{[0-9a-fA-F]+}} {{.*}} 'float' 2.000000e+00 } diff --git a/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl b/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl index 36f71f6860c06b..6395ddc2fee2a2 100644 --- a/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl +++ b/clang/test/CodeGenHLSL/builtins/ScalarSwizzles.hlsl @@ -55,7 +55,7 @@ vector<uint64_t,4> FillOneUnsignedLong(){ // CHECK: [[vec2:%.*]] = shufflevector <1 x double> [[vec1]], <1 x double> poison, <2 x i32> zeroinitializer // CHECK: ret <2 x double> [[vec2]] double2 FillTwoPointFive(){ - return 2.5.rr; + return 2.5l.rr; } // CHECK-LABEL: FillOneHalf @@ -65,7 +65,7 @@ double2 FillTwoPointFive(){ // CHECK: [[vec3:%.*]] = shufflevector <1 x double> [[vec1]], <1 x double> poison, <3 x i32> zeroinitializer // CHECK: ret <3 x double> [[vec3]] double3 FillOneHalf(){ - return .5.rrr; + return .5l.rrr; } // CHECK-LABEL: FillTwoPointFiveFloat @@ -110,7 +110,7 @@ float2 HowManyFloats(float V) { return V.rr.rr; } -// This codegen is gnarly because `1.` is a double, so this creates double +// This codegen is gnarly because `1.l` is a double, so this creates double // vectors that need to be truncated down to floats. The optimizer cleans this // up nicely too. @@ -123,6 +123,17 @@ float2 HowManyFloats(float V) { // CHECK: ret <3 x float> [[vec3f]] float3 AllRighty() { + return 1.l.rrr; +} + +// CHECK-LABEL: AllRighty2 +// CHECK: [[vec1Ptr:%.*]] = alloca <1 x float>, align 4 +// CHECK: store <1 x float> <float 1.000000e+00>, ptr [[vec1Ptr]], align 4 +// CHECK: [[vec1:%.*]] = load <1 x float>, ptr [[vec1Ptr]], align 4 +// CHECK: [[vec3:%.*]] = shufflevector <1 x float> [[vec1]], <1 x float> poison, <3 x i32> +// CHECK: ret <3 x float> [[vec3]] + +float3 AllRighty2() { return 1..rrr; } diff --git a/clang/test/SemaHLSL/literal_suffixes.hlsl b/clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes.hlsl similarity index 87% rename from clang/test/SemaHLSL/literal_suffixes.hlsl rename to clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes.hlsl index 25a4d3b5103c48..91324e57ce69ea 100644 --- a/clang/test/SemaHLSL/literal_suffixes.hlsl +++ b/clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes.hlsl @@ -49,10 +49,7 @@ 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<float, __decltype(1.0)>::value, "1.0 literal is 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"); diff --git a/clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes_202x.hlsl b/clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes_202x.hlsl new file mode 100644 index 00000000000000..2aeb4047565d6a --- /dev/null +++ b/clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes_202x.hlsl @@ -0,0 +1,115 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.4-library -finclude-default-header -verify %s +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.4-library -finclude-default-header -verify -fnative-half-type %s +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -finclude-default-header -verify %s +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -finclude-default-header -verify -fnative-half-type %s + +// This test is adapted from the test in DXC: +// tools/clang/test/SemaHLSL/v202x/conforming-literals/valid-literals.hlsl + +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; +}; + +bool B; // Used for ternary operator tests below + +//////////////////////////////////////////////////////////////////////////////// +// Literals Without Suffixes +//////////////////////////////////////////////////////////////////////////////// + +_Static_assert(is_same<__decltype(1.0), float>::value, "Literals are now float"); + +_Static_assert(is_same<__decltype(0), int>::value, "0 is int"); +_Static_assert(is_same<__decltype(1), int>::value, "1 is int"); + +// Decimal literals are always signed. +_Static_assert(is_same<__decltype(2147483647), int>::value, "2147483647 is int"); +_Static_assert(is_same<__decltype(2147483648), int64_t>::value, "2147483648 is int64_t"); +_Static_assert(is_same<__decltype(4294967296), int64_t>::value, "4294967296 is int64_t"); + +// This is an anomaly that exists in C as well as HLSL. This value can't be +// represented as a signed integer, but base-10 literals are always signed. +// Clang emits a warning that it is interpreting it as unsigned because that is +// not conforming to the C standard. + +// expected-warning@+1{{integer literal is too large to be represented in type 'long' and is subject to undefined behavior under C++98, interpreting as 'unsigned long'; this literal will be ill-formed in C++11 onwards}} +static const uint64_t V = 9223372036854775808; + +_Static_assert(is_same<__decltype(0x0), int>::value, "0x0 is int"); +_Static_assert(is_same<__decltype(0x70000000), int>::value, "0x70000000 is int"); +_Static_assert(is_same<__decltype(0xF0000000), uint>::value, "0xF0000000 is uint"); + +_Static_assert(is_same<__decltype(0x7000000000000000), int64_t>::value, "0x7000000000000000 is int64_t"); +_Static_assert(is_same<__decltype(0xF000000000000000), uint64_t>::value, "0xF000000000000000 is uint64_t"); + +//////////////////////////////////////////////////////////////////////////////// +// Integer literals With Suffixes +//////////////////////////////////////////////////////////////////////////////// + +_Static_assert(is_same<__decltype(1l), int64_t>::value, "1l is int64_t"); +_Static_assert(is_same<__decltype(1ul), uint64_t>::value, "1ul is uint64_t"); +_Static_assert(is_same<__decltype(1lu), uint64_t>::value, "1lu is uint64_t"); + +// HLSL 2021 does not define a `long long` type, so the suffix should be +// invalid. +_Static_assert(is_same<__decltype(1ll), int64_t>::value, "1ll is int64_t"); +_Static_assert(is_same<__decltype(1ull), uint64_t>::value, "1ull is uint64_t"); +_Static_assert(is_same<__decltype(1llu), uint64_t>::value, "1llu is uint64_t"); + +// Verify that the size of `long long` is the same as the size of `int64_t`. +_Static_assert(sizeof(__decltype(1ll)) == sizeof(int64_t), "sizeof(1ll) == sizeof(int64_t)"); +_Static_assert(sizeof(__decltype(1llu)) == sizeof(uint64_t), "sizeof(1llu) == sizeof(uint64_t)"); + +//////////////////////////////////////////////////////////////////////////////// +// Ternary operators on integer literals +//////////////////////////////////////////////////////////////////////////////// + +_Static_assert(is_same<__decltype(B ? 1 : 1), int>::value, "B ? 1 : 1 is int"); + +_Static_assert(is_same<__decltype(B ? 1l : 1), int64_t>::value, "B ? 1l : 1 is int64_t"); +_Static_assert(is_same<__decltype(B ? 1 : 1l), int64_t>::value, "B ? 1 : 1l is int64_t"); + +_Static_assert(is_same<__decltype(B ? 1ul : 1), uint64_t>::value, "B ? 1ul : 1 is uint64_t"); +_Static_assert(is_same<__decltype(B ? 1 : 1ul), uint64_t>::value, "B ? 1 : 1ul is uint64_t"); + +//////////////////////////////////////////////////////////////////////////////// +// Floating point literals With Suffixes +//////////////////////////////////////////////////////////////////////////////// + +_Static_assert(is_same<__decltype(1.0h), half>::value, "1.0h is half"); +_Static_assert(is_same<__decltype(1.0f), float>::value, "1.0f is float"); +_Static_assert(is_same<__decltype(1.0l), double>::value, "1.0l is double"); + +//////////////////////////////////////////////////////////////////////////////// +// Ternary operators on floating point literals +//////////////////////////////////////////////////////////////////////////////// + +_Static_assert(is_same<__decltype(B ? 1.0 : 1.0), float>::value, "B ? 1.0 : 1.0 is float"); + +_Static_assert(is_same<__decltype(B ? 1.0l : 1.0l), double>::value, "B ? 1.0l : 1.0l is double"); +_Static_assert(is_same<__decltype(B ? 1.0f : 1.0f), float>::value, "B ? 1.0f : 1.0f is float"); + + +_Static_assert(is_same<__decltype(B ? 1.0f : 1.0l), double>::value, "B ? 1.0f : 1.0l is double"); +_Static_assert(is_same<__decltype(B ? 1.0l : 1.0f), double>::value, "B ? 1.0l : 1.0f is double"); + +_Static_assert(is_same<__decltype(B ? 1.0l : 1.0), double>::value, "B ? 1.0l : 1.0 is double"); +_Static_assert(is_same<__decltype(B ? 1.0 : 1.0l), double>::value, "B ? 1.0 : 1.0l is double"); +_Static_assert(is_same<__decltype(B ? 1.0f : 1.0), float>::value, "B ? 1.0f : 1.0 is float"); +_Static_assert(is_same<__decltype(B ? 1.0 : 1.0f), float>::value, "B ? 1.0 : 1.0f is float"); + +_Static_assert(is_same<__decltype(B ? 1.0h : 1.0h), half>::value, "B ? 1.0h : 1.0h is half"); + +_Static_assert(is_same<__decltype(B ? 1.0f : 1.0h), float>::value, "B ? 1.0f : 1.0h is float"); +_Static_assert(is_same<__decltype(B ? 1.0h : 1.0f), float>::value, "B ? 1.0h : 1.0f is float"); + +_Static_assert(is_same<__decltype(B ? 1.0l : 1.0h), double>::value, "B ? 1.0l : 1.0h is double"); +_Static_assert(is_same<__decltype(B ? 1.0h : 1.0l), double>::value, "B ? 1.0h : 1.0l is double"); + +_Static_assert(is_same<__decltype(B ? 1.0h : 1.0), float>::value, "B ? 1.0h : 1.0 is float"); +_Static_assert(is_same<__decltype(B ? 1.0 : 1.0h), float>::value, "B ? 1.0 : 1.0h is float"); diff --git a/clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl b/clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes_no_16bit.hlsl similarity index 86% rename from clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl rename to clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes_no_16bit.hlsl index 73e57041329e88..f7e3e6ba577d68 100644 --- a/clang/test/SemaHLSL/literal_suffixes_no_16bit.hlsl +++ b/clang/test/SemaHLSL/Types/Arithmetic/literal_suffixes_no_16bit.hlsl @@ -49,10 +49,7 @@ 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<float, __decltype(1.0)>::value, "1.0 literal is 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"); diff --git a/clang/test/SemaHLSL/Types/BuiltinVector/ScalarSwizzles.hlsl b/clang/test/SemaHLSL/Types/BuiltinVector/ScalarSwizzles.hlsl index a2e9a5f865ece1..4fa04f3d598898 100644 --- a/clang/test/SemaHLSL/Types/BuiltinVector/ScalarSwizzles.hlsl +++ b/clang/test/SemaHLSL/Types/BuiltinVector/ScalarSwizzles.hlsl @@ -54,7 +54,7 @@ vector<uint64_t,4> FillOneUnsignedLong(){ // CHECK-NEXT: FloatingLiteral {{.*}} 'double' 2.500000e+00 double2 FillTwoPointFive(){ - return 2.5.rr; + return 2.5l.rr; } // CHECK-LABEL: FillOneHalf @@ -63,7 +63,7 @@ double2 FillTwoPointFive(){ // CHECK-NEXT: FloatingLiteral {{.*}} 'double' 5.000000e-01 double3 FillOneHalf(){ - return .5.rrr; + return .5l.rrr; } // CHECK-LABEL: FillTwoPointFiveFloat @@ -119,5 +119,14 @@ int64_t4 HooBoy() { // CHECK-NEXT: FloatingLiteral {{.*}} 'double' 1.000000e+00 float3 AllRighty() { + return 1.l.rrr; +} + +// CHECK-LABEL: AllRighty2 +// CHECK: ExtVectorElementExpr {{.*}} 'float __attribute__((ext_vector_type(3)))' rrr +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float __attribute__((ext_vector_type(1)))' <VectorSplat> +// CHECK-NEXT: FloatingLiteral {{.*}} 'float' 1.000000e+00 + +float3 AllRighty2() { return 1..rrr; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits