Index: include/llvm/Analysis/TargetLibraryInfo.h =================================================================== --- include/llvm/Analysis/TargetLibraryInfo.h +++ include/llvm/Analysis/TargetLibraryInfo.h @@ -51,6 +51,7 @@ unsigned char AvailableArray[(LibFunc::NumLibFuncs+3)/4]; llvm::DenseMap CustomNames; static const char *const StandardNames[LibFunc::NumLibFuncs]; + bool ShouldExtI32Param, ShouldExtI32Return; enum AvailabilityState { StandardName = 3, // (memset to all ones) @@ -171,6 +172,13 @@ /// /// Set VF to the vectorization factor. StringRef getScalarizedFunction(StringRef F, unsigned &VF) const; + + /// Set whether int and unsigned int parameters and returns should have + /// signext or zeroext attributes, respectively. + void setShouldExtI32(bool Param, bool Return) { + ShouldExtI32Param = Param; + ShouldExtI32Return = Return; + } }; /// Provides information about what library functions are available for @@ -267,6 +275,20 @@ return Impl->CustomNames.find(F)->second; } + /// Returns true iff i32 parameters to library functions should have + /// signext or zeroext attributes if they correspond to C-level int or + /// unsigned int, respectively. + bool shouldExtI32Param() const { + return Impl->ShouldExtI32Param; + } + + /// Returns true iff i32 returns from library functions should have + /// signext or zeroext attributes if they correspond to C-level int or + /// unsigned int, respectively. + bool shouldExtI32Return() const { + return Impl->ShouldExtI32Return; + } + /// Handle invalidation from the pass manager. /// /// If we try to invalidate this info, just return false. It cannot become Index: include/llvm/Transforms/InstrProfiling.h =================================================================== --- include/llvm/Transforms/InstrProfiling.h +++ include/llvm/Transforms/InstrProfiling.h @@ -21,6 +21,8 @@ namespace llvm { +class TargetLibraryInfo; + /// Instrumenation based profiling lowering pass. This pass lowers /// the profile instrumented code generated by FE or the IR based /// instrumentation pass. @@ -30,7 +32,7 @@ InstrProfiling(const InstrProfOptions &Options) : Options(Options) {} PreservedAnalyses run(Module &M, AnalysisManager &AM); - bool run(Module &M); + bool run(Module &M, const TargetLibraryInfo *TLI); private: InstrProfOptions Options; @@ -67,7 +69,8 @@ void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins); /// Replace instrprof_value_profile with a call to runtime library. - void lowerValueProfileInst(InstrProfValueProfileInst *Ins); + void lowerValueProfileInst(InstrProfValueProfileInst *Ins, + const TargetLibraryInfo *TLI); /// Replace instrprof_increment with an increment of the appropriate value. void lowerIncrement(InstrProfIncrementInst *Inc); Index: lib/Analysis/TargetLibraryInfo.cpp =================================================================== --- lib/Analysis/TargetLibraryInfo.cpp +++ lib/Analysis/TargetLibraryInfo.cpp @@ -412,6 +412,19 @@ } TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); + + // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and + // returns corresponding to C-level ints. Mips64 needs it for parameters + // only. + bool ShouldExtI32Param = false, ShouldExtI32Return = false; + if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le || + T.getArch() == Triple::sparcv9 || T.getArch() == Triple::systemz) { + ShouldExtI32Param = true; + ShouldExtI32Return = true; + } + if (T.getArch() == Triple::mips64 || T.getArch() == Triple::mips64el) + ShouldExtI32Param = true; + TLI.setShouldExtI32(ShouldExtI32Param, ShouldExtI32Return); } TargetLibraryInfoImpl::TargetLibraryInfoImpl() { @@ -429,14 +442,17 @@ } TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) - : CustomNames(TLI.CustomNames) { + : CustomNames(TLI.CustomNames), ShouldExtI32Param(TLI.ShouldExtI32Param), + ShouldExtI32Return(TLI.ShouldExtI32Return) { memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); VectorDescs = TLI.VectorDescs; ScalarDescs = TLI.ScalarDescs; } TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI) - : CustomNames(std::move(TLI.CustomNames)) { + : CustomNames(std::move(TLI.CustomNames)), + ShouldExtI32Param(TLI.ShouldExtI32Param), + ShouldExtI32Return(TLI.ShouldExtI32Return) { std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), AvailableArray); VectorDescs = TLI.VectorDescs; @@ -445,12 +461,16 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) { CustomNames = TLI.CustomNames; + ShouldExtI32Param = TLI.ShouldExtI32Param; + ShouldExtI32Return = TLI.ShouldExtI32Return; memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); return *this; } TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) { CustomNames = std::move(TLI.CustomNames); + ShouldExtI32Param = TLI.ShouldExtI32Param; + ShouldExtI32Return = TLI.ShouldExtI32Return; std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), AvailableArray); return *this; Index: lib/Transforms/Instrumentation/InstrProfiling.cpp =================================================================== --- lib/Transforms/Instrumentation/InstrProfiling.cpp +++ lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -15,6 +15,7 @@ #include "llvm/Transforms/InstrProfiling.h" #include "llvm/ADT/Triple.h" +#include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" @@ -57,26 +58,34 @@ return "Frontend instrumentation-based coverage lowering"; } - bool runOnModule(Module &M) override { return InstrProf.run(M); } + bool runOnModule(Module &M) override { + return InstrProf.run(M, &getAnalysis().getTLI()); + } void getAnalysisUsage(AnalysisUsage &AU) const override { AU.setPreservesCFG(); + AU.addRequired(); } }; } // anonymous namespace PreservedAnalyses InstrProfiling::run(Module &M, AnalysisManager &AM) { - if (!run(M)) + auto TLI = &AM.getResult(M); + if (!run(M, TLI)) return PreservedAnalyses::all(); return PreservedAnalyses::none(); } char InstrProfilingLegacyPass::ID = 0; -INITIALIZE_PASS(InstrProfilingLegacyPass, "instrprof", - "Frontend instrumentation-based coverage lowering.", false, - false) +INITIALIZE_PASS_BEGIN( + InstrProfilingLegacyPass, "instrprof", + "Frontend instrumentation-based coverage lowering.", false, false) +INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) +INITIALIZE_PASS_END( + InstrProfilingLegacyPass, "instrprof", + "Frontend instrumentation-based coverage lowering.", false, false) ModulePass * llvm::createInstrProfilingLegacyPass(const InstrProfOptions &Options) { @@ -107,7 +116,7 @@ return getInstrProfCoverageSectionName(isMachO()); } -bool InstrProfiling::run(Module &M) { +bool InstrProfiling::run(Module &M, const TargetLibraryInfo *TLI) { bool MadeChange = false; this->M = &M; @@ -142,7 +151,7 @@ lowerIncrement(Inc); MadeChange = true; } else if (auto *Ind = dyn_cast(Instr)) { - lowerValueProfileInst(Ind); + lowerValueProfileInst(Ind, TLI); MadeChange = true; } } @@ -165,7 +174,8 @@ return true; } -static Constant *getOrInsertValueProfilingCall(Module &M) { +static Constant *getOrInsertValueProfilingCall(Module &M, + const TargetLibraryInfo *TLI) { LLVMContext &Ctx = M.getContext(); auto *ReturnTy = Type::getVoidTy(M.getContext()); Type *ParamTypes[] = { @@ -174,8 +184,12 @@ }; auto *ValueProfilingCallTy = FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false); - return M.getOrInsertFunction(getInstrProfValueProfFuncName(), - ValueProfilingCallTy); + Constant *Res = M.getOrInsertFunction(getInstrProfValueProfFuncName(), + ValueProfilingCallTy); + Function *FunRes = dyn_cast(Res); + if (TLI->shouldExtI32Param() && FunRes) + FunRes->addAttribute(3, Attribute::ZExt); + return Res; } void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) { @@ -192,7 +206,8 @@ It->second.NumValueSites[ValueKind] = Index + 1; } -void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) { +void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind, + const TargetLibraryInfo *TLI) { GlobalVariable *Name = Ind->getName(); auto It = ProfileDataMap.find(Name); @@ -209,8 +224,11 @@ Value *Args[3] = {Ind->getTargetValue(), Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()), Builder.getInt32(Index)}; - Ind->replaceAllUsesWith( - Builder.CreateCall(getOrInsertValueProfilingCall(*M), Args)); + CallInst *Call = Builder.CreateCall(getOrInsertValueProfilingCall(*M, TLI), + Args); + if (TLI->shouldExtI32Param()) + Call->addAttribute(3, Attribute::ZExt); + Ind->replaceAllUsesWith(Call); Ind->eraseFromParent(); }