[clang] 77f72ac - [HLSL] Enable half type for hlsl.

Xiang Li via cfe-commits cfe-commits at lists.llvm.org
Thu Jun 23 12:56:33 PDT 2022


Author: Xiang Li
Date: 2022-06-23T12:56:26-07:00
New Revision: 77f72ac15bcac8923c6bd104f303feaa1e964692

URL: https://github.com/llvm/llvm-project/commit/77f72ac15bcac8923c6bd104f303feaa1e964692
DIFF: https://github.com/llvm/llvm-project/commit/77f72ac15bcac8923c6bd104f303feaa1e964692.diff

LOG: [HLSL] Enable half type for hlsl.

HLSL supports half type.
When enable-16bit-types is not set, half will be treated as float.
When enable-16bit-types is set, half will be treated like real 16bit float type and map to llvm half type.
Also change CXXABI to Microsoft to match dxc behavior.
The mangle name for half is "$f16@" when half is treat as native half type and "$halff@" when treat as float.

In AST, half is still half.
The special thing is done at clang codeGen, when NativeHalfType is false, half will translated into float.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D124790

Added: 
    clang/test/CodeGenHLSL/half.hlsl

Modified: 
    clang/include/clang/Driver/Options.td
    clang/lib/AST/ASTContext.cpp
    clang/lib/AST/MicrosoftMangle.cpp
    clang/lib/Basic/LangOptions.cpp
    clang/lib/Basic/Targets/DirectX.h
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Driver/ToolChains/HLSL.cpp
    clang/test/CodeGenHLSL/basic_types.hlsl

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index c79b748acbfc0..5410b5d3e617f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -6850,3 +6850,6 @@ def emit_pristine_llvm : DXCFlag<"emit-pristine-llvm">,
   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<emit_pristine_llvm>;
+def enable_16bit_types : DXCFlag<"enable-16bit-types">, Alias<fnative_half_type>,
+  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
index b4b02da0c3510..fe1ef6799048f 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1707,8 +1707,17 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
   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
index e84946d1f21ec..09075e60142a7 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -2461,7 +2461,12 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
     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
index 7549f3f2e23b4..0bf410c053ed9 100644
--- a/clang/lib/Basic/LangOptions.cpp
+++ b/clang/lib/Basic/LangOptions.cpp
@@ -195,8 +195,8 @@ void LangOptions::setLangDefaults(LangOptions &Opts, Language Lang,
   // 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
index 90ef1dfa55c89..a773090b413f7 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -57,8 +57,9 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public TargetInfo {
     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
index c6a8e34204977..f4cca95c09176 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3479,9 +3479,12 @@ static void RenderOpenCLOptions(const ArgList &Args, ArgStringList &CmdArgs,
 
 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 @@ static void RenderHLSLOptions(const ArgList &Args, ArgStringList &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");
+  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
index 023780817ef4b..584e00bb7f058 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -177,5 +177,7 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
                         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
index fcb0815c3af57..f76e134743e54 100644
--- 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 at H$01 at __clang@@A" = global <2 x i32> zeroinitializer, align 8
+// CHECK:"?int3_Val@@3T?$__vector at H$02 at __clang@@A" = global <3 x i32> zeroinitializer, align 16
+// CHECK:"?int4_Val@@3T?$__vector at H$03 at __clang@@A" = global <4 x i32> zeroinitializer, align 16
+// CHECK:"?uint2_Val@@3T?$__vector at I$01 at __clang@@A" = global <2 x i32> zeroinitializer, align 8
+// CHECK:"?uint3_Val@@3T?$__vector at I$02 at __clang@@A" = global <3 x i32> zeroinitializer, align 16
+// CHECK:"?uint4_Val@@3T?$__vector at I$03 at __clang@@A" = global <4 x i32> zeroinitializer, align 16
+// CHECK:"?int64_t2_Val@@3T?$__vector at J$01 at __clang@@A" = global <2 x i64> zeroinitializer, align 16
+// CHECK:"?int64_t3_Val@@3T?$__vector at J$02 at __clang@@A" = global <3 x i64> zeroinitializer, align 32
+// CHECK:"?int64_t4_Val@@3T?$__vector at J$03 at __clang@@A" = global <4 x i64> zeroinitializer, align 32
+// CHECK:"?uint64_t2_Val@@3T?$__vector at K$01 at __clang@@A" = global <2 x i64> zeroinitializer, align 16
+// CHECK:"?uint64_t3_Val@@3T?$__vector at K$02 at __clang@@A" = global <3 x i64> zeroinitializer, align 32
+// CHECK:"?uint64_t4_Val@@3T?$__vector at K$03 at __clang@@A" = global <4 x i64> zeroinitializer, align 32
+// CHECK:"?float2_Val@@3T?$__vector at M$01 at __clang@@A" = global <2 x float> zeroinitializer, align 8
+// CHECK:"?float3_Val@@3T?$__vector at M$02 at __clang@@A" = global <3 x float> zeroinitializer, align 16
+// CHECK:"?float4_Val@@3T?$__vector at M$03 at __clang@@A" = global <4 x float> zeroinitializer, align 16
+// CHECK:"?double2_Val@@3T?$__vector at N$01 at __clang@@A" = global <2 x double> zeroinitializer, align 16
+// CHECK:"?double3_Val@@3T?$__vector at N$02 at __clang@@A" = global <3 x double> zeroinitializer, align 32
+// CHECK:"?double4_Val@@3T?$__vector at N$03 at __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
index 0000000000000..90ef77f4bec54
--- /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 at 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 at 0@Z"(half{{[^,]+}}, half{{[^,)]+}})
+// HALF-NOT:float
+// HALF:ret half %
+half foo(half a, half b) {
+  return a+b;
+}


        


More information about the cfe-commits mailing list