diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h --- a/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -1643,6 +1643,9 @@ /// false, but it shouldn't matter what it returns anyway. bool hasArmWideBranch(bool Thumb) const; + /// \return The maximum number of function arguments the target supports. + unsigned getMaxNumArgs() const; + /// @} private: @@ -2003,6 +2006,7 @@ virtual VPLegalization getVPLegalizationStrategy(const VPIntrinsic &PI) const = 0; virtual bool hasArmWideBranch(bool Thumb) const = 0; + virtual unsigned getMaxNumArgs() const = 0; }; template @@ -2694,6 +2698,10 @@ bool hasArmWideBranch(bool Thumb) const override { return Impl.hasArmWideBranch(Thumb); } + + unsigned getMaxNumArgs() const override { + return Impl.getMaxNumArgs(); + } }; template diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h --- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -878,6 +878,8 @@ bool hasArmWideBranch(bool) const { return false; } + unsigned getMaxNumArgs() const { return UINT_MAX; } + protected: // Obtain the minimum required size to hold the value (without the sign) // In case of a vector it returns the min required size for one element. diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -1194,6 +1194,10 @@ return TTIImpl->hasArmWideBranch(Thumb); } +unsigned TargetTransformInfo::getMaxNumArgs() const { + return TTIImpl->getMaxNumArgs(); +} + bool TargetTransformInfo::shouldExpandReduction(const IntrinsicInst *II) const { return TTIImpl->shouldExpandReduction(II); } diff --git a/llvm/lib/Target/BPF/BPFTargetTransformInfo.h b/llvm/lib/Target/BPF/BPFTargetTransformInfo.h --- a/llvm/lib/Target/BPF/BPFTargetTransformInfo.h +++ b/llvm/lib/Target/BPF/BPFTargetTransformInfo.h @@ -77,6 +77,10 @@ return Options; } + unsigned getMaxNumArgs() const { + return 5; + } + }; } // end namespace llvm diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -781,6 +781,7 @@ // Check to see which arguments are promotable. If an argument is promotable, // add it to ArgsToPromote. DenseMap> ArgsToPromote; + unsigned NumArgsAfterPromote = F->getFunctionType()->getNumParams(); for (Argument *PtrArg : PointerArgs) { // Replace sret attribute with noalias. This reduces register pressure by // avoiding a register copy. @@ -804,6 +805,7 @@ Types.push_back(Pair.second.Ty); if (areTypesABICompatible(Types, *F, TTI)) { + NumArgsAfterPromote += ArgParts.size() - 1; ArgsToPromote.insert({PtrArg, std::move(ArgParts)}); } } @@ -813,6 +815,9 @@ if (ArgsToPromote.empty()) return nullptr; + if (NumArgsAfterPromote > TTI.getMaxNumArgs()) + return nullptr; + return doPromotion(F, FAM, ArgsToPromote); }