diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6051,7 +6051,7 @@ // These options cannot be marshalled, because they are used to set up the LangOptions defaults. def finclude_default_header : Flag<["-"], "finclude-default-header">, - HelpText<"Include default header file for OpenCL">; + HelpText<"Include default header file for OpenCL and HLSL">; def fdeclare_opencl_builtins : Flag<["-"], "fdeclare-opencl-builtins">, HelpText<"Add OpenCL builtin function declarations (experimental)">; @@ -6780,6 +6780,8 @@ def dxc_help : Option<["/", "-", "--"], "help", KIND_JOINED>, Group, Flags<[DXCOption, NoXarchOption]>, Alias, HelpText<"Display available options">; +def dxc_no_stdinc : DXCFlag<"hlsl-no-stdinc">, + HelpText<"HLSL only. Disables all standard includes containing non-native compiler types and functions.">; def Fo : DXCJoinedOrSeparate<"Fo">, Alias, HelpText<"Output object file">; def dxil_validator_version : Option<["/", "-"], "validator-version", KIND_SEPARATE>, diff --git a/clang/lib/Basic/LangOptions.cpp b/clang/lib/Basic/LangOptions.cpp --- a/clang/lib/Basic/LangOptions.cpp +++ b/clang/lib/Basic/LangOptions.cpp @@ -117,6 +117,8 @@ Opts.Digraphs = Std.hasDigraphs(); Opts.HLSL = Lang == Language::HLSL; + if (Opts.HLSL && Opts.IncludeDefaultHeader) + Includes.push_back("hlsl.h"); // Set OpenCL Version. Opts.OpenCL = Std.isOpenCL(); diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3484,6 +3484,9 @@ for (const auto &Arg : ForwardedArguments) if (const auto *A = Args.getLastArg(Arg)) A->renderAsInput(Args, CmdArgs); + // Add the default headers if dxc_no_stdinc is not set. + if (!Args.hasArg(options::OPT_dxc_no_stdinc)) + CmdArgs.push_back("-finclude-default-header"); } static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -4202,6 +4202,10 @@ ((LangOpts.DeclareOpenCLBuiltins && I == "opencl-c-base.h") || I == "opencl-c.h")) continue; + // Don't generate HLSL includes. They are implied by other flags that are + // generated elsewhere. + if (LangOpts.HLSL && I == "hlsl.h") + continue; GenerateArg(Args, OPT_include, I, SA); } diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -377,6 +377,10 @@ Builder.defineMacro("__HLSL_VERSION", Twine((unsigned)LangOpts.getHLSLVersion())); + if (LangOpts.NativeHalfType) + Builder.defineMacro("__HLSL_ENABLE_16_BIT", + Twine((unsigned)LangOpts.getHLSLVersion())); + // Shader target information // "enums" for shader stages Builder.defineMacro("__SHADER_STAGE_VERTEX", diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -62,6 +62,11 @@ __clang_hip_runtime_wrapper.h ) +set(hlsl_files + hlsl.h + hlsl/hlsl_basic_types.h + ) + set(mips_msa_files msa.h ) @@ -212,6 +217,7 @@ ${cuda_files} ${hexagon_files} ${hip_files} + ${hlsl_files} ${mips_msa_files} ${opencl_files} ${ppc_files} @@ -405,6 +411,7 @@ add_header_target("x86-resource-headers" "${x86_files}") # Other header groupings +add_header_target("hlsl-resource-headers" ${hlsl_files}) add_header_target("opencl-resource-headers" ${opencl_files}) add_header_target("openmp-resource-headers" ${openmp_wrapper_files}) add_header_target("windows-resource-headers" ${windows_only_files}) @@ -538,6 +545,12 @@ EXCLUDE_FROM_ALL COMPONENT x86-resource-headers) +install( + FILES ${hlsl_files} + DESTINATION ${header_install_dir} + EXCLUDE_FROM_ALL + COMPONENT hlsl-resource-headers) + install( FILES ${opencl_files} DESTINATION ${header_install_dir} @@ -614,6 +627,9 @@ DEPENDS webassembly-resource-headers COMPONENT webassembly-resource-headers) + add_llvm_install_targets(install-hlsl-resource-headers + DEPENDS hlsl-resource-headers + COMPONENT hlsl-resource-headers) add_llvm_install_targets(install-opencl-resource-headers DEPENDS opencl-resource-headers COMPONENT opencl-resource-headers) diff --git a/clang/lib/Headers/hlsl.h b/clang/lib/Headers/hlsl.h new file mode 100644 --- /dev/null +++ b/clang/lib/Headers/hlsl.h @@ -0,0 +1,14 @@ +//===----- hlsl.h - HLSL definitions --------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _HLSL_H_ +#define _HLSL_H_ + +#include "hlsl/hlsl_basic_types.h" + +#endif //_HLSL_H_ diff --git a/clang/lib/Headers/hlsl/hlsl_basic_types.h b/clang/lib/Headers/hlsl/hlsl_basic_types.h new file mode 100644 --- /dev/null +++ b/clang/lib/Headers/hlsl/hlsl_basic_types.h @@ -0,0 +1,64 @@ +//===----- hlsl_basic_types.h - HLSL definitions for basic types ----------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef _HLSL_HLSL_BASIC_TYPES_H_ +#define _HLSL_HLSL_BASIC_TYPES_H_ + +// built-in scalar data types: + +#ifdef __HLSL_ENABLE_16_BIT +// 16-bit integer. +typedef unsigned short uint16_t; +typedef short int16_t; +#endif + +// unsigned 32-bit integer. +typedef unsigned int uint; + +// 64-bit integer. +typedef unsigned long uint64_t; +typedef long int64_t; + +// built-in vector data types: + +#ifdef __HLSL_ENABLE_16_BIT +typedef int16_t int16_t2 __attribute__((ext_vector_type(2))); +typedef int16_t int16_t3 __attribute__((ext_vector_type(3))); +typedef int16_t int16_t4 __attribute__((ext_vector_type(4))); +typedef uint16_t uint16_t2 __attribute__((ext_vector_type(2))); +typedef uint16_t uint16_t3 __attribute__((ext_vector_type(3))); +typedef uint16_t uint16_t4 __attribute__((ext_vector_type(4))); +#endif + +typedef int int2 __attribute__((ext_vector_type(2))); +typedef int int3 __attribute__((ext_vector_type(3))); +typedef int int4 __attribute__((ext_vector_type(4))); +typedef uint uint2 __attribute__((ext_vector_type(2))); +typedef uint uint3 __attribute__((ext_vector_type(3))); +typedef uint uint4 __attribute__((ext_vector_type(4))); +typedef int64_t int64_t2 __attribute__((ext_vector_type(2))); +typedef int64_t int64_t3 __attribute__((ext_vector_type(3))); +typedef int64_t int64_t4 __attribute__((ext_vector_type(4))); +typedef uint64_t uint64_t2 __attribute__((ext_vector_type(2))); +typedef uint64_t uint64_t3 __attribute__((ext_vector_type(3))); +typedef uint64_t uint64_t4 __attribute__((ext_vector_type(4))); + +#ifdef __HLSL_ENABLE_16_BIT +typedef half half2 __attribute__((ext_vector_type(2))); +typedef half half3 __attribute__((ext_vector_type(3))); +typedef half half4 __attribute__((ext_vector_type(4))); +#endif + +typedef float float2 __attribute__((ext_vector_type(2))); +typedef float float3 __attribute__((ext_vector_type(3))); +typedef float float4 __attribute__((ext_vector_type(4))); +typedef double double2 __attribute__((ext_vector_type(2))); +typedef double double3 __attribute__((ext_vector_type(3))); +typedef double double4 __attribute__((ext_vector_type(4))); + +#endif //_HLSL_HLSL_BASIC_TYPES_H_ diff --git a/clang/test/CodeGenHLSL/basic_types.hlsl b/clang/test/CodeGenHLSL/basic_types.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenHLSL/basic_types.hlsl @@ -0,0 +1,76 @@ +// RUN: %clang_dxc -Tlib_6_7 -fcgl -Fo - %s | FileCheck %s + +// FIXME: check 16bit types once enable-16bit-types is ready. + +// CHECK:@uint_Val = global i32 0, align 4 +// CHECK:@uint64_t_Val = global i64 0, align 8 +// CHECK:@int64_t_Val = global i64 0, align 8 +// CHECK:@int2_Val = global <2 x i32> zeroinitializer, align 8 +// CHECK:@int3_Val = global <3 x i32> zeroinitializer, align 16 +// CHECK:@int4_Val = global <4 x i32> zeroinitializer, align 16 +// CHECK:@uint2_Val = global <2 x i32> zeroinitializer, align 8 +// CHECK:@uint3_Val = global <3 x i32> zeroinitializer, align 16 +// CHECK:@uint4_Val = global <4 x i32> zeroinitializer, align 16 +// CHECK:@int64_t2_Val = global <2 x i64> zeroinitializer, align 16 +// CHECK:@int64_t3_Val = global <3 x i64> zeroinitializer, align 32 +// CHECK:@int64_t4_Val = global <4 x i64> zeroinitializer, align 32 +// CHECK:@uint64_t2_Val = global <2 x i64> zeroinitializer, align 16 +// CHECK:@uint64_t3_Val = global <3 x i64> zeroinitializer, align 32 +// CHECK:@uint64_t4_Val = global <4 x i64> zeroinitializer, align 32 +// CHECK:@float2_Val = global <2 x float> zeroinitializer, align 8 +// CHECK:@float3_Val = global <3 x float> zeroinitializer, align 16 +// CHECK:@float4_Val = global <4 x float> zeroinitializer, align 16 +// CHECK:@double2_Val = global <2 x double> zeroinitializer, align 16 +// CHECK:@double3_Val = global <3 x double> zeroinitializer, align 32 +// CHECK:@double4_Val = global <4 x double> zeroinitializer, align 32 + +#define TYPE_DECL(T) T T##_Val + +#ifdef __HLSL_ENABLE_16_BIT +TYPE_DECL(uint16_t); +TYPE_DECL(int16_t); +#endif + +// unsigned 32-bit integer. +TYPE_DECL(uint); + +// 64-bit integer. +TYPE_DECL(uint64_t); +TYPE_DECL(int64_t); + +// built-in vector data types: + +#ifdef __HLSL_ENABLE_16_BIT +TYPE_DECL(int16_t2 ); +TYPE_DECL(int16_t3 ); +TYPE_DECL(int16_t4 ); +TYPE_DECL( uint16_t2 ); +TYPE_DECL( uint16_t3 ); +TYPE_DECL( uint16_t4 ); +#endif + +TYPE_DECL( int2 ); +TYPE_DECL( int3 ); +TYPE_DECL( int4 ); +TYPE_DECL( uint2 ); +TYPE_DECL( uint3 ); +TYPE_DECL( uint4 ); +TYPE_DECL( int64_t2 ); +TYPE_DECL( int64_t3 ); +TYPE_DECL( int64_t4 ); +TYPE_DECL( uint64_t2 ); +TYPE_DECL( uint64_t3 ); +TYPE_DECL( uint64_t4 ); + +#ifdef __HLSL_ENABLE_16_BIT +TYPE_DECL(half2 ); +TYPE_DECL(half3 ); +TYPE_DECL(half4 ); +#endif + +TYPE_DECL( float2 ); +TYPE_DECL( float3 ); +TYPE_DECL( float4 ); +TYPE_DECL( double2 ); +TYPE_DECL( double3 ); +TYPE_DECL( double4 ); diff --git a/clang/test/Driver/hlsl_no_stdinc.hlsl b/clang/test/Driver/hlsl_no_stdinc.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/Driver/hlsl_no_stdinc.hlsl @@ -0,0 +1,12 @@ +// RUN: %clang_dxc -Tlib_6_7 -fcgl -Fo - %s -### 2>&1 | FileCheck %s --check-prefix=STDINC +// RUN: %clang_dxc -Tlib_6_7 -hlsl-no-stdinc -fcgl -Fo - %s -### 2>&1 | FileCheck %s --check-prefix=NOSTDINC + +// RUN: %clang -cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -ast-dump -o - %s -verify + +// Make sure hlsl-no-stdinc is translated into finclude-default-header. +// STDINC:"-finclude-default-header" +// NOSTDINC-NOT:"-finclude-default-header" + +// Make sure uint not work when finclude-default-header is off. +// expected-error@+1 {{unknown type name 'uint'}} +uint a;