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 @@ -6762,3 +6762,6 @@ HelpText<"Emit pristine LLVM IR from the frontend by not running any LLVM passes at all." "Same as -S + -emit-llvm + -disable-llvm-passes.">; def fcgl : DXCFlag<"fcgl">, Alias; +def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias, + HelpText<"Enable 16-bit types and disable min precision types." + "Available in HLSL 2018 and shader model 6.2.">; 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 @@ -193,8 +193,8 @@ // OpenCL, C++ and C2x have bool, true, false keywords. Opts.Bool = Opts.OpenCL || Opts.CPlusPlus || Opts.C2x; - // OpenCL has half keyword - Opts.Half = Opts.OpenCL; + // OpenCL and HLSL have half keyword + Opts.Half = Opts.OpenCL || Opts.HLSL; } FPOptions FPOptions::defaultWithoutTrailingStorage(const LangOptions &LO) { diff --git a/clang/lib/Basic/Targets/DirectX.h b/clang/lib/Basic/Targets/DirectX.h --- a/clang/lib/Basic/Targets/DirectX.h +++ b/clang/lib/Basic/Targets/DirectX.h @@ -58,7 +58,7 @@ resetDataLayout("e-m:e-p:32:32-i1:32-i8:8-i16:16-i32:32-i64:64-f16:16-f32:" "32-f64:64-n8:16:32:64"); } - + bool useFP16ConversionIntrinsics() const override { return false; } void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override; 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 @@ -3473,11 +3473,13 @@ types::ID InputType) { const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version, options::OPT_S, options::OPT_emit_llvm, - options::OPT_disable_llvm_passes}; + options::OPT_disable_llvm_passes, + options::OPT_fnative_half_type}; for (const auto &Arg : ForwardedArguments) if (const auto *A = Args.getLastArg(Arg)) A->renderAsInput(Args, CmdArgs); + CmdArgs.push_back("-fallow-half-arguments-and-returns"); } static void RenderARCMigrateToolOptions(const Driver &D, const ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp b/clang/lib/Driver/ToolChains/HLSL.cpp --- a/clang/lib/Driver/ToolChains/HLSL.cpp +++ b/clang/lib/Driver/ToolChains/HLSL.cpp @@ -188,5 +188,7 @@ Opts.getOption(options::OPT_dxil_validator_version), DefaultValidatorVer); } + // FIXME: add validation for enable_16bit_types should be after HLSL 2018 and + // shader model 6.2. return DAL; } diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1508,7 +1508,13 @@ << "_Float16"; Result = Context.Float16Ty; break; - case DeclSpec::TST_half: Result = Context.HalfTy; break; + case DeclSpec::TST_half: + // For HLSL, when not enable native half type, half will be treat as float. + if (S.getLangOpts().HLSL && !S.getLangOpts().NativeHalfType) + Result = Context.FloatTy; + else + Result = Context.HalfTy; + break; case DeclSpec::TST_BFloat16: if (!S.Context.getTargetInfo().hasBFloat16Type()) S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) diff --git a/clang/test/CodeGenHLSL/half.hlsl b/clang/test/CodeGenHLSL/half.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenHLSL/half.hlsl @@ -0,0 +1,15 @@ +// RUN: %clang_dxc -Tlib_6_7 -fcgl -Fo - %s | FileCheck %s --check-prefix=FLOAT +// RUN: %clang_dxc -Tlib_6_7 -enable-16bit-types -fcgl -Fo - %s | FileCheck %s --check-prefix=HALF + +// Make sure use float when not enable-16bit-types. +// FLOAT:define {{.*}}float @_Z3fooff(float{{[^,]+}}, float{{[^,)]+}}) +// FLOAT-NOT:half +// FLOAT:ret float % + +// Make sure use half when enable-16bit-types. +// HALF:define {{.*}}half @_Z3fooDhDh(half{{[^,]+}}, half{{[^,)]+}}) +// HALF-NOT:float +// HALF:ret half % +half foo(half a, half b) { + return a+b; +} diff --git a/clang/test/SemaHLSL/half.hlsl b/clang/test/SemaHLSL/half.hlsl new file mode 100644 --- /dev/null +++ b/clang/test/SemaHLSL/half.hlsl @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -xhlsl -triple dxil-pc-shadermodel6.7-compute -validator-version 1.0 -fnative-half-arguments-and-returns -ast-dump -fnative-half-type -o - %s | FileCheck %s --check-prefix=F16 +// RUN: %clang_cc1 -xhlsl -triple dxil-pc-shadermodel6.7-compute -validator-version 1.0 -fnative-half-arguments-and-returns -ast-dump -o - %s | FileCheck %s --check-prefix=F32 + +// Make sure when -fnative-half-type is enabled, half is half in ast. +// F16:FunctionDecl 0x{{.*}} <{{.*}}\half.hlsl:27:1, line:29:1> line:27:6 foo 'half (half, float)' +// F16:ParmVarDecl 0x{{.*}} col:15 used a 'half' +// F16:ImplicitCastExpr 0x{{.*}} 'half' +// F16:BinaryOperator 0x{{.*}} 'float' '+' +// F16:VarDecl 0x{{.*}} col:19 used h 'const half' static cinit +// F16:ImplicitCastExpr 0x{{.*}} 'const half' +// F16:VarDecl 0x{{.*}} col:20 used f 'const float' static cinit +// F16:VarDecl 0x{{.*}} col:19 h2 'const half' static cinit +// F16:ImplicitCastExpr 0x{{.*}} 'const half' + +// Make sure when -fnative-half-type is disabled, half is float in ast. +// F32:FunctionDecl 0x{{.*}} <{{.*}}\half.hlsl:27:1, line:29:1> line:27:6 foo 'float (float, float)' +// F32:ParmVarDecl 0x{{.*}} col:15 used a 'float' +// F32-NOT:FloatingCast +// F32:BinaryOperator 0x{{.*}} 'float' '+' +// F32:VarDecl 0x{{.*}} col:19 used h 'const float' static cinit +// F32-NOT:FloatingCast +// F32:VarDecl 0x{{.*}} col:20 used f 'const float' static cinit +// F32-NOT:FloatingCast +// F32:VarDecl 0x{{.*}} col:19 h2 'const float' static cinit +// F32:BinaryOperator 0x{{.*}} 'float' '+' + +half foo(half a, float b) { + return a+b; +} + +static const half h = 1.0f; +static const float f = 2.0f; +static const half h2 = h + f; + +