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 StringRef const StandardNames[LibFunc::NumLibFuncs]; + bool ShouldExtI32Param, ShouldExtI32Return, ShouldSignExtI32Param; enum AvailabilityState { StandardName = 3, // (memset to all ones) @@ -172,6 +173,26 @@ /// /// Set VF to the vectorization factor. StringRef getScalarizedFunction(StringRef F, unsigned &VF) const; + + /// Set to true iff i32 parameters to library functions should have signext + /// or zeroext attributes if they correspond to C-level int or unsigned int, + /// respectively. + void setShouldExtI32Param(bool Val) { + ShouldExtI32Param = Val; + } + + /// Set to true iff i32 results from library functions should have signext + /// or zeroext attributes if they correspond to C-level int or unsigned int, + /// respectively. + void setShouldExtI32Return(bool Val) { + ShouldExtI32Return = Val; + } + + /// Set to true iff i32 parameters to library functions should have signext + /// attribute if they correspond to C-level int or unsigned int. + void setShouldSignExtI32Param(bool Val) { + ShouldSignExtI32Param = Val; + } }; /// Provides information about what library functions are available for @@ -268,6 +289,26 @@ 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; + } + + /// Returns true iff i32 parameters to library functions should have + /// signext attribute if they correspond to C-level int or unsigned int. + bool shouldSignExtI32Param() const { + return Impl->ShouldSignExtI32Param; + } + /// Handle invalidation from the pass manager. /// /// If we try to invalidate this info, just return false. It cannot become Index: lib/Analysis/TargetLibraryInfo.cpp =================================================================== --- lib/Analysis/TargetLibraryInfo.cpp +++ lib/Analysis/TargetLibraryInfo.cpp @@ -414,6 +414,25 @@ } TLI.addVectorizableFunctionsFromVecLib(ClVectorLibrary); + + bool ShouldExtI32Param = false, ShouldExtI32Return = false, + ShouldSignExtI32Param = false; + // PowerPC64, Sparc64, SystemZ need signext/zeroext on i32 parameters and + // returns corresponding to C-level ints and unsigned ints. + if (T.getArch() == Triple::ppc64 || T.getArch() == Triple::ppc64le || + T.getArch() == Triple::sparcv9 || T.getArch() == Triple::systemz) { + ShouldExtI32Param = true; + ShouldExtI32Return = true; + } + // Mips, on the other hand, needs signext on i32 parameters corresponding + // to both signed and unsigned ints. + if (T.getArch() == Triple::mips || T.getArch() == Triple::mipsel || + T.getArch() == Triple::mips64 || T.getArch() == Triple::mips64el) { + ShouldSignExtI32Param = true; + } + TLI.setShouldExtI32Param(ShouldExtI32Param); + TLI.setShouldExtI32Return(ShouldExtI32Return); + TLI.setShouldSignExtI32Param(ShouldSignExtI32Param); } TargetLibraryInfoImpl::TargetLibraryInfoImpl() { @@ -431,14 +450,19 @@ } TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI) - : CustomNames(TLI.CustomNames) { + : CustomNames(TLI.CustomNames), ShouldExtI32Param(TLI.ShouldExtI32Param), + ShouldExtI32Return(TLI.ShouldExtI32Return), + ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) { 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), + ShouldSignExtI32Param(TLI.ShouldSignExtI32Param) { std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), AvailableArray); VectorDescs = TLI.VectorDescs; @@ -447,12 +471,18 @@ TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const TargetLibraryInfoImpl &TLI) { CustomNames = TLI.CustomNames; + ShouldExtI32Param = TLI.ShouldExtI32Param; + ShouldExtI32Return = TLI.ShouldExtI32Return; + ShouldSignExtI32Param = TLI.ShouldSignExtI32Param; memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray)); return *this; } TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&TLI) { CustomNames = std::move(TLI.CustomNames); + ShouldExtI32Param = TLI.ShouldExtI32Param; + ShouldExtI32Return = TLI.ShouldExtI32Return; + ShouldSignExtI32Param = TLI.ShouldSignExtI32Param; std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray), AvailableArray); return *this; Index: test/Instrumentation/InstrProfiling/icall.ll =================================================================== --- test/Instrumentation/InstrProfiling/icall.ll +++ test/Instrumentation/InstrProfiling/icall.ll @@ -2,6 +2,13 @@ ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -vp-static-alloc=true -instrprof -S | FileCheck %s --check-prefix=STATIC ; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC +; RUN: opt < %s -mtriple=powerpc-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC +; RUN: opt < %s -mtriple=sparc-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC +; RUN: opt < %s -mtriple=s390x-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-EXT +; RUN: opt < %s -mtriple=powerpc64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-EXT +; RUN: opt < %s -mtriple=sparc64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-EXT +; RUN: opt < %s -mtriple=mips-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-SEXT +; RUN: opt < %s -mtriple=mips64-unknown-linux -instrprof -vp-static-alloc=true -S | FileCheck %s --check-prefix=STATIC-SEXT ; RUN: opt < %s -mtriple=x86_64-apple-macosx10.10.0 -vp-static-alloc=false -instrprof -S | FileCheck %s --check-prefix=DYN ; RUN: opt < %s -mtriple=x86_64-unknown-linux -instrprof -vp-static-alloc=false -S | FileCheck %s --check-prefix=DYN @@ -29,3 +36,11 @@ ; DYN-NOT: @__profvp_foo ; DYN-NOT: @__llvm_prf_vnodes + +; STATIC: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 0) +; STATIC-EXT: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 zeroext 0) +; STATIC-SEXT: call void @__llvm_profile_instrument_target(i64 %3, i8* bitcast ({ i64, i64, i64*, i8*, i8*, i32, [1 x i16] }* @__profd_foo to i8*), i32 signext 0) + +; STATIC: declare void @__llvm_profile_instrument_target(i64, i8*, i32) +; STATIC-EXT: declare void @__llvm_profile_instrument_target(i64, i8*, i32 zeroext) +; STATIC-SEXT: declare void @__llvm_profile_instrument_target(i64, i8*, i32 signext)