51#define DEBUG_TYPE "instcombine" 
   54          "Negator: Number of negations attempted to be sinked");
 
   56          "Negator: Number of negations successfully sinked");
 
   57STATISTIC(NegatorMaxDepthVisited, 
"Negator: Maximal traversal depth ever " 
   58                                  "reached while attempting to sink negation");
 
   60          "Negator: How many times did the traversal depth limit was reached " 
   63    NegatorNumValuesVisited,
 
   64    "Negator: Total number of values visited during attempts to sink negation");
 
   66          "Negator: How many negations did we retrieve/reuse from cache");
 
   68          "Negator: Maximal number of values ever visited while attempting to " 
   71          "Negator: Number of new negated instructions created, total");
 
   73          "Negator: Maximal number of new instructions created during negation " 
   76          "Negator: Number of new negated instructions created in successful " 
   77          "negation sinking attempts");
 
   80              "Controls Negator transformations in InstCombine pass");
 
   84                   cl::desc(
"Should we attempt to sink negations?"));
 
   89                    cl::desc(
"What is the maximal lookup depth when trying to " 
   90                             "check for viability of negation sinking."));
 
   93                 bool IsTrulyNegation_)
 
   96                ++NegatorNumInstructionsCreatedTotal;
 
   97                NewInstructions.push_back(
I);
 
   99      DT(DT_), IsTrulyNegation(IsTrulyNegation_) {}
 
  103  NegatorMaxTotalValuesVisited.updateMax(NumValuesVisitedInThisNegator);
 
  111std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(
Instruction *
I) {
 
  112  assert(
I->getNumOperands() == 2 && 
"Only for binops!");
 
  113  std::array<Value *, 2> 
Ops{
I->getOperand(0), 
I->getOperand(1)};
 
  122[[nodiscard]] 
Value *Negator::visitImpl(
Value *V, 
bool IsNSW, 
unsigned Depth) {
 
  128  if (
V->getType()->isIntOrIntVectorTy(1))
 
  149  if (!
V->hasOneUse() && !IsTrulyNegation)
 
  153  unsigned BitWidth = 
I->getType()->getScalarSizeInBits();
 
  157  InstCombiner::BuilderTy::InsertPointGuard Guard(Builder);
 
  160  Builder.SetInsertPoint(
I);
 
  163  switch (
I->getOpcode()) {
 
  164  case Instruction::Add: {
 
  165    std::array<Value *, 2> 
Ops = getSortedOperandsOfBinOp(
I);
 
  168      return Builder.CreateNot(
Ops[0], 
I->getName() + 
".neg");
 
  171  case Instruction::Xor:
 
  174      return Builder.CreateAdd(
X, ConstantInt::get(
X->getType(), 1),
 
  175                               I->getName() + 
".neg");
 
  177  case Instruction::AShr:
 
  178  case Instruction::LShr: {
 
  182      Value *BO = 
I->getOpcode() == Instruction::AShr
 
  183                      ? Builder.CreateLShr(
I->getOperand(0), 
I->getOperand(1))
 
  184                      : Builder.CreateAShr(
I->getOperand(0), 
I->getOperand(1));
 
  186        NewInstr->copyIRFlags(
I);
 
  187        NewInstr->setName(
I->getName() + 
".neg");
 
  197  case Instruction::SExt:
 
  198  case Instruction::ZExt:
 
  200    if (
I->getOperand(0)->getType()->isIntOrIntVectorTy(1))
 
  201      return I->getOpcode() == Instruction::SExt
 
  202                 ? Builder.CreateZExt(
I->getOperand(0), 
I->getType(),
 
  203                                      I->getName() + 
".neg")
 
  204                 : Builder.CreateSExt(
I->getOperand(0), 
I->getType(),
 
  205                                      I->getName() + 
".neg");
 
  207  case Instruction::Select: {
 
  216      return Builder.CreateSelect(Sel->getCondition(), NegTrueC, NegFalseC,
 
  217                                  I->getName() + 
".neg", 
I);
 
  221  case Instruction::Call:
 
  223      return Builder.CreateIntrinsic(CI->getType(), CI->getIntrinsicID(),
 
  224                                     {CI->getRHS(), CI->getLHS()});
 
  230  if (
I->getOpcode() == Instruction::Sub &&
 
  235    return Builder.CreateSub(
I->getOperand(1), 
I->getOperand(0),
 
  236                             I->getName() + 
".neg", 
false,
 
  237                             IsNSW && 
I->hasNoSignedWrap());
 
  245  switch (
I->getOpcode()) {
 
  246  case Instruction::ZExt: {
 
  249    Value *SrcOp = 
I->getOperand(0);
 
  251    const APInt &FullShift = APInt(SrcWidth, SrcWidth - 1);
 
  252    if (IsTrulyNegation &&
 
  254      Value *Ashr = Builder.CreateAShr(
X, FullShift);
 
  255      return Builder.CreateSExt(Ashr, 
I->getType());
 
  259  case Instruction::And: {
 
  265      unsigned BW = 
X->getType()->getScalarSizeInBits();
 
  266      Constant *BWMinusOne = ConstantInt::get(
X->getType(), BW - 1);
 
  267      Value *
R = Builder.CreateShl(
X, Builder.CreateSub(BWMinusOne, ShAmt));
 
  268      R = Builder.CreateAShr(R, BWMinusOne);
 
  269      return Builder.CreateTruncOrBitCast(R, 
I->getType());
 
  273  case Instruction::SDiv:
 
  278      if (!Op1C->containsUndefOrPoisonElement() &&
 
  279          Op1C->isNotMinSignedValue() && Op1C->isNotOneValue()) {
 
  284          NewInstr->setIsExact(
I->isExact());
 
  293    LLVM_DEBUG(
dbgs() << 
"Negator: reached maximal allowed traversal depth in " 
  294                      << *V << 
". Giving up.\n");
 
  295    ++NegatorTimesDepthLimitReached;
 
  299  switch (
I->getOpcode()) {
 
  300  case Instruction::Freeze: {
 
  302    Value *NegOp = negate(
I->getOperand(0), IsNSW, 
Depth + 1);
 
  305    return Builder.CreateFreeze(NegOp, 
I->getName() + 
".neg");
 
  307  case Instruction::PHI: {
 
  311    for (
auto I : 
zip(
PHI->incoming_values(), NegatedIncomingValues)) {
 
  313      if (DT.dominates(
PHI->getParent(), std::get<0>(
I)))
 
  315      if (!(std::get<1>(
I) =
 
  316                negate(std::get<0>(
I), IsNSW, 
Depth + 1))) 
 
  320    PHINode *NegatedPHI = Builder.CreatePHI(
 
  321        PHI->getType(), 
PHI->getNumOperands(), 
PHI->getName() + 
".neg");
 
  322    for (
auto I : 
zip(NegatedIncomingValues, 
PHI->blocks()))
 
  326  case Instruction::Select: {
 
  333      NewSelect->swapValues();
 
  335      NewSelect->setName(
I->getName() + 
".neg");
 
  337      Value *TV = NewSelect->getTrueValue();
 
  338      Value *FV = NewSelect->getFalseValue();
 
  347      Builder.Insert(NewSelect);
 
  351    Value *NegOp1 = negate(
I->getOperand(1), IsNSW, 
Depth + 1);
 
  354    Value *NegOp2 = negate(
I->getOperand(2), IsNSW, 
Depth + 1);
 
  358    return Builder.CreateSelect(
I->getOperand(0), NegOp1, NegOp2,
 
  359                                I->getName() + 
".neg", 
I);
 
  361  case Instruction::ShuffleVector: {
 
  364    Value *NegOp0 = negate(
I->getOperand(0), IsNSW, 
Depth + 1);
 
  367    Value *NegOp1 = negate(
I->getOperand(1), IsNSW, 
Depth + 1);
 
  370    return Builder.CreateShuffleVector(NegOp0, NegOp1, Shuf->getShuffleMask(),
 
  371                                       I->getName() + 
".neg");
 
  373  case Instruction::ExtractElement: {
 
  376    Value *NegVector = negate(EEI->getVectorOperand(), IsNSW, 
Depth + 1);
 
  379    return Builder.CreateExtractElement(NegVector, EEI->getIndexOperand(),
 
  380                                        I->getName() + 
".neg");
 
  382  case Instruction::InsertElement: {
 
  386    Value *NegVector = negate(IEI->getOperand(0), IsNSW, 
Depth + 1);
 
  389    Value *NegNewElt = negate(IEI->getOperand(1), IsNSW, 
Depth + 1);
 
  392    return Builder.CreateInsertElement(NegVector, NegNewElt, IEI->getOperand(2),
 
  393                                       I->getName() + 
".neg");
 
  395  case Instruction::Trunc: {
 
  397    Value *NegOp = negate(
I->getOperand(0),  
false, 
Depth + 1);
 
  400    return Builder.CreateTrunc(NegOp, 
I->getType(), 
I->getName() + 
".neg");
 
  402  case Instruction::Shl: {
 
  404    IsNSW &= 
I->hasNoSignedWrap();
 
  405    if (
Value *NegOp0 = negate(
I->getOperand(0), IsNSW, 
Depth + 1))
 
  406      return Builder.CreateShl(NegOp0, 
I->getOperand(1), 
I->getName() + 
".neg",
 
  412    return Builder.CreateMul(
 
  415        I->getName() + 
".neg", 
false, IsNSW);
 
  417  case Instruction::Or: {
 
  420    std::array<Value *, 2> 
Ops = getSortedOperandsOfBinOp(
I);
 
  424      return Builder.CreateNot(
Ops[0], 
I->getName() + 
".neg");
 
  428  case Instruction::Add: {
 
  430    SmallVector<Value *, 2> NegatedOps, NonNegatedOps;
 
  439      if (!IsTrulyNegation)
 
  444           "Internal consistency check failed.");
 
  446    if (NegatedOps.
size() == 2) 
 
  447      return Builder.CreateAdd(NegatedOps[0], NegatedOps[1],
 
  448                               I->getName() + 
".neg");
 
  449    assert(IsTrulyNegation && 
"We should have early-exited then.");
 
  451    if (NonNegatedOps.
size() == 2)
 
  454    return Builder.CreateSub(NegatedOps[0], NonNegatedOps[0],
 
  455                             I->getName() + 
".neg");
 
  457  case Instruction::Xor: {
 
  458    std::array<Value *, 2> 
Ops = getSortedOperandsOfBinOp(
I);
 
  462      if (IsTrulyNegation) {
 
  464        return Builder.CreateAdd(
Xor, ConstantInt::get(
Xor->getType(), 1),
 
  465                                 I->getName() + 
".neg");
 
  470  case Instruction::Mul: {
 
  471    std::array<Value *, 2> 
Ops = getSortedOperandsOfBinOp(
I);
 
  473    Value *NegatedOp, *OtherOp;
 
  479    } 
else if (
Value *NegOp0 = negate(
Ops[0],  
false, 
Depth + 1)) {
 
  485    return Builder.CreateMul(NegatedOp, OtherOp, 
I->getName() + 
".neg",
 
  486                             false, IsNSW && 
I->hasNoSignedWrap());
 
  495[[nodiscard]] 
Value *Negator::negate(
Value *V, 
bool IsNSW, 
unsigned Depth) {
 
  496  NegatorMaxDepthVisited.updateMax(
Depth);
 
  497  ++NegatorNumValuesVisited;
 
  500  ++NumValuesVisitedInThisNegator;
 
  505  Value *Placeholder = 
reinterpret_cast<Value *
>(
static_cast<uintptr_t
>(-1));
 
  509  auto NegationsCacheIterator = NegationsCache.find(V);
 
  510  if (NegationsCacheIterator != NegationsCache.end()) {
 
  511    ++NegatorNumNegationsFoundInCache;
 
  512    Value *NegatedV = NegationsCacheIterator->second;
 
  513    assert(NegatedV != Placeholder && 
"Encountered a cycle during negation.");
 
  521  NegationsCache[
V] = Placeholder;
 
  527  NegationsCache[
V] = NegatedV;
 
  532[[nodiscard]] std::optional<Negator::Result> Negator::run(
Value *Root,
 
  534  Value *Negated = negate(Root, IsNSW, 0);
 
  539      I->eraseFromParent();
 
  547  ++NegatorTotalNegationsAttempted;
 
  548  LLVM_DEBUG(
dbgs() << 
"Negator: attempting to sink negation into " << *Root
 
  556  std::optional<Result> Res = 
N.run(Root, IsNSW);
 
  558    LLVM_DEBUG(
dbgs() << 
"Negator: failed to sink negation into " << *Root
 
  563  LLVM_DEBUG(
dbgs() << 
"Negator: successfully sunk negation into " << *Root
 
  564                    << 
"\n         NEW: " << *Res->second << 
"\n");
 
  565  ++NegatorNumTreesNegated;
 
  577                    << 
" instrs to InstCombine\n");
 
  578  NegatorMaxInstructionsCreated.updateMax(Res->first.size());
 
  579  NegatorNumInstructionsNegatedSuccess += Res->first.size();
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
This file implements a class to represent arbitrary precision integral constant values and operations...
 
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
 
This file contains the declarations for the subclasses of Constant, which represent the different fla...
 
This file provides an implementation of debug counters.
 
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
 
This file defines the DenseMap class.
 
This defines the Use class.
 
This file provides internal interfaces used to implement the InstCombine.
 
static constexpr unsigned NegatorDefaultMaxDepth
 
static cl::opt< bool > NegatorEnabled("instcombine-negator-enabled", cl::init(true), cl::desc("Should we attempt to sink negations?"))
 
static cl::opt< unsigned > NegatorMaxDepth("instcombine-negator-max-depth", cl::init(NegatorDefaultMaxDepth), cl::desc("What is the maximal lookup depth when trying to " "check for viability of negation sinking."))
 
This file provides the interface for the instcombine pass implementation.
 
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
 
This file defines the SmallVector class.
 
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
 
#define STATISTIC(VARNAME, DESC)
 
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
 
static LLVM_ABI Constant * getNot(Constant *C)
 
static LLVM_ABI Constant * getNeg(Constant *C, bool HasNSW=false)
 
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
 
A parsed version of the target data layout string in and methods for querying it.
 
static bool shouldExecute(unsigned CounterName)
 
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
 
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
 
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
 
void ClearInsertionPoint()
Clear the insertion point: created instructions will not be inserted into a block.
 
Provides an 'InsertHelper' that calls a user-provided callback after performing the default insertion...
 
const DataLayout & getDataLayout() const
 
DominatorTree & getDominatorTree() const
 
static unsigned getComplexity(Value *V)
Assign a complexity or rank value to LLVM Values.
 
This is an important class for using LLVM in a threaded context.
 
static Value * Negate(bool LHSIsZero, bool IsNSW, Value *Root, InstCombinerImpl &IC)
Attempt to negate Root.
 
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
 
reference emplace_back(ArgTypes &&... Args)
 
TargetFolder - Create constants with target dependent folding.
 
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
 
LLVM Value Representation.
 
Type * getType() const
All values are typed, get the type of this value.
 
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
 
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
@ C
The default llvm calling convention, compatible with C.
 
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
 
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
 
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
 
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
 
match_combine_or< CastInst_match< OpTy, TruncInst >, OpTy > m_TruncOrSelf(const OpTy &Op)
 
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
 
bool match(Val *V, const Pattern &P)
 
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
 
specific_intval< true > m_SpecificIntAllowPoison(const APInt &V)
 
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
 
cst_pred_ty< is_any_apint > m_AnyIntegralConstant()
Match an integer or vector with any integral constant.
 
match_immconstant_ty m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
 
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
 
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
 
auto m_Undef()
Match an arbitrary undef constant.
 
initializer< Ty > init(const Ty &Val)
 
This is an optimization pass for GlobalISel generic memory operations.
 
detail::zippy< detail::zip_shortest, T, U, Args... > zip(T &&t, U &&u, Args &&...args)
zip iterator for two or more iteratable types.
 
FunctionAddr VTableAddr Value
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
auto reverse(ContainerTy &&C)
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
 
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
 
@ Xor
Bitwise or logical XOR of integers.
 
DWARFExpression::Operation Op
 
ArrayRef(const T &OneElt) -> ArrayRef< T >
 
constexpr unsigned BitWidth
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
LLVM_ABI bool isKnownNegation(const Value *X, const Value *Y, bool NeedNSW=false, bool AllowPoison=true)
Return true if the two given values are negation.
 
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.