summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2013-12-01 04:32:33 +0000
committerBill Wendling <isanbard@gmail.com>2013-12-01 04:32:33 +0000
commit51d85463d5debc70d034c257c60b245591495367 (patch)
tree515d72af699c3745c99ed921b9c7719d475fed8a /utils
parent2ec68b410d5e2b711f4aa96bafd6512fbcefafa5 (diff)
downloadclang-51d85463d5debc70d034c257c60b245591495367.tar.gz
clang-51d85463d5debc70d034c257c60b245591495367.tar.bz2
clang-51d85463d5debc70d034c257c60b245591495367.tar.xz
Merging r195844:
------------------------------------------------------------------------ r195844 | jiangning | 2013-11-27 06:02:55 -0800 (Wed, 27 Nov 2013) | 2 lines Fix the AArch64 NEON bug exposed by checking constant integer argument range of ACLE intrinsics. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_34@196012 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'utils')
-rw-r--r--utils/TableGen/NeonEmitter.cpp25
1 files changed, 16 insertions, 9 deletions
diff --git a/utils/TableGen/NeonEmitter.cpp b/utils/TableGen/NeonEmitter.cpp
index 2762ecb438..f672c39888 100644
--- a/utils/TableGen/NeonEmitter.cpp
+++ b/utils/TableGen/NeonEmitter.cpp
@@ -2210,10 +2210,17 @@ static unsigned GetNeonEnum(const std::string &proto, StringRef typestr) {
return Flags.getFlags();
}
+// We don't check 'a' in this function, because for builtin function the
+// argument matching to 'a' uses a vector type splatted from a scalar type.
static bool ProtoHasScalar(const std::string proto)
{
return (proto.find('s') != std::string::npos
- || proto.find('r') != std::string::npos);
+ || proto.find('z') != std::string::npos
+ || proto.find('r') != std::string::npos
+ || proto.find('b') != std::string::npos
+ || proto.find('$') != std::string::npos
+ || proto.find('y') != std::string::npos
+ || proto.find('o') != std::string::npos);
}
// Generate the definition for this intrinsic, e.g. __builtin_neon_cls(a)
@@ -2783,6 +2790,8 @@ NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
PrintFatalError(R->getLoc(), "Builtin has no class kind");
ClassKind ck = ClassMap[R->getSuperClasses()[1]];
+ if (!ProtoHasScalar(Proto))
+ ck = ClassB;
// Do not include AArch64 range checks if not generating code for AArch64.
bool isA64 = R->getValueAsBit("isA64");
@@ -2821,17 +2830,15 @@ NeonEmitter::genIntrinsicRangeCheckCode(raw_ostream &OS,
rangestr += "u = " +
utostr(RangeScalarShiftImm(Proto[immPos - 1], TypeVec[ti]));
- } else if (!ProtoHasScalar(Proto)) {
+ } else if (R->getValueAsBit("isShift")) {
// Builtins which are overloaded by type will need to have their upper
// bound computed at Sema time based on the type constant.
- ck = ClassB;
- if (R->getValueAsBit("isShift")) {
- shiftstr = ", true";
+ shiftstr = ", true";
+
+ // Right shifts have an 'r' in the name, left shifts do not.
+ if (name.find('r') != std::string::npos)
+ rangestr = "l = 1; ";
- // Right shifts have an 'r' in the name, left shifts do not.
- if (name.find('r') != std::string::npos)
- rangestr = "l = 1; ";
- }
rangestr += "u = RFT(TV" + shiftstr + ")";
} else {
// The immediate generally refers to a lane in the preceding argument.