60#define DEBUG_TYPE "instcombine"
63 "Negator: Number of negations attempted to be sinked");
65 "Negator: Number of negations successfully sinked");
66STATISTIC(NegatorMaxDepthVisited,
"Negator: Maximal traversal depth ever "
67 "reached while attempting to sink negation");
69 "Negator: How many times did the traversal depth limit was reached "
72 NegatorNumValuesVisited,
73 "Negator: Total number of values visited during attempts to sink negation");
75 "Negator: How many negations did we retrieve/reuse from cache");
77 "Negator: Maximal number of values ever visited while attempting to "
80 "Negator: Number of new negated instructions created, total");
82 "Negator: Maximal number of new instructions created during negation "
85 "Negator: Number of new negated instructions created in successful "
86 "negation sinking attempts");
89 "Controls Negator transformations in InstCombine pass");
93 cl::desc(
"Should we attempt to sink negations?"));
98 cl::desc(
"What is the maximal lookup depth when trying to "
99 "check for viability of negation sinking."));
105 ++NegatorNumInstructionsCreatedTotal;
106 NewInstructions.push_back(
I);
108 DL(DL_), AC(AC_), DT(DT_), IsTrulyNegation(IsTrulyNegation_) {}
112 NegatorMaxTotalValuesVisited.updateMax(NumValuesVisitedInThisNegator);
120std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(
Instruction *
I) {
121 assert(
I->getNumOperands() == 2 &&
"Only for binops!");
122 std::array<Value *, 2> Ops{
I->getOperand(0),
I->getOperand(1)};
131[[nodiscard]]
Value *Negator::visitImpl(
Value *V,
bool IsNSW,
unsigned Depth) {
137 if (
V->getType()->isIntOrIntVectorTy(1))
152 if (!isa<Instruction>(V))
158 if (!
V->hasOneUse() && !IsTrulyNegation)
161 auto *
I = cast<Instruction>(V);
162 unsigned BitWidth =
I->getType()->getScalarSizeInBits();
172 switch (
I->getOpcode()) {
173 case Instruction::Add: {
174 std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(
I);
177 return Builder.
CreateNot(Ops[0],
I->getName() +
".neg");
180 case Instruction::Xor:
184 I->getName() +
".neg");
186 case Instruction::AShr:
187 case Instruction::LShr: {
191 Value *BO =
I->getOpcode() == Instruction::AShr
192 ? Builder.
CreateLShr(
I->getOperand(0),
I->getOperand(1))
193 : Builder.
CreateAShr(
I->getOperand(0),
I->getOperand(1));
194 if (
auto *NewInstr = dyn_cast<Instruction>(BO)) {
195 NewInstr->copyIRFlags(
I);
196 NewInstr->
setName(
I->getName() +
".neg");
206 case Instruction::SExt:
207 case Instruction::ZExt:
209 if (
I->getOperand(0)->getType()->isIntOrIntVectorTy(1))
210 return I->getOpcode() == Instruction::SExt
212 I->getName() +
".neg")
214 I->getName() +
".neg");
216 case Instruction::Select: {
219 auto *Sel = cast<SelectInst>(
I);
225 return Builder.
CreateSelect(Sel->getCondition(), NegTrueC, NegFalseC,
226 I->getName() +
".neg",
I);
234 if (
I->getOpcode() == Instruction::Sub &&
239 return Builder.
CreateSub(
I->getOperand(1),
I->getOperand(0),
240 I->getName() +
".neg",
false,
241 IsNSW &&
I->hasNoSignedWrap());
249 switch (
I->getOpcode()) {
250 case Instruction::ZExt: {
254 unsigned SrcWidth =
SrcOp->getType()->getScalarSizeInBits();
255 const APInt &FullShift =
APInt(SrcWidth, SrcWidth - 1);
256 if (IsTrulyNegation &&
263 case Instruction::And: {
269 unsigned BW =
X->getType()->getScalarSizeInBits();
277 case Instruction::SDiv:
281 if (
auto *Op1C = dyn_cast<Constant>(
I->getOperand(1))) {
282 if (!Op1C->containsUndefOrPoisonElement() &&
283 Op1C->isNotMinSignedValue() && Op1C->isNotOneValue()) {
286 I->getName() +
".neg");
287 if (
auto *NewInstr = dyn_cast<Instruction>(BO))
288 NewInstr->setIsExact(
I->isExact());
297 LLVM_DEBUG(
dbgs() <<
"Negator: reached maximal allowed traversal depth in "
298 << *V <<
". Giving up.\n");
299 ++NegatorTimesDepthLimitReached;
303 switch (
I->getOpcode()) {
304 case Instruction::Freeze: {
306 Value *NegOp = negate(
I->getOperand(0), IsNSW,
Depth + 1);
311 case Instruction::PHI: {
313 auto *
PHI = cast<PHINode>(
I);
315 for (
auto I :
zip(
PHI->incoming_values(), NegatedIncomingValues)) {
316 if (!(std::get<1>(
I) =
317 negate(std::get<0>(
I), IsNSW,
Depth + 1)))
322 PHI->getType(),
PHI->getNumOperands(),
PHI->getName() +
".neg");
323 for (
auto I :
zip(NegatedIncomingValues,
PHI->blocks()))
327 case Instruction::Select: {
331 auto *NewSelect = cast<SelectInst>(
I->clone());
333 NewSelect->swapValues();
335 NewSelect->setName(
I->getName() +
".neg");
336 Builder.
Insert(NewSelect);
340 Value *NegOp1 = negate(
I->getOperand(1), IsNSW,
Depth + 1);
343 Value *NegOp2 = negate(
I->getOperand(2), IsNSW,
Depth + 1);
347 return Builder.
CreateSelect(
I->getOperand(0), NegOp1, NegOp2,
348 I->getName() +
".neg",
I);
350 case Instruction::ShuffleVector: {
352 auto *Shuf = cast<ShuffleVectorInst>(
I);
353 Value *NegOp0 = negate(
I->getOperand(0), IsNSW,
Depth + 1);
356 Value *NegOp1 = negate(
I->getOperand(1), IsNSW,
Depth + 1);
360 I->getName() +
".neg");
362 case Instruction::ExtractElement: {
364 auto *EEI = cast<ExtractElementInst>(
I);
365 Value *NegVector = negate(EEI->getVectorOperand(), IsNSW,
Depth + 1);
369 I->getName() +
".neg");
371 case Instruction::InsertElement: {
374 auto *IEI = cast<InsertElementInst>(
I);
375 Value *NegVector = negate(IEI->getOperand(0), IsNSW,
Depth + 1);
378 Value *NegNewElt = negate(IEI->getOperand(1), IsNSW,
Depth + 1);
382 I->getName() +
".neg");
384 case Instruction::Trunc: {
386 Value *NegOp = negate(
I->getOperand(0),
false,
Depth + 1);
389 return Builder.
CreateTrunc(NegOp,
I->getType(),
I->getName() +
".neg");
391 case Instruction::Shl: {
393 IsNSW &=
I->hasNoSignedWrap();
394 if (
Value *NegOp0 = negate(
I->getOperand(0), IsNSW,
Depth + 1))
395 return Builder.
CreateShl(NegOp0,
I->getOperand(1),
I->getName() +
".neg",
398 auto *Op1C = dyn_cast<Constant>(
I->getOperand(1));
399 if (!Op1C || !IsTrulyNegation)
404 I->getName() +
".neg",
false, IsNSW);
406 case Instruction::Or: {
410 std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(
I);
414 return Builder.
CreateNot(Ops[0],
I->getName() +
".neg");
418 case Instruction::Add: {
429 if (!IsTrulyNegation)
434 "Internal consistency check failed.");
436 if (NegatedOps.
size() == 2)
437 return Builder.
CreateAdd(NegatedOps[0], NegatedOps[1],
438 I->getName() +
".neg");
439 assert(IsTrulyNegation &&
"We should have early-exited then.");
441 if (NonNegatedOps.
size() == 2)
444 return Builder.
CreateSub(NegatedOps[0], NonNegatedOps[0],
445 I->getName() +
".neg");
447 case Instruction::Xor: {
448 std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(
I);
451 if (
auto *
C = dyn_cast<Constant>(Ops[1])) {
454 I->getName() +
".neg");
458 case Instruction::Mul: {
459 std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(
I);
461 Value *NegatedOp, *OtherOp;
464 if (
Value *NegOp1 = negate(Ops[1],
false,
Depth + 1)) {
467 }
else if (
Value *NegOp0 = negate(Ops[0],
false,
Depth + 1)) {
473 return Builder.
CreateMul(NegatedOp, OtherOp,
I->getName() +
".neg",
474 false, IsNSW &&
I->hasNoSignedWrap());
483[[nodiscard]]
Value *Negator::negate(
Value *V,
bool IsNSW,
unsigned Depth) {
484 NegatorMaxDepthVisited.updateMax(
Depth);
485 ++NegatorNumValuesVisited;
488 ++NumValuesVisitedInThisNegator;
493 Value *Placeholder =
reinterpret_cast<Value *
>(
static_cast<uintptr_t
>(-1));
497 auto NegationsCacheIterator = NegationsCache.find(V);
498 if (NegationsCacheIterator != NegationsCache.end()) {
499 ++NegatorNumNegationsFoundInCache;
500 Value *NegatedV = NegationsCacheIterator->second;
501 assert(NegatedV != Placeholder &&
"Encountered a cycle during negation.");
509 NegationsCache[
V] = Placeholder;
515 NegationsCache[
V] = NegatedV;
520[[nodiscard]] std::optional<Negator::Result> Negator::run(
Value *Root,
522 Value *Negated = negate(Root, IsNSW, 0);
527 I->eraseFromParent();
535 ++NegatorTotalNegationsAttempted;
536 LLVM_DEBUG(
dbgs() <<
"Negator: attempting to sink negation into " << *Root
544 std::optional<Result> Res =
N.run(Root, IsNSW);
546 LLVM_DEBUG(
dbgs() <<
"Negator: failed to sink negation into " << *Root
551 LLVM_DEBUG(
dbgs() <<
"Negator: successfully sunk negation into " << *Root
552 <<
"\n NEW: " << *Res->second <<
"\n");
553 ++NegatorNumTreesNegated;
565 <<
" instrs to InstCombine\n");
566 NegatorMaxInstructionsCreated.updateMax(Res->first.size());
567 NegatorNumInstructionsNegatedSuccess += Res->first.size();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements a class to represent arbitrary precision integral constant values and operations...
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.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
This defines the Use class.
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
A cache of @llvm.assume calls within a function.
static Constant * getNot(Constant *C)
static Constant * getShl(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static Constant * getNeg(Constant *C, bool HasNUW=false, bool HasNSW=false)
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
This is an important base class in LLVM.
static Constant * getAllOnesValue(Type *Ty)
This class represents an Operation in the Expression.
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.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateNot(Value *V, const Twine &Name="")
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateSDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
void ClearInsertionPoint()
Clear the insertion point: created instructions will not be inserted into a block.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateTruncOrBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
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.
AssumptionCache & getAssumptionCache() const
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)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetFolder - Create constants with target dependent folding.
LLVM Value Representation.
void setName(const Twine &Name)
Change the name of the value.
LLVMContext & getContext() const
All values hold a context through their type.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#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< LHS, RHS, Instruction::And, true > m_c_And(const LHS &L, const RHS &R)
Matches an And with LHS and RHS in either order.
bool match(Val *V, const Pattern &P)
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.
OneUse_match< T > m_OneUse(const T &SubPattern)
BinaryOp_match< cst_pred_ty< is_zero_int >, ValTy, Instruction::Sub > m_Neg(const ValTy &V)
Matches a 'Neg' as 'sub 0, V'.
match_combine_and< class_match< Constant >, match_unless< constantexpr_match > > m_ImmConstant()
Match an arbitrary immediate Constant and ignore it.
match_combine_or< CastClass_match< OpTy, Instruction::Trunc >, OpTy > m_TruncOrSelf(const OpTy &Op)
specific_intval< true > m_SpecificIntAllowUndef(APInt V)
apint_match m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
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.
BinaryOp_match< cst_pred_ty< is_all_ones >, ValTy, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
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.
bool isKnownNegation(const Value *X, const Value *Y, bool NeedNSW=false)
Return true if the two given values are negation.
auto reverse(ContainerTy &&C)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool haveNoCommonBitsSet(const Value *LHS, const Value *RHS, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if LHS and RHS have no common bits set.
@ Xor
Bitwise or logical XOR of integers.
constexpr unsigned BitWidth
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.