summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2011-11-16 21:32:23 +0000
committerBob Wilson <bob.wilson@apple.com>2011-11-16 21:32:23 +0000
commit4648255cebd2fc7c18293c1f93afd6e9add9cccc (patch)
treec43629d138762bef6ee52f84c3a8ca17b529a48b
parente42a0ab77ca4ad5201591aac5679ef47a08af4b6 (diff)
Fix Neon builtin pointer argument checking for "sret" builtins.
The code for checking Neon builtin pointer argument types was assuming that there would only be one pointer argument. But, for vld2-4 builtins, the first argument is a special sret pointer where the result will be stored. So, instead of scanning all the arguments to find a pointer, have TableGen figure out the index of the pointer argument that needs checking. That's better than scanning all the arguments regardless. <rdar://problem/10448804> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144834 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaChecking.cpp40
-rw-r--r--utils/TableGen/NeonEmitter.cpp30
2 files changed, 42 insertions, 28 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index f4968f697a..760b5f33b2 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -298,7 +298,7 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
unsigned mask = 0;
unsigned TV = 0;
- bool HasPtr = false;
+ int PtrArgNum = -1;
bool HasConstPtr = false;
switch (BuiltinID) {
#define GET_NEON_OVERLOAD_CHECK
@@ -319,28 +319,24 @@ bool Sema::CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
<< TheCall->getArg(ImmArg)->getSourceRange();
}
- if (HasPtr || HasConstPtr) {
+ if (PtrArgNum >= 0) {
// Check that pointer arguments have the specified type.
- for (unsigned ArgNo = 0; ArgNo < ImmArg; ++ArgNo) {
- Expr *Arg = TheCall->getArg(ArgNo);
- if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg))
- Arg = ICE->getSubExpr();
- ExprResult RHS = DefaultFunctionArrayLvalueConversion(Arg);
- QualType RHSTy = RHS.get()->getType();
- if (!RHSTy->isPointerType())
- continue;
- QualType EltTy = getNeonEltType(NeonTypeFlags(TV), Context);
- 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;
- }
+ 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);
+ 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;
}
// For NEON intrinsics which take an immediate value as part of the
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index fec16b957e..589fbde771 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -1336,14 +1336,32 @@ void NeonEmitter::runHeader(raw_ostream &OS) {
mask |= 1 << GetNeonEnum(Proto, TypeVec[ti]);
}
}
- bool HasPtr = (Proto.find('p') != std::string::npos);
- bool HasConstPtr = (Proto.find('c') != std::string::npos);
+
+ // Check if the builtin function has a pointer or const pointer argument.
+ int PtrArgNum = -1;
+ bool HasConstPtr = false;
+ for (unsigned arg = 1, arge = Proto.size(); arg != arge; ++arg) {
+ char ArgType = Proto[arg];
+ if (ArgType == 'c') {
+ HasConstPtr = true;
+ PtrArgNum = arg - 1;
+ break;
+ }
+ if (ArgType == 'p') {
+ PtrArgNum = arg - 1;
+ break;
+ }
+ }
+ // For sret builtins, adjust the pointer argument index.
+ if (PtrArgNum >= 0 && (Proto[0] >= '2' && Proto[0] <= '4'))
+ PtrArgNum += 1;
+
if (mask) {
OS << "case ARM::BI__builtin_neon_"
<< MangleName(name, TypeVec[si], ClassB)
<< ": mask = " << "0x" << utohexstr(mask);
- if (HasPtr)
- OS << "; HasPtr = true";
+ if (PtrArgNum >= 0)
+ OS << "; PtrArgNum = " << PtrArgNum;
if (HasConstPtr)
OS << "; HasConstPtr = true";
OS << "; break;\n";
@@ -1352,8 +1370,8 @@ void NeonEmitter::runHeader(raw_ostream &OS) {
OS << "case ARM::BI__builtin_neon_"
<< MangleName(name, TypeVec[qi], ClassB)
<< ": mask = " << "0x" << utohexstr(qmask);
- if (HasPtr)
- OS << "; HasPtr = true";
+ if (PtrArgNum >= 0)
+ OS << "; PtrArgNum = " << PtrArgNum;
if (HasConstPtr)
OS << "; HasConstPtr = true";
OS << "; break;\n";