diff options
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/AutoUpgrade.cpp | 26 | ||||
-rw-r--r-- | lib/VMCore/Function.cpp | 9 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 32 |
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. |