<div dir="ltr">Hi Oliver,<div><br></div><div>Here comes a small test case reproducing the failure.</div><div><br></div><div><div>$ cat bb.c</div><div>      float32x4_t result;</div><div>      arg1 = vcombine_f16(vcreate_f16(UINT64_C(0x3f0aa8903edf40f8)),</div>
<div>                          vcreate_f16(UINT64_C(0x3f614f463e8b06ca)));</div><div>      result = vreinterpretq_f32_f16(arg1);</div><div>}</div><div>$ clang -O0 -target arm64-linux-gnueabi -c bb.c</div><div>fatal error: error in backend: Cannot select: 0x29bf1f8: v4f32 = bitcast 0x29be608 [ORD=34] [ID=25]</div>
<div>  0x29be608: v8f16 = concat_vectors 0x29be3f8, 0x29bc300 [ORD=27] [ID=24]</div><div>    0x29be3f8: v4f16,ch = load 0x29bded0, 0x29bdfd8, 0x29bb7a8<LD8[%__p0.addr.i6]> [ORD=25] [ID=23]</div><div>      0x29bdfd8: i64 = FrameIndex<2> [ID=8]</div>
<div>      0x29bb7a8: i64 = undef [ID=3]</div><div>    0x29bc300: v4f16 = bitcast 0x29bbee0 [ORD=20] [ID=17]</div><div>      0x29bbee0: i64 = Constant<4567018660245997258> [ID=5]</div><div>In function: dotests_2970</div>
<div>clang-3.5: error: clang frontend command failed with exit code 70 (use -v to see invocation)</div><div>clang version 3.6.0 (216557)</div><div>Target: arm64--linux-gnueabi</div><div>Thread model: posix</div><div>clang-3.5: note: diagnostic msg: PLEASE submit a bug report to <a href="http://llvm.org/bugs/">http://llvm.org/bugs/</a> and include the crash backtrace, preprocessed source, and associated run script.</div>
<div>clang-3.5: note: diagnostic msg: </div><div>********************</div><div><br></div><div>PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:</div><div>Preprocessed source(s) and associated run script(s) are located at:</div>
<div>clang-3.5: note: diagnostic msg: /tmp/bb-a66a58.c</div><div>clang-3.5: note: diagnostic msg: /tmp/bb-a66a58.sh</div><div>clang-3.5: note: diagnostic msg: </div><div><br></div><div>********************</div></div><div>
<br></div><div>Thanks,</div><div>-Jiangning</div><div><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-08-28 12:53 GMT+08:00 Jiangning Liu <span dir="ltr"><<a href="mailto:liujiangning1@gmail.com" target="_blank">liujiangning1@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">This commit triggered assertion failure<br><br>fatal error: error in backend: Cannot select: 0xd785e58: v4f32 = bitcast 0xcca5910 [ORD=59] [ID=45]<br>
  0xcca5910: v8f16,ch = load 0xc1d09d0, 0xbfff270, 0xc1be168<LD16[%arg1]> [ORD=56] [ID=44]<br>
    0xbfff270: i64 = FrameIndex<9> [ID=15]<br>    0xc1be168: i64 = undef [ID=3]<br>In function: dotests_2970<br>clang-3.6: error: clang frontend command failed with exit code 70 (use -v to see invocation)<br>clang version 3.6.0 (216641)<br>

Target: arm64--linux-gnueabi<br>Thread model: posix<br>clang-3.6: note: diagnostic msg: PLEASE submit a bug report to <a href="http://llvm.org/bugs/" target="_blank">http://llvm.org/bugs/</a> and include the crash backtrace, preprocessed source, and associated run script.<br>

