https://github.com/arsenm created 
https://github.com/llvm/llvm-project/pull/207212

Follow up to #174494. Remove the remnants of the control to
use llvm.convert.to.fp16/llvm.convert.from.fp16. Prefer
directly using the IR half type, unless the value is used
in an ABI context where it needs to remain as i16.

I did the first 80% of this a long time ago, and AI finished
the last bit and handled the recent rebases and test updates.

Co-authored-by: Claude (Opus 4.8) <[email protected]>

>From bb9a3c209804806753d04f35036bda728d406be5 Mon Sep 17 00:00:00 2001
From: Matt Arsenault <[email protected]>
Date: Mon, 5 Jan 2026 23:15:43 +0100
Subject: [PATCH] clang: Remove useFP16ConversionIntrinsics target option

Follow up to #174494. Remove the remnants of the control to
use llvm.convert.to.fp16/llvm.convert.from.fp16. Prefer
directly using the IR half type, unless the value is used
in an ABI context where it needs to remain as i16.

I did the first 80% of this a long time ago, and AI finished
the last bit and handled the recent rebases and test updates.

Co-authored-by: Claude (Opus 4.8) <[email protected]>
---
 clang/include/clang/Basic/TargetInfo.h       | 10 ---
 clang/lib/Basic/Targets/AArch64.h            |  4 -
 clang/lib/Basic/Targets/AMDGPU.h             |  2 -
 clang/lib/Basic/Targets/ARM.h                |  4 -
 clang/lib/Basic/Targets/DirectX.h            |  1 -
 clang/lib/Basic/Targets/LoongArch.h          |  2 -
 clang/lib/Basic/Targets/NVPTX.h              |  2 -
 clang/lib/Basic/Targets/RISCV.h              |  4 -
 clang/lib/Basic/Targets/SPIR.h               |  4 -
 clang/lib/Basic/Targets/SystemZ.h            |  2 -
 clang/lib/Basic/Targets/WebAssembly.h        |  1 -
 clang/lib/Basic/Targets/X86.h                |  4 -
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp | 10 +--
 clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp   | 22 +-----
 clang/lib/CIR/CodeGen/CIRGenTypes.cpp        |  8 +-
 clang/lib/CodeGen/CGExprConstant.cpp         | 12 +--
 clang/lib/CodeGen/CGExprScalar.cpp           | 54 ++++----------
 clang/lib/CodeGen/CodeGenTypes.cpp           | 28 +++----
 clang/lib/CodeGen/TargetBuiltins/NVPTX.cpp   | 22 +-----
 clang/lib/Sema/SemaChecking.cpp              | 20 ++---
 clang/lib/Sema/SemaExpr.cpp                  |  3 +-
 clang/test/CodeGen/builtin_float.c           |  7 +-
 clang/test/CodeGen/builtin_float_strictfp.c  |  8 +-
 clang/test/CodeGen/wasm-fp16.c               | 77 ++++++++------------
 24 files changed, 79 insertions(+), 232 deletions(-)

diff --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index d1914d626c753..b3af03cbc2f66 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1017,16 +1017,6 @@ class TargetInfo : public TransferrableTargetInfo,
     return ComplexLongDoubleUsesFP2Ret;
   }
 
