[clang-tools-extra] Changes to support running tests for Windows arm64 asan (PR #66973)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/66973 >From 141c9aa7f9b1a6f7b4f877a82c4ccf92ae2b8287 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Wed, 20 Sep 2023 22:58:08 -0400 Subject: [PATCH] Changes to support running tests for Windows arm64 asan 1. Differentiate SANITIZER_WINDOWS64 for x64 and arm64 2. fix A Warning where asserts needs messages 3. turn of interception tests that expect x86 assembly --- compiler-rt/lib/interception/interception_win.cpp | 4 ++-- .../lib/interception/tests/interception_win_test.cpp | 2 ++ compiler-rt/lib/sanitizer_common/sanitizer_platform.h | 8 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp index 1b681ada37b170d..4c1c4ca098ee71e 100644 --- a/compiler-rt/lib/interception/interception_win.cpp +++ b/compiler-rt/lib/interception/interception_win.cpp @@ -462,7 +462,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { return 4; #endif -#if SANITIZER_WINDOWS64 +#if SANITIZER_WINDOWSx64 if (memcmp((u8*)address, kPrologueWithShortJump1, sizeof(kPrologueWithShortJump1)) == 0 || memcmp((u8*)address, kPrologueWithShortJump2, @@ -544,7 +544,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { return 7; } -#if SANITIZER_WINDOWS64 +#if SANITIZER_WINDOWSx64 switch (*(u8*)address) { case 0xA1: // A1 XX XX XX XX XX XX XX XX : // movabs eax, dword ptr ds:[] diff --git a/compiler-rt/lib/interception/tests/interception_win_test.cpp b/compiler-rt/lib/interception/tests/interception_win_test.cpp index 9159ce405f2dc49..629cdf437f342ec 100644 --- a/compiler-rt/lib/interception/tests/interception_win_test.cpp +++ b/compiler-rt/lib/interception/tests/interception_win_test.cpp @@ -17,6 +17,7 @@ // Too slow for debug build #if !SANITIZER_DEBUG #if SANITIZER_WINDOWS +#if !SANITIZER_WINDOWSARM64 #include @@ -793,5 +794,6 @@ TEST(Interception, EmptyExportTable) { } // namespace __interception +#endif // !SANITIZER_WINDOWSARM64 #endif // SANITIZER_WINDOWS #endif // #if !SANITIZER_DEBUG diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 3e1b078a0212f5e..9d2050518947679 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -260,6 +260,14 @@ # define SANITIZER_ARM64 0 #endif +#if SANITIZER_WINDOWS64 && SANITIZER_ARM64 +# define SANITIZER_WINDOWSARM64 1 +# define SANITIZER_WINDOWSx64 0 +#else +# define SANITIZER_WINDOWSARM64 0 +# define SANITIZER_WINDOWSx64 1 +#endif + #if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32 # define SANITIZER_SOLARIS32 1 #else ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Changes to support running tests for Windows arm64 asan (PR #66973)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/66973 >From 141c9aa7f9b1a6f7b4f877a82c4ccf92ae2b8287 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Wed, 20 Sep 2023 22:58:08 -0400 Subject: [PATCH] Changes to support running tests for Windows arm64 asan 1. Differentiate SANITIZER_WINDOWS64 for x64 and arm64 2. fix A Warning where asserts needs messages 3. turn of interception tests that expect x86 assembly --- compiler-rt/lib/interception/interception_win.cpp | 4 ++-- .../lib/interception/tests/interception_win_test.cpp | 2 ++ compiler-rt/lib/sanitizer_common/sanitizer_platform.h | 8 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp index 1b681ada37b170d..4c1c4ca098ee71e 100644 --- a/compiler-rt/lib/interception/interception_win.cpp +++ b/compiler-rt/lib/interception/interception_win.cpp @@ -462,7 +462,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { return 4; #endif -#if SANITIZER_WINDOWS64 +#if SANITIZER_WINDOWSx64 if (memcmp((u8*)address, kPrologueWithShortJump1, sizeof(kPrologueWithShortJump1)) == 0 || memcmp((u8*)address, kPrologueWithShortJump2, @@ -544,7 +544,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { return 7; } -#if SANITIZER_WINDOWS64 +#if SANITIZER_WINDOWSx64 switch (*(u8*)address) { case 0xA1: // A1 XX XX XX XX XX XX XX XX : // movabs eax, dword ptr ds:[] diff --git a/compiler-rt/lib/interception/tests/interception_win_test.cpp b/compiler-rt/lib/interception/tests/interception_win_test.cpp index 9159ce405f2dc49..629cdf437f342ec 100644 --- a/compiler-rt/lib/interception/tests/interception_win_test.cpp +++ b/compiler-rt/lib/interception/tests/interception_win_test.cpp @@ -17,6 +17,7 @@ // Too slow for debug build #if !SANITIZER_DEBUG #if SANITIZER_WINDOWS +#if !SANITIZER_WINDOWSARM64 #include @@ -793,5 +794,6 @@ TEST(Interception, EmptyExportTable) { } // namespace __interception +#endif // !SANITIZER_WINDOWSARM64 #endif // SANITIZER_WINDOWS #endif // #if !SANITIZER_DEBUG diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 3e1b078a0212f5e..9d2050518947679 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -260,6 +260,14 @@ # define SANITIZER_ARM64 0 #endif +#if SANITIZER_WINDOWS64 && SANITIZER_ARM64 +# define SANITIZER_WINDOWSARM64 1 +# define SANITIZER_WINDOWSx64 0 +#else +# define SANITIZER_WINDOWSARM64 0 +# define SANITIZER_WINDOWSx64 1 +#endif + #if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32 # define SANITIZER_SOLARIS32 1 #else ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From 5082bc7fb49761424c7984a594a5afad9a03f04d Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in BuiltinsHLSL.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. As a side note adding the dot product intrinsic to BuiltinsHLSL.td had a significant impact on re-compile time speeds. I recommend we move the other hlsl functions here. Further it lets us tap into the existing target specifc code organizations that exist in Sema and CodeGen. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is a target specific intrinsic and so needed to establish a pattern for Target builtins via EmitDXILBuiltinExpr. The call chain looks like this now: EmitBuiltinExpr -> EmitTargetBuiltinExpr -> EmitTargetArchBuiltinExpr -> EmitDXILBuiltinExp EmitDXILBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a target specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/BuiltinsHLSL.td| 15 ++ clang/include/clang/Basic/CMakeLists.txt | 4 + clang/include/clang/Basic/TargetBuiltins.h | 10 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/Basic/Targets/DirectX.cpp | 13 ++ clang/lib/Basic/Targets/DirectX.h| 4 +- clang/lib/CodeGen/CGBuiltin.cpp | 41 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 68 +++ clang/lib/Sema/SemaChecking.cpp | 74 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 202 +++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 43 llvm/include/llvm/IR/IntrinsicsDirectX.td| 5 + 13 files changed, 473 insertions(+), 8 deletions(-) create mode 100644 clang/include/clang/Basic/BuiltinsHLSL.td create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/BuiltinsHLSL.td b/clang/include/clang/Basic/BuiltinsHLSL.td new file mode 100644 index 00..edff801f905641 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsHLSL.td @@ -0,0 +1,15 @@ +//===--- BuiltinsHLSL.td - HLSL Builtin function database -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +include "clang/Basic/BuiltinsBase.td" + +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 9689a0f48c3ca3..29e5211602a9c8 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -65,6 +65,10 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins SOURCE BuiltinsBPF.td TARGET ClangBuiltinsBPF) + clang_tablegen(BuiltinsHLSL.inc -gen-clang-builtins + SOURCE BuiltinsHLSL.td + TARGET ClangBuiltinsHLSL) + # ARM NEON and MVE clang_tablegen(arm_neon.inc -gen-arm-neon-sema SOURCE arm_neon.td diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index a4abaaef44c06c..38452553bd2df2 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -89,6 +89,16 @@ namespace clang { }; } + /// HLSL builtins + namespace hlsl { + enum { +LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsHLSL.inc" +LastTSBuiltin + }; + } // namespace hlsl + /// PPC builtins namespace PPC { enum { diff --git a/clang/include/clang/Sema/Sema.
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -4518,6 +4518,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; farzonl wrote: I have added SemaChecking However I have 4 cases I can't check via `SemaChecking.cpp` Because `BuildRecoveryCallExpr` is usurping calls to `BuildResolvedCallExpr`. This seems to be caused by how we are defining apis via `hlsl_intrinsics.h` and it doesn't seem to matter if I added Types to the table gen or not like so ```python class HLSLMathTemplate : Template<["__fp16", "float", "double", "short", "int", "int64_t", "unsigned short", "uint32_t", "uint64_t" ], ["f16","", "f64","i16", "i32", "i64", "u16","u32", "u64"]>; def HLSLDotProduct : LangBuiltin<"HLSL_LANG">, HLSLMathTemplate { let Spellings = ["__builtin_hlsl_dot"]; let Attributes = [NoThrow, Const, CustomTypeChecking]; let Prototype = "T(_Complex T , _Complex T )"; } ``` Example test cases that hit `BuildRecoveryCallExpr`: ```hlsl float test_dot_scalar_mismatch ( float p0, int p1 ) { return dot ( p0, p1 ); } float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) { return dot ( p0, p1 ); } float test__no_second_arg ( float2 p0) { return dot ( p0 ); } float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) { return dot ( p0, p1 ); } ``` For example If we take `sin`: ```hlsl // RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ // RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ // RUN: -emit-llvm -disable-llvm-passes -o - float4 test( int4 p0) { return sin ( p0 ); } ``` I get the same errors: ``` clang\test\CodeGenHLSL\builtins\dot2.hlsl:6:10: error: no matching function for call to 'sin' 6 | return sin ( p0 ); | ^~~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:611:6: note: candidate function not viable: no known conversion from 'int4' (aka 'vector') to 'half' for 1st argument 611 | half sin(half); | ^ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:613:7: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 613 | half2 sin(half2); | ^ ~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:615:7: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 615 | half3 sin(half3); | ^ ~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:617:7: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 617 | half4 sin(half4); | ^ ~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:621:7: note: candidate function not viable: no known conversion from 'int4' (aka 'vector') to 'float' for 1st argument 621 | float sin(float); | ^ ~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:623:8: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 623 | float2 sin(float2); |^ ~~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:625:8: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 625 | float3 sin(float3); |^ ~~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:627:8: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 627 | float4 sin(float4); |^ ~~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:630:8: note: candidate function not viable: no known conversion from 'int4' (aka 'vector') to 'double' for 1st argument 630 | double sin(double); |^ ~~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:632:9: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 632 | double2 sin(double2); | ^ ~~~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:634:9: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 634 | double3 sin(double3); | ^ ~~~ D:\projects\llvm_win_clang-cl_debug_build\lib\clang\19\include\hlsl/hlsl_intrinsics.h:636:9: note: candidate function not viable: no known conversion from 'vector' to 'vector' for 1st argument 636 | double4 sin(double4); | ^ ~~~ 1
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -144,6 +144,92 @@ double3 cos(double3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos) double4 cos(double4); +//===--===// +// dot product builtins +//===--===// +#ifdef __HLSL_ENABLE_16_BIT +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half, half); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half2, half2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half3, half3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half4, half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t, int16_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t2, int16_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t3, int16_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t4, int16_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t, uint16_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t2, uint16_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t3, uint16_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t4, uint16_t4); +#endif + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float, float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float2, float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float3, float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float4, float4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double, double); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double2, double2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double3, double3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double4, double4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int dot(int, int); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int dot(int2, int2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int dot(int3, int3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int dot(int4, int4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint dot(uint, uint); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint dot(uint2, uint2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint dot(uint3, uint3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint dot(uint4, uint4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int64_t dot(int64_t, int64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int64_t dot(int64_t2, int64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int64_t dot(int64_t3, int64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int64_t dot(int64_t4, int64_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint64_t dot(uint64_t, uint64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint64_t dot(uint64_t2, uint64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint64_t dot(uint64_t3, uint64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint64_t dot(uint64_t4, uint64_t4); farzonl wrote: 1. I removed the `int64` and `uint64` support and tests, but it does seem like it is supported see `fn6` and `fn7`. Left the scalar support for both. 2. You are correct no double vector support so removed it. However scalar double is supported see `fn8`. Left this one. https://godbolt.org/z/vT9xTMffE https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : Intrinsic<[llvm_i32_ty], [], [IntrNoMe def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">, Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>; -} + +def int_dx_dot : +Intrinsic<[LLVMVectorElementType<0>], +[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], +[IntrNoMem, IntrWillReturn, Commutative] >; farzonl wrote: This might have to come later when I start to work on lowering. https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : Intrinsic<[llvm_i32_ty], [], [IntrNoMe def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">, Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>; -} + +def int_dx_dot : +Intrinsic<[LLVMVectorElementType<0>], +[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], farzonl wrote: @python3kgae Are you ok with leaving this as is? https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -144,6 +144,92 @@ double3 cos(double3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos) double4 cos(double4); +//===--===// +// dot product builtins +//===--===// +#ifdef __HLSL_ENABLE_16_BIT +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half, half); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half2, half2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half3, half3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half4, half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t, int16_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t2, int16_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t3, int16_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t4, int16_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t, uint16_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t2, uint16_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t3, uint16_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t4, uint16_t4); +#endif + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float, float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float2, float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float3, float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float4, float4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double, double); farzonl wrote: mentioned in another conversation. only the scalar case of double remains. https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From 4103940b5a2578efc08df554ccdf80cb34925d09 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in BuiltinsHLSL.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. As a side note adding the dot product intrinsic to BuiltinsHLSL.td had a significant impact on re-compile time speeds. I recommend we move the other hlsl functions here. Further it lets us tap into the existing target specifc code organizations that exist in Sema and CodeGen. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is a target specific intrinsic and so needed to establish a pattern for Target builtins via EmitDXILBuiltinExpr. The call chain looks like this now: EmitBuiltinExpr -> EmitTargetBuiltinExpr -> EmitTargetArchBuiltinExpr -> EmitDXILBuiltinExp EmitDXILBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a target specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/BuiltinsHLSL.td| 15 ++ clang/include/clang/Basic/CMakeLists.txt | 4 + clang/include/clang/Basic/TargetBuiltins.h | 10 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/Basic/Targets/DirectX.cpp | 13 ++ clang/lib/Basic/Targets/DirectX.h| 4 +- clang/lib/CodeGen/CGBuiltin.cpp | 41 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 68 +++ clang/lib/Sema/SemaChecking.cpp | 71 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 202 +++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 43 llvm/include/llvm/IR/IntrinsicsDirectX.td| 5 + 13 files changed, 470 insertions(+), 8 deletions(-) create mode 100644 clang/include/clang/Basic/BuiltinsHLSL.td create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/BuiltinsHLSL.td b/clang/include/clang/Basic/BuiltinsHLSL.td new file mode 100644 index 00..edff801f905641 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsHLSL.td @@ -0,0 +1,15 @@ +//===--- BuiltinsHLSL.td - HLSL Builtin function database -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +include "clang/Basic/BuiltinsBase.td" + +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 9689a0f48c3ca3..29e5211602a9c8 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -65,6 +65,10 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins SOURCE BuiltinsBPF.td TARGET ClangBuiltinsBPF) + clang_tablegen(BuiltinsHLSL.inc -gen-clang-builtins + SOURCE BuiltinsHLSL.td + TARGET ClangBuiltinsHLSL) + # ARM NEON and MVE clang_tablegen(arm_neon.inc -gen-arm-neon-sema SOURCE arm_neon.td diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index a4abaaef44c06c..38452553bd2df2 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -89,6 +89,16 @@ namespace clang { }; } + /// HLSL builtins + namespace hlsl { + enum { +LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsHLSL.inc" +LastTSBuiltin + }; + } // namespace hlsl + /// PPC builtins namespace PPC { enum { diff --git a/clang/include/clang/Sema/Sema.
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From 73cc9fde36a44ba1715a3c9fc6d48196602d5dc4 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in BuiltinsHLSL.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. As a side note adding the dot product intrinsic to BuiltinsHLSL.td had a significant impact on re-compile time speeds. I recommend we move the other hlsl functions here. Further it lets us tap into the existing target specifc code organizations that exist in Sema and CodeGen. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is a target specific intrinsic and so needed to establish a pattern for Target builtins via EmitDXILBuiltinExpr. The call chain looks like this now: EmitBuiltinExpr -> EmitTargetBuiltinExpr -> EmitTargetArchBuiltinExpr -> EmitDXILBuiltinExp EmitDXILBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a target specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/BuiltinsHLSL.td| 15 ++ clang/include/clang/Basic/CMakeLists.txt | 6 +- clang/include/clang/Basic/TargetBuiltins.h | 10 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/Basic/Targets/DirectX.cpp | 13 ++ clang/lib/Basic/Targets/DirectX.h| 4 +- clang/lib/CodeGen/CGBuiltin.cpp | 41 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 68 +++ clang/lib/Sema/SemaChecking.cpp | 71 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 202 +++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 43 llvm/include/llvm/IR/IntrinsicsDirectX.td| 5 + 13 files changed, 471 insertions(+), 9 deletions(-) create mode 100644 clang/include/clang/Basic/BuiltinsHLSL.td create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/BuiltinsHLSL.td b/clang/include/clang/Basic/BuiltinsHLSL.td new file mode 100644 index 00..edff801f905641 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsHLSL.td @@ -0,0 +1,15 @@ +//===--- BuiltinsHLSL.td - HLSL Builtin function database -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +include "clang/Basic/BuiltinsBase.td" + +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 7785fb430c069b..01233eb44feffc 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -65,7 +65,11 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins SOURCE BuiltinsBPF.td TARGET ClangBuiltinsBPF) -clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins +clang_tablegen(BuiltinsHLSL.inc -gen-clang-builtins + SOURCE BuiltinsHLSL.td + TARGET ClangBuiltinsHLSL) + + clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins SOURCE BuiltinsRISCV.td TARGET ClangBuiltinsRISCV) diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 4333830bf34f24..15cf111ae5e9e5 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -89,6 +89,16 @@ namespace clang { }; } + /// HLSL builtins + namespace hlsl { + enum { +LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsHLSL.inc" +LastTSBuiltin + }; + } // namespace hlsl + /// PPC built
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected + +float test_first_arg_is_not_vector ( float p0, float2 p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{first two arguments to 'dot' must be vectors}} +} + +float test_second_arg_is_not_vector ( float2 p0, float p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{first two arguments to 'dot' must be vectors}} +} + +int test_dot_unsupported_scalar_arg0 ( bool p0, int p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'bool')}} +} + +int test_dot_unsupported_scalar_arg1 ( int p0, bool p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{2nd argument must be a vector, integer or floating point type (was 'bool')}} +} + +float test_dot_scalar_mismatch ( float p0, int p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{call to 'dot' is ambiguous}} +} + +float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{no matching function for call to 'dot'}} +} + +float test__no_second_arg ( float2 p0) { + return dot ( p0 ); + // expected-error@-1 {{no matching function for call to 'dot'}} +} + +float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{no matching function for call to 'dot'}} farzonl wrote: see @llvm-beanz comment: https://github.com/llvm/llvm-project/pull/81190#discussion_r1488101504. His PR needs to land. Once it does I suspect I will be able to remove this test case. https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -0,0 +1,202 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -D__HLSL_ENABLE_16_BIT -o - | FileCheck %s --check-prefix=NO_HALF farzonl wrote: You are correct only lines 140-170 for the half cases are going to be different. They are supposed to be the same except for the float16 cases. I'm not sure I agree with the suggestion, `NO_HALF` is how we are doing all the other intrinsics I don't understand why this needs to be a special case.., That said I can model these tests more like sin.hlsl where we only do the half checks on the half code: https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGenHLSL/builtins/sin.hlsl#L8C1-L35C2 And not like https://github.com/llvm/llvm-project/blob/main/clang/test/CodeGenHLSL/builtins/max.hlsl where we do it on every test case if you think that would add some clarity. https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC] Add API documentation and annotations (PR #78635)
farzonl wrote: It might be worth adding a .dox file something like this: ``` /*! \mainpage HLSL Overview \tableofcontents \section hlsl-introduction Introduction to HLSL - \ref hlsl_basic_types.h defines hlsl types -\ref - hlsl_intrinsics.h defines hlsl spec apis. \n \section hlsl-list HLSL Types - \ref float2- A vector of 2 floats - \ref float3- A vector of 3 floats - \ref float4- A vector of 4 floats ``` https://github.com/llvm/llvm-project/pull/78635 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] add BuiltinsHLSL and set it up as target builtins. (PR #81902)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/81902 1. This change moves hlsl specific builtins from Builtins.td to BuiltinsHLSL.td. 2. Adds changes to the build system to build BuiltinsHLSL.td. 3. Setups HLSL builtins as TargetBuiltins. >From 1c86da726134e9d4a659fb5b1ab149b5df80f378 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 15 Feb 2024 13:46:55 -0500 Subject: [PATCH] [HLSL] add BuiltinsHLSL and set it up as target builtins. 1. This change moves hlsl specific builtins from Builtins.td to BuiltinsHLSL.td. 2. Adds changes to the build system to build BuiltinsHLSL.td. 3. Setups HLSL builtins as TargetBuiltins. --- clang/include/clang/Basic/Builtins.td | 13 - clang/include/clang/Basic/BuiltinsHLSL.td | 21 + clang/include/clang/Basic/CMakeLists.txt | 6 +- clang/include/clang/Basic/TargetBuiltins.h | 10 ++ clang/lib/Basic/Targets/DirectX.cpp| 13 + clang/lib/Basic/Targets/DirectX.h | 4 +--- 6 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 clang/include/clang/Basic/BuiltinsHLSL.td diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..2943911b662191 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4511,19 +4511,6 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> { let Prototype = "char const*(...)"; } -// HLSL -def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { - let Spellings = ["__builtin_hlsl_wave_active_count_bits"]; - let Attributes = [NoThrow, Const]; - let Prototype = "unsigned int(bool)"; -} - -def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { - let Spellings = ["__builtin_hlsl_create_handle"]; - let Attributes = [NoThrow, Const]; - let Prototype = "void*(unsigned char)"; -} - // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/BuiltinsHLSL.td b/clang/include/clang/Basic/BuiltinsHLSL.td new file mode 100644 index 00..98088f920a9940 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsHLSL.td @@ -0,0 +1,21 @@ +//===--- BuiltinsHLSL.td - HLSL Builtin function database -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +include "clang/Basic/BuiltinsBase.td" + +def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_active_count_bits"]; + let Attributes = [NoThrow, Const]; + let Prototype = "unsigned int(bool)"; +} + +def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_create_handle"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void*(unsigned char)"; +} diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 7785fb430c069b..01233eb44feffc 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -65,7 +65,11 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins SOURCE BuiltinsBPF.td TARGET ClangBuiltinsBPF) -clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins +clang_tablegen(BuiltinsHLSL.inc -gen-clang-builtins + SOURCE BuiltinsHLSL.td + TARGET ClangBuiltinsHLSL) + + clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins SOURCE BuiltinsRISCV.td TARGET ClangBuiltinsRISCV) diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 4333830bf34f24..15cf111ae5e9e5 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -89,6 +89,16 @@ namespace clang { }; } + /// HLSL builtins + namespace hlsl { + enum { +LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsHLSL.inc" +LastTSBuiltin + }; + } // namespace hlsl + /// PPC builtins namespace PPC { enum { diff --git a/clang/lib/Basic/Targets/DirectX.cpp b/clang/lib/Basic/Targets/DirectX.cpp index 0dd27e6e93b33b..83cc049e5963aa 100644 --- a/clang/lib/Basic/Targets/DirectX.cpp +++ b/clang/lib/Basic/Targets/DirectX.cpp @@ -12,11 +12,24 @@ #include "DirectX.h" #include "Targets.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/TargetBuiltins.h" using namespace clang; using namespace clang::targets; +static constexpr Builtin::Info BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#include "clang/Basic/BuiltinsHLSL.inc" +}; + void DirectXTargetInfo::getTargetDefines(cons
[clang] [HLSL] add BuiltinsHLSL and set it up as target builtins. (PR #81902)
farzonl wrote: create handle test: ``` D:\projects\llvm-project>python ..\directx-llvm-build\bin\llvm-lit.py -sv clang\test\CodeGenHLSL\builtins\create_handle.hlsl llvm-lit.py: D:\projects\llvm-project\llvm\utils\lit\lit\llvm\config.py:57: note: using lit tools: C:\Program Files\Git\usr\bin llvm-lit.py: D:\projects\llvm-project\llvm\utils\lit\lit\llvm\config.py:502: note: using clang: d:\projects\directx-llvm-build\bin\clang.exe -- Testing: 1 tests, 1 workers -- Testing: 0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. Testing Time: 6.71s Total Discovered Tests: 1 Passed: 1 (100.00%) ``` WaveActiveCountBits Sema Tests: ``` D:\projects\llvm-project>python ..\directx-llvm-build\bin\llvm-lit.py -sv clang\test\SemaHLSL\WaveBuiltinAvailability.hlsl llvm-lit.py: D:\projects\llvm-project\llvm\utils\lit\lit\llvm\config.py:57: note: using lit tools: C:\Program Files\Git\usr\bin llvm-lit.py: D:\projects\llvm-project\llvm\utils\lit\lit\llvm\config.py:502: note: using clang: d:\projects\directx-llvm-build\bin\clang.exe -- Testing: 1 tests, 1 workers -- Testing: 0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. Testing Time: 0.37s Total Discovered Tests: 1 Passed: 1 (100.00%) D:\projects\llvm-project>python ..\directx-llvm-build\bin\llvm-lit.py -sv clang\test\SemaHLSL\Wave.hlsl llvm-lit.py: D:\projects\llvm-project\llvm\utils\lit\lit\llvm\config.py:57: note: using lit tools: C:\Program Files\Git\usr\bin llvm-lit.py: D:\projects\llvm-project\llvm\utils\lit\lit\llvm\config.py:502: note: using clang: d:\projects\directx-llvm-build\bin\clang.exe -- Testing: 1 tests, 1 workers -- Testing: 0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. Testing Time: 0.28s Total Discovered Tests: 1 Passed: 1 (100.00%) ``` https://github.com/llvm/llvm-project/pull/81902 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] add BuiltinsHLSL and set it up as target builtins. (PR #81902)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/81902 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] add BuiltinsHLSL and set it up as target builtins. (PR #81902)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81902 >From 97022e196fdad0f4aff9e628607e3c24bef863df Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 15 Feb 2024 13:46:55 -0500 Subject: [PATCH] [HLSL] add BuiltinsHLSL and set it up as target builtins. 1. This change moves hlsl specific builtins from Builtins.td to BuiltinsHLSL.td. 2. Adds changes to the build system to build BuiltinsHLSL.td. 3. Setups HLSL builtins as TargetBuiltins. --- clang/include/clang/Basic/Builtins.td | 6 -- clang/include/clang/Basic/BuiltinsHLSL.td | 15 +++ clang/include/clang/Basic/CMakeLists.txt | 6 +- clang/include/clang/Basic/TargetBuiltins.h | 10 ++ clang/lib/Basic/Targets/DirectX.cpp| 13 + clang/lib/Basic/Targets/DirectX.h | 4 +--- 6 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 clang/include/clang/Basic/BuiltinsHLSL.td diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..1936c38f64cfff 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4512,12 +4512,6 @@ def GetDeviceSideMangledName : LangBuiltin<"CUDA_LANG"> { } // HLSL -def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { - let Spellings = ["__builtin_hlsl_wave_active_count_bits"]; - let Attributes = [NoThrow, Const]; - let Prototype = "unsigned int(bool)"; -} - def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_create_handle"]; let Attributes = [NoThrow, Const]; diff --git a/clang/include/clang/Basic/BuiltinsHLSL.td b/clang/include/clang/Basic/BuiltinsHLSL.td new file mode 100644 index 00..738cabf5ffb85d --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsHLSL.td @@ -0,0 +1,15 @@ +//===--- BuiltinsHLSL.td - HLSL Builtin function database -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +include "clang/Basic/BuiltinsBase.td" + +def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_active_count_bits"]; + let Attributes = [NoThrow, Const]; + let Prototype = "unsigned int(bool)"; +} diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 7785fb430c069b..01233eb44feffc 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -65,7 +65,11 @@ clang_tablegen(BuiltinsBPF.inc -gen-clang-builtins SOURCE BuiltinsBPF.td TARGET ClangBuiltinsBPF) -clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins +clang_tablegen(BuiltinsHLSL.inc -gen-clang-builtins + SOURCE BuiltinsHLSL.td + TARGET ClangBuiltinsHLSL) + + clang_tablegen(BuiltinsRISCV.inc -gen-clang-builtins SOURCE BuiltinsRISCV.td TARGET ClangBuiltinsRISCV) diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 4333830bf34f24..15cf111ae5e9e5 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -89,6 +89,16 @@ namespace clang { }; } + /// HLSL builtins + namespace hlsl { + enum { +LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsHLSL.inc" +LastTSBuiltin + }; + } // namespace hlsl + /// PPC builtins namespace PPC { enum { diff --git a/clang/lib/Basic/Targets/DirectX.cpp b/clang/lib/Basic/Targets/DirectX.cpp index 0dd27e6e93b33b..83cc049e5963aa 100644 --- a/clang/lib/Basic/Targets/DirectX.cpp +++ b/clang/lib/Basic/Targets/DirectX.cpp @@ -12,11 +12,24 @@ #include "DirectX.h" #include "Targets.h" +#include "clang/Basic/MacroBuilder.h" +#include "clang/Basic/TargetBuiltins.h" using namespace clang; using namespace clang::targets; +static constexpr Builtin::Info BuiltinInfo[] = { +#define BUILTIN(ID, TYPE, ATTRS) \ + {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, +#include "clang/Basic/BuiltinsHLSL.inc" +}; + void DirectXTargetInfo::getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const { DefineStd(Builder, "DIRECTX", Opts); } + +ArrayRef DirectXTargetInfo::getTargetBuiltins() const { + return llvm::ArrayRef(BuiltinInfo, +clang::hlsl::LastTSBuiltin - Builtin::FirstTSBuiltin); +} diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h index acfcc8c47ba950..99c9522b0dd542 100644 --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -73,9 +73,7 @@ class LLVM_LIBRARY_VISIBILITY Dir
[clang] [HLSL] add BuiltinsHLSL and set it up as target builtins. (PR #81902)
https://github.com/farzonl closed https://github.com/llvm/llvm-project/pull/81902 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From 23c277da327c595633d159c13bc710f413024cb2 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 50 + clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 80 clang/lib/Sema/SemaChecking.cpp | 84 +++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 179 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 449 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fb44495199ee56..9957f4e743e9cb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 53f06bcaeca166..d79fd07c8069e5 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14054,6 +14054,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 9bc60466d09be6..ae5d8ae36f0065 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuilt
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From 2baaf5b41d80639fa7dfe739ad5501d2f5359bfa Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 + clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 80 clang/lib/Sema/SemaChecking.cpp | 84 +++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 179 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 + llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 448 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fb44495199ee56..9957f4e743e9cb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 53f06bcaeca166..d79fd07c8069e5 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14054,6 +14054,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 9bc60466d09be6..1d8c1d26470639 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuilt
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -0,0 +1,202 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -emit-llvm -disable-llvm-passes \ +// RUN: -D__HLSL_ENABLE_16_BIT -o - | FileCheck %s --check-prefix=NO_HALF farzonl wrote: This Pr fixed a bunch of the issues mentioned: https://github.com/llvm/llvm-project/pull/81782/files I've updated these tests to be similar. https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -verify -verify-ignore-unexpected + +float test_first_arg_is_not_vector ( float p0, float2 p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{first two arguments to 'dot' must be vectors}} +} + +float test_second_arg_is_not_vector ( float2 p0, float p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{first two arguments to 'dot' must be vectors}} +} + +int test_dot_unsupported_scalar_arg0 ( bool p0, int p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{1st argument must be a vector, integer or floating point type (was 'bool')}} +} + +int test_dot_unsupported_scalar_arg1 ( int p0, bool p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{2nd argument must be a vector, integer or floating point type (was 'bool')}} +} + +float test_dot_scalar_mismatch ( float p0, int p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{call to 'dot' is ambiguous}} +} + +float test_dot_vector_size_mismatch ( float3 p0, float2 p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{no matching function for call to 'dot'}} +} + +float test__no_second_arg ( float2 p0) { + return dot ( p0 ); + // expected-error@-1 {{no matching function for call to 'dot'}} +} + +float test_dot_element_type_mismatch ( int2 p0, float2 p1 ) { + return dot ( p0, p1 ); + // expected-error@-1 {{no matching function for call to 'dot'}} farzonl wrote: I've listed thes tests as `XFAIL` so that when the behavior changes this testcase won't fail with it. https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From f6dbbfbf6b8aa221035e39735c5c6e2d0936219c Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fb44495199ee56..9957f4e743e9cb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 53f06bcaeca166..d79fd07c8069e5 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14054,6 +14054,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 9bc60466d09be6..1d8c1d26470639 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuiltinE
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -144,6 +144,92 @@ double3 cos(double3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos) double4 cos(double4); +//===--===// +// dot product builtins +//===--===// +#ifdef __HLSL_ENABLE_16_BIT +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half, half); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half2, half2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half3, half3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +half dot(half4, half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t, int16_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t2, int16_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t3, int16_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int16_t dot(int16_t4, int16_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t, uint16_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t2, uint16_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t3, uint16_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint16_t dot(uint16_t4, uint16_t4); +#endif + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float, float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float2, float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float3, float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +float dot(float4, float4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double, double); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double2, double2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double3, double3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +double dot(double4, double4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int dot(int, int); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int dot(int2, int2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int dot(int3, int3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int dot(int4, int4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint dot(uint, uint); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint dot(uint2, uint2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint dot(uint3, uint3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint dot(uint4, uint4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int64_t dot(int64_t, int64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int64_t dot(int64_t2, int64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int64_t dot(int64_t3, int64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +int64_t dot(int64_t4, int64_t4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint64_t dot(uint64_t, uint64_t); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint64_t dot(uint64_t2, uint64_t2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint64_t dot(uint64_t3, uint64_t3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_dot) +uint64_t dot(uint64_t4, uint64_t4); farzonl wrote: I think we all came to agreement these should be added back so updated the pr to add support back. https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl deleted https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -19,4 +19,9 @@ def int_dx_flattened_thread_id_in_group : Intrinsic<[llvm_i32_ty], [], [IntrNoMe def int_dx_create_handle : ClangBuiltin<"__builtin_hlsl_create_handle">, Intrinsic<[ llvm_ptr_ty ], [llvm_i8_ty], [IntrWillReturn]>; -} + +def int_dx_dot : +Intrinsic<[LLVMVectorElementType<0>], +[llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], +[IntrNoMem, IntrWillReturn, Commutative] >; farzonl wrote: with inclusion of i64 I don't think this request is needed anymore. https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From bebb3ad19cc1793090265e68b25c282f90b35227 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index fb44495199ee56..9957f4e743e9cb 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e9cd42ae777df5..3557db56905ff8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14055,6 +14055,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index d454ccc1dd8613..4bad41a9be214e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuiltinE
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl ready_for_review https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From 586ee65c5e820365a6fd150d7f246fbfa679ec3e Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6e3cebc311eeb9..46f5424038d8b0 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e9cd42ae777df5..3557db56905ff8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14055,6 +14055,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index d454ccc1dd8613..4bad41a9be214e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuiltinE
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From 595ce41f71bd9e0f83679bd5c742b3015bf30626 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/2] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6e3cebc311eeb9..46f5424038d8b0 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 89215bf3d1c69a..6fe10fad45daff 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14055,6 +14055,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index d454ccc1dd8613..4bad41a9be214e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -18015,38 +18015,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) farzonl wrote: `X->getType()` is a `Type` pointer. `E->getArg(0)->getType()` is a `QualType`. Only QualTypes allow us to use `hasFloatingRepresentation` https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -5254,7 +5250,11 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { QualType ExpectedType = S->Context.FloatTy; for (unsigned i = 0; i < TheCall->getNumArgs(); ++i) { QualType PassedType = TheCall->getArg(i)->getType(); -if (!PassedType->hasFloatingRepresentation()) { +ExpectedType = PassedType->isHalfType() && S->getLangOpts().NativeHalfType + ? S->Context.HalfTy + : S->Context.FloatTy; +if (PassedType == S->Context.DoubleTy || +!PassedType->hasFloatingRepresentation()) { farzonl wrote: I have a solution I think will make things more clear. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From 7dde8faaad046b715027a0f9fb772af90b6ffb30 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 7 Mar 2024 20:48:46 -0500 Subject: [PATCH 1/4] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 CGBuiltin.cpp - - simplify lerp intrinsic IntrinsicsDirectX.td - simplify lerp intrinsic SemaChecking.cpp - remove unnecessary check DXILIntrinsicExpansion.* - add intrinsic to instruction expansion cases DXILOpLowering.cpp - make sure DXILIntrinsicExpansion happens first DirectX.h - changes to support new pass DirectXTargetMachine.cpp - changes to support new pass --- clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 2 - clang/test/CodeGenHLSL/builtins/lerp.hlsl | 13 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 187 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 133 + llvm/test/CodeGen/DirectX/exp-vec.ll | 23 +++ llvm/test/CodeGen/DirectX/exp.ll | 38 llvm/test/CodeGen/DirectX/lerp.ll | 64 ++ llvm/test/CodeGen/DirectX/rcp.ll | 63 ++ 15 files changed, 564 insertions(+), 47 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 93ab465079777b..25e4793c3e22d8 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18015,38 +18015,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V = Builder.CreateFSub(Y, X); -V = Builder.CreateFMul(S, V); -return Builder.CreateFAdd(X, V, "dx.lerp"); - } - llvm_unreachable("Scalar Lerp is only supported on floats."); -} -// A VectorSplat should have happened -assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && - "Lerp of vector and scalar is not supported."); - -[[maybe_unused]] auto *XVecTy = -E->getArg(0)->getType()->getAs(); -[[maybe_unused]] auto *YVecTy = -E->getArg(1)->getType()->getAs(); -[[maybe_unused]] auto *SVecTy = -E->getArg(2)->getType()->getAs(); -// A HLSLVectorTruncation should have happend -assert(XVecTy->getNumElements() == YVecTy->getNumElements() && - XVecTy->getNumElements() == SVecTy->getNumElements() && - "Lerp requires vectors to be of the same size."); -assert(XVecTy->getElementType()->isRealFloatingType() && - XVecTy->getElementType() == YVecTy->getElementType() && - XVecTy->getElementType() == SVecTy->getElementType() && - "Lerp requires float vectors to be of the same type."); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("lerp operand must have a float representation"); return Builder.CreateIntrinsic( -/*ReturnType=*/Xty, Intrinsic::dx_lerp, ArrayRef{X, Y, S}, -nullptr, "dx.lerp"); +/*ReturnType=*/X->getType(), Intrinsic::dx_lerp, +ArrayRef{X, Y, S}, nullptr, "dx.lerp"); } case Builtin::BI__builtin_hlsl_elementwise_frac: { Value *Op0 = EmitScalarExpr(E->getArg(0)); diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..8a2b7384a0b0d5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5300,8 +5300,6 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinElementwiseTernaryMath(TheCall)) return true; -if (CheckAllArgsHaveFloatRepresentation(this, TheCall)) - return true; break; } case Builtin::BI__builtin_hlsl_mad: { diff --git a/clang/test/CodeGenHLSL/builtins/lerp.hlsl b/clang/test/CodeGenHLSL/builtins/le
[clang] [llvm] [HLSL] Implement `rsqrt` intrinsic (PR #84820)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84820 >From a46ecdee6356e744a80f3c29748e7c3482a89760 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Mon, 11 Mar 2024 15:17:35 -0400 Subject: [PATCH 1/3] [HLSL] Implement `rsqrt` intrinsic This change implements #70074 - `hlsl_intrinsics.h - add the rsqrt api - `DXIL.td` add the llvm intrinsic to DXIL op lowering map. - `Builtins.td` - add an hlsl builtin for rsqrt. - `CGBuiltin.cpp` add the ir generation for the rsqrt intrinsic. - `SemaChecking.cpp` - reuse the one arg float only checks. - `IntrinsicsDirectX.td -add an `rsqrt` intrinsic. --- clang/include/clang/Basic/Builtins.td | 6 +++ clang/lib/CodeGen/CGBuiltin.cpp | 8 +++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 32 +++ clang/lib/Sema/SemaChecking.cpp | 1 + clang/test/CodeGenHLSL/builtins/rsqrt.hlsl| 53 +++ clang/test/SemaHLSL/BuiltIns/dot-warning.ll | 49 + .../test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl | 27 ++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 3 ++ llvm/test/CodeGen/DirectX/rsqrt.ll| 31 +++ 10 files changed, 211 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/rsqrt.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-warning.ll create mode 100644 clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/rsqrt.ll diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 9c703377ca8d3e..de0cfb4e46b8bd 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4590,6 +4590,12 @@ def HLSLRcp : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_rsqrt"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 20c35757939152..d2c83a5e405f42 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18077,6 +18077,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/Op0->getType(), Intrinsic::dx_rcp, ArrayRef{Op0}, nullptr, "dx.rcp"); } + case Builtin::BI__builtin_hlsl_elementwise_rsqrt: { +Value *Op0 = EmitScalarExpr(E->getArg(0)); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("rsqrt operand must have a float representation"); +return Builder.CreateIntrinsic( +/*ReturnType=*/Op0->getType(), Intrinsic::dx_rsqrt, +ArrayRef{Op0}, nullptr, "dx.rsqrt"); + } } return nullptr; } diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 45f8544392584e..71238a4f268ede 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -1153,6 +1153,38 @@ double3 rcp(double3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rcp) double4 rcp(double4); +//===--===// +// rsqrt builtins +//===--===// + +/// \fn T rsqrt(T x) +/// \brief RReturns the reciprocal of the square root of the specified value \a +/// x. \param x The specified input value. +/// +/// This function uses the following formula: 1 / sqrt(x). + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half rsqrt(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half2 rsqrt(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half3 rsqrt(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half4 rsqrt(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float rsqrt(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float2 rsqrt(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float3 rsqrt(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float4 rsqrt(float4); + //===--===// // round builtins //===--===// diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a5f42b630c3fa2..0dafff47ab4040 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5285,6 +5285,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *The
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,105 @@ +; RUN: opt -S -dxil-op-lower < %s | FileCheck %s + +; Make sure dxil operation function calls for any are generated for float and half. + +; CHECK:icmp ne i1 %{{.*}}, false farzonl wrote: That was my thinking as well, but all the other tests in this directory lacked the space and I didn't want to go against the the grain. https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implement `rsqrt` intrinsic (PR #84820)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84820 >From 9d3ae7bb5c40d2323a74c9d467c6c38f468ad038 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 14 Mar 2024 14:27:21 -0400 Subject: [PATCH 1/4] rebase PR, add error checking for rsqrt --- clang/include/clang/Basic/Builtins.td | 6 +++ clang/lib/CodeGen/CGBuiltin.cpp | 8 +++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 32 +++ clang/lib/Sema/SemaChecking.cpp | 1 + clang/test/CodeGenHLSL/builtins/rsqrt.hlsl| 53 +++ clang/test/SemaHLSL/BuiltIns/dot-warning.ll | 49 + .../test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl | 27 ++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 1 + llvm/lib/Target/DirectX/DXIL.td | 4 ++ llvm/test/CodeGen/DirectX/rsqrt.ll| 31 +++ llvm/test/CodeGen/DirectX/rsqrt_error.ll | 14 + 11 files changed, 226 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/rsqrt.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-warning.ll create mode 100644 clang/test/SemaHLSL/BuiltIns/rsqrt-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/rsqrt.ll create mode 100644 llvm/test/CodeGen/DirectX/rsqrt_error.ll diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 9c703377ca8d3e..de0cfb4e46b8bd 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4590,6 +4590,12 @@ def HLSLRcp : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLRSqrt : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_rsqrt"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 528a13fb275124..0a860c687921d9 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18089,6 +18089,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/Op0->getType(), Intrinsic::dx_rcp, ArrayRef{Op0}, nullptr, "dx.rcp"); } + case Builtin::BI__builtin_hlsl_elementwise_rsqrt: { +Value *Op0 = EmitScalarExpr(E->getArg(0)); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("rsqrt operand must have a float representation"); +return Builder.CreateIntrinsic( +/*ReturnType=*/Op0->getType(), Intrinsic::dx_rsqrt, +ArrayRef{Op0}, nullptr, "dx.rsqrt"); + } } return nullptr; } diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 45f8544392584e..71238a4f268ede 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -1153,6 +1153,38 @@ double3 rcp(double3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rcp) double4 rcp(double4); +//===--===// +// rsqrt builtins +//===--===// + +/// \fn T rsqrt(T x) +/// \brief RReturns the reciprocal of the square root of the specified value \a +/// x. \param x The specified input value. +/// +/// This function uses the following formula: 1 / sqrt(x). + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half rsqrt(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half2 rsqrt(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half3 rsqrt(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +half4 rsqrt(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float rsqrt(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float2 rsqrt(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float3 rsqrt(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_rsqrt) +float4 rsqrt(float4); + //===--===// // round builtins //===--===// diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 124fb2b65438b5..9f1eb6106f5b53 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5286,6 +5286,7 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; break; } + case Builtin::BI__builtin_hlsl_elementwise_rsqrt: case Builtin::BI__builtin_hlsl_elementwise_rcp: case Builtin::BI__builtin_hlsl_elementwise_frac: { if (PrepareBuiltinElementwiseM
[clang] [llvm] [HLSL] implement the `isinf` intrinsic (PR #84927)
https://github.com/farzonl deleted https://github.com/llvm/llvm-project/pull/84927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] implement the `isinf` intrinsic (PR #84927)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84927 >From b21e8806ccc559d4326e26432cdce8ba13dc0984 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Mon, 11 Mar 2024 15:28:49 -0400 Subject: [PATCH 1/2] [HLSL] implement the `isinf` intrinsic This change implements part 1 of 2 for #70095 - `hlsl_intrinsics.h - add the `isinf` api - `Builtins.td` - add an hlsl builtin for `isinf`. - `CGBuiltin.cpp` add the ir generation for `isinf` intrinsic. - `SemaChecking.cpp` - add a non-math elementwise checks because this is a bool return. - `IntrinsicsDirectX.td - add an `isinf` intrinsic. DXIL.td lowering is left, but changes need to be made there before we can support this case. --- clang/include/clang/Basic/Builtins.td | 6 +++ clang/lib/CodeGen/CGBuiltin.cpp | 15 +++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 33 ++ clang/lib/Sema/SemaChecking.cpp | 16 +++ clang/test/CodeGenHLSL/builtins/isinf.hlsl| 45 +++ .../test/SemaHLSL/BuiltIns/isinf-errors.hlsl | 27 +++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 4 ++ 7 files changed, 146 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/isinf.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 9c703377ca8d3e..b3376b316cd222 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4572,6 +4572,12 @@ def HLSLFrac : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLIsinf : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_isinf"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLLerp : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_lerp"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 528a13fb275124..0d55322c275f41 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18062,6 +18062,21 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/Op0->getType(), Intrinsic::dx_frac, ArrayRef{Op0}, nullptr, "dx.frac"); } + case Builtin::BI__builtin_hlsl_elementwise_isinf: { +Value *Op0 = EmitScalarExpr(E->getArg(0)); +llvm::Type *Xty = Op0->getType(); +llvm::Type *retType = llvm::Type::getInt1Ty(this->getLLVMContext()); +if (Xty->isVectorTy()) { + auto *XVecTy = E->getArg(0)->getType()->getAs(); + retType = llvm::VectorType::get( + retType, ElementCount::getFixed(XVecTy->getNumElements())); +} +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("isinf operand must have a float representation"); +return Builder.CreateIntrinsic( +/*ReturnType=*/retType, Intrinsic::dx_isinf, ArrayRef{Op0}, +nullptr, "dx.isinf"); + } case Builtin::BI__builtin_hlsl_mad: { Value *M = EmitScalarExpr(E->getArg(0)); Value *A = EmitScalarExpr(E->getArg(1)); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 45f8544392584e..2c3ab46d959137 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -525,6 +525,39 @@ float3 frac(float3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) float4 frac(float4); +//===--===// +// isinf builtins +//===--===// + +/// \fn T isinf(T x) +/// \brief Determines if the specified value \a x is infinite. +/// \param x The specified input value. +/// +/// Returns a value of the same size as the input, with a value set +/// to True if the x parameter is +INF or -INF. Otherwise, False. + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool isinf(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool2 isinf(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool3 isinf(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool4 isinf(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool isinf(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool2 isinf(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool3 isinf(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool4 isinf(float4); + //===--===// // lerp builtins //===--===// diff --git a/clang/lib/Sema/Se
[clang] [llvm] [HLSL] implement the `isinf` intrinsic (PR #84927)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84927 >From b21e8806ccc559d4326e26432cdce8ba13dc0984 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Mon, 11 Mar 2024 15:28:49 -0400 Subject: [PATCH 1/2] [HLSL] implement the `isinf` intrinsic This change implements part 1 of 2 for #70095 - `hlsl_intrinsics.h - add the `isinf` api - `Builtins.td` - add an hlsl builtin for `isinf`. - `CGBuiltin.cpp` add the ir generation for `isinf` intrinsic. - `SemaChecking.cpp` - add a non-math elementwise checks because this is a bool return. - `IntrinsicsDirectX.td - add an `isinf` intrinsic. DXIL.td lowering is left, but changes need to be made there before we can support this case. --- clang/include/clang/Basic/Builtins.td | 6 +++ clang/lib/CodeGen/CGBuiltin.cpp | 15 +++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 33 ++ clang/lib/Sema/SemaChecking.cpp | 16 +++ clang/test/CodeGenHLSL/builtins/isinf.hlsl| 45 +++ .../test/SemaHLSL/BuiltIns/isinf-errors.hlsl | 27 +++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 4 ++ 7 files changed, 146 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/isinf.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 9c703377ca8d3e..b3376b316cd222 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4572,6 +4572,12 @@ def HLSLFrac : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLIsinf : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_isinf"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLLerp : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_lerp"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 528a13fb275124..0d55322c275f41 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18062,6 +18062,21 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/Op0->getType(), Intrinsic::dx_frac, ArrayRef{Op0}, nullptr, "dx.frac"); } + case Builtin::BI__builtin_hlsl_elementwise_isinf: { +Value *Op0 = EmitScalarExpr(E->getArg(0)); +llvm::Type *Xty = Op0->getType(); +llvm::Type *retType = llvm::Type::getInt1Ty(this->getLLVMContext()); +if (Xty->isVectorTy()) { + auto *XVecTy = E->getArg(0)->getType()->getAs(); + retType = llvm::VectorType::get( + retType, ElementCount::getFixed(XVecTy->getNumElements())); +} +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("isinf operand must have a float representation"); +return Builder.CreateIntrinsic( +/*ReturnType=*/retType, Intrinsic::dx_isinf, ArrayRef{Op0}, +nullptr, "dx.isinf"); + } case Builtin::BI__builtin_hlsl_mad: { Value *M = EmitScalarExpr(E->getArg(0)); Value *A = EmitScalarExpr(E->getArg(1)); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 45f8544392584e..2c3ab46d959137 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -525,6 +525,39 @@ float3 frac(float3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) float4 frac(float4); +//===--===// +// isinf builtins +//===--===// + +/// \fn T isinf(T x) +/// \brief Determines if the specified value \a x is infinite. +/// \param x The specified input value. +/// +/// Returns a value of the same size as the input, with a value set +/// to True if the x parameter is +INF or -INF. Otherwise, False. + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool isinf(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool2 isinf(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool3 isinf(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool4 isinf(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool isinf(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool2 isinf(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool3 isinf(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool4 isinf(float4); + //===--===// // lerp builtins //===--===// diff --git a/clang/lib/Sema/Se
[clang] [llvm] [HLSL] Implement `rsqrt` intrinsic (PR #84820)
https://github.com/farzonl closed https://github.com/llvm/llvm-project/pull/84820 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] implement the `isinf` intrinsic (PR #84927)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84927 >From c240a73ea6edc4e7697ca3c7e4012849ec9a3583 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 14 Mar 2024 16:54:12 -0400 Subject: [PATCH 1/3] address merge conflict --- clang/include/clang/Basic/Builtins.td | 6 +++ clang/lib/CodeGen/CGBuiltin.cpp | 15 +++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 33 ++ clang/lib/Sema/SemaChecking.cpp | 16 +++ clang/test/CodeGenHLSL/builtins/isinf.hlsl| 45 +++ .../test/SemaHLSL/BuiltIns/isinf-errors.hlsl | 27 +++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 4 ++ 7 files changed, 146 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/isinf.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/isinf-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index de0cfb4e46b8bd..15fcdb3ced95c1 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4572,6 +4572,12 @@ def HLSLFrac : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLIsinf : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_isinf"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLLerp : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_lerp"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0a860c687921d9..2c8f17eebe2d52 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18062,6 +18062,21 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/Op0->getType(), Intrinsic::dx_frac, ArrayRef{Op0}, nullptr, "dx.frac"); } + case Builtin::BI__builtin_hlsl_elementwise_isinf: { +Value *Op0 = EmitScalarExpr(E->getArg(0)); +llvm::Type *Xty = Op0->getType(); +llvm::Type *retType = llvm::Type::getInt1Ty(this->getLLVMContext()); +if (Xty->isVectorTy()) { + auto *XVecTy = E->getArg(0)->getType()->getAs(); + retType = llvm::VectorType::get( + retType, ElementCount::getFixed(XVecTy->getNumElements())); +} +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("isinf operand must have a float representation"); +return Builder.CreateIntrinsic( +/*ReturnType=*/retType, Intrinsic::dx_isinf, ArrayRef{Op0}, +nullptr, "dx.isinf"); + } case Builtin::BI__builtin_hlsl_mad: { Value *M = EmitScalarExpr(E->getArg(0)); Value *A = EmitScalarExpr(E->getArg(1)); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 3bdb0a3d68b9de..718fb9a9b35c04 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -525,6 +525,39 @@ float3 frac(float3); _HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) float4 frac(float4); +//===--===// +// isinf builtins +//===--===// + +/// \fn T isinf(T x) +/// \brief Determines if the specified value \a x is infinite. +/// \param x The specified input value. +/// +/// Returns a value of the same size as the input, with a value set +/// to True if the x parameter is +INF or -INF. Otherwise, False. + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool isinf(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool2 isinf(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool3 isinf(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool4 isinf(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool isinf(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool2 isinf(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool3 isinf(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_isinf) +bool4 isinf(float4); + //===--===// // lerp builtins //===--===// diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 7ba02f6d3b793c..366ab1abbd8efd 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5268,6 +5268,15 @@ bool CheckAllArgsHaveFloatRepresentation(Sema *S, CallExpr *TheCall) { return false; } +void SetInputRepresentationReturnType(Sema *S, CallExpr *TheCall, + QualType ReturnType) { + auto *VecTyA = TheCall->getArg(0)->getTyp
[clang] [llvm] [HLSL] implement the `isinf` intrinsic (PR #84927)
https://github.com/farzonl closed https://github.com/llvm/llvm-project/pull/84927 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From 3f515637fc87a41db1df4ea7627679c7dd75503a Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 14 Mar 2024 18:53:33 -0400 Subject: [PATCH 1/2] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 `CGBuiltin.cpp` - - simplify `lerp` intrinsic `IntrinsicsDirectX.td` - simplify `lerp` intrinsic `SemaChecking.cpp` - remove unnecessary check `DXILIntrinsicExpansion.*` - add intrinsic to instruction expansion cases `DXILOpLowering.cpp` - make sure `DXILIntrinsicExpansion` happens first `DirectX.h` - changes to support new pass `DirectXTargetMachine.cpp` - changes to support new pass Why `any`, and `lerp` as instruction expansion just for DXIL? - SPIR-V there is an [OpAny](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpAny) - SPIR-V has a GLSL lerp extension via [Fmix](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#FMix) Why `exp` instruction expansion? - We have an `exp2` opcode and `exp` reuses that opcode. So instruction expansion is a convenient way to do preprocessing. - Further SPIR-V has a GLSL exp extension via [Exp](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#Exp) and [Exp2](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#Exp2) Why `rcp` as instruction expansion? This one is a bit of the odd man out and might have to move to `cgbuiltins` when we better understand SPIRV requirements. However I included it because it seems like [fast math mode has an AllowRecip flag](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_fp_fast_math_mode) which lets you compute the reciprocal without performing the division. We don't have that in DXIL so thought to include it. --- clang/include/clang/AST/Type.h| 5 + clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 51 +++-- .../CodeGenHLSL/builtins/lerp-builtin.hlsl| 22 --- clang/test/CodeGenHLSL/builtins/lerp.hlsl | 27 ++- clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl | 17 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 4 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 186 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 105 ++ llvm/test/CodeGen/DirectX/exp-vec.ll | 16 ++ llvm/test/CodeGen/DirectX/exp.ll | 29 +++ llvm/test/CodeGen/DirectX/lerp.ll | 53 + llvm/test/CodeGen/DirectX/rcp.ll | 48 + 18 files changed, 557 insertions(+), 89 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1942b0e67f65a3..10916053cdfbf5 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2244,6 +2244,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 + bool isFloat32Type() const; bool isBFloat16Type() const; bool isFloat128Type() const; bool isIbm128Type() const; @@ -7452,6 +7453,10 @@ inline bool Type::isFloat16Type() const { return isSpecificBuiltinType(BuiltinType::Float16); } +inline bool Type::isFloat32Type() const { + return isSpecificBuiltinType(BuiltinType::Float); +} + inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b9d1a4912385e1..b09bf563622089 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18021,38 +18021,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/84526 >From 3f515637fc87a41db1df4ea7627679c7dd75503a Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 14 Mar 2024 18:53:33 -0400 Subject: [PATCH 1/3] [DXIL] exp, any, lerp, & rcp Intrinsic Lowering This change implements lowering for #70076, #70100, #70072, & #70102 `CGBuiltin.cpp` - - simplify `lerp` intrinsic `IntrinsicsDirectX.td` - simplify `lerp` intrinsic `SemaChecking.cpp` - remove unnecessary check `DXILIntrinsicExpansion.*` - add intrinsic to instruction expansion cases `DXILOpLowering.cpp` - make sure `DXILIntrinsicExpansion` happens first `DirectX.h` - changes to support new pass `DirectXTargetMachine.cpp` - changes to support new pass Why `any`, and `lerp` as instruction expansion just for DXIL? - SPIR-V there is an [OpAny](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpAny) - SPIR-V has a GLSL lerp extension via [Fmix](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#FMix) Why `exp` instruction expansion? - We have an `exp2` opcode and `exp` reuses that opcode. So instruction expansion is a convenient way to do preprocessing. - Further SPIR-V has a GLSL exp extension via [Exp](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#Exp) and [Exp2](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#Exp2) Why `rcp` as instruction expansion? This one is a bit of the odd man out and might have to move to `cgbuiltins` when we better understand SPIRV requirements. However I included it because it seems like [fast math mode has an AllowRecip flag](https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#_fp_fast_math_mode) which lets you compute the reciprocal without performing the division. We don't have that in DXIL so thought to include it. --- clang/include/clang/AST/Type.h| 5 + clang/lib/CodeGen/CGBuiltin.cpp | 35 +--- clang/lib/Sema/SemaChecking.cpp | 51 +++-- .../CodeGenHLSL/builtins/lerp-builtin.hlsl| 22 --- clang/test/CodeGenHLSL/builtins/lerp.hlsl | 27 ++- clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl | 17 +- llvm/include/llvm/IR/IntrinsicsDirectX.td | 4 +- llvm/lib/Target/DirectX/CMakeLists.txt| 1 + .../Target/DirectX/DXILIntrinsicExpansion.cpp | 186 ++ .../Target/DirectX/DXILIntrinsicExpansion.h | 33 llvm/lib/Target/DirectX/DXILOpLowering.cpp| 6 +- llvm/lib/Target/DirectX/DirectX.h | 6 + .../Target/DirectX/DirectXTargetMachine.cpp | 2 + llvm/test/CodeGen/DirectX/any.ll | 105 ++ llvm/test/CodeGen/DirectX/exp-vec.ll | 16 ++ llvm/test/CodeGen/DirectX/exp.ll | 29 +++ llvm/test/CodeGen/DirectX/lerp.ll | 53 + llvm/test/CodeGen/DirectX/rcp.ll | 48 + 18 files changed, 557 insertions(+), 89 deletions(-) create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.cpp create mode 100644 llvm/lib/Target/DirectX/DXILIntrinsicExpansion.h create mode 100644 llvm/test/CodeGen/DirectX/any.ll create mode 100644 llvm/test/CodeGen/DirectX/exp-vec.ll create mode 100644 llvm/test/CodeGen/DirectX/exp.ll create mode 100644 llvm/test/CodeGen/DirectX/lerp.ll create mode 100644 llvm/test/CodeGen/DirectX/rcp.ll diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1942b0e67f65a3..10916053cdfbf5 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2244,6 +2244,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 + bool isFloat32Type() const; bool isBFloat16Type() const; bool isFloat128Type() const; bool isIbm128Type() const; @@ -7452,6 +7453,10 @@ inline bool Type::isFloat16Type() const { return isSpecificBuiltinType(BuiltinType::Float16); } +inline bool Type::isFloat32Type() const { + return isSpecificBuiltinType(BuiltinType::Float); +} + inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b9d1a4912385e1..b09bf563622089 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18021,38 +18021,11 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, Value *X = EmitScalarExpr(E->getArg(0)); Value *Y = EmitScalarExpr(E->getArg(1)); Value *S = EmitScalarExpr(E->getArg(2)); -llvm::Type *Xty = X->getType(); -llvm::Type *Yty = Y->getType(); -llvm::Type *Sty = S->getType(); -if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { - if (Xty->isFloatingPointTy()) { -auto V
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl closed https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] implement `clamp` intrinsic (PR #85424)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/85424 closes #70071 - `CGBuiltin.cpp` - Add the unsigned\generic clamp intrinsic emitter. - `IntrinsicsDirectX.td` - add the `dx.clamp` & `dx.uclamp` intrinsics - `DXILIntrinsicExpansion.cpp` - add the `clamp` instruction expansion while maintaining vector form. - `SemaChecking.cpp` - Add `clamp` builtin Sema Checks. - `Builtins.td` - add a `clamp` builtin - `hlsl_intrinsics.h` - add the `clamp` api Why `clamp` as instruction expansion for DXIL? 1. SPIR-V has a GLSL `clamp` extension via: - [FClamp](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#FClamp) - [UClamp](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#UClamp) - [SClamp](https://registry.khronos.org/SPIR-V/specs/1.0/GLSL.std.450.html#SClamp) 2. Further Clamp lowers to `min(max( x, min_range ), max_range)` which we have float, signed, & unsigned dixilOps. >From 681f4bbbc4aba08e285864ded62a7f01e178bf38 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 14 Mar 2024 15:26:26 -0400 Subject: [PATCH 1/2] [HLSL] Implement the intrinsic --- clang/include/clang/Basic/Builtins.td | 6 + clang/lib/CodeGen/CGBuiltin.cpp | 8 ++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 110 ++ clang/lib/Sema/SemaChecking.cpp | 15 +- .../CodeGenHLSL/builtins/clamp-builtin.hlsl | 8 ++ clang/test/CodeGenHLSL/builtins/clamp.hlsl| 134 ++ .../test/SemaHLSL/BuiltIns/clamp-errors.hlsl | 91 llvm/include/llvm/IR/IntrinsicsDirectX.td | 2 +- llvm/lib/Target/DirectX/DXIL.td | 10 ++ .../Target/DirectX/DXILIntrinsicExpansion.cpp | 48 +++ llvm/test/CodeGen/DirectX/clamp.ll| 64 + llvm/test/CodeGen/DirectX/fmax.ll | 31 llvm/test/CodeGen/DirectX/fmin.ll | 31 llvm/test/CodeGen/DirectX/smax.ll | 31 llvm/test/CodeGen/DirectX/smin.ll | 31 llvm/test/CodeGen/DirectX/umax.ll | 29 ++-- llvm/test/CodeGen/DirectX/umin.ll | 31 17 files changed, 664 insertions(+), 16 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/clamp.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/clamp.ll create mode 100644 llvm/test/CodeGen/DirectX/fmax.ll create mode 100644 llvm/test/CodeGen/DirectX/fmin.ll create mode 100644 llvm/test/CodeGen/DirectX/smax.ll create mode 100644 llvm/test/CodeGen/DirectX/smin.ll create mode 100644 llvm/test/CodeGen/DirectX/umin.ll diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 58a2d22e7641fc..64599aaee0ced7 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4554,6 +4554,12 @@ def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { let Prototype = "unsigned int(bool)"; } +def HLSLClamp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_clamp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_create_handle"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b09bf563622089..f831694fe9bc23 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -17981,6 +17981,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/llvm::Type::getInt1Ty(getLLVMContext()), Intrinsic::dx_any, ArrayRef{Op0}, nullptr, "dx.any"); } + case Builtin::BI__builtin_hlsl_elementwise_clamp: { +Value *OpX = EmitScalarExpr(E->getArg(0)); +Value *OpMin = EmitScalarExpr(E->getArg(1)); +Value *OpMax = EmitScalarExpr(E->getArg(2)); +return Builder.CreateIntrinsic( +/*ReturnType=*/OpX->getType(), Intrinsic::dx_clamp, +ArrayRef{OpX, OpMin, OpMax}, nullptr, "dx.clamp"); + } case Builtin::BI__builtin_hlsl_dot: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 718fb9a9b35c04..5e703772b7ee4f 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -252,6 +252,116 @@ double3 ceil(double3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil) double4 ceil(double4); +//===--===// +// clamp builtins +//===--===// + +/// \fn T clamp(T X, T Min, T Max) +/// \brief Clamps the specified value \a X to the specified +/// minimum ( \a Min) and maximum (
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
@@ -0,0 +1,186 @@ +//===- DXILIntrinsicExpansion.cpp - Prepare LLVM Module for DXIL encoding--===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +/// +/// \file This file contains DXIL intrinsic expansions for those that don't have +// opcodes in DirectX Intermediate Language (DXIL). +//===--===// + +#include "DXILIntrinsicExpansion.h" +#include "DirectX.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include "llvm/IR/IntrinsicsDirectX.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/IR/Type.h" +#include "llvm/Pass.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" + +#define DEBUG_TYPE "dxil-intrinsic-expansion" + +using namespace llvm; + +static bool isIntrinsicExpansion(Function &F) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: + case Intrinsic::dx_any: + case Intrinsic::dx_lerp: + case Intrinsic::dx_rcp: +return true; + } + return false; +} + +static bool expandExpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *Log2eConst = + Ty->isVectorTy() ? ConstantVector::getSplat( + ElementCount::getFixed( + cast(Ty)->getNumElements()), + ConstantFP::get(EltTy, numbers::log2e)) + : ConstantFP::get(EltTy, numbers::log2e); + Value *NewX = Builder.CreateFMul(Log2eConst, X); + auto *Exp2Call = + Builder.CreateIntrinsic(Ty, Intrinsic::exp2, {NewX}, nullptr, "dx.exp2"); + Exp2Call->setTailCall(Orig->isTailCall()); + Exp2Call->setAttributes(Orig->getAttributes()); + Orig->replaceAllUsesWith(Exp2Call); + Orig->eraseFromParent(); + return true; +} + +static bool expandAnyIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + + if (!Ty->isVectorTy()) { +Value *Cond = EltTy->isFloatingPointTy() + ? Builder.CreateFCmpUNE(X, ConstantFP::get(EltTy, 0)) + : Builder.CreateICmpNE(X, ConstantInt::get(EltTy, 0)); +Orig->replaceAllUsesWith(Cond); + } else { +auto *XVec = dyn_cast(Ty); +Value *Cond = +EltTy->isFloatingPointTy() +? Builder.CreateFCmpUNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantFP::get(EltTy, 0))) +: Builder.CreateICmpNE( + X, ConstantVector::getSplat( + ElementCount::getFixed(XVec->getNumElements()), + ConstantInt::get(EltTy, 0))); +Value *Result = Builder.CreateExtractElement(Cond, (uint64_t)0); +for (unsigned I = 1; I < XVec->getNumElements(); I++) { + Value *Elt = Builder.CreateExtractElement(Cond, I); + Result = Builder.CreateOr(Result, Elt); +} +Orig->replaceAllUsesWith(Result); + } + Orig->eraseFromParent(); + return true; +} + +static bool expandLerpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + Value *Y = Orig->getOperand(1); + Value *S = Orig->getOperand(2); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + auto *V = Builder.CreateFSub(Y, X); + V = Builder.CreateFMul(S, V); + auto *Result = Builder.CreateFAdd(X, V, "dx.lerp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandRcpIntrinsic(CallInst *Orig) { + Value *X = Orig->getOperand(0); + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + Type *Ty = X->getType(); + Type *EltTy = Ty->getScalarType(); + Constant *One = + Ty->isVectorTy() + ? ConstantVector::getSplat( +ElementCount::getFixed( +dyn_cast(Ty)->getNumElements()), +ConstantFP::get(EltTy, 1.0)) + : ConstantFP::get(EltTy, 1.0); + auto *Result = Builder.CreateFDiv(One, X, "dx.rcp"); + Orig->replaceAllUsesWith(Result); + Orig->eraseFromParent(); + return true; +} + +static bool expandIntrinsic(Function &F, CallInst *Orig) { + switch (F.getIntrinsicID()) { + case Intrinsic::exp: +return expandExpIntrinsic(Orig); + case Intrinsic::dx_any: +
[clang] [llvm] [HLSL] implement `clamp` intrinsic (PR #85424)
@@ -132,12 +134,60 @@ static bool expandRcpIntrinsic(CallInst *Orig) { return true; } +static Intrinsic::ID getCorrectMaxIntrinsic(Type *elemTy, +Intrinsic::ID clampIntrinsic) { farzonl wrote: Will do. As an aside this function started off generic until I found out I couldn't use `getSignBit()` to distinguish unsigned clamp vs signed clamp. The only way I could determine signed-ness was in codeGen. https://github.com/llvm/llvm-project/pull/85424 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] implement `clamp` intrinsic (PR #85424)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/85424 >From 681f4bbbc4aba08e285864ded62a7f01e178bf38 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 14 Mar 2024 15:26:26 -0400 Subject: [PATCH 1/3] [HLSL] Implement the intrinsic --- clang/include/clang/Basic/Builtins.td | 6 + clang/lib/CodeGen/CGBuiltin.cpp | 8 ++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 110 ++ clang/lib/Sema/SemaChecking.cpp | 15 +- .../CodeGenHLSL/builtins/clamp-builtin.hlsl | 8 ++ clang/test/CodeGenHLSL/builtins/clamp.hlsl| 134 ++ .../test/SemaHLSL/BuiltIns/clamp-errors.hlsl | 91 llvm/include/llvm/IR/IntrinsicsDirectX.td | 2 +- llvm/lib/Target/DirectX/DXIL.td | 10 ++ .../Target/DirectX/DXILIntrinsicExpansion.cpp | 48 +++ llvm/test/CodeGen/DirectX/clamp.ll| 64 + llvm/test/CodeGen/DirectX/fmax.ll | 31 llvm/test/CodeGen/DirectX/fmin.ll | 31 llvm/test/CodeGen/DirectX/smax.ll | 31 llvm/test/CodeGen/DirectX/smin.ll | 31 llvm/test/CodeGen/DirectX/umax.ll | 29 ++-- llvm/test/CodeGen/DirectX/umin.ll | 31 17 files changed, 664 insertions(+), 16 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/clamp-builtin.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/clamp.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/clamp-errors.hlsl create mode 100644 llvm/test/CodeGen/DirectX/clamp.ll create mode 100644 llvm/test/CodeGen/DirectX/fmax.ll create mode 100644 llvm/test/CodeGen/DirectX/fmin.ll create mode 100644 llvm/test/CodeGen/DirectX/smax.ll create mode 100644 llvm/test/CodeGen/DirectX/smin.ll create mode 100644 llvm/test/CodeGen/DirectX/umin.ll diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 58a2d22e7641fc..64599aaee0ced7 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4554,6 +4554,12 @@ def HLSLWaveActiveCountBits : LangBuiltin<"HLSL_LANG"> { let Prototype = "unsigned int(bool)"; } +def HLSLClamp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_clamp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_create_handle"]; let Attributes = [NoThrow, Const]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index b09bf563622089..f831694fe9bc23 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -17981,6 +17981,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType=*/llvm::Type::getInt1Ty(getLLVMContext()), Intrinsic::dx_any, ArrayRef{Op0}, nullptr, "dx.any"); } + case Builtin::BI__builtin_hlsl_elementwise_clamp: { +Value *OpX = EmitScalarExpr(E->getArg(0)); +Value *OpMin = EmitScalarExpr(E->getArg(1)); +Value *OpMax = EmitScalarExpr(E->getArg(2)); +return Builder.CreateIntrinsic( +/*ReturnType=*/OpX->getType(), Intrinsic::dx_clamp, +ArrayRef{OpX, OpMin, OpMax}, nullptr, "dx.clamp"); + } case Builtin::BI__builtin_hlsl_dot: { Value *Op0 = EmitScalarExpr(E->getArg(0)); Value *Op1 = EmitScalarExpr(E->getArg(1)); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 718fb9a9b35c04..5e703772b7ee4f 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -252,6 +252,116 @@ double3 ceil(double3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil) double4 ceil(double4); +//===--===// +// clamp builtins +//===--===// + +/// \fn T clamp(T X, T Min, T Max) +/// \brief Clamps the specified value \a X to the specified +/// minimum ( \a Min) and maximum ( \a Max) range. +/// \param X A value to clamp. +/// \param Min The specified minimum range. +/// \param Max The specified maximum range. +/// +/// Returns The clamped value for the \a X parameter. +/// For values of -INF or INF, clamp will behave as expected. +/// However for values of NaN, the results are undefined. + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +half clamp(half, half, half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +half2 clamp(half2, half2, half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +half3 clamp(half3, half3, half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_clamp) +half4 clamp(half4, half4, half4); + +#ifdef
[clang] [llvm] [HLSL] implement `clamp` intrinsic (PR #85424)
https://github.com/farzonl closed https://github.com/llvm/llvm-project/pull/85424 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] `exp`, `any`, `lerp`, & `rcp` Intrinsic Lowering (PR #84526)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/84526 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] implement dot intrinsic lowering for integers (PR #85662)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/85662 this implements part 1 of 2 for #83626 - `CGBuiltin.cpp` - modified to have seperate cases for signed and unsigned integers. - `SemaChecking.cpp` - modified to prevent the generation of a double dot product intrinsic if the builtin were to be called directly. - `IntrinsicsDirectX.td` creation of the signed and unsigned dot intrinsics needed for instruction expansion. - `DXILIntrinsicExpansion.cpp` - handle instruction expansion cases for integer dot product. >From e7738ae379375ed40558b2e93cc67a5a726aadbc Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Fri, 15 Mar 2024 18:19:52 -0400 Subject: [PATCH] [DXIL] implement dot intrinsic lowering for integers this implements part 1 of 2 for #83626 - `CGBuiltin.cpp` - modified to have seperate cases for signed and unsigned integers. - `SemaChecking.cpp` - modified to prevent the generation of a double dot product intrinsic if the builtin were to be called directly. - `IntrinsicsDirectX.td` creation of the signed and unsigned dot intrinsics needed for instruction expansion. - `DXILIntrinsicExpansion.cpp` - handle instruction expansion cases for integer dot product. --- clang/lib/CodeGen/CGBuiltin.cpp | 14 ++- clang/lib/Sema/SemaChecking.cpp | 15 +++ clang/test/CodeGenHLSL/builtins/dot.hlsl | 36 +++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 9 ++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 11 +- .../Target/DirectX/DXILIntrinsicExpansion.cpp | 36 +++ llvm/test/CodeGen/DirectX/idot.ll | 100 ++ 7 files changed, 201 insertions(+), 20 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/idot.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index e965df810add54..e89691ab7921c3 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18036,6 +18036,17 @@ llvm::Value *CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments, return Arg; } +Intrinsic::ID getDotProductIntrinsic(QualType QT) { + if (QT->hasSignedIntegerRepresentation()) +return Intrinsic::dx_sdot; + if (QT->hasUnsignedIntegerRepresentation()) +return Intrinsic::dx_udot; + + assert(QT->hasFloatingRepresentation()); + return Intrinsic::dx_dot; + ; +} + Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (!getLangOpts().HLSL) @@ -18096,7 +18107,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, "Dot product requires vectors to be of the same size."); return Builder.CreateIntrinsic( -/*ReturnType=*/T0->getScalarType(), Intrinsic::dx_dot, +/*ReturnType=*/T0->getScalarType(), +getDotProductIntrinsic(E->getArg(0)->getType()), ArrayRef{Op0, Op1}, nullptr, "dx.dot"); } break; case Builtin::BI__builtin_hlsl_lerp: { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a0b256ab5579ee..384b929d37bc82 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5484,6 +5484,19 @@ bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { checkFloatorHalf); } +bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) { + auto checkDoubleVector = [](clang::QualType PassedType) -> bool { +if (PassedType->isVectorType() && PassedType->hasFloatingRepresentation()) { + clang::QualType BaseType = + PassedType->getAs()->getElementType(); + return !BaseType->isHalfType() && !BaseType->isFloat32Type(); +} +return false; + }; + return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, + checkDoubleVector); +} + void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall, QualType ReturnType) { auto *VecTyA = TheCall->getArg(0)->getType()->getAs(); @@ -5520,6 +5533,8 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinVectorToScalarMath(TheCall)) return true; +if (CheckNoDoubleVectors(this, TheCall)) + return true; break; } case Builtin::BI__builtin_hlsl_elementwise_rcp: { diff --git a/clang/test/CodeGenHLSL/builtins/dot.hlsl b/clang/test/CodeGenHLSL/builtins/dot.hlsl index c064d118caf3e7..0f993193c00cce 100644 --- a/clang/test/CodeGenHLSL/builtins/dot.hlsl +++ b/clang/test/CodeGenHLSL/builtins/dot.hlsl @@ -11,15 +11,15 @@ // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short(int16_t p0, int16_t p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v2i16(<2 x i16> %0, <2 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.sdot.v2i16(<2 x i16> %0, <2 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short2(int16_t2 p0, int16_t2 p1
[clang] [llvm] [DXIL] implement dot intrinsic lowering for integers (PR #85662)
@@ -39,11 +39,44 @@ static bool isIntrinsicExpansion(Function &F) { case Intrinsic::dx_uclamp: case Intrinsic::dx_lerp: case Intrinsic::dx_rcp: + case Intrinsic::dx_sdot: + case Intrinsic::dx_udot: return true; } return false; } +static bool expandIntegerDot(CallInst *Orig, Intrinsic::ID DotIntrinsic) { + assert(DotIntrinsic == Intrinsic::dx_sdot || + DotIntrinsic == Intrinsic::dx_udot); + Intrinsic::ID MadIntrinsic = DotIntrinsic == Intrinsic::dx_sdot + ? Intrinsic::dx_imad + : Intrinsic::dx_umad; + Value *A = Orig->getOperand(0); + Value *B = Orig->getOperand(1); + Type *ATy = A->getType(); + Type *BTy = B->getType(); + assert(ATy->isVectorTy() && BTy->isVectorTy()); + + IRBuilder<> Builder(Orig->getParent()); + Builder.SetInsertPoint(Orig); + + auto *AVec = dyn_cast(A->getType()); + Value *Elt0 = Builder.CreateExtractElement(A, (uint64_t)0); + Value *Elt1 = Builder.CreateExtractElement(B, (uint64_t)0); + Value *Result = Builder.CreateMul(Elt0, Elt1); + for (unsigned I = 1; I < AVec->getNumElements(); I++) { +Elt0 = Builder.CreateExtractElement(A, I); +Elt1 = Builder.CreateExtractElement(B, I); +Result = Builder.CreateIntrinsic(Result->getType(), MadIntrinsic, + ArrayRef{Elt0, Elt1, Result}, + nullptr, "dx.mad"); farzonl wrote: i thought about that, but then i would need to add a conditional to change the string and it didn't seem worth it. https://github.com/llvm/llvm-project/pull/85662 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] implement dot intrinsic lowering for integers (PR #85662)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/85662 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] implement dot intrinsic lowering for integers (PR #85662)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/85662 >From e7738ae379375ed40558b2e93cc67a5a726aadbc Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Fri, 15 Mar 2024 18:19:52 -0400 Subject: [PATCH 1/2] [DXIL] implement dot intrinsic lowering for integers this implements part 1 of 2 for #83626 - `CGBuiltin.cpp` - modified to have seperate cases for signed and unsigned integers. - `SemaChecking.cpp` - modified to prevent the generation of a double dot product intrinsic if the builtin were to be called directly. - `IntrinsicsDirectX.td` creation of the signed and unsigned dot intrinsics needed for instruction expansion. - `DXILIntrinsicExpansion.cpp` - handle instruction expansion cases for integer dot product. --- clang/lib/CodeGen/CGBuiltin.cpp | 14 ++- clang/lib/Sema/SemaChecking.cpp | 15 +++ clang/test/CodeGenHLSL/builtins/dot.hlsl | 36 +++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 9 ++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 11 +- .../Target/DirectX/DXILIntrinsicExpansion.cpp | 36 +++ llvm/test/CodeGen/DirectX/idot.ll | 100 ++ 7 files changed, 201 insertions(+), 20 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/idot.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index e965df810add54..e89691ab7921c3 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18036,6 +18036,17 @@ llvm::Value *CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments, return Arg; } +Intrinsic::ID getDotProductIntrinsic(QualType QT) { + if (QT->hasSignedIntegerRepresentation()) +return Intrinsic::dx_sdot; + if (QT->hasUnsignedIntegerRepresentation()) +return Intrinsic::dx_udot; + + assert(QT->hasFloatingRepresentation()); + return Intrinsic::dx_dot; + ; +} + Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (!getLangOpts().HLSL) @@ -18096,7 +18107,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, "Dot product requires vectors to be of the same size."); return Builder.CreateIntrinsic( -/*ReturnType=*/T0->getScalarType(), Intrinsic::dx_dot, +/*ReturnType=*/T0->getScalarType(), +getDotProductIntrinsic(E->getArg(0)->getType()), ArrayRef{Op0, Op1}, nullptr, "dx.dot"); } break; case Builtin::BI__builtin_hlsl_lerp: { diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index a0b256ab5579ee..384b929d37bc82 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5484,6 +5484,19 @@ bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { checkFloatorHalf); } +bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) { + auto checkDoubleVector = [](clang::QualType PassedType) -> bool { +if (PassedType->isVectorType() && PassedType->hasFloatingRepresentation()) { + clang::QualType BaseType = + PassedType->getAs()->getElementType(); + return !BaseType->isHalfType() && !BaseType->isFloat32Type(); +} +return false; + }; + return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, + checkDoubleVector); +} + void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall, QualType ReturnType) { auto *VecTyA = TheCall->getArg(0)->getType()->getAs(); @@ -5520,6 +5533,8 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return true; if (SemaBuiltinVectorToScalarMath(TheCall)) return true; +if (CheckNoDoubleVectors(this, TheCall)) + return true; break; } case Builtin::BI__builtin_hlsl_elementwise_rcp: { diff --git a/clang/test/CodeGenHLSL/builtins/dot.hlsl b/clang/test/CodeGenHLSL/builtins/dot.hlsl index c064d118caf3e7..0f993193c00cce 100644 --- a/clang/test/CodeGenHLSL/builtins/dot.hlsl +++ b/clang/test/CodeGenHLSL/builtins/dot.hlsl @@ -11,15 +11,15 @@ // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short(int16_t p0, int16_t p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v2i16(<2 x i16> %0, <2 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.sdot.v2i16(<2 x i16> %0, <2 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short2(int16_t2 p0, int16_t2 p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v3i16(<3 x i16> %0, <3 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.sdot.v3i16(<3 x i16> %0, <3 x i16> %1) // NATIVE_HALF: ret i16 %dx.dot int16_t test_dot_short3(int16_t3 p0, int16_t3 p1) { return dot(p0, p1); } -// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.dot.v4i16(<4 x i16> %0, <4 x i16> %1) +// NATIVE_HALF: %dx.dot = call i16 @llvm.dx.sdot.v4i16(<4 x i16> %0, <4
[clang] [llvm] [DXIL] implement dot intrinsic lowering for integers (PR #85662)
https://github.com/farzonl closed https://github.com/llvm/llvm-project/pull/85662 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] implement dot intrinsic lowering for integers (PR #85662)
farzonl wrote: > Hi @farzonl, your commit is causing at least one test failure on a build bot: > https://lab.llvm.org/buildbot/#/builders/139/builds/61732 > > ``` > TEST 'Clang :: SemaHLSL/BuiltIns/dot-errors.hlsl' FAILED > > Exit Code: 1 > Command Output (stderr): > -- > RUN: at line 1: > /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang > -cc1 -internal-isystem > /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/lib/clang/19/include > -nostdsysteminc -finclude-default-header -triple > dxil-pc-shadermodel6.6-library > /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl > -fnative-half-type -emit-llvm -disable-llvm-passes -verify > -verify-ignore-unexpected > + > /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang > -cc1 -internal-isystem > /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/lib/clang/19/include > -nostdsysteminc -finclude-default-header -triple > dxil-pc-shadermodel6.6-library > /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl > -fnative-half-type -emit-llvm -disable-llvm-passes -verify > -verify-ignore-unexpected > error: 'expected-error' diagnostics expected but not seen: > File > /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl > Line 117 (directive at > /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl:118): > passing 'double2' (aka 'vector') to parameter of incompatible > type '__attribute__((__vector_size__(2 * sizeof(float float' (vector of 2 > 'float' values) > 1 error generated. > -- > > ``` > > Other failing buildbots include: > > * https://lab.llvm.org/buildbot/#/builders/216/builds/36204 > * https://lab.llvm.org/buildbot/#/builders/247/builds/15516 > * https://lab.llvm.org/buildbot/#/builders/280/builds/469 > > Can you take a look and revert if you need time to investigate? This is my own test case failing. need: essentially this as a return but thats gettign complicated.`BaseType->isFloatingType() && !BaseType->isHalfType() && !BaseType->isFloat32Type();` But it would be simpler to just have a double check so im going to do something like this ` return VecTy->getElementType()->isDoubleType();` https://github.com/llvm/llvm-project/pull/85662 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Fix for build break introduced by #85662 (PR #85839)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/85839 This change fixes a test case failure caused by pr #85662 >From 7c2833dc32d8d2573454cba99b9a2c65a166d702 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Tue, 19 Mar 2024 14:01:29 -0400 Subject: [PATCH] This change fixes a test case failure caused by pr #85662 --- clang/include/clang/AST/Type.h | 5 + clang/lib/Sema/SemaChecking.cpp | 6 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 10916053cdfbf5..be18535e3e4c8c 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2245,6 +2245,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 bool isFloat32Type() const; + bool isDoubleType() const; bool isBFloat16Type() const; bool isFloat128Type() const; bool isIbm128Type() const; @@ -7457,6 +7458,10 @@ inline bool Type::isFloat32Type() const { return isSpecificBuiltinType(BuiltinType::Float); } +inline bool Type::isDoubleType() const { + return isSpecificBuiltinType(BuiltinType::Double); +} + inline bool Type::isBFloat16Type() const { return isSpecificBuiltinType(BuiltinType::BFloat16); } diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index f9112a29027acd..ef3ab16ba29b41 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5486,10 +5486,8 @@ bool CheckFloatOrHalfRepresentations(Sema *S, CallExpr *TheCall) { bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) { auto checkDoubleVector = [](clang::QualType PassedType) -> bool { -if (const auto *VecTy = dyn_cast(PassedType)) { - clang::QualType BaseType = VecTy->getElementType(); - return !BaseType->isHalfType() && !BaseType->isFloat32Type(); -} +if (const auto *VecTy = PassedType->getAs()) + return VecTy->getElementType()->isDoubleType(); return false; }; return CheckArgsTypesAreCorrect(S, TheCall, S->Context.FloatTy, ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] implement dot intrinsic lowering for integers (PR #85662)
farzonl wrote: @nico @dyung @llvm-beanz this pr should fix the build break: https://github.com/llvm/llvm-project/pull/85839/files https://github.com/llvm/llvm-project/pull/85662 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [DXIL] implement dot intrinsic lowering for integers (PR #85662)
farzonl wrote: > Also failing on http://45.33.8.238/linux/133623/step_7.txt > > It's been broken for over an hour now. Time to revert and fix async? I have a PR up to fix this, but I would be equally happy with just adding an XFAIL to SemaHLSL/BuiltIns/dot-errors.hlsl if you feel like my PR would take to long to land. https://github.com/llvm/llvm-project/pull/85662 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Fix for build break introduced by #85662 (PR #85839)
farzonl wrote: I'm confident this change fixes the build break: ```bash python ../debug-llvm-build/bin/llvm-lit -sv clang/test/SemaHLSL/ llvm-lit: /mnt/DevDrive/projects/llvm-project/llvm/utils/lit/lit/llvm/config.py:502: note: using clang: /mnt/DevDrive/projects/debug-llvm-build/bin/clang Testing Time: 0.67s Total Discovered Tests: 43 Passed : 42 (97.67%) Expectedly Failed: 1 (2.33%) python ../debug-llvm-build/bin/llvm-lit -sv clang/test/CodeGenHLSL/ llvm-lit: /mnt/DevDrive/projects/llvm-project/llvm/utils/lit/lit/llvm/config.py:502: note: using clang: /mnt/DevDrive/projects/debug-llvm-build/bin/clang Testing Time: 0.88s Total Discovered Tests: 63 Passed: 63 (100.00%) python ../debug-llvm-build/bin/llvm-lit -sv clang/test/Sema llvm-lit: /mnt/DevDrive/projects/llvm-project/llvm/utils/lit/lit/llvm/config.py:502: note: using clang: /mnt/DevDrive/projects/debug-llvm-build/bin/clang Testing Time: 26.09s Total Discovered Tests: 979 Unsupported: 1 (0.10%) Passed : 978 (99.90%) ``` https://github.com/llvm/llvm-project/pull/85839 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Fix for build break introduced by #85662 (PR #85839)
farzonl wrote: builds should be back to green all 51 checks passed: https://github.com/llvm/llvm-project/commit/3ff67d8c8069b9f42efcbe90ad7edeb6d8117a31 https://github.com/llvm/llvm-project/pull/85839 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Add Float `Dot` Intrinsic Lowering (PR #86071)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/86071 Completes #83626 - `CGBuiltin.cpp` - modify `getDotProductIntrinsic` to be able to emit `dot2`, `dot3`, and `dot4` intrinsics based on element count - `IntrinsicsDirectX.td` - for floating point add `dot2`, `dot3`, and `dot4` inntrinsics -`DXIL.td` add dxilop intrinsic lowering for `dot2`, `dot3`, & `dot4`. - `DXILOpLowering.cpp` - add vector arg flattening for dot product. - `DXILOpBuilder.h` - modify `createDXILOpCall` to take a smallVector instead of an iterator - `DXILOpBuilder.cpp` - modify `createDXILOpCall` by moving the small vector up to the calling function in `DXILOpLowering.cpp`. - Moving one function up gives us access to the `CallInst` and `Function` which were needed to distinguish the dot product intrinsics and get the operands without using the iterator. >From 7e794b6137d4ddb9d17a0412c637961cb622206a Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Tue, 19 Mar 2024 17:29:55 -0400 Subject: [PATCH] Add Float `Dot` Intrinsic Lowering Completes #83626 - `CGBuiltin.cpp` - modify `getDotProductIntrinsic` to be able to emit `dot2`, `dot3`, and `dot4` intrinsics based on element count - `IntrinsicsDirectX.td` - for floating point add `dot2`,`dot3`, and `dot4` inntrinsics -`DXIL.td` add dxilop intrinsic lowering for `dot2`,`dot3`, & `dot4`. -`DXILOpLowering.cpp` - add vector arg flattening for dot product. -`DXILOpBuilder.h` - modify `createDXILOpCall` to take a smallVector instead of an iterator - `DXILOpBuilder.cpp` - modify createDXILOpCall by moving the small vector up to the callee function in `DXILOpLowering.cpp`. Moving one function up gives us access to the callInst and Function Which were needed to distinguish the dot product intrinsics and get the operands without using the iterator. --- clang/lib/CodeGen/CGBuiltin.cpp| 25 +++--- clang/test/CodeGenHLSL/builtins/dot.hlsl | 28 +++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 10 ++- llvm/lib/Target/DirectX/DXIL.td| 9 +++ llvm/lib/Target/DirectX/DXILOpBuilder.cpp | 8 +- llvm/lib/Target/DirectX/DXILOpBuilder.h| 5 +- llvm/lib/Target/DirectX/DXILOpLowering.cpp | 55 - llvm/test/CodeGen/DirectX/dot2_error.ll| 10 +++ llvm/test/CodeGen/DirectX/dot3_error.ll| 10 +++ llvm/test/CodeGen/DirectX/dot4_error.ll| 10 +++ llvm/test/CodeGen/DirectX/fdot.ll | 94 ++ 11 files changed, 230 insertions(+), 34 deletions(-) create mode 100644 llvm/test/CodeGen/DirectX/dot2_error.ll create mode 100644 llvm/test/CodeGen/DirectX/dot3_error.ll create mode 100644 llvm/test/CodeGen/DirectX/dot4_error.ll create mode 100644 llvm/test/CodeGen/DirectX/fdot.ll diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 77cb269d43c5a8..a4b99181769326 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18036,15 +18036,22 @@ llvm::Value *CodeGenFunction::EmitScalarOrConstFoldImmArg(unsigned ICEArguments, return Arg; } -Intrinsic::ID getDotProductIntrinsic(QualType QT) { +Intrinsic::ID getDotProductIntrinsic(QualType QT, int elementCount) { + if (QT->hasFloatingRepresentation()) { +switch (elementCount) { +case 2: + return Intrinsic::dx_dot2; +case 3: + return Intrinsic::dx_dot3; +case 4: + return Intrinsic::dx_dot4; +} + } if (QT->hasSignedIntegerRepresentation()) return Intrinsic::dx_sdot; - if (QT->hasUnsignedIntegerRepresentation()) -return Intrinsic::dx_udot; - assert(QT->hasFloatingRepresentation()); - return Intrinsic::dx_dot; - ; + assert(QT->hasUnsignedIntegerRepresentation()); + return Intrinsic::dx_udot; } Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, @@ -18098,8 +18105,7 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, assert(T0->getScalarType() == T1->getScalarType() && "Dot product of vectors need the same element types."); -[[maybe_unused]] auto *VecTy0 = -E->getArg(0)->getType()->getAs(); +auto *VecTy0 = E->getArg(0)->getType()->getAs(); [[maybe_unused]] auto *VecTy1 = E->getArg(1)->getType()->getAs(); // A HLSLVectorTruncation should have happend @@ -18108,7 +18114,8 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, return Builder.CreateIntrinsic( /*ReturnType=*/T0->getScalarType(), -getDotProductIntrinsic(E->getArg(0)->getType()), +getDotProductIntrinsic(E->getArg(0)->getType(), + VecTy0->getNumElements()), ArrayRef{Op0, Op1}, nullptr, "dx.dot"); } break; case Builtin::BI__builtin_hlsl_lerp: { diff --git a/clang/test/CodeGenHLSL/builtins/dot.hlsl b/clang/test/CodeGenHLSL/builtins/dot.hlsl index 0f993193c00cce..307d71cce3cb6d 100644 --- a/clang/test/CodeGenHLSL/builtins/dot.hlsl +++ b/clang/test/CodeGenHLSL/builtins/dot.hlsl @
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl converted_to_draft https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From 595ce41f71bd9e0f83679bd5c742b3015bf30626 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/2] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6e3cebc311eeb9..46f5424038d8b0 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10267,6 +10267,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 89215bf3d1c69a..6fe10fad45daff 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14055,6 +14055,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index d454ccc1dd8613..4bad41a9be214e 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ebda201361fb07..5999b1ced36347 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fcccac10f4733a..c76c0df28334f8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ebda201361fb07..5999b1ced36347 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fcccac10f4733a..c76c0df28334f8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl deleted https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ebda201361fb07..5999b1ced36347 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fcccac10f4733a..c76c0df28334f8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ebda201361fb07..5999b1ced36347 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fcccac10f4733a..c76c0df28334f8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/3] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ebda201361fb07..5999b1ced36347 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fcccac10f4733a..c76c0df28334f8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl ready_for_review https://github.com/llvm/llvm-project/pull/81190 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/4] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ebda201361fb07..5999b1ced36347 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fcccac10f4733a..c76c0df28334f8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [HLSL] Fix casting asserts (PR #82827)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/82827 There are two issues here. first `ICK_Floating_Integral` were always defaulting to `CK_FloatingToIntegral` for vectors regardless of direction of cast. Check was scalar only so added a vec float check to the conditional. Second issue was float to int casts were resolving to ICK_Integral_Promotion when they need to be resolving to CK_FloatingToIntegral. This was fixed by changing the ordering of conversion checks. This fixes #82826 >From 7d77f7ac71f1928812fc6dcdbce29a7ea924 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Fri, 23 Feb 2024 15:28:13 -0500 Subject: [PATCH] [HLSL] Fix casting asserts There are two issues here. first ICK_Floating_Integral were always defaulting to CK_FloatingToIntegral for vectors regardless of direction of cast. Check was scalar only so added a vec float check to the conditional. Second issue was float to int casts were resolving to ICK_Integral_Promotion when they need to be resolving to CK_FloatingToIntegral. This was fixed by changing the ordering of conversion checks. This fixes #82826 --- clang/lib/Sema/SemaExprCXX.cpp| 2 +- clang/lib/Sema/SemaOverload.cpp | 16 +++ .../SemaHLSL/VectorOverloadResolution.hlsl| 44 +++ 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 322bd1c87b1d71..99f8abf77c0cb6 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4843,7 +4843,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, .get(); break; case ICK_Floating_Integral: - if (ToType->isRealFloatingType()) + if (ToType->isRealFloatingType() || ToType->hasFloatingRepresentation()) From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue, /*BasePath=*/nullptr, CCK) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f7645422348b65..324a7b20113fcd 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1883,9 +1883,16 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, ICK = ICK_Boolean_Conversion; return true; } + + if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || + (FromType->isIntegralOrUnscopedEnumerationType() && + ToType->isRealFloatingType())) { +ICK = ICK_Floating_Integral; +return true; + } if (S.IsIntegralPromotion(From, FromType, ToType)) { -ICK = ICK_Integral_Promotion; +ICK = ICK_Integral_Promotion; return true; } @@ -1895,13 +1902,6 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } - if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || - (FromType->isIntegralOrUnscopedEnumerationType() && - ToType->isRealFloatingType())) { -ICK = ICK_Floating_Integral; -return true; - } - return false; } diff --git a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl index e07391f803f899..d8794ef675768b 100644 --- a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl +++ b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl @@ -1,4 +1,8 @@ // RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-library -S -fnative-half-type -finclude-default-header -o - -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECKIR void Fn(double2 D); void Fn(half2 H); @@ -28,3 +32,43 @@ void Fn2(int16_t2 S); void Call2(int2 I) { Fn2(I); } + +void Fn3( int64_t2 p0); + +// CHECK: FunctionDecl {{.*}} Call3 'void (half2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x half> %0 to <2 x i64> +void Call3(half2 p0) { + Fn3(p0); +} + +// CHECK: FunctionDecl {{.*}} Call4 'void (float2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_t
[clang] [HLSL] Fix casting asserts (PR #82827)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/82827 >From 15eee3edd9ad834dc46fb5a1053874093b41a65a Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Fri, 23 Feb 2024 15:28:13 -0500 Subject: [PATCH] [HLSL] Fix casting asserts There are two issues here. first ICK_Floating_Integral were always defaulting to CK_FloatingToIntegral for vectors regardless of direction of cast. Check was scalar only so added a vec float check to the conditional. Second issue was float to int casts were resolving to ICK_Integral_Promotion when they need to be resolving to CK_FloatingToIntegral. This was fixed by changing the ordering of conversion checks. This fixes #82826 --- clang/lib/Sema/SemaExprCXX.cpp| 2 +- clang/lib/Sema/SemaOverload.cpp | 14 +++--- .../SemaHLSL/VectorOverloadResolution.hlsl| 44 +++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 322bd1c87b1d71..99f8abf77c0cb6 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4843,7 +4843,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, .get(); break; case ICK_Floating_Integral: - if (ToType->isRealFloatingType()) + if (ToType->isRealFloatingType() || ToType->hasFloatingRepresentation()) From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue, /*BasePath=*/nullptr, CCK) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f7645422348b65..ecad2b96816553 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1884,6 +1884,13 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } + if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || + (FromType->isIntegralOrUnscopedEnumerationType() && + ToType->isRealFloatingType())) { +ICK = ICK_Floating_Integral; +return true; + } + if (S.IsIntegralPromotion(From, FromType, ToType)) { ICK = ICK_Integral_Promotion; return true; @@ -1895,13 +1902,6 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } - if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || - (FromType->isIntegralOrUnscopedEnumerationType() && - ToType->isRealFloatingType())) { -ICK = ICK_Floating_Integral; -return true; - } - return false; } diff --git a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl index e07391f803f899..d8794ef675768b 100644 --- a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl +++ b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl @@ -1,4 +1,8 @@ // RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-library -S -fnative-half-type -finclude-default-header -o - -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECKIR void Fn(double2 D); void Fn(half2 H); @@ -28,3 +32,43 @@ void Fn2(int16_t2 S); void Call2(int2 I) { Fn2(I); } + +void Fn3( int64_t2 p0); + +// CHECK: FunctionDecl {{.*}} Call3 'void (half2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x half> %0 to <2 x i64> +void Call3(half2 p0) { + Fn3(p0); +} + +// CHECK: FunctionDecl {{.*}} Call4 'void (float2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x float> %0 to <2 x i64> +void Call4(float2 p0) { + Fn3(p0); +} + +void Fn4( float2 p0); + +// CHECK: FunctionDecl {{.*}} Call5 'void (int64_t2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*
[clang] [HLSL] Fix casting asserts (PR #82827)
@@ -4843,7 +4843,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, .get(); break; case ICK_Floating_Integral: - if (ToType->isRealFloatingType()) + if (ToType->isRealFloatingType() || ToType->hasFloatingRepresentation()) farzonl wrote: I can fix that up. For your second question line 4800 `assert(From->getType()->isVectorType() && ToType->isVectorType()`. It should just be vectors for now. https://github.com/llvm/llvm-project/pull/82827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Fix casting asserts (PR #82827)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/82827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [HLSL] Fix casting asserts (PR #82827)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/82827 >From 0ff2c7162d2676190b5ad370b7e7171581d8d21b Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Fri, 23 Feb 2024 15:28:13 -0500 Subject: [PATCH] [HLSL] Fix casting asserts There are two issues here. first ICK_Floating_Integral were always defaulting to CK_FloatingToIntegral for vectors regardless of direction of cast. Check was scalar only so added a vec float check to the conditional. Second issue was float to int casts were resolving to ICK_Integral_Promotion when they need to be resolving to CK_FloatingToIntegral. This was fixed by changing the ordering of conversion checks. This fixes #82826 --- clang/lib/Sema/SemaExprCXX.cpp| 2 +- clang/lib/Sema/SemaOverload.cpp | 14 +++ .../SemaHLSL/VectorOverloadResolution.hlsl| 41 +++ 3 files changed, 49 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 322bd1c87b1d71..59758d3bd6d1a3 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4843,7 +4843,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, .get(); break; case ICK_Floating_Integral: - if (ToType->isRealFloatingType()) + if (ToType->hasFloatingRepresentation()) From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue, /*BasePath=*/nullptr, CCK) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f7645422348b65..ecad2b96816553 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1884,6 +1884,13 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } + if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || + (FromType->isIntegralOrUnscopedEnumerationType() && + ToType->isRealFloatingType())) { +ICK = ICK_Floating_Integral; +return true; + } + if (S.IsIntegralPromotion(From, FromType, ToType)) { ICK = ICK_Integral_Promotion; return true; @@ -1895,13 +1902,6 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } - if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || - (FromType->isIntegralOrUnscopedEnumerationType() && - ToType->isRealFloatingType())) { -ICK = ICK_Floating_Integral; -return true; - } - return false; } diff --git a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl index e07391f803f899..c9adc36ca5e705 100644 --- a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl +++ b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-library -S -fnative-half-type -finclude-default-header -o - -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s --check-prefixes=CHECKIR void Fn(double2 D); void Fn(half2 H); @@ -28,3 +29,43 @@ void Fn2(int16_t2 S); void Call2(int2 I) { Fn2(I); } + +void Fn3( int64_t2 p0); + +// CHECK: FunctionDecl {{.*}} Call3 'void (half2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x half> %0 to <2 x i64> +void Call3(half2 p0) { + Fn3(p0); +} + +// CHECK: FunctionDecl {{.*}} Call4 'void (float2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x float> %0 to <2 x i64> +void Call4(float2 p0) { + Fn3(p0); +} + +void Fn4( float2 p0); + +// CHECK: FunctionDecl {{.*}} Call5 'void (int64_t2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(float2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (flo
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From fad7e6eac6a1a65ce00ab3e4f64d5774b426c91d Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/4] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index ebda201361fb07..5999b1ced36347 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index fcccac10f4733a..c76c0df28334f8 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
@@ -5161,6 +5166,157 @@ bool Sema::CheckPPCMMAType(QualType Type, SourceLocation TypeLoc) { return false; } +// Helper function for CheckHLSLBuiltinFunctionCall +// Note: UsualArithmeticConversions handles the case where at least +// one arg isn't a bool +bool PromoteBoolsToInt(Sema *S, CallExpr *TheCall) { + unsigned NumArgs = TheCall->getNumArgs(); + + for (unsigned i = 0; i < NumArgs; ++i) { +ExprResult A = TheCall->getArg(i); +if (!A.get()->getType()->isBooleanType()) + return false; + } + // if we got here all args are bool + for (unsigned i = 0; i < NumArgs; ++i) { +ExprResult A = TheCall->getArg(i); +ExprResult ResA = S->PerformImplicitConversion(A.get(), S->Context.IntTy, + Sema::AA_Converting); +if (ResA.isInvalid()) + return true; +TheCall->setArg(i, ResA.get()); + } + return false; +} + +// Helper function for CheckHLSLBuiltinFunctionCall +// Handles the CK_HLSLVectorTruncation case for builtins +void PromoteVectorArgTruncation(Sema *S, CallExpr *TheCall) { + assert(TheCall->getNumArgs() > 1); + ExprResult A = TheCall->getArg(0); + ExprResult B = TheCall->getArg(1); + QualType ArgTyA = A.get()->getType(); + QualType ArgTyB = B.get()->getType(); + + auto *VecTyA = ArgTyA->getAs(); + auto *VecTyB = ArgTyB->getAs(); + if (VecTyA == nullptr && VecTyB == nullptr) +return; + if (VecTyA == nullptr || VecTyB == nullptr) +return; + if (VecTyA->getNumElements() == VecTyB->getNumElements()) +return; + + Expr *LargerArg = B.get(); + Expr *SmallerArg = A.get(); + int largerIndex = 1; + if (VecTyA->getNumElements() > VecTyB->getNumElements()) { +LargerArg = A.get(); +SmallerArg = B.get(); +largerIndex = 0; + } + + S->Diag(TheCall->getExprLoc(), diag::warn_hlsl_impcast_vector_truncation) + << LargerArg->getType() << SmallerArg->getType() + << LargerArg->getSourceRange() << SmallerArg->getSourceRange(); + ExprResult ResLargerArg = S->ImpCastExprToType( + LargerArg, SmallerArg->getType(), CK_HLSLVectorTruncation); + TheCall->setArg(largerIndex, ResLargerArg.get()); + return; +} + +// Helper function for CheckHLSLBuiltinFunctionCall +void CheckVectorFloatPromotion(Sema *S, ExprResult &source, QualType targetTy, + SourceRange targetSrcRange, + SourceLocation BuiltinLoc) { + auto *vecTyTarget = source.get()->getType()->getAs(); + assert(vecTyTarget); + QualType vecElemT = vecTyTarget->getElementType(); + if (!vecElemT->isFloatingType() && targetTy->isFloatingType()) { +QualType floatVecTy = S->Context.getVectorType( +S->Context.FloatTy, vecTyTarget->getNumElements(), VectorKind::Generic); + +S->Diag(BuiltinLoc, diag::warn_impcast_integer_float_precision) +<< source.get()->getType() << floatVecTy +<< source.get()->getSourceRange() << targetSrcRange; +source = S->SemaConvertVectorExpr( +source.get(), S->Context.CreateTypeSourceInfo(floatVecTy), BuiltinLoc, +source.get()->getBeginLoc()); + } +} + +// Helper function for CheckHLSLBuiltinFunctionCall +void PromoteVectorArgSplat(Sema *S, ExprResult &source, QualType targetTy) { + QualType sourceTy = source.get()->getType(); + auto *vecTyTarget = targetTy->getAs(); + QualType vecElemT = vecTyTarget->getElementType(); + if (vecElemT->isFloatingType() && sourceTy != vecElemT) +// if float vec splat wil do an unnecessary cast to double +source = S->ImpCastExprToType(source.get(), vecElemT, CK_FloatingCast); + source = S->ImpCastExprToType(source.get(), targetTy, CK_VectorSplat); +} + +// Helper function for CheckHLSLBuiltinFunctionCall +bool CheckVectorElementCallArgs(Sema *S, CallExpr *TheCall) { + assert(TheCall->getNumArgs() > 1); + ExprResult A = TheCall->getArg(0); + ExprResult B = TheCall->getArg(1); + QualType ArgTyA = A.get()->getType(); + QualType ArgTyB = B.get()->getType(); + auto *VecTyA = ArgTyA->getAs(); + auto *VecTyB = ArgTyB->getAs(); + + if (VecTyA == nullptr && VecTyB == nullptr) +return false; + + if (VecTyA && VecTyB) { +if (VecTyA->getElementType() == VecTyB->getElementType()) { + TheCall->setType(VecTyA->getElementType()); + return false; +} +// Note: type promotion is intended to be handeled via the intrinsics +// and not the builtin itself. +S->Diag(TheCall->getBeginLoc(), diag::err_vec_builtin_incompatible_vector) +<< TheCall->getDirectCallee() +<< SourceRange(A.get()->getBeginLoc(), B.get()->getEndLoc()); +return true; + } + + if (VecTyB) { +CheckVectorFloatPromotion(S, B, ArgTyA, A.get()->getSourceRange(), + TheCall->getBeginLoc()); +PromoteVectorArgSplat(S, A, B.get()->getType()); + } + if (VecTyA) { +CheckVectorFloatPromotion(S, A, ArgTyB, B.get()->getSourceRange(), + TheCall->getBeginLoc()); +PromoteVector
[clang] [HLSL] Fix casting asserts (PR #82827)
@@ -1,4 +1,5 @@ // RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-library -S -fnative-half-type -finclude-default-header -o - -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple dxil-pc-shadermodel6.6-library %s -fnative-half-type -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s --check-prefixes=CHECKIR farzonl wrote: that's my bad I copied that from another test case. https://github.com/llvm/llvm-project/pull/82827 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From f6188a3308188aa3037b05f685a6065bfc2d69fa Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/5] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a7f2858477bee6..9cce89b92be309 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e457694e4625db..2c06c8edca329a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From f6188a3308188aa3037b05f685a6065bfc2d69fa Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/6] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a7f2858477bee6..9cce89b92be309 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e457694e4625db..2c06c8edca329a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [HLSL] Fix casting asserts (PR #82827)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/82827 >From 15eee3edd9ad834dc46fb5a1053874093b41a65a Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Fri, 23 Feb 2024 15:28:13 -0500 Subject: [PATCH 1/2] [HLSL] Fix casting asserts There are two issues here. first ICK_Floating_Integral were always defaulting to CK_FloatingToIntegral for vectors regardless of direction of cast. Check was scalar only so added a vec float check to the conditional. Second issue was float to int casts were resolving to ICK_Integral_Promotion when they need to be resolving to CK_FloatingToIntegral. This was fixed by changing the ordering of conversion checks. This fixes #82826 --- clang/lib/Sema/SemaExprCXX.cpp| 2 +- clang/lib/Sema/SemaOverload.cpp | 14 +++--- .../SemaHLSL/VectorOverloadResolution.hlsl| 44 +++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 322bd1c87b1d71..99f8abf77c0cb6 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4843,7 +4843,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, .get(); break; case ICK_Floating_Integral: - if (ToType->isRealFloatingType()) + if (ToType->isRealFloatingType() || ToType->hasFloatingRepresentation()) From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue, /*BasePath=*/nullptr, CCK) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f7645422348b65..ecad2b96816553 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1884,6 +1884,13 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } + if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || + (FromType->isIntegralOrUnscopedEnumerationType() && + ToType->isRealFloatingType())) { +ICK = ICK_Floating_Integral; +return true; + } + if (S.IsIntegralPromotion(From, FromType, ToType)) { ICK = ICK_Integral_Promotion; return true; @@ -1895,13 +1902,6 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } - if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || - (FromType->isIntegralOrUnscopedEnumerationType() && - ToType->isRealFloatingType())) { -ICK = ICK_Floating_Integral; -return true; - } - return false; } diff --git a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl index e07391f803f899..d8794ef675768b 100644 --- a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl +++ b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl @@ -1,4 +1,8 @@ // RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-library -S -fnative-half-type -finclude-default-header -o - -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECKIR void Fn(double2 D); void Fn(half2 H); @@ -28,3 +32,43 @@ void Fn2(int16_t2 S); void Call2(int2 I) { Fn2(I); } + +void Fn3( int64_t2 p0); + +// CHECK: FunctionDecl {{.*}} Call3 'void (half2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x half> %0 to <2 x i64> +void Call3(half2 p0) { + Fn3(p0); +} + +// CHECK: FunctionDecl {{.*}} Call4 'void (float2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x float> %0 to <2 x i64> +void Call4(float2 p0) { + Fn3(p0); +} + +void Fn4( float2 p0); + +// CHECK: FunctionDecl {{.*}} Call5 'void (int64_t2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr
[clang] [llvm] [HLSL] Implementation of dot intrinsic (PR #81190)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/81190 >From f6188a3308188aa3037b05f685a6065bfc2d69fa Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Thu, 8 Feb 2024 11:08:59 -0500 Subject: [PATCH 1/6] [HLSL] Implementation of dot intrinsic This change implements #70073 HLSL has a dot intrinsic defined here: https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-dot The intrinsic itself is defined as a HLSL_LANG LangBuiltin in Builtins.td. This is used to associate all the dot product typdef defined hlsl_intrinsics.h with a single intrinsic check in CGBuiltin.cpp & SemaChecking.cpp. In IntrinsicsDirectX.td we define the llvmIR for the dot product. A few goals were in mind for this IR. First it should operate on only vectors. Second the return type should be the vector element type. Third the second parameter vector should be of the same size as the first parameter. Finally `a dot b` should be the same as `b dot a`. In CGBuiltin.cpp hlsl has built on top of existing clang intrinsics via EmitBuiltinExpr. Dot product though is language specific intrinsic and so is guarded behind getLangOpts().HLSL. The call chain looks like this: EmitBuiltinExpr -> EmitHLSLBuiltinExp EmitHLSLBuiltinExp dot product intrinsics makes a destinction between vectors and scalars. This is because HLSL supports dot product on scalars which simplifies down to multiply. Sema.h & SemaChecking.cpp saw the addition of CheckHLSLBuiltinFunctionCall, a language specific semantic validation that can be expanded for other hlsl specific intrinsics. --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 2 + clang/include/clang/Sema/Sema.h | 1 + clang/lib/CodeGen/CGBuiltin.cpp | 49 clang/lib/CodeGen/CodeGenFunction.h | 1 + clang/lib/Headers/hlsl/hlsl_intrinsics.h | 92 clang/lib/Sema/SemaChecking.cpp | 84 ++- clang/test/CodeGenHLSL/builtins/dot.hlsl | 216 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 46 llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 497 insertions(+), 5 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/dot.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index df74026c5d2d50..771c4f5d4121f4 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4524,6 +4524,12 @@ def HLSLCreateHandle : LangBuiltin<"HLSL_LANG"> { let Prototype = "void*(unsigned char)"; } +def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_dot"]; + let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a7f2858477bee6..9cce89b92be309 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10270,6 +10270,8 @@ def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< "first two arguments to %0 must have the same type">; +def err_vec_builtin_incompatible_size : Error< + "first two arguments to %0 must have the same size">; def err_vsx_builtin_nonconstant_argument : Error< "argument %0 to %1 must be a 2-bit unsigned literal (i.e. 0, 1, 2 or 3)">; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e457694e4625db..2c06c8edca329a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -14057,6 +14057,7 @@ class Sema final { bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckRISCVLMUL(CallExpr *TheCall, unsigned ArgNum); bool CheckRISCVBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, CallExpr *TheCall); diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 734eb5a035ca49..393ab497fb15c4 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -44,6 +44,7 @@ #include "llvm/IR/IntrinsicsAMDGPU.h" #include "llvm/IR/IntrinsicsARM.h" #include "llvm/IR/IntrinsicsBPF.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/IntrinsicsNVPTX.h" #include "llvm/IR/IntrinsicsPowerPC.h" @@ -5982,6 +5983,10 @@ RValue CodeGenFunction::EmitBuil
[clang] [HLSL] Fix casting asserts (PR #82827)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/82827 >From 15eee3edd9ad834dc46fb5a1053874093b41a65a Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Fri, 23 Feb 2024 15:28:13 -0500 Subject: [PATCH 1/2] [HLSL] Fix casting asserts There are two issues here. first ICK_Floating_Integral were always defaulting to CK_FloatingToIntegral for vectors regardless of direction of cast. Check was scalar only so added a vec float check to the conditional. Second issue was float to int casts were resolving to ICK_Integral_Promotion when they need to be resolving to CK_FloatingToIntegral. This was fixed by changing the ordering of conversion checks. This fixes #82826 --- clang/lib/Sema/SemaExprCXX.cpp| 2 +- clang/lib/Sema/SemaOverload.cpp | 14 +++--- .../SemaHLSL/VectorOverloadResolution.hlsl| 44 +++ 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 322bd1c87b1d71..99f8abf77c0cb6 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4843,7 +4843,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, .get(); break; case ICK_Floating_Integral: - if (ToType->isRealFloatingType()) + if (ToType->isRealFloatingType() || ToType->hasFloatingRepresentation()) From = ImpCastExprToType(From, ToType, CK_IntegralToFloating, VK_PRValue, /*BasePath=*/nullptr, CCK) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index f7645422348b65..ecad2b96816553 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1884,6 +1884,13 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } + if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || + (FromType->isIntegralOrUnscopedEnumerationType() && + ToType->isRealFloatingType())) { +ICK = ICK_Floating_Integral; +return true; + } + if (S.IsIntegralPromotion(From, FromType, ToType)) { ICK = ICK_Integral_Promotion; return true; @@ -1895,13 +1902,6 @@ static bool IsVectorElementConversion(Sema &S, QualType FromType, return true; } - if ((FromType->isRealFloatingType() && ToType->isIntegralType(S.Context)) || - (FromType->isIntegralOrUnscopedEnumerationType() && - ToType->isRealFloatingType())) { -ICK = ICK_Floating_Integral; -return true; - } - return false; } diff --git a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl index e07391f803f899..d8794ef675768b 100644 --- a/clang/test/SemaHLSL/VectorOverloadResolution.hlsl +++ b/clang/test/SemaHLSL/VectorOverloadResolution.hlsl @@ -1,4 +1,8 @@ // RUN: %clang_cc1 -triple dxil-unknown-shadermodel6.6-library -S -fnative-half-type -finclude-default-header -o - -ast-dump %s | FileCheck %s +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -x hlsl -triple \ +// RUN: dxil-pc-shadermodel6.3-library %s -fnative-half-type \ +// RUN: -emit-llvm -disable-llvm-passes -O3 -o - | FileCheck %s \ +// RUN: --check-prefixes=CHECKIR void Fn(double2 D); void Fn(half2 H); @@ -28,3 +32,43 @@ void Fn2(int16_t2 S); void Call2(int2 I) { Fn2(I); } + +void Fn3( int64_t2 p0); + +// CHECK: FunctionDecl {{.*}} Call3 'void (half2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'half2':'half __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'half2':'half __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x half> %0 to <2 x i64> +void Call3(half2 p0) { + Fn3(p0); +} + +// CHECK: FunctionDecl {{.*}} Call4 'void (float2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int64_t2)' +// CHECK-NEXT: DeclRefExpr {{.*}} 'void (int64_t2)' lvalue Function {{.*}} 'Fn3' 'void (int64_t2)' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'int64_t2':'long __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECK-NEXT: DeclRefExpr {{.*}} 'float2':'float __attribute__((ext_vector_type(2)))' lvalue ParmVar {{.*}} 'p0' 'float2':'float __attribute__((ext_vector_type(2)))' +// CHECKIR: %conv = fptosi <2 x float> %0 to <2 x i64> +void Call4(float2 p0) { + Fn3(p0); +} + +void Fn4( float2 p0); + +// CHECK: FunctionDecl {{.*}} Call5 'void (int64_t2)' +// CHECK: CallExpr {{.*}} 'void' +// CHECK-NEXT: ImplicitCastExpr
[clang] [llvm] [HLSL] implementation of lerp intrinsic (PR #83077)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/83077 This is the start of implementing the lerp intrinsic https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-lerp Builtins.td - defines the builtin hlsl_intrinsics.h - defines the lerp api DiagnosticSemaKinds.td - needed a new error to be inclusive for more than two operands. CGBuiltin.cpp - add the lerp intrinsic lowering SemaChecking.cpp - type checks for lerp builtin IntrinsicsDirectX.td - define the lerp intrinsic this change implements the first half of #70102 >From c6f533e226efbf38bfb1dc9df382342ec813cc37 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Sun, 25 Feb 2024 20:08:09 -0500 Subject: [PATCH] [HLSL] Implementation lerp intrinsic This is the start of implementing the lerp intrinsic https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-lerp Builtins.td - defines the builtin hlsl_intrinsics.h - defines the lerp api DiagnosticSemaKinds.td - needed a new error to be inclusive for more than two operands. CGBuiltin.cpp - add the lerp intrinsic lowering SemaChecking.cpp - type checks for lerp builtin IntrinsicsDirectX.td - define the lerp intrinsic this change implements the first half of #70102 --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 5 + clang/lib/CodeGen/CGBuiltin.cpp | 37 ++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 36 ++ clang/lib/Sema/SemaChecking.cpp | 79 - .../CodeGenHLSL/builtins/lerp-builtin.hlsl| 37 ++ clang/test/CodeGenHLSL/builtins/lerp.hlsl | 105 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 28 ++--- clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl | 91 +++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 388 insertions(+), 41 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/lerp.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index e3432f7925ba14..755ef3631b2856 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4530,6 +4530,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLLerp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_lerp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 57784a4ba2e388..f1a5d30858f829 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10266,6 +10266,11 @@ def err_block_on_vm : Error< def err_sizeless_nonlocal : Error< "non-local variable with sizeless type %0">; +def err_vec_builtin_non_vector_all : Error< + "all arguments to %0 must be vectors">; +def err_vec_builtin_incompatible_vector_all : Error< + "all arguments to %0 must have vectors of the same type">; + def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 54d7451a9d6221..17b7af924e5ff0 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18006,6 +18006,43 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType*/ T0->getScalarType(), Intrinsic::dx_dot, ArrayRef{Op0, Op1}, nullptr, "dx.dot"); } break; + case Builtin::BI__builtin_hlsl_lerp: { +Value *X = EmitScalarExpr(E->getArg(0)); +Value *Y = EmitScalarExpr(E->getArg(1)); +Value *S = EmitScalarExpr(E->getArg(2)); +llvm::Type *Xty = X->getType(); +llvm::Type *Yty = Y->getType(); +llvm::Type *Sty = S->getType(); +if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { + if (Xty->isFloatingPointTy()) { +auto V = Builder.CreateFSub(Y, X); +V = Builder.CreateFMul(S, V); +return Builder.CreateFAdd(X, V, "dx.lerp"); + } + llvm_unreachable("Scalar Lerp is only supported on floats."); +} +// A VectorSplat should have happened +assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && + "Lerp of vector and scalar is not supported."); + +[[maybe_unused]] auto *XVecTy = +E->getArg(0)->getType()->getAs(); +[[maybe_unused]] auto *YVecTy = +E->getArg(1)->getType()->getAs(); +[[maybe_unused]] auto *SVecTy = +E->getArg(2)->getType()->getAs(); +// A HLSLVectorTruncation should have happend +
[clang] [llvm] [HLSL] implementation of lerp intrinsic (PR #83077)
@@ -24,4 +24,9 @@ def int_dx_dot : Intrinsic<[LLVMVectorElementType<0>], [llvm_anyvector_ty, LLVMScalarOrSameVectorWidth<0, LLVMVectorElementType<0>>], [IntrNoMem, IntrWillReturn, Commutative] >; + +def int_dx_lerp : +Intrinsic<[LLVMMatchType<0>], +[llvm_anyvector_ty, LLVMMatchType<0>, LLVMMatchType<0>], farzonl wrote: I think you are right. here is my understanding of the Tablegen. if you diff a `LLVMMatchType` vs `LLVMScalarOrSameVectorWidth` The thing that will pop out as different are the type signatures: https://github.com/llvm/llvm-project/assets/1802579/a6bad9a5-88b8-4316-aaea-f7fb7808c45b";> For `anonymous_78` 1. [15, 512] means 2. 512 maps to `EncMatchType` 3. 15 maps to `LLVMType` we compare that to `anonymous_6913` `31, 768, 42, 512` 1. 31 is `LLVMScalarOrSameVectorWidth` 2. 768 is `EncSameWidth` 3. 42 is `LLVMVectorElementType` 4. 512 maps to `EncMatchType` so when we match on anonymous_6913 we match on width and element type as well. so then if we look at just `int_dx_lerp` the type sig differences are [15, 7] vs [31, 3, 42, 7] with [15, 3] being the same for both. ``` def ArgKind { int Any = 0; int AnyInteger = 1; int AnyFloat = 2; int AnyVector = 3; int AnyPointer = 4; int MatchType = 7; } ``` The 7 just means match The 3 means any vector So with just LLVMMatchType we are matching on anyvector but any vector doesn't get encoded into the return or argument types. Further we don't get 42 the `LLVMVectorElementType` or 31 the `LLVMScalarOrSameVectorWidth`. Legend to determine signatures: ![image](https://github.com/llvm/llvm-project/assets/1802579/27b86f6d-14a2-4543-a8eb-3f887cdbea85) https://github.com/llvm/llvm-project/pull/83077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] implementation of lerp intrinsic (PR #83077)
https://github.com/farzonl edited https://github.com/llvm/llvm-project/pull/83077 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] implementation of lerp intrinsic (PR #83077)
https://github.com/farzonl updated https://github.com/llvm/llvm-project/pull/83077 >From d4384c5ac52596eeab512574111e499f230b7db7 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Sun, 25 Feb 2024 20:08:09 -0500 Subject: [PATCH] [HLSL] Implementation lerp intrinsic This is the start of implementing the lerp intrinsic https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-lerp Builtins.td - defines the builtin hlsl_intrinsics.h - defines the lerp api DiagnosticSemaKinds.td - needed a new error to be inclusive for more than two operands. CGBuiltin.cpp - add the lerp intrinsic lowering SemaChecking.cpp - type checks for lerp builtin IntrinsicsDirectX.td - define the lerp intrinsic this change implements the first half of #70102 --- clang/include/clang/Basic/Builtins.td | 6 + .../clang/Basic/DiagnosticSemaKinds.td| 5 + clang/lib/CodeGen/CGBuiltin.cpp | 37 ++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 36 ++ clang/lib/Sema/SemaChecking.cpp | 79 - .../CodeGenHLSL/builtins/lerp-builtin.hlsl| 37 ++ clang/test/CodeGenHLSL/builtins/lerp.hlsl | 105 ++ clang/test/SemaHLSL/BuiltIns/dot-errors.hlsl | 28 ++--- clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl | 91 +++ llvm/include/llvm/IR/IntrinsicsDirectX.td | 5 + 10 files changed, 388 insertions(+), 41 deletions(-) create mode 100644 clang/test/CodeGenHLSL/builtins/lerp-builtin.hlsl create mode 100644 clang/test/CodeGenHLSL/builtins/lerp.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/lerp-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index e3432f7925ba14..755ef3631b2856 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4530,6 +4530,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLLerp : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_lerp"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 57784a4ba2e388..63115d4bd49091 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10266,6 +10266,11 @@ def err_block_on_vm : Error< def err_sizeless_nonlocal : Error< "non-local variable with sizeless type %0">; +def err_vec_builtin_non_vector_all : Error< + "all arguments to %0 must be vectors">; +def err_vec_builtin_incompatible_vector_all : Error< + "all arguments to %0 must have vectors of the same type">; + def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 54d7451a9d6221..17b7af924e5ff0 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18006,6 +18006,43 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType*/ T0->getScalarType(), Intrinsic::dx_dot, ArrayRef{Op0, Op1}, nullptr, "dx.dot"); } break; + case Builtin::BI__builtin_hlsl_lerp: { +Value *X = EmitScalarExpr(E->getArg(0)); +Value *Y = EmitScalarExpr(E->getArg(1)); +Value *S = EmitScalarExpr(E->getArg(2)); +llvm::Type *Xty = X->getType(); +llvm::Type *Yty = Y->getType(); +llvm::Type *Sty = S->getType(); +if (!Xty->isVectorTy() && !Yty->isVectorTy() && !Sty->isVectorTy()) { + if (Xty->isFloatingPointTy()) { +auto V = Builder.CreateFSub(Y, X); +V = Builder.CreateFMul(S, V); +return Builder.CreateFAdd(X, V, "dx.lerp"); + } + llvm_unreachable("Scalar Lerp is only supported on floats."); +} +// A VectorSplat should have happened +assert(Xty->isVectorTy() && Yty->isVectorTy() && Sty->isVectorTy() && + "Lerp of vector and scalar is not supported."); + +[[maybe_unused]] auto *XVecTy = +E->getArg(0)->getType()->getAs(); +[[maybe_unused]] auto *YVecTy = +E->getArg(1)->getType()->getAs(); +[[maybe_unused]] auto *SVecTy = +E->getArg(2)->getType()->getAs(); +// A HLSLVectorTruncation should have happend +assert(XVecTy->getNumElements() == YVecTy->getNumElements() && + XVecTy->getNumElements() == SVecTy->getNumElements() && + "Lerp requires vectors to be of the same size."); +assert(XVecTy->getElementType()->isRealFloatingType() && + XVecTy->getElementType() == YVecTy->getElementType() && + XVecTy->getElementType() == SVecTy->getElementType() && + "Lerp requires float vectors to be of the same type."); +return Builder.CreateIntrinsic( +
[clang] [llvm] [HLSL] Implementation of the frac intrinsic (PR #83315)
https://github.com/farzonl created https://github.com/llvm/llvm-project/pull/83315 This change implements the frontend for #70099 Builtins.td - add the frac builtin CGBuiltin.cpp - add the builtin to DirectX intrinsic mapping hlsl_intrinsics.h - add the frac api SemaChecking.cpp - add type checks for builtin IntrinsicsDirectX.td - add the frac intrinsic The backend changes for this are going to be very simple: https://github.com/llvm/llvm-project/commit/f309a0eb558b65dfaff0d1d23b7d07fb07e27121 They were not included because llvm/lib/Target/DirectX/DXIL.td is going through a major refactor. >From cd8a27e4571b8e791ce5ccaaf51dd570ee8bc6d3 Mon Sep 17 00:00:00 2001 From: Farzon Lotfi Date: Wed, 28 Feb 2024 13:20:01 -0500 Subject: [PATCH] [HLSL] Implementation of the frac intrinsic This change implements the frontend for #70099 Builtins.td - add the frac builtin CGBuiltin.cpp - add the builtin to DirectX intrinsic mapping hlsl_intrinsics.h - add the frac api SemaChecking.cpp - add type checks for builtin IntrinsicsDirectX.td - add the frac intrinsic The backend changes for this are going to be very simple: https://github.com/llvm/llvm-project/commit/f309a0eb558b65dfaff0d1d23b7d07fb07e27121 They were not included because llvm/lib/Target/DirectX/DXIL.td is going through a major refactor. --- clang/include/clang/Basic/Builtins.td | 6 ++ clang/lib/CodeGen/CGBuiltin.cpp | 8 +++ clang/lib/Headers/hlsl/hlsl_intrinsics.h | 32 + clang/lib/Sema/SemaChecking.cpp | 15 clang/test/CodeGenHLSL/builtins/frac.hlsl | 69 +++ clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl | 27 .../test/SemaHLSL/OverloadResolutionBugs.hlsl | 12 llvm/include/llvm/IR/IntrinsicsDirectX.td | 2 + 8 files changed, 171 insertions(+) create mode 100644 clang/test/CodeGenHLSL/builtins/frac.hlsl create mode 100644 clang/test/SemaHLSL/BuiltIns/frac-errors.hlsl diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 3bc35c5bb38ecf..415552d19e0700 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -4536,6 +4536,12 @@ def HLSLDotProduct : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLFrac : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_elementwise_frac"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void(...)"; +} + // Builtins for XRay. def XRayCustomEvent : Builtin { let Spellings = ["__xray_customevent"]; diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 2d16e7cdc06053..fbf34ae94c0af6 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -18007,6 +18007,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, /*ReturnType*/ T0->getScalarType(), Intrinsic::dx_dot, ArrayRef{Op0, Op1}, nullptr, "dx.dot"); } break; + case Builtin::BI__builtin_hlsl_elementwise_frac: { +Value *Op0 = EmitScalarExpr(E->getArg(0)); +if (!E->getArg(0)->getType()->hasFloatingRepresentation()) + llvm_unreachable("frac operand must have a float representation"); +return Builder.CreateIntrinsic( +/*ReturnType*/ Op0->getType(), Intrinsic::dx_frac, +ArrayRef{Op0}, nullptr, "dx.frac"); + } } return nullptr; } diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 08e5d981a4a4ca..17b600abdfad1e 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -317,6 +317,38 @@ double3 floor(double3); _HLSL_BUILTIN_ALIAS(__builtin_elementwise_floor) double4 floor(double4); +//===--===// +// frac builtins +//===--===// + +/// \fn T frac(T x) +/// \brief Returns the fractional (or decimal) part of x. \a x parameter. +/// \param x The specified input value. +/// +/// If \a the return value is greater than or equal to 0 and less than 1. + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) +half frac(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) +half2 frac(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) +half3 frac(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) +half4 frac(half4); + +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) +float frac(float); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) +float2 frac(float2); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) +float3 frac(float3); +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_elementwise_frac) +float4 frac(float4); + //===-