<br>And this is blocking our regression test.<br><br>Thanks,<br>-Jiangning</div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-08-28 0:31 GMT+08:00 Oliver Stannard <span dir="ltr"><<a href="mailto:oliver.stannard@arm.com" target="_blank">oliver.stannard@arm.com</a>></span>:<div>
<div class="h5"><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: olista01<br>
Date: Wed Aug 27 11:31:57 2014<br>
New Revision: 216558<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=216558&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=216558&view=rev</a><br>
Log:<br>
Allow __fp16 as a function arg or return type for AArch64<br>
<br>
ACLE 2.0 allows __fp16 to be used as a function argument or return<br>
type. This enables this for AArch64.<br>
<br>
This also fixes an existing bug that causes clang to not allow<br>
homogeneous floating-point aggregates with a base type of __fp16. This<br>
is valid for AAPCS64, but not for AAPCS-VFP.<br>
<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/LangOptions.def<br>
    cfe/trunk/include/clang/Driver/CC1Options.td<br>
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br>
    cfe/trunk/lib/CodeGen/CGExprScalar.cpp<br>
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp<br>
    cfe/trunk/lib/CodeGen/TargetInfo.cpp<br>
    cfe/trunk/lib/Driver/Tools.cpp<br>
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
    cfe/trunk/lib/Sema/SemaType.cpp<br>
    cfe/trunk/test/CodeGen/arm64-aapcs-arguments.c<br>
<br>
Modified: cfe/trunk/include/clang/Basic/LangOptions.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.def?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Basic/LangOptions.def (original)<br>
+++ cfe/trunk/include/clang/Basic/LangOptions.def Wed Aug 27 11:31:57 2014<br>
@@ -128,6 +128,7 @@ LANGOPT(ShortEnums        , 1, 0, "short<br>
 LANGOPT(OpenCL            , 1, 0, "OpenCL")<br>
 LANGOPT(OpenCLVersion     , 32, 0, "OpenCL version")<br>
 LANGOPT(NativeHalfType    , 1, 0, "Native half type support")<br>
+LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns")<br>
 LANGOPT(CUDA              , 1, 0, "CUDA")<br>
 LANGOPT(OpenMP            , 1, 0, "OpenMP support")<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Driver/CC1Options.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)<br>
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Aug 27 11:31:57 2014<br>
@@ -511,6 +511,8 @@ def vtordisp_mode_EQ : Joined<["-"], "vt<br>
   HelpText<"Control vtordisp placement on win32 targets">;<br>
 def fno_rtti_data : Flag<["-"], "fno-rtti-data">,<br>
   HelpText<"Control emission of RTTI data">;<br>
+def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">,<br>
+  HelpText<"Allow function arguments and returns of type half">;<br>
<br>
 //===----------------------------------------------------------------------===//<br>
 // Header Search Options<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Wed Aug 27 11:31:57 2014<br>
@@ -1132,7 +1132,8 @@ llvm::Constant *CodeGenModule::EmitConst<br>
   case APValue::Float: {<br>
     const llvm::APFloat &Init = Value.getFloat();<br>
     if (&Init.getSemantics() == &llvm::APFloat::IEEEhalf &&<br>
-         !Context.getLangOpts().NativeHalfType)<br>
+        !Context.getLangOpts().NativeHalfType &&<br>
+        !Context.getLangOpts().HalfArgsAndReturns)<br>
       return llvm::ConstantInt::get(VMContext, Init.bitcastToAPInt());<br>
     else<br>
       return llvm::ConstantFP::get(VMContext, Init);<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Wed Aug 27 11:31:57 2014<br>
@@ -701,7 +701,8 @@ Value *ScalarExprEmitter::EmitScalarConv<br>
   llvm::Type *SrcTy = Src->getType();<br>
<br>
   // If casting to/from storage-only half FP, use special intrinsics.<br>
-  if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {<br>
+  if (SrcType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType &&<br>
+      !CGF.getContext().getLangOpts().HalfArgsAndReturns) {<br>
     Src = Builder.CreateCall(<br>
         CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,<br>
                              CGF.CGM.FloatTy),<br>
@@ -773,7 +774,8 @@ Value *ScalarExprEmitter::EmitScalarConv<br>
                              DstTy);<br>
<br>
   // Cast to half via float<br>
-  if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType)<br>
+  if (DstType->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType &&<br>
+      !CGF.getContext().getLangOpts().HalfArgsAndReturns)<br>
     DstTy = CGF.FloatTy;<br>
