|
LLVM 23.0.0git
|
#include "llvm/Transforms/AggressiveInstCombine/AggressiveInstCombine.h"#include "AggressiveInstCombineInternal.h"#include "llvm/ADT/Statistic.h"#include "llvm/Analysis/AliasAnalysis.h"#include "llvm/Analysis/AssumptionCache.h"#include "llvm/Analysis/BasicAliasAnalysis.h"#include "llvm/Analysis/ConstantFolding.h"#include "llvm/Analysis/DomTreeUpdater.h"#include "llvm/Analysis/GlobalsModRef.h"#include "llvm/Analysis/TargetLibraryInfo.h"#include "llvm/Analysis/TargetTransformInfo.h"#include "llvm/Analysis/ValueTracking.h"#include "llvm/IR/DataLayout.h"#include "llvm/IR/Dominators.h"#include "llvm/IR/Function.h"#include "llvm/IR/IRBuilder.h"#include "llvm/IR/Instruction.h"#include "llvm/IR/MDBuilder.h"#include "llvm/IR/PatternMatch.h"#include "llvm/IR/ProfDataUtils.h"#include "llvm/Support/Casting.h"#include "llvm/Support/CommandLine.h"#include "llvm/Transforms/Utils/BasicBlockUtils.h"#include "llvm/Transforms/Utils/BuildLibCalls.h"#include "llvm/Transforms/Utils/Local.h"Go to the source code of this file.
Classes | |
| struct | LoadOps |
| This is used by foldLoadsRecursive() to capture a Root Load node which is of type or(load, load) and recursively build the wide load. More... | |
| struct | PartStore |
| ValWidth bits starting at ValOffset of Val stored at PtrBase+PtrOffset. More... | |
Namespaces | |
| namespace | llvm |
| This is an optimization pass for GlobalISel generic memory operations. | |
Macros | |
| #define | DEBUG_TYPE "aggressive-instcombine" |
Functions | |
| STATISTIC (NumAnyOrAllBitsSet, "Number of any/all-bits-set patterns folded") | |
| STATISTIC (NumGuardedRotates, "Number of guarded rotates transformed into funnel shifts") | |
| STATISTIC (NumGuardedFunnelShifts, "Number of guarded funnel shifts transformed into funnel shifts") | |
| STATISTIC (NumPopCountRecognized, "Number of popcount idioms recognized") | |
| STATISTIC (NumSelectCTTZFolded, "Number of select-based split cttz patterns folded") | |
| STATISTIC (NumSelectCTLZFolded, "Number of select-based split ctlz patterns folded") | |
| static bool | foldSelectSplitCTTZ (Instruction &I) |
| Try to fold a select-based split cttz pattern into a single full-width cttz. | |
| static bool | foldSelectSplitCTLZ (Instruction &I) |
| Same as foldSelectSplitCTTZ but for leading zeros (ctlz). | |
| static bool | foldGuardedFunnelShift (Instruction &I, const DominatorTree &DT) |
| Match a pattern for a bitwise funnel/rotate operation that partially guards against undefined behavior by branching around the funnel-shift/rotation when the shift amount is 0. | |
| static bool | matchAndOrChain (Value *V, MaskOps &MOps) |
| This is a recursive helper for foldAnyOrAllBitsSet() that walks through a chain of 'and' or 'or' instructions looking for shift ops of a common source value. | |
| static bool | foldAnyOrAllBitsSet (Instruction &I) |
| Match patterns that correspond to "any-bits-set" and "all-bits-set". | |
| static bool | tryToRecognizePopCount (Instruction &I) |
| static bool | tryToRecognizePopCount2n3 (Instruction &I) |
| static bool | tryToFPToSat (Instruction &I, TargetTransformInfo &TTI) |
| Fold smin(smax(fptosi(x), C1), C2) to llvm.fptosi.sat(x), providing C1 and C2 saturate the value of the fp conversion. | |
| static bool | foldSqrt (CallInst *Call, LibFunc Func, TargetTransformInfo &TTI, TargetLibraryInfo &TLI, AssumptionCache &AC, DominatorTree &DT) |
| Try to replace a mathlib call to sqrt with the LLVM intrinsic. | |
| static bool | isCTTZTable (Constant *Table, const APInt &Mul, const APInt &Shift, const APInt &AndMask, Type *AccessTy, unsigned InputBits, const APInt &GEPIdxFactor, const DataLayout &DL) |
| static bool | tryToRecognizeTableBasedCttz (Instruction &I, const DataLayout &DL) |
| static bool | isLog2Table (Constant *Table, const APInt &Mul, const APInt &Shift, Type *AccessTy, unsigned InputBits, const APInt &GEPIdxFactor, const DataLayout &DL) |
| static bool | tryToRecognizeTableBasedLog2 (Instruction &I, const DataLayout &DL, TargetTransformInfo &TTI) |
| static bool | foldLoadsRecursive (Value *V, LoadOps &LOps, const DataLayout &DL, AliasAnalysis &AA, bool IsRoot=false) |
| static bool | foldConsecutiveLoads (Instruction &I, const DataLayout &DL, TargetTransformInfo &TTI, AliasAnalysis &AA, const DominatorTree &DT) |
| static std::optional< PartStore > | matchPartStore (Instruction &I, const DataLayout &DL) |
| static bool | mergeConsecutivePartStores (ArrayRef< PartStore > Parts, unsigned Width, const DataLayout &DL, TargetTransformInfo &TTI) |
| static bool | mergePartStores (SmallVectorImpl< PartStore > &Parts, const DataLayout &DL, TargetTransformInfo &TTI) |
| static bool | foldConsecutiveStores (BasicBlock &BB, const DataLayout &DL, TargetTransformInfo &TTI, AliasAnalysis &AA) |
| static Value * | optimizeShiftInOrChain (Value *V, IRBuilder<> &Builder) |
| Combine away instructions providing they are still equivalent when compared against 0. | |
| static bool | foldICmpOrChain (Instruction &I, const DataLayout &DL, TargetTransformInfo &TTI, AliasAnalysis &AA, const DominatorTree &DT) |
| static std::pair< APInt, APInt > | getStrideAndModOffsetOfGEP (Value *PtrOp, const DataLayout &DL) |
| static bool | foldPatternedLoads (Instruction &I, const DataLayout &DL) |
| If C is a constant patterned array and all valid loaded results for given alignment are same to a constant, return that constant. | |
| static bool | foldMemChr (CallInst *Call, DomTreeUpdater *DTU, const DataLayout &DL) |
| Convert memchr with a small constant string into a switch. | |
| static bool | foldLibCalls (Instruction &I, TargetTransformInfo &TTI, TargetLibraryInfo &TLI, AssumptionCache &AC, DominatorTree &DT, const DataLayout &DL, bool &MadeCFGChange) |
| static bool | foldMulHigh (Instruction &I) |
| Match high part of long multiplication. | |
| static bool | foldUnusualPatterns (Function &F, DominatorTree &DT, TargetTransformInfo &TTI, TargetLibraryInfo &TLI, AliasAnalysis &AA, AssumptionCache &AC, bool &MadeCFGChange) |
| This is the entry point for folds that could be implemented in regular InstCombine, but they are separated because they are not expected to occur frequently and/or have more than a constant-length pattern match. | |
| static bool | runImpl (Function &F, AssumptionCache &AC, TargetTransformInfo &TTI, TargetLibraryInfo &TLI, DominatorTree &DT, AliasAnalysis &AA, bool &MadeCFGChange) |
| This is the entry point for all transforms. | |
Variables | |
| static cl::opt< unsigned > | MaxInstrsToScan ("aggressive-instcombine-max-scan-instrs", cl::init(64), cl::Hidden, cl::desc("Max number of instructions to scan for aggressive instcombine.")) |
| static cl::opt< unsigned > | StrNCmpInlineThreshold ("strncmp-inline-threshold", cl::init(3), cl::Hidden, cl::desc("The maximum length of a constant string for a builtin string cmp " "call eligible for inlining. The default value is 3.")) |
| static cl::opt< unsigned > | MemChrInlineThreshold ("memchr-inline-threshold", cl::init(3), cl::Hidden, cl::desc("The maximum length of a constant string to " "inline a memchr call.")) |
| #define DEBUG_TYPE "aggressive-instcombine" |
Definition at line 44 of file AggressiveInstCombine.cpp.
|
static |
Match patterns that correspond to "any-bits-set" and "all-bits-set".
These will include a chain of 'or' or 'and'-shifted bits from a common source value: and (or (lshr X, C), ...), 1 --> (X & CMask) != 0 and (and (lshr X, C), ...), 1 --> (X & CMask) == CMask Note: "any-bits-clear" and "all-bits-clear" are variations of these patterns that differ only with a final 'not' of the result. We expect that final 'not' to be folded with the compare that we create here (invert predicate).
Definition at line 446 of file AggressiveInstCombine.cpp.
References I, llvm::PatternMatch::m_And(), llvm::PatternMatch::m_c_And(), llvm::PatternMatch::m_One(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Or(), llvm::PatternMatch::m_Trunc(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), matchAndOrChain(), and X.
Referenced by foldUnusualPatterns().
|
static |
Definition at line 1272 of file AggressiveInstCombine.cpp.
References LoadOps::AATags, DL, llvm::DominatorTree::dominates(), llvm::CallingConv::Fast, foldLoadsRecursive(), LoadOps::FoundRoot, llvm::IntegerType::get(), llvm::Value::getType(), I, llvm::isa(), LoadOps::LoadSize, LoadOps::Root, LoadOps::RootInsert, llvm::Instruction::setAAMetadata(), LoadOps::Shift, llvm::Value::stripAndAccumulateConstantOffsets(), llvm::Value::takeName(), and LoadOps::ZextType.
Referenced by foldICmpOrChain(), and foldUnusualPatterns().
|
static |
Definition at line 1455 of file AggressiveInstCombine.cpp.
References llvm::SmallVectorImpl< T >::clear(), DL, llvm::SmallVectorTemplateCommon< T, typename >::empty(), llvm::MemoryLocation::getBeforeOrAfter(), llvm::BatchAAResults::getModRefInfo(), I, llvm::isModOrRefSet(), llvm::make_early_inc_range(), matchPartStore(), mergePartStores(), and llvm::SmallVectorTemplateBase< T, bool >::push_back().
Referenced by foldUnusualPatterns().
|
static |
Match a pattern for a bitwise funnel/rotate operation that partially guards against undefined behavior by branching around the funnel-shift/rotation when the shift amount is 0.
Definition at line 262 of file AggressiveInstCombine.cpp.
References assert(), llvm::cast(), llvm::DominatorTree::dominates(), llvm::BasicBlock::getFirstInsertionPt(), llvm::BasicBlock::getTerminator(), I, llvm::CmpInst::ICMP_EQ, llvm::isGuaranteedNotToBePoison(), llvm::isPowerOf2_32(), llvm::PatternMatch::m_Br(), llvm::PatternMatch::m_c_Or(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_LShr(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Shl(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificBB(), llvm::PatternMatch::m_SpecificICmp(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Sub(), llvm::PatternMatch::m_Value(), llvm::MIPatternMatch::m_ZeroInt(), llvm::PatternMatch::match(), matchFunnelShift(), llvm::Intrinsic::not_intrinsic, and std::swap().
Referenced by foldUnusualPatterns().
|
static |
Definition at line 1524 of file AggressiveInstCombine.cpp.
References DL, llvm::dyn_cast(), foldConsecutiveLoads(), I, llvm::ICmpInst::isEquality(), llvm::PatternMatch::m_ICmp(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), llvm::PatternMatch::match(), and optimizeShiftInOrChain().
Referenced by foldUnusualPatterns().
|
static |
Definition at line 1917 of file AggressiveInstCombine.cpp.
References DL, llvm::dyn_cast(), foldMemChr(), foldSqrt(), llvm::TargetLibraryInfo::getLibFunc(), I, and llvm::isLibFuncEmittable().
Referenced by foldUnusualPatterns().
|
static |
Definition at line 1123 of file AggressiveInstCombine.cpp.
References LoadOps::AATags, llvm::AAMDNodes::concat(), DL, llvm::dyn_cast(), foldLoadsRecursive(), LoadOps::FoundRoot, llvm::IntegerType::get(), llvm::MemoryLocation::get(), llvm::Instruction::getAAMetadata(), llvm::Value::getContext(), llvm::ilist_detail::node_parent_access< NodeTy, ParentTy >::getParent(), llvm::LoadInst::getPointerAddressSpace(), llvm::LoadInst::getPointerOperand(), llvm::Type::getPrimitiveSizeInBits(), llvm::Value::getType(), llvm::isModSet(), llvm::LoadInst::isSimple(), LoadOps::LoadSize, llvm::PatternMatch::m_c_Or(), llvm::PatternMatch::m_Instruction(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_ShlOrSelf(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_ZExt(), llvm::make_range(), llvm::PatternMatch::match(), MaxInstrsToScan, llvm::LocationSize::precise(), llvm::Reverse, LoadOps::Root, LoadOps::RootInsert, LoadOps::Shift, llvm::APInt::slt(), llvm::Value::stripAndAccumulateConstantOffsets(), std::swap(), X, and LoadOps::ZextType.
Referenced by foldConsecutiveLoads(), and foldLoadsRecursive().
|
static |
Convert memchr with a small constant string into a switch.
Definition at line 1838 of file AggressiveInstCombine.cpp.
References llvm::PHINode::addIncoming(), llvm::GenericDomTreeUpdater< DerivedT, DomTreeT, PostDomTreeT >::applyUpdates(), llvm::sampleprof::Base, llvm::BasicBlock::begin(), Call, llvm::BasicBlock::Create(), llvm::PHINode::Create(), llvm::IRBuilderBase::CreateBr(), llvm::IRBuilderBase::CreateInBoundsPtrAdd(), llvm::IRBuilderBase::CreatePHI(), llvm::IRBuilderBase::CreateSwitch(), llvm::IRBuilderBase::CreateTrunc(), DEBUG_TYPE, DL, llvm::dyn_cast(), llvm::Instruction::eraseFromParent(), llvm::getConstantStringInfo(), llvm::IRBuilderBase::getInt8Ty(), llvm::Constant::getNullValue(), llvm::BasicBlock::getParent(), llvm::BasicBlock::getTerminator(), I, llvm::DominatorTreeBase< BasicBlock, false >::Insert, llvm::SmallPtrSetImpl< PtrType >::insert(), llvm::isa(), MemChrInlineThreshold, N, PHI, llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::IRBuilderBase::SetCurrentDebugLocation(), llvm::setExplicitlyUnknownBranchWeightsIfProfiled(), llvm::IRBuilderBase::SetInsertPoint(), and llvm::SplitBlock().
Referenced by foldLibCalls().
|
static |
Match high part of long multiplication.
Considering a multiply made up of high and low parts, we can split the multiply into: x * y == (xh*T + xl) * (yh*T + yl) where xh == x>>32 and xl == x & 0xffffffff. T = 2^32. This expands to xh*yh*T*T + xh*yl*T + xl*yh*T + xl*yl which can be drawn as [ xh*yh ] [ xh*yl ] [ xl*yh ] [ xl*yl ] We are looking for the "high" half, which is xh*yh + xh*yl>>32 + xl*yh>>32 + some carrys. The carry makes this difficult and there are multiple ways of representing it. The ones we attempt to support here are: Carry: xh*yh + carry + lowsum carry = lowsum < xh*yl ? 0x1000000 : 0 lowsum = xh*yl + xl*yh + (xl*yl>>32) Ladder: xh*yh + c2>>32 + c3>>32 c2 = xh*yl + (xl*yl>>32); c3 = c2&0xffffffff + xl*yh or c2 = (xl*yh&0xffffffff) + xh*yl + (xl*yl>>32); c3 = xl*yh Carry4: xh*yh + carry + crosssum>>32 + (xl*yl + crosssum&0xffffffff) >> 32 crosssum = xh*yl + xl*yh carry = crosssum < xh*yl ? 0x1000000 : 0 Ladder4: xh*yh + (xl*yh)>>32 + (xh*yl)>>32 + low>>32; low = (xl*yl)>>32 + (xl*yh)&0xffffffff + (xh*yl)&0xffffffff
They all start by matching xh*yh + 2 or 3 other operands. The bottom of the tree is xh*yh, xh*yl, xl*yh and xl*yl.
Ladder4: xh*yh + (xl*yh)>>32 + (xh+yl)>>32 + low>>32; low = (xl*yl)>>32 + (xl*yh)&0xffffffff + (xh*yl)&0xffffffff
Definition at line 1990 of file AggressiveInstCombine.cpp.
References A(), B(), llvm::BitWidth, llvm::CallingConv::C, llvm::dbgs(), llvm::APInt::getLowBitsSet(), llvm::APInt::getOneBitSet(), llvm::Type::getWithNewBitWidth(), llvm::Value::hasNUsesOrMore(), llvm::Value::hasOneUse(), High, I, llvm::CmpInst::ICMP_ULT, LLVM_DEBUG, llvm::Low, llvm::PatternMatch::m_Add(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_c_Add(), llvm::PatternMatch::m_c_Mul(), llvm::PatternMatch::m_Instruction(), llvm::PatternMatch::m_LShr(), llvm::PatternMatch::m_Mul(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Select(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificICmp(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::m_Zero(), llvm::PatternMatch::match(), Mul, std::swap(), llvm::Value::takeName(), X, and Y.
Referenced by foldUnusualPatterns().
|
static |
If C is a constant patterned array and all valid loaded results for given alignment are same to a constant, return that constant.
Definition at line 1594 of file AggressiveInstCombine.cpp.
References llvm::CallingConv::C, llvm::ConstantFoldLoadFromConst(), DL, llvm::dyn_cast(), E(), getAlign(), getStrideAndModOffsetOfGEP(), llvm::getUnderlyingObject(), and I.
Referenced by foldUnusualPatterns().
|
static |
Same as foldSelectSplitCTTZ but for leading zeros (ctlz).
shr = lshr iN val, N/2 hi = trunc iN shr to i(N/2) cmp = icmp eq i(N/2) hi, 0 (or icmp eq iN shr, 0) lo = trunc iN val to i(N/2) ctlz_lo = call i(N/2) @llvm.ctlz.i(N/2)(i(N/2) lo, ...) lo_plus = add/or_disjoint i(N/2) ctlz_lo, N/2 ctlz_hi = call i(N/2) @llvm.ctlz.i(N/2)(i(N/2) hi, ...) result = select i1 cmp, i(N/2) lo_plus, i(N/2) ctlz_hi --> ctlz_wide = call iN @llvm.ctlz.iN(iN val, i1 false) result = trunc iN ctlz_wide to i(N/2)
Alive proof (for i64/i32): https://alive2.llvm.org/ce/z/WfQepH
Definition at line 176 of file AggressiveInstCombine.cpp.
References Cond, llvm::Type::getIntegerBitWidth(), llvm::Value::getType(), I, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::Type::isIntegerTy(), llvm::PatternMatch::m_AddLike(), llvm::PatternMatch::m_Intrinsic(), llvm::PatternMatch::m_LShr(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Select(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificICmp(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Trunc(), llvm::PatternMatch::m_Value(), llvm::MIPatternMatch::m_ZeroInt(), and llvm::PatternMatch::match().
Referenced by foldUnusualPatterns().
|
static |
Try to fold a select-based split cttz pattern into a single full-width cttz.
lo = trunc iN val to i(N/2) cmp = icmp eq i(N/2) lo, 0 shr = lshr iN val, N/2 hi = trunc iN shr to i(N/2) cttz_hi = call i(N/2) @llvm.cttz.i(N/2)(i(N/2) hi, ...) hi_plus = add/or_disjoint i(N/2) cttz_hi, N/2 cttz_lo = call i(N/2) @llvm.cttz.i(N/2)(i(N/2) lo, ...) result = select i1 cmp, i(N/2) hi_plus, i(N/2) cttz_lo --> cttz_wide = call iN @llvm.cttz.iN(iN val, i1 false) result = trunc iN cttz_wide to i(N/2) Alive proof (for i64/i32): https://alive2.llvm.org/ce/z/-s14-s
Definition at line 89 of file AggressiveInstCombine.cpp.
References Cond, llvm::Type::getIntegerBitWidth(), llvm::Value::getType(), I, llvm::CmpInst::ICMP_EQ, llvm::CmpInst::ICMP_NE, llvm::Type::isIntegerTy(), llvm::PatternMatch::m_AddLike(), llvm::PatternMatch::m_Intrinsic(), llvm::PatternMatch::m_LShr(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_Select(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificICmp(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Trunc(), llvm::PatternMatch::m_Value(), llvm::MIPatternMatch::m_ZeroInt(), and llvm::PatternMatch::match().
Referenced by foldUnusualPatterns().
|
static |
Try to replace a mathlib call to sqrt with the LLVM intrinsic.
This avoids pessimistic codegen that has to account for setting errno and can enable vectorization.
Definition at line 732 of file AggressiveInstCombine.cpp.
References Call, and llvm::cannotBeOrderedLessThanZero().
Referenced by foldLibCalls().
|
static |
This is the entry point for folds that could be implemented in regular InstCombine, but they are separated because they are not expected to occur frequently and/or have more than a constant-length pattern match.
Definition at line 2286 of file AggressiveInstCombine.cpp.
References DL, F, foldAnyOrAllBitsSet(), foldConsecutiveLoads(), foldConsecutiveStores(), foldGuardedFunnelShift(), foldICmpOrChain(), foldLibCalls(), foldMulHigh(), foldPatternedLoads(), foldSelectSplitCTLZ(), foldSelectSplitCTTZ(), I, llvm::DominatorTree::isReachableFromEntry(), llvm::make_early_inc_range(), llvm::reverse(), llvm::SimplifyInstructionsInBlock(), tryToFPToSat(), tryToRecognizePopCount(), tryToRecognizePopCount2n3(), tryToRecognizeTableBasedCttz(), and tryToRecognizeTableBasedLog2().
Referenced by runImpl().
|
static |
Definition at line 1553 of file AggressiveInstCombine.cpp.
References DL, llvm::dyn_cast(), GEP, llvm::APInt::getOneBitSet(), llvm::Value::getType(), llvm::APIntOps::GreatestCommonDivisor(), llvm::isa(), llvm::APInt::isNegative(), and llvm::APInt::srem().
Referenced by foldPatternedLoads().
|
static |
Definition at line 764 of file AggressiveInstCombine.cpp.
References llvm::CallingConv::C, llvm::ConstantFoldLoadFromConst(), DL, llvm::dyn_cast_or_null(), llvm::APInt::getOneBitSet(), and Mul.
Referenced by tryToRecognizeTableBasedCttz().
|
static |
Definition at line 927 of file AggressiveInstCombine.cpp.
References llvm::CallingConv::C, llvm::ConstantFoldLoadFromConst(), DL, llvm::dyn_cast_or_null(), llvm::APInt::getLowBitsSet(), llvm::APInt::isZero(), and Mul.
Referenced by tryToRecognizeTableBasedLog2().
This is a recursive helper for foldAnyOrAllBitsSet() that walks through a chain of 'and' or 'or' instructions looking for shift ops of a common source value.
Examples: or (or (or X, (X >> 3)), (X >> 5)), (X >> 8) returns { X, 0x129 } and (and (X >> 1), 1), (X >> 4) returns { X, 0x12 }
Definition at line 400 of file AggressiveInstCombine.cpp.
References llvm::APInt::getBitWidth(), llvm::APInt::getZExtValue(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_LShr(), llvm::PatternMatch::m_One(), llvm::PatternMatch::m_Or(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), matchAndOrChain(), llvm::APInt::setBit(), and llvm::APInt::uge().
Referenced by foldAnyOrAllBitsSet(), and matchAndOrChain().
|
static |
Definition at line 1348 of file AggressiveInstCombine.cpp.
References DL, llvm::dyn_cast(), llvm::Type::getPrimitiveSizeInBits(), llvm::Value::getType(), I, llvm::Type::isIntegerTy(), llvm::PatternMatch::m_LShrOrSelf(), llvm::PatternMatch::m_Trunc(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), and llvm::Value::stripAndAccumulateConstantOffsets().
Referenced by foldConsecutiveStores().
|
static |
Definition at line 1372 of file AggressiveInstCombine.cpp.
References llvm::AAMDNodes::concat(), DL, llvm::drop_begin(), llvm::CallingConv::Fast, llvm::First, llvm::ArrayRef< T >::front(), llvm::Type::getIntNTy(), llvm::DebugLoc::getMergedLocations(), llvm::SmallVectorTemplateBase< T, bool >::push_back(), llvm::SmallVectorImpl< T >::reserve(), and llvm::ArrayRef< T >::size().
Referenced by mergePartStores().
|
static |
Definition at line 1422 of file AggressiveInstCombine.cpp.
References llvm::ArrayRef(), Changed, DL, llvm::SmallVectorTemplateCommon< T, typename >::end(), llvm::First, mergeConsecutivePartStores(), llvm::SmallVectorTemplateCommon< T, typename >::size(), and llvm::sort().
Referenced by foldConsecutiveStores().
Combine away instructions providing they are still equivalent when compared against 0.
i.e do they have any bits set.
Definition at line 1496 of file AggressiveInstCombine.cpp.
References A(), llvm::dyn_cast(), I, llvm::PatternMatchHelpers::m_CombineOr(), llvm::PatternMatch::m_NSWShl(), llvm::PatternMatch::m_NUWShl(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), and optimizeShiftInOrChain().
Referenced by foldICmpOrChain(), and optimizeShiftInOrChain().
|
static |
This is the entry point for all transforms.
Pass manager differences are handled in the callers of this function.
Definition at line 2337 of file AggressiveInstCombine.cpp.
References DL, F, foldUnusualPatterns(), and llvm::TruncInstCombine::run().
| STATISTIC | ( | NumAnyOrAllBitsSet | , |
| "Number of any/all-bits-set patterns folded" | ) |
| STATISTIC | ( | NumGuardedFunnelShifts | , |
| "Number of guarded funnel shifts transformed into funnel shifts" | ) |
| STATISTIC | ( | NumGuardedRotates | , |
| "Number of guarded rotates transformed into funnel shifts" | ) |
| STATISTIC | ( | NumPopCountRecognized | , |
| "Number of popcount idioms recognized" | ) |
| STATISTIC | ( | NumSelectCTLZFolded | , |
| "Number of select-based split ctlz patterns folded" | ) |
| STATISTIC | ( | NumSelectCTTZFolded | , |
| "Number of select-based split cttz patterns folded" | ) |
|
static |
Fold smin(smax(fptosi(x), C1), C2) to llvm.fptosi.sat(x), providing C1 and C2 saturate the value of the fp conversion.
The transform is not reversable as the fptosi.sat is more defined than the input - all values produce a valid value for the fptosi.sat, where as some produce poison for original that were out of range of the integer conversion. The reversed pattern may use fmax and fmin instead. As we cannot directly reverse the transform, and it is not always profitable, we make it conditional on the cost being reported as lower by TTI.
Definition at line 677 of file AggressiveInstCombine.cpp.
References llvm::dyn_cast(), llvm::IntegerType::get(), llvm::VectorType::get(), I, llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_FPToSI(), llvm::MIPatternMatch::m_OneUse(), llvm::PatternMatch::m_SMax(), llvm::PatternMatch::m_SMin(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::TargetTransformInfo::None, and llvm::TargetTransformInfo::TCK_RecipThroughput.
Referenced by foldUnusualPatterns().
|
static |
Definition at line 504 of file AggressiveInstCombine.cpp.
References llvm::cast(), llvm::dbgs(), llvm::APInt::getSplat(), I, llvm::APInt::isSubsetOf(), LLVM_DEBUG, llvm::PatternMatch::m_And(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_c_Add(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_LShr(), llvm::PatternMatch::m_Mul(), llvm::PatternMatch::m_Specific(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Sub(), llvm::PatternMatch::m_Value(), llvm::MaskedValueIsZero(), MaskShift(), and llvm::PatternMatch::match().
Referenced by foldUnusualPatterns().
|
static |
Definition at line 597 of file AggressiveInstCombine.cpp.
References llvm::dbgs(), llvm::APInt::getSplat(), I, llvm::isPowerOf2_32(), LLVM_DEBUG, llvm::PatternMatch::m_Add(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_c_Add(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_LShr(), llvm::PatternMatch::m_Mul(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Sub(), llvm::PatternMatch::m_Value(), and llvm::PatternMatch::match().
Referenced by foldUnusualPatterns().
|
static |
Definition at line 839 of file AggressiveInstCombine.cpp.
References B(), llvm::cast(), llvm::ConstantFoldLoadFromConst(), llvm::MDBuilder::createUnlikelyBranchWeights(), DL, llvm::dyn_cast(), llvm::MapVector< KeyT, ValueT, MapType, VectorType >::front(), GEP, llvm::APInt::getAllOnes(), llvm::GlobalVariable::getInitializer(), llvm::LoadInst::getPointerOperand(), llvm::Type::getScalarSizeInBits(), llvm::Value::getType(), llvm::ConstantInt::getZExtValue(), llvm::GlobalVariable::hasInitializer(), I, llvm::GlobalVariable::isConstant(), isCTTZTable(), llvm::Type::isIntegerTy(), llvm::PatternMatch::m_And(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_c_And(), llvm::PatternMatch::m_CastOrSelf(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_LShr(), llvm::PatternMatch::m_Mul(), llvm::MIPatternMatch::m_Neg(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::ProfcheckDisableMetadataFixes, llvm::Value::replaceAllUsesWith(), Select, and llvm::MapVector< KeyT, ValueT, MapType, VectorType >::size().
Referenced by foldUnusualPatterns().
|
static |
Definition at line 1007 of file AggressiveInstCombine.cpp.
References B(), llvm::cast(), llvm::ConstantFoldLoadFromConst(), llvm::MDBuilder::createUnlikelyBranchWeights(), DL, llvm::dyn_cast(), llvm::MapVector< KeyT, ValueT, MapType, VectorType >::front(), GEP, llvm::PoisonValue::get(), llvm::GlobalVariable::getInitializer(), llvm::LoadInst::getPointerOperand(), llvm::Value::getType(), llvm::GlobalVariable::hasInitializer(), I, llvm::GlobalVariable::isConstant(), llvm::Type::isIntegerTy(), isLog2Table(), llvm::Log2_32(), llvm::PatternMatch::m_APInt(), llvm::PatternMatch::m_c_Or(), llvm::PatternMatch::m_CastOrSelf(), llvm::PatternMatch::m_Deferred(), llvm::PatternMatch::m_LShr(), llvm::PatternMatch::m_Mul(), llvm::PatternMatch::m_SpecificInt(), llvm::PatternMatch::m_Value(), llvm::PatternMatch::match(), llvm::ProfcheckDisableMetadataFixes, llvm::Value::replaceAllUsesWith(), Select, llvm::MapVector< KeyT, ValueT, MapType, VectorType >::size(), llvm::Sub, llvm::TargetTransformInfo::TCC_Basic, llvm::TargetTransformInfo::TCK_SizeAndLatency, X, and Y.
Referenced by foldUnusualPatterns().
|
static |
Referenced by foldLoadsRecursive(), and isMemModifiedBetween().
|
static |
Referenced by foldMemChr().
|
static |