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 @@ -1198,6 +1198,12 @@ /// Intrinsics") Use of %evl is discouraged when that is not the case. bool hasActiveVectorLength() const; + /// \returns True if the target permits SpeculateOneExpensiveInst in + /// SimplifyCFG. Both this and SimplifyCFG commandline option + /// SpeculateOneExpensiveInst need to be True for the actual transformation + /// taking place. + bool allowSpeculateOneExpensiveInst() const; + /// @} /// @} @@ -1465,6 +1471,7 @@ virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0; virtual unsigned getGISelRematGlobalCost() const = 0; virtual bool hasActiveVectorLength() const = 0; + virtual bool allowSpeculateOneExpensiveInst() const = 0; virtual int getInstructionLatency(const Instruction *I) = 0; }; @@ -1949,6 +1956,10 @@ return Impl.hasActiveVectorLength(); } + bool allowSpeculateOneExpensiveInst() const override { + return Impl.allowSpeculateOneExpensiveInst(); + } + int getInstructionLatency(const Instruction *I) override { return Impl.getInstructionLatency(I); } 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 @@ -638,6 +638,8 @@ bool hasActiveVectorLength() const { return false; } + bool allowSpeculateOneExpensiveInst() const { return true; } + 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 @@ -946,6 +946,10 @@ return TTIImpl->getGISelRematGlobalCost(); } +bool TargetTransformInfo::allowSpeculateOneExpensiveInst() const { + return TTIImpl->allowSpeculateOneExpensiveInst(); +} + int TargetTransformInfo::getInstructionLatency(const Instruction *I) const { return TTIImpl->getInstructionLatency(I); } 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 @@ -44,6 +44,8 @@ return INT_MAX; } + + bool allowSpeculateOneExpensiveInst() const { return !ST->getHasAdjustOpt(); } }; } // end namespace llvm diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -403,8 +403,11 @@ // or other expensive operation. The speculation of an expensive instruction // is expected to be undone in CodeGenPrepare if the speculation has not // enabled further IR optimizations. + bool AllowSpeculateOneExpensiveInst = SpeculateOneExpensiveInst && + TTI.allowSpeculateOneExpensiveInst(); if (BudgetRemaining < 0 && - (!SpeculateOneExpensiveInst || !AggressiveInsts.empty() || Depth > 0)) + (!AllowSpeculateOneExpensiveInst || !AggressiveInsts.empty() || + Depth > 0)) return false; // Okay, we can only really hoist these out if their operands do