diff options
author | Bill Wendling <isanbard@gmail.com> | 2013-12-01 04:32:33 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2013-12-01 04:32:33 +0000 |
commit | 51d85463d5debc70d034c257c60b245591495367 (patch) | |
tree | 515d72af699c3745c99ed921b9c7719d475fed8a /utils | |
parent | 2ec68b410d5e2b711f4aa96bafd6512fbcefafa5 (diff) | |
download | clang-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.cpp | 25 |
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. |