diff options
author | Tim Northover <tnorthover@apple.com> | 2014-02-19 10:37:05 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-02-19 10:37:05 +0000 |
commit | 12670418a3251e33a8b3787185cf4713a5fd2b95 (patch) | |
tree | 4dc198e6b4721651feb99903450175fd4041d5d1 /clang/lib/Sema/SemaChecking.cpp | |
parent | d496355b53fd1daf983c1bc75cafc9a9d673b7a0 (diff) | |
download | bcm5719-llvm-12670418a3251e33a8b3787185cf4713a5fd2b95.tar.gz bcm5719-llvm-12670418a3251e33a8b3787185cf4713a5fd2b95.zip |
ARM & AArch64: merge the semantic checking of NEON intrinsics
There are two kinds of automatically generated tests for NEON intrinsics, both
of which can be merged without adversely affecting users.
1. We check that a valid kind of __builtin_neon_XYZ overload is requested (e.g.
we're not asking for a float32x4_t version when it only accepts integers. Since
the __builtin_neon_XYZ intrinsics should only be used in arm_neon.h, relaxing
this test and permitting AArch64 types for AArch32 should not cause a problem.
The extra arm_neon.h definitions should be #ifdefed out anyway.
2. We check that intrinsics which take immediates are actually given
compile-time constants within range. Since all NEON intrinsics should be
backwards compatible, these tests should be identical on AArch64 and AArch32
anyway.
This patch, therefore, merges the separate AArch64 and 32-bit checks.
rdar://problem/16035743
llvm-svn: 201659
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 77 |
1 files changed, 21 insertions, 56 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index dfacba84efe..cfd042f9459 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -388,24 +388,21 @@ static QualType getNeonEltType(NeonTypeFlags Flags, ASTContext &Context, llvm_unreachable("Invalid NeonTypeFlag!"); } -bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, - CallExpr *TheCall) { - +bool Sema::CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { llvm::APSInt Result; - uint64_t mask = 0; unsigned TV = 0; int PtrArgNum = -1; bool HasConstPtr = false; switch (BuiltinID) { -#define GET_NEON_AARCH64_OVERLOAD_CHECK +#define GET_NEON_OVERLOAD_CHECK #include "clang/Basic/arm_neon.inc" -#undef GET_NEON_AARCH64_OVERLOAD_CHECK +#undef GET_NEON_OVERLOAD_CHECK } // For NEON intrinsics which are overloaded on vector element type, validate // the immediate which specifies which variant to emit. - unsigned ImmArg = TheCall->getNumArgs() - 1; + unsigned ImmArg = TheCall->getNumArgs()-1; if (mask) { if (SemaBuiltinConstantArg(TheCall, ImmArg, Result)) return true; @@ -413,7 +410,7 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, TV = Result.getLimitedValue(64); if ((TV > 63) || (mask & (1ULL << TV)) == 0) return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code) - << TheCall->getArg(ImmArg)->getSourceRange(); + << TheCall->getArg(ImmArg)->getSourceRange(); } if (PtrArgNum >= 0) { @@ -423,7 +420,10 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, Arg = ICE->getSubExpr(); ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); QualType RHSTy = RHS.get()->getType(); - QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, true); + + bool IsAArch64 = + Context.getTargetInfo().getTriple().getArch() == llvm::Triple::aarch64; + QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, IsAArch64); if (HasConstPtr) EltTy = EltTy.withConst(); QualType LHSTy = Context.getPointerType(EltTy); @@ -442,9 +442,9 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, switch (BuiltinID) { default: return false; -#define GET_NEON_AARCH64_IMMEDIATE_CHECK +#define GET_NEON_IMMEDIATE_CHECK #include "clang/Basic/arm_neon.inc" -#undef GET_NEON_AARCH64_IMMEDIATE_CHECK +#undef GET_NEON_IMMEDIATE_CHECK } ; @@ -466,6 +466,14 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, return false; } +bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, + CallExpr *TheCall) { + if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) + return true; + + return false; +} + bool Sema::CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall) { assert((BuiltinID == ARM::BI__builtin_arm_ldrex || BuiltinID == ARM::BI__builtin_arm_strex) && @@ -580,48 +588,8 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { return CheckARMBuiltinExclusiveCall(BuiltinID, TheCall); } - uint64_t mask = 0; - unsigned TV = 0; - int PtrArgNum = -1; - bool HasConstPtr = false; - switch (BuiltinID) { -#define GET_NEON_OVERLOAD_CHECK -#include "clang/Basic/arm_neon.inc" -#undef GET_NEON_OVERLOAD_CHECK - } - - // For NEON intrinsics which are overloaded on vector element type, validate - // the immediate which specifies which variant to emit. - unsigned ImmArg = TheCall->getNumArgs()-1; - if (mask) { - if (SemaBuiltinConstantArg(TheCall, ImmArg, Result)) - return true; - - TV = Result.getLimitedValue(64); - if ((TV > 63) || (mask & (1ULL << TV)) == 0) - return Diag(TheCall->getLocStart(), diag::err_invalid_neon_type_code) - << TheCall->getArg(ImmArg)->getSourceRange(); - } - - if (PtrArgNum >= 0) { - // Check that pointer arguments have the specified type. - Expr *Arg = TheCall->getArg(PtrArgNum); - if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) - Arg = ICE->getSubExpr(); - ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg); - QualType RHSTy = RHS.get()->getType(); - QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context, false); - if (HasConstPtr) - EltTy = EltTy.withConst(); - QualType LHSTy = Context.getPointerType(EltTy); - AssignConvertType ConvTy; - ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS); - if (RHS.isInvalid()) - return true; - if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), LHSTy, RHSTy, - RHS.get(), AA_Assigning)) - return true; - } + if (CheckNeonBuiltinFunctionCall(BuiltinID, TheCall)) + return true; // For NEON intrinsics which take an immediate value as part of the // instruction, range check them here. @@ -634,9 +602,6 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { case ARM::BI__builtin_arm_vcvtr_d: i = 1; u = 1; break; case ARM::BI__builtin_arm_dmb: case ARM::BI__builtin_arm_dsb: l = 0; u = 15; break; -#define GET_NEON_IMMEDIATE_CHECK -#include "clang/Basic/arm_neon.inc" -#undef GET_NEON_IMMEDIATE_CHECK }; // We can't check the value of a dependent argument. |