aboutsummaryrefslogtreecommitdiffstats
path: root/lib/VMCore
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/AutoUpgrade.cpp26
-rw-r--r--lib/VMCore/Function.cpp9
-rw-r--r--lib/VMCore/Verifier.cpp32
3 files changed, 52 insertions, 15 deletions
diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp
index a48fbd2..221dc06 100644
--- a/lib/VMCore/AutoUpgrade.cpp
+++ b/lib/VMCore/AutoUpgrade.cpp
@@ -40,24 +40,38 @@ static bool UpgradeIntrinsicFunction1(Function *F, Function *&NewFn) {
switch (Name[5]) {
default: break;
case 'a':
- // This upgrades the llvm.atomic.lcs, llvm.atomic.las, and llvm.atomic.lss
- // to their new function name
- if (Name.compare(5,8,"atomic.l",8) == 0) {
+ // This upgrades the llvm.atomic.lcs, llvm.atomic.las, llvm.atomic.lss,
+ // and atomics with default address spaces to their new names to their new
+ // function name (e.g. llvm.atomic.add.i32 => llvm.atomic.add.i32.p0i32)
+ if (Name.compare(5,7,"atomic.",7) == 0) {
if (Name.compare(12,3,"lcs",3) == 0) {
std::string::size_type delim = Name.find('.',12);
- F->setName("llvm.atomic.cmp.swap"+Name.substr(delim));
+ F->setName("llvm.atomic.cmp.swap" + Name.substr(delim) +
+ ".p0" + Name.substr(delim+1));
NewFn = F;
return true;
}
else if (Name.compare(12,3,"las",3) == 0) {
std::string::size_type delim = Name.find('.',12);
- F->setName("llvm.atomic.load.add"+Name.substr(delim));
+ F->setName("llvm.atomic.load.add"+Name.substr(delim)
+ + ".p0" + Name.substr(delim+1));
NewFn = F;
return true;
}
else if (Name.compare(12,3,"lss",3) == 0) {
std::string::size_type delim = Name.find('.',12);
- F->setName("llvm.atomic.load.sub"+Name.substr(delim));
+ F->setName("llvm.atomic.load.sub"+Name.substr(delim)
+ + ".p0" + Name.substr(delim+1));
+ NewFn = F;
+ return true;
+ }
+ else if (Name.rfind(".p") == std::string::npos) {
+ // We don't have an address space qualifier so this has be upgraded
+ // to the new name. Copy the type name at the end of the intrinsic
+ // and add to it
+ std::string::size_type delim = Name.find_last_of('.');
+ assert(delim != std::string::npos && "can not find type");
+ F->setName(Name + ".p0" + Name.substr(delim+1));
NewFn = F;
return true;
}
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index 1b4e39f..f819a18 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -328,9 +328,14 @@ std::string Intrinsic::getName(ID id, const Type **Tys, unsigned numTys) {
if (numTys == 0)
return Table[id];
std::string Result(Table[id]);
- for (unsigned i = 0; i < numTys; ++i)
- if (Tys[i])
+ for (unsigned i = 0; i < numTys; ++i) {
+ if (const PointerType* PTyp = dyn_cast<PointerType>(Tys[i])) {
+ Result += ".p" + llvm::utostr(PTyp->getAddressSpace()) +
+ MVT::getMVT(PTyp->getElementType()).getMVTString();
+ }
+ else if (Tys[i])
Result += "." + MVT::getMVT(Tys[i]).getMVTString();
+ }
return Result;
}
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 96f2076..00a5870 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -1327,7 +1327,6 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID,
unsigned Count, ...) {
va_list VA;
va_start(VA, Count);
-
const FunctionType *FTy = F->getFunctionType();
// For overloaded intrinsics, the Suffix of the function name must match the
@@ -1423,6 +1422,21 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID,
else
CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is not a "
"pointer and a pointer is required.", F);
+ }
+ } else if (VT == MVT::iPTRAny) {
+ // Outside of TableGen, we don't distinguish iPTRAny (to any address
+ // space) and iPTR. In the verifier, we can not distinguish which case
+ // we have so allow either case to be legal.
+ if (const PointerType* PTyp = dyn_cast<PointerType>(Ty)) {
+ Suffix += ".p" + utostr(PTyp->getAddressSpace()) +
+ MVT::getMVT(PTyp->getElementType()).getMVTString();
+ } else {
+ if (ArgNo == 0)
+ CheckFailed("Intrinsic result type is not a "
+ "pointer and a pointer is required.", F);
+ else
+ CheckFailed("Intrinsic parameter #" + utostr(ArgNo-1) + " is not a "
+ "pointer and a pointer is required.", F);
break;
}
} else if (MVT((MVT::SimpleValueType)VT).isVector()) {
@@ -1456,17 +1470,21 @@ void Verifier::VerifyIntrinsicPrototype(Intrinsic::ID ID,
va_end(VA);
- // If we computed a Suffix then the intrinsic is overloaded and we need to
- // make sure that the name of the function is correct. We add the suffix to
- // the name of the intrinsic and compare against the given function name. If
- // they are not the same, the function name is invalid. This ensures that
- // overloading of intrinsics uses a sane and consistent naming convention.
+ // For intrinsics without pointer arguments, if we computed a Suffix then the
+ // intrinsic is overloaded and we need to make sure that the name of the
+ // function is correct. We add the suffix to the name of the intrinsic and
+ // compare against the given function name. If they are not the same, the
+ // function name is invalid. This ensures that overloading of intrinsics
+ // uses a sane and consistent naming convention. Note that intrinsics with
+ // pointer argument may or may not be overloaded so we will check assuming it
+ // has a suffix and not.
if (!Suffix.empty()) {
std::string Name(Intrinsic::getName(ID));
- if (Name + Suffix != F->getName())
+ if (Name + Suffix != F->getName()) {
CheckFailed("Overloaded intrinsic has incorrect suffix: '" +
F->getName().substr(Name.length()) + "'. It should be '" +
Suffix + "'", F);
+ }
}
// Check parameter attributes.