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 @@ -6847,3 +6847,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/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1707,8 +1707,17 @@ case BuiltinType::BFloat16: return Target->getBFloat16Format(); case BuiltinType::Float16: - case BuiltinType::Half: return Target->getHalfFormat(); + case BuiltinType::Half: + // For HLSL, when the native half type is disabled, half will be treat as + // float. + if (getLangOpts().HLSL) + if (getLangOpts().NativeHalfType) + return Target->getHalfFormat(); + else + return Target->getFloatFormat(); + else + return Target->getHalfFormat(); case BuiltinType::Float: return Target->getFloatFormat(); case BuiltinType::Double: return Target->getDoubleFormat(); case BuiltinType::Ibm128: diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -2461,7 +2461,12 @@ break; case BuiltinType::Half: - mangleArtificialTagType(TTK_Struct, "_Half", {"__clang"}); + if (!getASTContext().getLangOpts().HLSL) + mangleArtificialTagType(TTK_Struct, "_Half", {"__clang"}); + else if (getASTContext().getLangOpts().NativeHalfType) + Out << "$f16@"; + else + Out << "$halff@"; break; #define SVE_TYPE(Name, Id, SingletonId) \ 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 @@ -195,8 +195,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 @@ -57,8 +57,9 @@ NoAsmVariants = true; 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"); + TheCXXABI.set(TargetCXXABI::Microsoft); } - + 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 @@ -3479,9 +3479,12 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &CmdArgs, types::ID InputType) { - const unsigned ForwardedArguments[] = { - options::OPT_dxil_validator_version, options::OPT_D, options::OPT_S, - options::OPT_emit_llvm, options::OPT_disable_llvm_passes}; + const unsigned ForwardedArguments[] = {options::OPT_dxil_validator_version, + options::OPT_D, + options::OPT_S, + options::OPT_emit_llvm, + options::OPT_disable_llvm_passes, + options::OPT_fnative_half_type}; for (const auto &Arg : ForwardedArguments) if (const auto *A = Args.getLastArg(Arg)) @@ -3489,6 +3492,7 @@ // 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"); + 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 @@ -177,5 +177,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/test/CodeGenHLSL/basic_types.hlsl b/clang/test/CodeGenHLSL/basic_types.hlsl --- a/clang/test/CodeGenHLSL/basic_types.hlsl +++ b/clang/test/CodeGenHLSL/basic_types.hlsl @@ -2,27 +2,27 @@ // 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 +// CHECK:"?uint_Val@@3IA" = global i32 0, align 4 +// CHECK:"?uint64_t_Val@@3KA" = global i64 0, align 8 +// CHECK:"?int64_t_Val@@3JA" = global i64 0, align 8 +// CHECK:"?int2_Val@@3T?$__vector@H$01@__clang@@A" = global <2 x i32> zeroinitializer, align 8 +// CHECK:"?int3_Val@@3T?$__vector@H$02@__clang@@A" = global <3 x i32> zeroinitializer, align 16 +// CHECK:"?int4_Val@@3T?$__vector@H$03@__clang@@A" = global <4 x i32> zeroinitializer, align 16 +// CHECK:"?uint2_Val@@3T?$__vector@I$01@__clang@@A" = global <2 x i32> zeroinitializer, align 8 +// CHECK:"?uint3_Val@@3T?$__vector@I$02@__clang@@A" = global <3 x i32> zeroinitializer, align 16 +// CHECK:"?uint4_Val@@3T?$__vector@I$03@__clang@@A" = global <4 x i32> zeroinitializer, align 16 +// CHECK:"?int64_t2_Val@@3T?$__vector@J$01@__clang@@A" = global <2 x i64> zeroinitializer, align 16 +// CHECK:"?int64_t3_Val@@3T?$__vector@J$02@__clang@@A" = global <3 x i64> zeroinitializer, align 32 +// CHECK:"?int64_t4_Val@@3T?$__vector@J$03@__clang@@A" = global <4 x i64> zeroinitializer, align 32 +// CHECK:"?uint64_t2_Val@@3T?$__vector@K$01@__clang@@A" = global <2 x i64> zeroinitializer, align 16 +// CHECK:"?uint64_t3_Val@@3T?$__vector@K$02@__clang@@A" = global <3 x i64> zeroinitializer, align 32 +// CHECK:"?uint64_t4_Val@@3T?$__vector@K$03@__clang@@A" = global <4 x i64> zeroinitializer, align 32 +// CHECK:"?float2_Val@@3T?$__vector@M$01@__clang@@A" = global <2 x float> zeroinitializer, align 8 +// CHECK:"?float3_Val@@3T?$__vector@M$02@__clang@@A" = global <3 x float> zeroinitializer, align 16 +// CHECK:"?float4_Val@@3T?$__vector@M$03@__clang@@A" = global <4 x float> zeroinitializer, align 16 +// CHECK:"?double2_Val@@3T?$__vector@N$01@__clang@@A" = global <2 x double> zeroinitializer, align 16 +// CHECK:"?double3_Val@@3T?$__vector@N$02@__clang@@A" = global <3 x double> zeroinitializer, align 32 +// CHECK:"?double4_Val@@3T?$__vector@N$03@__clang@@A" = global <4 x double> zeroinitializer, align 32 #define TYPE_DECL(T) T T##_Val 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 @"?foo@@YA$halff@$halff@0@Z"(float{{[^,]+}}, float{{[^,)]+}}) +// FLOAT-NOT:half +// FLOAT:ret float % + +// Make sure use half when enable-16bit-types. +// HALF:define {{.*}}half @"?foo@@YA$f16@$f16@0@Z"(half{{[^,]+}}, half{{[^,)]+}}) +// HALF-NOT:float +// HALF:ret half % +half foo(half a, half b) { + return a+b; +}