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 @@ -1146,6 +1146,10 @@ /// to a stack reload. unsigned getGISelRematGlobalCost() const; + /// \returns True if the target does not want to introduce a new variable + /// with a better value range compared to existing variable. + bool preferNoNewValueRange() const; + /// @} private: @@ -1393,6 +1397,7 @@ ReductionFlags) const = 0; virtual bool shouldExpandReduction(const IntrinsicInst *II) const = 0; virtual unsigned getGISelRematGlobalCost() const = 0; + virtual bool preferNoNewValueRange() const = 0; virtual int getInstructionLatency(const Instruction *I) = 0; }; @@ -1875,6 +1880,10 @@ return Impl.getGISelRematGlobalCost(); } + bool preferNoNewValueRange () const override { + return Impl.preferNoNewValueRange(); + } + 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 @@ -611,6 +611,10 @@ return 1; } + bool preferNoNewValueRange() const { + return false; + } + 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 @@ -850,6 +850,10 @@ return TTIImpl->getGISelRematGlobalCost(); } +bool TargetTransformInfo::preferNoNewValueRange() const { + return TTIImpl->preferNoNewValueRange(); +} + int TargetTransformInfo::getInstructionLatency(const Instruction *I) const { return TTIImpl->getInstructionLatency(I); } diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.h b/llvm/lib/Target/BPF/BPFTargetMachine.h --- a/llvm/lib/Target/BPF/BPFTargetMachine.h +++ b/llvm/lib/Target/BPF/BPFTargetMachine.h @@ -32,6 +32,8 @@ return &Subtarget; } + TargetTransformInfo getTargetTransformInfo(const Function &F) override; + TargetPassConfig *createPassConfig(PassManagerBase &PM) override; TargetLoweringObjectFile *getObjFileLowering() const override { diff --git a/llvm/lib/Target/BPF/BPFTargetMachine.cpp b/llvm/lib/Target/BPF/BPFTargetMachine.cpp --- a/llvm/lib/Target/BPF/BPFTargetMachine.cpp +++ b/llvm/lib/Target/BPF/BPFTargetMachine.cpp @@ -12,8 +12,11 @@ #include "BPFTargetMachine.h" #include "BPF.h" +#include "BPFTargetTransformInfo.h" #include "MCTargetDesc/BPFMCAsmInfo.h" #include "TargetInfo/BPFTargetInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/BasicTTIImpl.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h" #include "llvm/CodeGen/TargetPassConfig.h" @@ -93,6 +96,11 @@ return new BPFPassConfig(*this, PM); } +TargetTransformInfo +BPFTargetMachine::getTargetTransformInfo(const Function &F) { + return TargetTransformInfo(BPFTTIImpl(this, F)); +} + void BPFPassConfig::addIRPasses() { addPass(createBPFAbstractMemberAccess(&getBPFTargetMachine())); diff --git a/llvm/lib/Target/BPF/BPFTargetTransformInfo.h b/llvm/lib/Target/BPF/BPFTargetTransformInfo.h new file mode 100644 --- /dev/null +++ b/llvm/lib/Target/BPF/BPFTargetTransformInfo.h @@ -0,0 +1,45 @@ +//===------ BPFTargetTransformInfo.h - BPF specific TTI ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file a TargetTransformInfo::Concept conforming object specific to the +// BPF target machine. It uses the target's detailed information to +// provide more precise answers to certain TTI queries, while letting the +// target independent and default TTI implementations handle the rest. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H +#define LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H + +#include "BPFTargetMachine.h" +#include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/CodeGen/BasicTTIImpl.h" + +namespace llvm { +class BPFTTIImpl : public BasicTTIImplBase { + typedef BasicTTIImplBase BaseT; + typedef TargetTransformInfo TTI; + friend BaseT; + + const BPFSubtarget *ST; + const BPFTargetLowering *TLI; + + const BPFSubtarget *getST() const { return ST; } + const BPFTargetLowering *getTLI() const { return TLI; } + +public: + explicit BPFTTIImpl(const BPFTargetMachine *TM, const Function &F) + : BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)), + TLI(ST->getTargetLowering()) {} + + bool preferNoNewValueRange() const { return true; } +}; + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_BPF_BPFTARGETTRANSFORMINFO_H diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -13,6 +13,7 @@ #include "InstCombineInternal.h" #include "llvm/Analysis/CmpInstAnalysis.h" #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Transforms/Utils/Local.h" #include "llvm/IR/ConstantRange.h" #include "llvm/IR/Intrinsics.h" @@ -177,6 +178,11 @@ return Builder.CreateICmp(Pred, V, ConstantInt::get(Ty, Hi)); } + // Bail out if the target prefers not to create a new variable even with better + // value range. + if (TTI.preferNoNewValueRange()) + return nullptr; + // V >= Lo && V < Hi --> V - Lo u< Hi - Lo // V < Lo || V >= Hi --> V - Lo u>= Hi - Lo Value *VMinusLo = diff --git a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h --- a/llvm/lib/Transforms/InstCombine/InstCombineInternal.h +++ b/llvm/lib/Transforms/InstCombine/InstCombineInternal.h @@ -61,6 +61,7 @@ class OptimizationRemarkEmitter; class ProfileSummaryInfo; class TargetLibraryInfo; +class TargetTransformInfo; class User; /// Assign a complexity or rank value to LLVM Values. This is used to reduce @@ -327,6 +328,7 @@ OptimizationRemarkEmitter &ORE; BlockFrequencyInfo *BFI; ProfileSummaryInfo *PSI; + TargetTransformInfo &TTI; // Optional analyses. When non-null, these can both be used to do better // combining and will be updated to reflect any changes. @@ -339,10 +341,12 @@ bool MinimizeSize, bool ExpensiveCombines, AliasAnalysis *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, - ProfileSummaryInfo *PSI, const DataLayout &DL, LoopInfo *LI) + ProfileSummaryInfo *PSI, const DataLayout &DL, + TargetTransformInfo &TTI, LoopInfo *LI) : Worklist(Worklist), Builder(Builder), MinimizeSize(MinimizeSize), ExpensiveCombines(ExpensiveCombines), AA(AA), AC(AC), TLI(TLI), DT(DT), - DL(DL), SQ(DL, &TLI, &DT, &AC), ORE(ORE), BFI(BFI), PSI(PSI), LI(LI) {} + DL(DL), SQ(DL, &TLI, &DT, &AC), ORE(ORE), BFI(BFI), PSI(PSI), TTI(TTI), + LI(LI) {} /// Run the combiner over the entire worklist until it is empty. /// diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -59,6 +59,7 @@ #include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Analysis/TargetFolder.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" @@ -3557,8 +3558,8 @@ Function &F, InstCombineWorklist &Worklist, AliasAnalysis *AA, AssumptionCache &AC, TargetLibraryInfo &TLI, DominatorTree &DT, OptimizationRemarkEmitter &ORE, BlockFrequencyInfo *BFI, - ProfileSummaryInfo *PSI, bool ExpensiveCombines = true, - LoopInfo *LI = nullptr) { + ProfileSummaryInfo *PSI, TargetTransformInfo &TTI, + bool ExpensiveCombines = true, LoopInfo *LI = nullptr) { auto &DL = F.getParent()->getDataLayout(); ExpensiveCombines |= EnableExpensiveCombines; @@ -3588,7 +3589,7 @@ MadeIRChange |= prepareICWorklistFromFunction(F, DL, &TLI, Worklist); InstCombiner IC(Worklist, Builder, F.hasMinSize(), ExpensiveCombines, AA, - AC, TLI, DT, ORE, BFI, PSI, DL, LI); + AC, TLI, DT, ORE, BFI, PSI, DL, TTI, LI); IC.MaxArraySizeForCombine = MaxArraySize; if (!IC.run()) @@ -3614,9 +3615,10 @@ MAM.getCachedResult(*F.getParent()); auto *BFI = (PSI && PSI->hasProfileSummary()) ? &AM.getResult(F) : nullptr; + TargetTransformInfo &TTI = AM.getResult(F); if (!combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, ORE, - BFI, PSI, ExpensiveCombines, LI)) + BFI, PSI, TTI, ExpensiveCombines, LI)) // No changes, all analyses are preserved. return PreservedAnalyses::all(); @@ -3641,6 +3643,7 @@ AU.addPreserved(); AU.addPreserved(); AU.addRequired(); + AU.addRequired(); LazyBlockFrequencyInfoPass::getLazyBFIAnalysisUsage(AU); } @@ -3664,9 +3667,10 @@ (PSI && PSI->hasProfileSummary()) ? &getAnalysis().getBFI() : nullptr; + auto &TTI = getAnalysis().getTTI(F); return combineInstructionsOverFunction(F, Worklist, AA, AC, TLI, DT, ORE, - BFI, PSI, ExpensiveCombines, LI); + BFI, PSI, TTI, ExpensiveCombines, LI); } char InstructionCombiningPass::ID = 0; @@ -3686,6 +3690,7 @@ INITIALIZE_PASS_DEPENDENCY(OptimizationRemarkEmitterWrapperPass) INITIALIZE_PASS_DEPENDENCY(LazyBlockFrequencyInfoPass) INITIALIZE_PASS_DEPENDENCY(ProfileSummaryInfoWrapperPass) +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass) INITIALIZE_PASS_END(InstructionCombiningPass, "instcombine", "Combine redundant instructions", false, false) diff --git a/llvm/test/Transforms/InstCombine/BPF/no-insert-range-test.ll b/llvm/test/Transforms/InstCombine/BPF/no-insert-range-test.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/BPF/no-insert-range-test.ll @@ -0,0 +1,18 @@ +; RUN: opt < %s -instcombine -S | FileCheck %s +; REQUIRES: bpf-registered-target + +; bpf target should not perform insertRangeTest. + +target datalayout = "e-m:e-p:64:64-i64:64-n32:64-S128" +target triple = "bpf" + +define dso_local i32 @test(i32 %arg) local_unnamed_addr { +entry: + %cmp = icmp sgt i32 %arg, 0 + %cmp1 = icmp slt i32 %arg, 8 +; CHECK-NOT: add i32 %arg, -1 + %0 = and i1 %cmp, %cmp1 +; CHECK: %0 = and i1 %cmp, %cmp1 + %. = zext i1 %0 to i32 + ret i32 %. +}