<br>
   if (isa<llvm::IntegerType>(SrcTy)) {<br>
@@ -1691,7 +1693,8 @@ ScalarExprEmitter::EmitScalarPrePostIncD<br>
     // Add the inc/dec to the real part.<br>
     llvm::Value *amt;<br>
<br>
-    if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType) {<br>
+    if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType &&<br>
+        !CGF.getContext().getLangOpts().HalfArgsAndReturns) {<br>
       // Another special case: half FP increment should be done via float<br>
       value = Builder.CreateCall(<br>
           CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_from_fp16,<br>
@@ -1714,7 +1717,8 @@ ScalarExprEmitter::EmitScalarPrePostIncD<br>
     }<br>
     value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec");<br>
<br>
-    if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType)<br>
+    if (type->isHalfType() && !CGF.getContext().getLangOpts().NativeHalfType &&<br>
+        !CGF.getContext().getLangOpts().HalfArgsAndReturns)<br>
       value = Builder.CreateCall(<br>
           CGF.CGM.getIntrinsic(llvm::Intrinsic::convert_to_fp16,<br>
                                CGF.CGM.FloatTy),<br>
<br>
Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Wed Aug 27 11:31:57 2014<br>
@@ -358,9 +358,10 @@ llvm::Type *CodeGenTypes::ConvertType(Qu<br>
<br>
     case BuiltinType::Half:<br>
       // Half FP can either be storage-only (lowered to i16) or native.<br>
-      ResultType = getTypeForFormat(getLLVMContext(),<br>
-          Context.getFloatTypeSemantics(T),<br>
-          Context.getLangOpts().NativeHalfType);<br>
+      ResultType =<br>
+          getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T),<br>
+                           Context.getLangOpts().NativeHalfType ||<br>
+                               Context.getLangOpts().HalfArgsAndReturns);<br>
       break;<br>
     case BuiltinType::Float:<br>
     case BuiltinType::Double:<br>
<br>
Modified: cfe/trunk/lib/CodeGen/TargetInfo.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/TargetInfo.cpp?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/CodeGen/TargetInfo.cpp (original)<br>
+++ cfe/trunk/lib/CodeGen/TargetInfo.cpp Wed Aug 27 11:31:57 2014<br>
@@ -3544,8 +3544,9 @@ public:<br>
 };<br>
 }<br>
