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<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/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:10, col:15> col:15 used a 'half'
+// F16:ImplicitCastExpr 0x{{.*}} <col:10, col:12> 'half' <FloatingCast>
+// F16:BinaryOperator 0x{{.*}} <col:10, col:12> 'float' '+'
+// F16:VarDecl 0x{{.*}} <line:31:1, col:23> col:19 used h 'const half' static cinit
+// F16:ImplicitCastExpr 0x{{.*}} <col:23> 'const half' <FloatingCast>
+// F16:VarDecl 0x{{.*}} <line:32:1, col:24> col:20 used f 'const float' static cinit
+// F16:VarDecl 0x{{.*}} <line:33:1, col:28> col:19 h2 'const half' static cinit
+// F16:ImplicitCastExpr 0x{{.*}} <col:24, col:28> 'const half' <FloatingCast>
+
+// 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:10, col:15> col:15 used a 'float'
+// F32-NOT:FloatingCast
+// F32:BinaryOperator 0x{{.*}} <col:10, col:12> 'float' '+'
+// F32:VarDecl 0x{{.*}} <line:31:1, col:23> col:19 used h 'const float' static cinit
+// F32-NOT:FloatingCast
+// F32:VarDecl 0x{{.*}} <line:32:1, col:24> col:20 used f 'const float' static cinit
+// F32-NOT:FloatingCast
+// F32:VarDecl 0x{{.*}} <line:33:1, col:28> col:19 h2 'const float' static cinit
+// F32:BinaryOperator 0x{{.*}} <col:24, col:28> '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;
+
+