-  /// Check whether conversions to and from __fp16 should go through an integer
-  /// bitcast with i16.
-  ///
-  /// FIXME: This function should be removed. The intrinsics / no longer exist,
-  /// and are emulated with bitcast + fp cast. This only exists because of
-  /// misuse in ABI determining contexts.
-  virtual bool useFP16ConversionIntrinsics() const {
-    return true;
-  }
-
   /// Specify if mangling based on address space map should be used or
   /// not for language specific address spaces
   bool useAddressSpaceMapMangling() const {
diff --git a/clang/lib/Basic/Targets/AArch64.h 
b/clang/lib/Basic/Targets/AArch64.h
index b4b66db34b9b7..04d0fa84684ef 100644
--- a/clang/lib/Basic/Targets/AArch64.h
+++ b/clang/lib/Basic/Targets/AArch64.h
@@ -171,10 +171,6 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public 
TargetInfo {
 
   llvm::APInt getFMVPriority(ArrayRef<StringRef> Features) const override;
 
-  bool useFP16ConversionIntrinsics() const override {
-    return false;
-  }
-
   void getTargetDefinesARMV81A(const LangOptions &Opts,
                                MacroBuilder &Builder) const;
   void getTargetDefinesARMV82A(const LangOptions &Opts,
diff --git a/clang/lib/Basic/Targets/AMDGPU.h b/clang/lib/Basic/Targets/AMDGPU.h
index b13e9008b67a4..7bd34526105d3 100644
--- a/clang/lib/Basic/Targets/AMDGPU.h
+++ b/clang/lib/Basic/Targets/AMDGPU.h
@@ -263,8 +263,6 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : 
public TargetInfo {
 
   llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
 
-  bool useFP16ConversionIntrinsics() const override { return false; }
-
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override;
 
diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h
index 8bd56c8855fe3..976e1e06ae9b2 100644
--- a/clang/lib/Basic/Targets/ARM.h
+++ b/clang/lib/Basic/Targets/ARM.h
@@ -177,10 +177,6 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public 
TargetInfo {
 
   bool setFPMath(StringRef Name) override;
 
-  bool useFP16ConversionIntrinsics() const override {
-    return false;
-  }
-
   void getTargetDefinesARMV81A(const LangOptions &Opts,
                                MacroBuilder &Builder) const;
   void getTargetDefinesARMV82A(const LangOptions &Opts,
diff --git a/clang/lib/Basic/Targets/DirectX.h 
b/clang/lib/Basic/Targets/DirectX.h
index 8b21b86bac264..64e5533bbffeb 100644
--- a/clang/lib/Basic/Targets/DirectX.h
+++ b/clang/lib/Basic/Targets/DirectX.h
@@ -70,7 +70,6 @@ class LLVM_LIBRARY_VISIBILITY DirectXTargetInfo : public 
TargetInfo {
     resetDataLayout();
     TheCXXABI.set(TargetCXXABI::GenericItanium);
   }
-  bool useFP16ConversionIntrinsics() const override { return false; }
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override;
 
diff --git a/clang/lib/Basic/Targets/LoongArch.h 
b/clang/lib/Basic/Targets/LoongArch.h
index 16124a87d4955..4c98f9d0e40ae 100644
--- a/clang/lib/Basic/Targets/LoongArch.h
+++ b/clang/lib/Basic/Targets/LoongArch.h
@@ -107,8 +107,6 @@ class LLVM_LIBRARY_VISIBILITY LoongArchTargetInfo : public 
TargetInfo {
 
   bool hasBFloat16Type() const override { return true; }
 
-  bool useFP16ConversionIntrinsics() const override { return false; }
-
   bool handleTargetFeatures(std::vector<std::string> &Features,
                             DiagnosticsEngine &Diags) override;
 
diff --git a/clang/lib/Basic/Targets/NVPTX.h b/clang/lib/Basic/Targets/NVPTX.h
index 8af9cb91c47ab..00be0fe54c1bd 100644
--- a/clang/lib/Basic/Targets/NVPTX.h
+++ b/clang/lib/Basic/Targets/NVPTX.h
@@ -82,8 +82,6 @@ class LLVM_LIBRARY_VISIBILITY NVPTXTargetInfo : public 
TargetInfo {
 
   llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;
 
-  bool useFP16ConversionIntrinsics() const override { return false; }
-
   bool isCLZForZeroUndef() const override { return false; }
 
   bool
diff --git a/clang/lib/Basic/Targets/RISCV.h b/clang/lib/Basic/Targets/RISCV.h
index 193f77fe68a0b..73287c5d2d58d 100644
--- a/clang/lib/Basic/Targets/RISCV.h
+++ b/clang/lib/Basic/Targets/RISCV.h
@@ -117,10 +117,6 @@ class RISCVTargetInfo : public TargetInfo {
 
   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override;
 
-  bool useFP16ConversionIntrinsics() const override {
-    return false;
-  }
-
   bool isValidCPUName(StringRef Name) const override;
   void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;
   bool isValidTuneCPUName(StringRef Name) const override;
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index 389cc075a3a0b..42256920f353e 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -173,10 +173,6 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public 
TargetInfo {
   }
 
 public:
-  // SPIR supports the half type and the only llvm intrinsic allowed in SPIR is
-  // memcpy as per section 3 of the SPIR spec.
-  bool useFP16ConversionIntrinsics() const override { return false; }
-
   llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override {
     return {};
   }
diff --git a/clang/lib/Basic/Targets/SystemZ.h 
b/clang/lib/Basic/Targets/SystemZ.h
index 70b529e8ca854..d56306c7c4a88 100644
--- a/clang/lib/Basic/Targets/SystemZ.h
+++ b/clang/lib/Basic/Targets/SystemZ.h
@@ -107,8 +107,6 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public 
TargetInfo {
 
   unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const override;
 
-  bool useFP16ConversionIntrinsics() const override { return false; }
-
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override;
 
diff --git a/clang/lib/Basic/Targets/WebAssembly.h 
b/clang/lib/Basic/Targets/WebAssembly.h
index 88192a756cc4f..0b0266a48469a 100644
--- a/clang/lib/Basic/Targets/WebAssembly.h
+++ b/clang/lib/Basic/Targets/WebAssembly.h
@@ -120,7 +120,6 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : 
public TargetInfo {
 
   StringRef getABI() const override;
   bool setABI(const std::string &Name) override;
-  bool useFP16ConversionIntrinsics() const override { return !HasFP16; }
 
 protected:
   void getTargetDefines(const LangOptions &Opts,
diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h
index b0daffbea4576..641bb78906610 100644
--- a/clang/lib/Basic/Targets/X86.h
+++ b/clang/lib/Basic/Targets/X86.h
@@ -338,10 +338,6 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public 
TargetInfo {
     return "";
   }
 
-  bool useFP16ConversionIntrinsics() const override {
-    return false;
-  }
-
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override;
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 384b975b3f422..ffb0f9148c876 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -1304,18 +1304,10 @@ mlir::Attribute ConstantEmitter::tryEmitPrivate(const 
APValue &value,
     return cir::IntAttr::get(ty, value.getInt());
   }
   case APValue::Float: {
-    const llvm::APFloat &init = value.getFloat();
-    if (&init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
-        !cgm.getASTContext().getLangOpts().NativeHalfType &&
-        cgm.getASTContext().getTargetInfo().useFP16ConversionIntrinsics()) {
-      cgm.errorNYI("ConstExprEmitter::tryEmitPrivate half");
-      return {};
-    }
-
     mlir::Type ty = cgm.convertType(destType);
     assert(mlir::isa<cir::FPTypeInterface>(ty) &&
            "expected floating-point type");
-    return cir::FPAttr::get(ty, init);
+    return cir::FPAttr::get(ty, value.getFloat());
   }
   case APValue::Array: {
     const ArrayType *arrayTy = cgm.getASTContext().getAsArrayType(destType);
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
index 3c2d2726ac9fa..645cca9fe16eb 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp
@@ -969,19 +969,10 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
     if (srcType->isHalfType() &&
         !cgf.getContext().getLangOpts().NativeHalfType) {
       // Cast to FP using the intrinsic if the half type itself isn't 
supported.
-      if (mlir::isa<cir::FPTypeInterface>(mlirDstType)) {
-        if (cgf.getContext().getTargetInfo().useFP16ConversionIntrinsics())
-          cgf.getCIRGenModule().errorNYI(loc,
-                                         "cast via llvm.convert.from.fp16");
-      } else {
-        // Cast to other types through float, using either the intrinsic or
-        // FPExt, depending on whether the half type itself is supported (as
-        // opposed to operations on half, available with NativeHalfType).
-        if (cgf.getContext().getTargetInfo().useFP16ConversionIntrinsics())
-          cgf.getCIRGenModule().errorNYI(loc,
-                                         "cast via llvm.convert.from.fp16");
-        // FIXME(cir): For now lets pretend we shouldn't use the conversion
-        // intrinsics and insert a cast here unconditionally.
+      if (!mlir::isa<cir::FPTypeInterface>(mlirDstType)) {
+        // Cast to other types through float, using FPExt, depending on whether
+        // the half type itself is supported (as opposed to operations on half,
+        // available with NativeHalfType).
         src = builder.createCast(cgf.getLoc(loc), cir::CastKind::floating, src,
                                  cgf.floatTy);
         srcType = cgf.getContext().FloatTy;
@@ -1039,11 +1030,6 @@ class ScalarExprEmitter : public 
StmtVisitor<ScalarExprEmitter, mlir::Value> {
     res = emitScalarCast(src, srcType, dstType, mlirSrcType, mlirDstType, 
opts);
 
     if (mlirDstType != resTy) {
-      if (cgf.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
-        cgf.getCIRGenModule().errorNYI(loc, "cast via llvm.convert.to.fp16");
-      }
-      // FIXME(cir): For now we never use FP16 conversion intrinsics even if
-      // required by the target. Change that once this is implemented
       res = builder.createCast(cgf.getLoc(loc), cir::CastKind::floating, res,
                                resTy);
     }
diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp 
b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
index 3170666304a06..298c44d849782 100644
--- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp
@@ -449,13 +449,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
       resultType = cgm.fP16Ty;
       break;
     case BuiltinType::Half:
-      if (astContext.getLangOpts().NativeHalfType ||
-          !astContext.getTargetInfo().useFP16ConversionIntrinsics()) {
-        resultType = cgm.fP16Ty;
-      } else {
-        cgm.errorNYI(SourceLocation(), "processing of built-in type", type);
-        resultType = cgm.sInt32Ty;
-      }
+      resultType = cgm.fP16Ty;
       break;
     case BuiltinType::BFloat16:
       resultType = cgm.bFloat16Ty;
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp 
b/clang/lib/CodeGen/CGExprConstant.cpp
index 7a2b00647f189..27b7423a42f98 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -2598,16 +2598,8 @@ ConstantEmitter::tryEmitPrivate(const APValue &Value, 
QualType DestType,
         llvm::StructType::get(Complex[0]->getType(), Complex[1]->getType());
     return llvm::ConstantStruct::get(STy, Complex);
   }
-  case APValue::Float: {
-    const llvm::APFloat &Init = Value.getFloat();
-    if (&Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
-        !CGM.getContext().getLangOpts().NativeHalfType &&
-        CGM.getContext().getTargetInfo().useFP16ConversionIntrinsics())
-      return llvm::ConstantInt::get(CGM.getLLVMContext(),
-                                    Init.bitcastToAPInt());
-    else
-      return llvm::ConstantFP::get(CGM.getLLVMContext(), Init);
-  }
+  case APValue::Float:
+    return llvm::ConstantFP::get(CGM.getLLVMContext(), Value.getFloat());
   case APValue::ComplexFloat: {
     llvm::Constant *Complex[2];
 
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp 
b/clang/lib/CodeGen/CGExprScalar.cpp
index 18ed6570730f4..6f7b7e7d6840e 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -1690,28 +1690,17 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value 
*Src, QualType SrcType,
   bool OBWrapInvolved =
       (DstOBT && DstOBT->isWrapKind()) || (SrcOBT && SrcOBT->isWrapKind());
 
-  // Cast from half through float if half isn't a native type.
-  if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) 
{
-    // Cast to FP using the intrinsic if the half type itself isn't supported.
-    if (DstTy->isFloatingPointTy()) {
-      if (CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics()) {
-        Value *BitCast = Builder.CreateBitCast(Src, CGF.CGM.HalfTy);
-        return Builder.CreateFPExt(BitCast, DstTy, "conv");
-      }
-    } else {
-      // Cast to other types through float, using either the intrinsic or 
FPExt,
-      // depending on whether the half type itself is supported
-      // (as opposed to operations on half, available with NativeHalfType).
+  // If half isn't a native type, cast to float for evaluation.
+  if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType 
&&
+      SrcTy == CGF.CGM.HalfTy && DstTy != CGF.CGM.HalfTy) {
+    if (DstTy->isFloatingPointTy())
+      return Builder.CreateFPExt(Src, DstTy, "conv");
 
-      if (Src->getType() != CGF.CGM.HalfTy) {
-        assert(CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics());
-        Src = Builder.CreateBitCast(Src, CGF.CGM.HalfTy);
-      }
-
-      Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv");
-      SrcType = CGF.getContext().FloatTy;
-      SrcTy = CGF.FloatTy;
-    }
+    // Cast to other types through float (as opposed to operations on half,
+    // available with NativeHalfType).
+    Src = Builder.CreateFPExt(Src, CGF.CGM.FloatTy, "conv");
+    SrcType = CGF.getContext().FloatTy;
+    SrcTy = CGF.FloatTy;
   }
 
   // Ignore conversions like int -> uint.
@@ -1816,23 +1805,13 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value 
*Src, QualType SrcType,
     EmitFloatConversionCheck(OrigSrc, OrigSrcType, Src, SrcType, DstType, 
DstTy,
                              Loc);
 
-  // Cast to half through float if half isn't a native type.
-  if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) 
{
+  // Cast to half from float if half isn't a native type. When __fp16 isn't
+  // native, arithmetic is evaluated as float.
+  if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType 
&&
+      DstTy == CGF.CGM.HalfTy) {
     // Make sure we cast in a single step if from another FP type.
-    if (SrcTy->isFloatingPointTy()) {
-      // Handle the case where the half type is represented as an integer (as
-      // opposed to operations on half, available with NativeHalfType).
-
-      // If the half type is supported, just use an fptrunc.
-      Value *Res = Builder.CreateFPTrunc(Src, CGF.CGM.HalfTy, "conv");
-      if (DstTy == CGF.CGM.HalfTy)
-        return Res;
-
-      assert(DstTy->isIntegerTy(16) &&
-             CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics() &&
-             "Only half FP requires extra conversion");
-      return Builder.CreateBitCast(Res, DstTy);
-    }
+    if (SrcTy->isFloatingPointTy())
+      return Builder.CreateFPTrunc(Src, CGF.CGM.HalfTy, "conv");
 
     DstTy = CGF.FloatTy;
   }
@@ -1844,7 +1823,6 @@ Value *ScalarExprEmitter::EmitScalarConversion(Value 
*Src, QualType SrcType,
 
     if (ResTy != CGF.CGM.HalfTy) {
       assert(ResTy->isIntegerTy(16) &&
-             CGF.getContext().getTargetInfo().useFP16ConversionIntrinsics() &&
              "Only half FP requires extra conversion");
       Res = Builder.CreateBitCast(Res, ResTy);
     }
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp 
b/clang/lib/CodeGen/CodeGenTypes.cpp
index 3de3bad6affb5..c68a24ca045bc 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -300,14 +300,9 @@ void CodeGenTypes::RefreshTypeCacheForClass(const 
CXXRecordDecl *RD) {
 }
 
 static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,
-                                    const llvm::fltSemantics &format,
-                                    bool UseNativeHalf = false) {
-  if (&format == &llvm::APFloat::IEEEhalf()) {
-    if (UseNativeHalf)
-      return llvm::Type::getHalfTy(VMContext);
-    else
-      return llvm::Type::getInt16Ty(VMContext);
-  }
+                                    const llvm::fltSemantics &format) {
+  if (&format == &llvm::APFloat::IEEEhalf())
+    return llvm::Type::getHalfTy(VMContext);
   if (&format == &llvm::APFloat::BFloat())
     return llvm::Type::getBFloatTy(VMContext);
   if (&format == &llvm::APFloat::IEEEsingle())
@@ -485,16 +480,14 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
 
     case BuiltinType::Float16:
       ResultType =
-          getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T),
-                           /* UseNativeHalf = */ true);
+          getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T));
       break;
 
     case BuiltinType::Half:
-      // Half FP can either be storage-only (lowered to i16) or native.
-      ResultType = getTypeForFormat(
-          getLLVMContext(), Context.getFloatTypeSemantics(T),
-          Context.getLangOpts().NativeHalfType ||
-              !Context.getTargetInfo().useFP16ConversionIntrinsics());
+      // Half FP can either be storage-only (lowered to i16 for ABI purposes) 
or
+      // native.
+      ResultType =
+          getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T));
       break;
     case BuiltinType::LongDouble:
       LongDoubleReferenced = true;
@@ -504,9 +497,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
     case BuiltinType::Double:
     case BuiltinType::Float128:
     case BuiltinType::Ibm128:
-      ResultType = getTypeForFormat(getLLVMContext(),
-                                    Context.getFloatTypeSemantics(T),
-                                    /* UseNativeHalf = */ false);
+      ResultType =
+          getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T));
       break;
 
     case BuiltinType::NullPtr:
diff --git a/clang/lib/CodeGen/TargetBuiltins/NVPTX.cpp 
b/clang/lib/CodeGen/TargetBuiltins/NVPTX.cpp
index 0be166ce7bb38..48b6866147281 100644
--- a/clang/lib/CodeGen/TargetBuiltins/NVPTX.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/NVPTX.cpp
@@ -393,23 +393,8 @@ static Value *MakeCpAsync(unsigned IntrinsicID, unsigned 
IntrinsicIDS,
                                        CGF.EmitScalarExpr(E->getArg(1))});
 }
 
-static bool EnsureNativeHalfSupport(unsigned BuiltinID, const CallExpr *E,
-                                    CodeGenFunction &CGF) {
-  auto &C = CGF.CGM.getContext();
-  if (!C.getLangOpts().NativeHalfType &&
-      C.getTargetInfo().useFP16ConversionIntrinsics()) {
-    CGF.CGM.Error(E->getExprLoc(), C.BuiltinInfo.getQuotedName(BuiltinID) +
-                                       " requires native half type support.");
-    return false;
-  }
-  return true;
-}
-
 static Value *MakeHalfType(Function *Intrinsic, unsigned BuiltinID,
                            const CallExpr *E, CodeGenFunction &CGF) {
-  if (!EnsureNativeHalfSupport(BuiltinID, E, CGF))
-    return nullptr;
-
   SmallVector<Value *, 16> Args;
   auto *FTy = Intrinsic->getFunctionType();
   unsigned ICEArguments = 0;
@@ -1128,13 +1113,10 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned 
BuiltinID,
                                         EmitScalarExpr(E->getArg(0)));
   case NVPTX::BI__nvvm_ldg_h:
   case NVPTX::BI__nvvm_ldg_h2:
-    return EnsureNativeHalfSupport(BuiltinID, E, *this) ? MakeLdg(*this, E)
-                                                        : nullptr;
+    return MakeLdg(*this, E);
   case NVPTX::BI__nvvm_ldu_h:
   case NVPTX::BI__nvvm_ldu_h2:
-    return EnsureNativeHalfSupport(BuiltinID, E, *this)
-               ? MakeLdu(Intrinsic::nvvm_ldu_global_f, *this, E)
-               : nullptr;
+    return MakeLdu(Intrinsic::nvvm_ldu_global_f, *this, E);
   case NVPTX::BI__nvvm_cp_async_ca_shared_global_4:
     return MakeCpAsync(Intrinsic::nvvm_cp_async_ca_shared_global_4,
                        Intrinsic::nvvm_cp_async_ca_shared_global_4_s, *this, E,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 01b1f4c26f017..24fa9055e4f9d 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6416,22 +6416,12 @@ bool Sema::BuiltinFPClassification(CallExpr *TheCall, 
unsigned NumArgs,
   if (OrigArg->isTypeDependent())
     return false;
 
-  // Usual Unary Conversions will convert half to float, which we want for
-  // machines that use fp16 conversion intrinsics. Else, we wnat to leave the
-  // type how it is, but do normal L->Rvalue conversions.
-  if (Context.getTargetInfo().useFP16ConversionIntrinsics()) {
-    ExprResult Res = UsualUnaryConversions(OrigArg);
-
-    if (!Res.isUsable())
-      return true;
-    OrigArg = Res.get();
-  } else {
-    ExprResult Res = DefaultFunctionArrayLvalueConversion(OrigArg);
+  // We want to leave the type how it is, but do normal L->Rvalue conversions.
+  ExprResult Res = DefaultFunctionArrayLvalueConversion(OrigArg);
+  if (!Res.isUsable())
+    return true;
+  OrigArg = Res.get();
 
-    if (!Res.isUsable())
-      return true;
-    OrigArg = Res.get();
-  }
   TheCall->setArg(FPArgNo, OrigArg);
 
   QualType VectorResultTy;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 2e3f242aaff22..256bb598cceb6 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -15528,8 +15528,7 @@ static ExprResult convertHalfVecBinOp(Sema &S, 
ExprResult LHS, ExprResult RHS,
 /// is needed.
 static bool needsConversionOfHalfVec(bool OpRequiresConversion, ASTContext 
&Ctx,
                                      Expr *E0, Expr *E1 = nullptr) {
-  if (!OpRequiresConversion || Ctx.getLangOpts().NativeHalfType ||
-      Ctx.getTargetInfo().useFP16ConversionIntrinsics())
+  if (!OpRequiresConversion || Ctx.getLangOpts().NativeHalfType)
     return false;
 
   auto HasVectorOfHalfType = [&Ctx](Expr *E) {
diff --git a/clang/test/CodeGen/builtin_float.c 
b/clang/test/CodeGen/builtin_float.c
index f79b6bd4ff5e0..1c1ce6195b4be 100644
--- a/clang/test/CodeGen/builtin_float.c
+++ b/clang/test/CodeGen/builtin_float.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-pc -o - %s | FileCheck %s 
--check-prefixes=CHECK,FP16
-// RUN: %clang_cc1 -emit-llvm -triple ppc64-be -o - %s -DNO_FP16 | FileCheck 
%s --check-prefixes=CHECK,NOFP16
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-pc -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple ppc64-be -o - %s -DNO_FP16 | FileCheck %s
 
 // test to ensure that these builtins don't do the variadic promotion of 
float->double.
 void test_floats(float f1, float f2) {
@@ -49,8 +49,7 @@ void test_half(__fp16 *H, __fp16 *H2) {
   // CHECK: fcmp ogt float
   // CHECK-NEXT: zext i1
   (void)__builtin_isinf(*H);
-  // FP16: call i1 @llvm.is.fpclass.f16(half %{{.*}}, i32 516)
-  // NOFP16: call i1 @llvm.is.fpclass.f32(float %{{.*}}, i32 516)
+  // CHECK: call i1 @llvm.is.fpclass.f16(half %{{.*}}, i32 516)
 }
 
 void test_mixed(double d1, float f2) {
diff --git a/clang/test/CodeGen/builtin_float_strictfp.c 
b/clang/test/CodeGen/builtin_float_strictfp.c
index 81bf89228f59c..7966110ddfcd1 100644
--- a/clang/test/CodeGen/builtin_float_strictfp.c
+++ b/clang/test/CodeGen/builtin_float_strictfp.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-pc 
-ffp-exception-behavior=maytrap -o - %s | FileCheck %s 
--check-prefixes=CHECK,FP16
-// RUN: %clang_cc1 -emit-llvm -triple ppc64-be -ffp-exception-behavior=maytrap 
-o - %s | FileCheck %s --check-prefixes=CHECK,NOFP16
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-windows-pc 
-ffp-exception-behavior=maytrap -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -triple ppc64-be -ffp-exception-behavior=maytrap 
-o - %s | FileCheck %s
 
 // test to ensure that these builtins don't do the variadic promotion of 
float->double.
 
@@ -11,8 +11,8 @@
 // CHECK-LABEL: @test_half
 void test_half(__fp16 *H, __fp16 *H2) {
   (void)__builtin_isgreater(*H, *H2);
-  // FP16: call float @llvm.experimental.constrained.fpext.f32.f16(half 
%{{.*}}, metadata !"fpexcept.strict")
-  // FP16: call float @llvm.experimental.constrained.fpext.f32.f16(half 
%{{.*}}, metadata !"fpexcept.strict")
+  // CHECK: call float @llvm.experimental.constrained.fpext.f32.f16(half 
%{{.*}}, metadata !"fpexcept.strict")
+  // CHECK: call float @llvm.experimental.constrained.fpext.f32.f16(half 
%{{.*}}, metadata !"fpexcept.strict")
   // CHECK: call i1 @llvm.experimental.constrained.fcmp.f32(float %{{.*}}, 
float %{{.*}}, metadata !"ogt", metadata !"fpexcept.strict")
   // CHECK-NEXT: zext i1
   (void)__builtin_isinf(*H);
diff --git a/clang/test/CodeGen/wasm-fp16.c b/clang/test/CodeGen/wasm-fp16.c
index 8fa35b975ab97..1649a6396baa7 100644
--- a/clang/test/CodeGen/wasm-fp16.c
+++ b/clang/test/CodeGen/wasm-fp16.c
@@ -4,7 +4,7 @@
 __fp16 g = 2.0f;
 
 //.
-// CHECK: @g = global i16 16384, align 2
+// CHECK: @g = global half 2.000000e+00, align 2
 //.
 // CHECK-LABEL: define float @test_memory_fp16_to_float(
 // CHECK-SAME: ptr noundef [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
@@ -12,9 +12,8 @@ __fp16 g = 2.0f;
 // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6:![0-9]+]]
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
-// CHECK-NEXT:    [[TMP1:%.*]] = load i16, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9:![0-9]+]]
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast i16 [[TMP1]] to half
-// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP2]] to float
+// CHECK-NEXT:    [[TMP1:%.*]] = load half, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9:![0-9]+]]
+// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP1]] to float
 // CHECK-NEXT:    ret float [[CONV]]
 //
 float test_memory_fp16_to_float(__fp16 *ptr) {
@@ -30,9 +29,8 @@ float test_memory_fp16_to_float(__fp16 *ptr) {
 // CHECK-NEXT:    store float [[VAL]], ptr [[VAL_ADDR]], align 4, !tbaa 
[[FLOAT_TBAA11:![0-9]+]]
 // CHECK-NEXT:    [[TMP0:%.*]] = load float, ptr [[VAL_ADDR]], align 4, !tbaa 
[[FLOAT_TBAA11]]
 // CHECK-NEXT:    [[CONV:%.*]] = fptrunc float [[TMP0]] to half
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast half [[CONV]] to i16
-// CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
-// CHECK-NEXT:    store i16 [[TMP1]], ptr [[TMP2]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
+// CHECK-NEXT:    store half [[CONV]], ptr [[TMP1]], align 2, !tbaa 
[[__FP16_TBAA9]]
 // CHECK-NEXT:    ret void
 //
 void test_memory_float_from_fp16(__fp16* ptr, float val) {
@@ -45,15 +43,12 @@ void test_memory_float_from_fp16(__fp16* ptr, float val) {
 // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
-// CHECK-NEXT:    [[TMP1:%.*]] = load i16, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast i16 [[TMP1]] to half
-// CHECK-NEXT:    [[INCDEC_CONV:%.*]] = fpext half [[TMP2]] to float
+// CHECK-NEXT:    [[TMP1:%.*]] = load half, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[INCDEC_CONV:%.*]] = fpext half [[TMP1]] to float
 // CHECK-NEXT:    [[INC:%.*]] = fadd float [[INCDEC_CONV]], 1.000000e+00
 // CHECK-NEXT:    [[INCDEC_CONV1:%.*]] = fptrunc float [[INC]] to half
-// CHECK-NEXT:    [[TMP3:%.*]] = bitcast half [[INCDEC_CONV1]] to i16
-// CHECK-NEXT:    store i16 [[TMP3]], ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16 [[TMP3]] to half
-// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP4]] to float
+// CHECK-NEXT:    store half [[INCDEC_CONV1]], ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[INCDEC_CONV1]] to float
 // CHECK-NEXT:    ret float [[CONV]]
 //
 float test_memory_fp16_preinc(__fp16 *ptr) {
@@ -66,15 +61,12 @@ float test_memory_fp16_preinc(__fp16 *ptr) {
 // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
-// CHECK-NEXT:    [[TMP1:%.*]] = load i16, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast i16 [[TMP1]] to half
-// CHECK-NEXT:    [[INCDEC_CONV:%.*]] = fpext half [[TMP2]] to float
+// CHECK-NEXT:    [[TMP1:%.*]] = load half, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[INCDEC_CONV:%.*]] = fpext half [[TMP1]] to float
 // CHECK-NEXT:    [[INC:%.*]] = fadd float [[INCDEC_CONV]], 1.000000e+00
 // CHECK-NEXT:    [[INCDEC_CONV1:%.*]] = fptrunc float [[INC]] to half
-// CHECK-NEXT:    [[TMP3:%.*]] = bitcast half [[INCDEC_CONV1]] to i16
-// CHECK-NEXT:    store i16 [[TMP3]], ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16 [[TMP1]] to half
-// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP4]] to float
+// CHECK-NEXT:    store half [[INCDEC_CONV1]], ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP1]] to float
 // CHECK-NEXT:    ret float [[CONV]]
 //
 float test_memory_fp16_postinc(__fp16 *ptr) {
@@ -87,15 +79,12 @@ float test_memory_fp16_postinc(__fp16 *ptr) {
 // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
-// CHECK-NEXT:    [[TMP1:%.*]] = load i16, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast i16 [[TMP1]] to half
-// CHECK-NEXT:    [[INCDEC_CONV:%.*]] = fpext half [[TMP2]] to float
+// CHECK-NEXT:    [[TMP1:%.*]] = load half, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[INCDEC_CONV:%.*]] = fpext half [[TMP1]] to float
 // CHECK-NEXT:    [[DEC:%.*]] = fadd float [[INCDEC_CONV]], -1.000000e+00
 // CHECK-NEXT:    [[INCDEC_CONV1:%.*]] = fptrunc float [[DEC]] to half
-// CHECK-NEXT:    [[TMP3:%.*]] = bitcast half [[INCDEC_CONV1]] to i16
-// CHECK-NEXT:    store i16 [[TMP3]], ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16 [[TMP3]] to half
-// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP4]] to float
+// CHECK-NEXT:    store half [[INCDEC_CONV1]], ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[INCDEC_CONV1]] to float
 // CHECK-NEXT:    ret float [[CONV]]
 //
 float test_memory_fp16_predec(__fp16 *ptr) {
@@ -108,36 +97,30 @@ float test_memory_fp16_predec(__fp16 *ptr) {
 // CHECK-NEXT:    [[PTR_ADDR:%.*]] = alloca ptr, align 8
 // CHECK-NEXT:    store ptr [[PTR]], ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
 // CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[PTR_ADDR]], align 8, !tbaa 
[[__FP16PTR_TBAA6]]
-// CHECK-NEXT:    [[TMP1:%.*]] = load i16, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP2:%.*]] = bitcast i16 [[TMP1]] to half
-// CHECK-NEXT:    [[INCDEC_CONV:%.*]] = fpext half [[TMP2]] to float
+// CHECK-NEXT:    [[TMP1:%.*]] = load half, ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[INCDEC_CONV:%.*]] = fpext half [[TMP1]] to float
 // CHECK-NEXT:    [[DEC:%.*]] = fadd float [[INCDEC_CONV]], -1.000000e+00
 // CHECK-NEXT:    [[INCDEC_CONV1:%.*]] = fptrunc float [[DEC]] to half
-// CHECK-NEXT:    [[TMP3:%.*]] = bitcast half [[INCDEC_CONV1]] to i16
-// CHECK-NEXT:    store i16 [[TMP3]], ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP4:%.*]] = bitcast i16 [[TMP1]] to half
-// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP4]] to float
+// CHECK-NEXT:    store half [[INCDEC_CONV1]], ptr [[TMP0]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP1]] to float
 // CHECK-NEXT:    ret float [[CONV]]
 //
 float test_memory_fp16_postdec(__fp16 *ptr) {
   return (*ptr)--;
 }
 
-// CHECK-LABEL: define i16 @test_arg_return(
-// CHECK-SAME: i16 noundef [[X:%.*]]) #[[ATTR0]] {
+// CHECK-LABEL: define half @test_arg_return(
+// CHECK-SAME: half noundef [[X:%.*]]) #[[ATTR0]] {
 // CHECK-NEXT:  [[ENTRY:.*:]]
-// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca i16, align 2
-// CHECK-NEXT:    store i16 [[X]], ptr [[X_ADDR]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP0:%.*]] = load i16, ptr [[X_ADDR]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP1:%.*]] = bitcast i16 [[TMP0]] to half
-// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP1]] to float
-// CHECK-NEXT:    [[TMP2:%.*]] = load i16, ptr [[X_ADDR]], align 2, !tbaa 
[[__FP16_TBAA9]]
-// CHECK-NEXT:    [[TMP3:%.*]] = bitcast i16 [[TMP2]] to half
-// CHECK-NEXT:    [[CONV1:%.*]] = fpext half [[TMP3]] to float
+// CHECK-NEXT:    [[X_ADDR:%.*]] = alloca half, align 2
+// CHECK-NEXT:    store half [[X]], ptr [[X_ADDR]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[TMP0:%.*]] = load half, ptr [[X_ADDR]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[CONV:%.*]] = fpext half [[TMP0]] to float
+// CHECK-NEXT:    [[TMP1:%.*]] = load half, ptr [[X_ADDR]], align 2, !tbaa 
[[__FP16_TBAA9]]
+// CHECK-NEXT:    [[CONV1:%.*]] = fpext half [[TMP1]] to float
 // CHECK-NEXT:    [[ADD:%.*]] = fadd float [[CONV]], [[CONV1]]
 // CHECK-NEXT:    [[CONV2:%.*]] = fptrunc float [[ADD]] to half
-// CHECK-NEXT:    [[TMP4:%.*]] = bitcast half [[CONV2]] to i16
-// CHECK-NEXT:    ret i16 [[TMP4]]
+// CHECK-NEXT:    ret half [[CONV2]]
 //
 __fp16 test_arg_return(__fp16 x) {
     return x + x;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to