<br>
-static bool isHomogeneousAggregate(QualType Ty, const Type *&Base,<br>
+static bool isARMHomogeneousAggregate(QualType Ty, const Type *&Base,<br>
                                    ASTContext &Context,<br>
+                                   bool isAArch64,<br>
                                    uint64_t *HAMembers = nullptr);<br>
<br>
 ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty,<br>
@@ -3627,7 +3628,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgum<br>
   // Homogeneous Floating-point Aggregates (HFAs) need to be expanded.<br>
   const Type *Base = nullptr;<br>
   uint64_t Members = 0;<br>
-  if (isHomogeneousAggregate(Ty, Base, getContext(), &Members)) {<br>
+  if (isARMHomogeneousAggregate(Ty, Base, getContext(), true, &Members)) {<br>
     IsHA = true;<br>
     if (!IsNamedArg && isDarwinPCS()) {<br>
       // With the Darwin ABI, variadic arguments are always passed on the stack<br>
@@ -3685,7 +3686,7 @@ ABIArgInfo AArch64ABIInfo::classifyRetur<br>
     return ABIArgInfo::getIgnore();<br>
<br>
   const Type *Base = nullptr;<br>
-  if (isHomogeneousAggregate(RetTy, Base, getContext()))<br>
+  if (isARMHomogeneousAggregate(RetTy, Base, getContext(), true))<br>
     // Homogeneous Floating-point Aggregates (HFAs) are returned directly.<br>
     return ABIArgInfo::getDirect();<br>
<br>
@@ -3822,7 +3823,7 @@ static llvm::Value *EmitAArch64VAArg(llv<br>
<br>
   const Type *Base = nullptr;<br>
   uint64_t NumMembers;<br>
-  bool IsHFA = isHomogeneousAggregate(Ty, Base, Ctx, &NumMembers);<br>
+  bool IsHFA = isARMHomogeneousAggregate(Ty, Base, Ctx, true, &NumMembers);<br>
   if (IsHFA && NumMembers > 1) {<br>
     // Homogeneous aggregates passed in registers will have their elements split<br>
     // and stored 16-bytes apart regardless of size (they're notionally in qN,<br>
@@ -3965,7 +3966,7 @@ llvm::Value *AArch64ABIInfo::EmitDarwinV<br>
   uint64_t Align = CGF.getContext().getTypeAlign(Ty) / 8;<br>
<br>
   const Type *Base = nullptr;<br>
-  bool isHA = isHomogeneousAggregate(Ty, Base, getContext());<br>
+  bool isHA = isARMHomogeneousAggregate(Ty, Base, getContext(), true);<br>
<br>
   bool isIndirect = false;<br>
   // Arguments bigger than 16 bytes which aren't homogeneous aggregates should<br>
@@ -4251,15 +4252,16 @@ void ARMABIInfo::setRuntimeCC() {<br>
     RuntimeCC = abiCC;<br>
 }<br>
<br>
-/// isHomogeneousAggregate - Return true if a type is an AAPCS-VFP homogeneous<br>
+/// isARMHomogeneousAggregate - Return true if a type is an AAPCS-VFP homogeneous<br>
 /// aggregate.  If HAMembers is non-null, the number of base elements<br>
 /// contained in the type is returned through it; this is used for the<br>
 /// recursive calls that check aggregate component types.<br>
-static bool isHomogeneousAggregate(QualType Ty, const Type *&Base,<br>
-                                   ASTContext &Context, uint64_t *HAMembers) {<br>
+static bool isARMHomogeneousAggregate(QualType Ty, const Type *&Base,<br>
+                                   ASTContext &Context, bool isAArch64,<br>
+                                   uint64_t *HAMembers) {<br>
   uint64_t Members = 0;<br>
   if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {<br>
-    if (!isHomogeneousAggregate(AT->getElementType(), Base, Context, &Members))<br>
+    if (!isARMHomogeneousAggregate(AT->getElementType(), Base, Context, isAArch64, &Members))<br>
       return false;<br>
     Members *= AT->getSize().getZExtValue();<br>
   } else if (const RecordType *RT = Ty->getAs<RecordType>()) {<br>
@@ -4270,7 +4272,7 @@ static bool isHomogeneousAggregate(QualT<br>
     Members = 0;<br>
     for (const auto *FD : RD->fields()) {<br>
       uint64_t FldMembers;<br>
-      if (!isHomogeneousAggregate(FD->getType(), Base, Context, &FldMembers))<br>
+      if (!isARMHomogeneousAggregate(FD->getType(), Base, Context, isAArch64, &FldMembers))<br>
         return false;<br>
<br>
       Members = (RD->isUnion() ?<br>
@@ -4284,12 +4286,22 @@ static bool isHomogeneousAggregate(QualT<br>
     }<br>
<br>
     // Homogeneous aggregates for AAPCS-VFP must have base types of float,<br>
-    // double, or 64-bit or 128-bit vectors.<br>
+    // double, or 64-bit or 128-bit vectors. "long double" has the same machine<br>
+    // type as double, so it is also allowed as a base type.<br>
+    // Homogeneous aggregates for AAPCS64 must have base types of a floating<br>
+    // point type or a short-vector type. This is the same as the 32-bit ABI,<br>
+    // but with the difference that any floating-point type is allowed,<br>
+    // including __fp16.<br>
     if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) {<br>
-      if (BT->getKind() != BuiltinType::Float &&<br>
-          BT->getKind() != BuiltinType::Double &&<br>
-          BT->getKind() != BuiltinType::LongDouble)<br>
-        return false;<br>
+      if (isAArch64) {<br>
+        if (!BT->isFloatingPoint())<br>
+          return false;<br>
+      } else {<br>
+        if (BT->getKind() != BuiltinType::Float &&<br>
+            BT->getKind() != BuiltinType::Double &&<br>
+            BT->getKind() != BuiltinType::LongDouble)<br>
+          return false;<br>
+      }<br>
     } else if (const VectorType *VT = Ty->getAs<VectorType>()) {<br>
       unsigned VecSize = Context.getTypeSize(VT);<br>
       if (VecSize != 64 && VecSize != 128)<br>
@@ -4491,7 +4503,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentT<br>
     // into VFP registers.<br>
     const Type *Base = nullptr;<br>
     uint64_t Members = 0;<br>
-    if (isHomogeneousAggregate(Ty, Base, getContext(), &Members)) {<br>
+    if (isARMHomogeneousAggregate(Ty, Base, getContext(), false, &Members)) {<br>
       assert(Base && "Base class should be set for homogeneous aggregate");<br>
       // Base can be a floating-point or a vector.<br>
       if (Base->isVectorType()) {<br>
@@ -4696,7 +4708,7 @@ ABIArgInfo ARMABIInfo::classifyReturnTyp<br>
   // Check for homogeneous aggregates with AAPCS-VFP.<br>
   if (getABIKind() == AAPCS_VFP && !isVariadic) {<br>
     const Type *Base = nullptr;<br>
-    if (isHomogeneousAggregate(RetTy, Base, getContext())) {<br>
+    if (isARMHomogeneousAggregate(RetTy, Base, getContext(), false)) {<br>
       assert(Base && "Base class should be set for homogeneous aggregate");<br>
       // Homogeneous Aggregates are returned directly.<br>
       return ABIArgInfo::getDirect(nullptr, 0, nullptr, !isAAPCS_VFP);<br>
<br>
Modified: cfe/trunk/lib/Driver/Tools.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Driver/Tools.cpp (original)<br>
+++ cfe/trunk/lib/Driver/Tools.cpp Wed Aug 27 11:31:57 2014<br>
@@ -3714,6 +3714,10 @@ void Clang::ConstructJob(Compilation &C,<br>
     CmdArgs.push_back(Args.MakeArgString("-mstack-alignment=" + alignment));<br>
   }<br>
<br>
+  if (getToolChain().getTriple().getArch() == llvm::Triple::aarch64 ||<br>
+      getToolChain().getTriple().getArch() == llvm::Triple::aarch64_be)<br>
+    CmdArgs.push_back("-fallow-half-arguments-and-returns");<br>
+<br>
   if (Arg *A = Args.getLastArg(options::OPT_mrestrict_it,<br>
                                options::OPT_mno_restrict_it)) {<br>
     if (A->getOption().matches(options::OPT_mrestrict_it)) {<br>
<br>
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Aug 27 11:31:57 2014<br>
@@ -1500,6 +1500,8 @@ static void ParseLangArgs(LangOptions &O<br>
   Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name);<br>
   Opts.ImplementationOfModule =<br>
       Args.getLastArgValue(OPT_fmodule_implementation_of);<br>
+  Opts.NativeHalfType = Opts.NativeHalfType;<br>
+  Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns);<br>
<br>
   if (!Opts.CurrentModule.empty() && !Opts.ImplementationOfModule.empty() &&<br>
       Opts.CurrentModule != Opts.ImplementationOfModule) {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaType.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaType.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaType.cpp Wed Aug 27 11:31:57 2014<br>
@@ -1746,7 +1746,7 @@ bool Sema::CheckFunctionReturnType(QualT<br>
   }<br>
<br>
   // Functions cannot return half FP.<br>
-  if (T->isHalfType()) {<br>
+  if (T->isHalfType() && !getLangOpts().HalfArgsAndReturns) {<br>
     Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 1 <<<br>
       FixItHint::CreateInsertion(Loc, "*");<br>
     return true;<br>
@@ -1776,7 +1776,7 @@ QualType Sema::BuildFunctionType(QualTyp<br>
     if (ParamType->isVoidType()) {<br>
       Diag(Loc, diag::err_param_with_void_type);<br>
       Invalid = true;<br>
-    } else if (ParamType->isHalfType()) {<br>
+    } else if (ParamType->isHalfType() && !getLangOpts().HalfArgsAndReturns) {<br>
       // Disallow half FP arguments.<br>
       Diag(Loc, diag::err_parameters_retval_cannot_have_fp16_type) << 0 <<<br>
         FixItHint::CreateInsertion(Loc, "*");<br>
@@ -2751,7 +2751,7 @@ static TypeSourceInfo *GetFullTypeForDec<br>
             S.Diag(D.getIdentifierLoc(), diag::err_opencl_half_return) << T;<br>
             D.setInvalidType(true);<br>
           }<br>
-        } else {<br>
+        } else if (!S.getLangOpts().HalfArgsAndReturns) {<br>
           S.Diag(D.getIdentifierLoc(),<br>
             diag::err_parameters_retval_cannot_have_fp16_type) << 1;<br>
           D.setInvalidType(true);<br>
@@ -2941,7 +2941,7 @@ static TypeSourceInfo *GetFullTypeForDec<br>
                 D.setInvalidType();<br>
                 Param->setInvalidDecl();<br>
               }<br>
-            } else {<br>
+            } else if (!S.getLangOpts().HalfArgsAndReturns) {<br>
               S.Diag(Param->getLocation(),<br>
                 diag::err_parameters_retval_cannot_have_fp16_type) << 0;<br>
               D.setInvalidType();<br>
<br>
Modified: cfe/trunk/test/CodeGen/arm64-aapcs-arguments.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm64-aapcs-arguments.c?rev=216558&r1=216557&r2=216558&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/arm64-aapcs-arguments.c?rev=216558&r1=216557&r2=216558&view=diff</a><br>


==============================================================================<br>
--- cfe/trunk/test/CodeGen/arm64-aapcs-arguments.c (original)<br>
+++ cfe/trunk/test/CodeGen/arm64-aapcs-arguments.c Wed Aug 27 11:31:57 2014<br>
@@ -1,4 +1,4 @@<br>
-// RUN: %clang_cc1 -triple arm64-linux-gnu -target-feature +neon -target-abi aapcs -ffreestanding -emit-llvm -w -o - %s | FileCheck %s<br>
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -target-feature +neon -target-abi aapcs -ffreestanding -fallow-half-arguments-and-returns -emit-llvm -w -o - %s | FileCheck %s<br>
<br>
 // AAPCS clause C.8 says: If the argument has an alignment of 16 then the NGRN<br>
 // is rounded up to the next even number.<br>
@@ -40,3 +40,12 @@ void test4(BigHFA v0_v2, BigHFA v3_v5, B<br>
 // CHECK: define i8 @test5(i8 %a, i16 %b)<br>
 unsigned char test5(unsigned char a, signed short b) {<br>
 }<br>
+<br>
+// __fp16 can be used as a function argument or return type (ACLE 2.0)<br>
+// CHECK: define half @test_half(half %{{.*}})<br>
+__fp16 test_half(__fp16 A) { }<br>
+<br>
+// __fp16 is a base type for homogeneous floating-point aggregates for AArch64 (but not 32-bit ARM).<br>
+// CHECK: define %struct.HFA_half @test_half_hfa(half %{{.*}}, half %{{.*}}, half %{{.*}}, half %{{.*}})<br>
+struct HFA_half { __fp16 a[4]; };<br>
+struct HFA_half test_half_hfa(struct HFA_half A) { }<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu" target="_blank">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div></div></div><br></div>
</blockquote></div><br></div>