Skip to content

Commit

Permalink
[InstCombine] Use disjoint flag instead of haveNoCommonBitsSet()
Browse files Browse the repository at this point in the history
Slightly stronger, if disjoint was inferred earlier with information
that is no longer available.
  • Loading branch information
nikic committed Dec 5, 2023
1 parent 17168f7 commit cd865e3
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 9 deletions.
4 changes: 1 addition & 3 deletions llvm/lib/Transforms/InstCombine/InstCombineInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,13 +739,11 @@ class Negator final {
using BuilderTy = IRBuilder<TargetFolder, IRBuilderCallbackInserter>;
BuilderTy Builder;

const SimplifyQuery &SQ;

const bool IsTrulyNegation;

SmallDenseMap<Value *, Value *> NegationsCache;

Negator(LLVMContext &C, const SimplifyQuery &SQ, bool IsTrulyNegation);
Negator(LLVMContext &C, const DataLayout &DL, bool IsTrulyNegation);

#if LLVM_ENABLE_STATS
unsigned NumValuesVisitedInThisNegator = 0;
Expand Down
11 changes: 5 additions & 6 deletions llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ static cl::opt<unsigned>
cl::desc("What is the maximal lookup depth when trying to "
"check for viability of negation sinking."));

Negator::Negator(LLVMContext &C, const SimplifyQuery &SQ, bool IsTrulyNegation_)
: Builder(C, TargetFolder(SQ.DL),
Negator::Negator(LLVMContext &C, const DataLayout &DL, bool IsTrulyNegation_)
: Builder(C, TargetFolder(DL),
IRBuilderCallbackInserter([&](Instruction *I) {
++NegatorNumInstructionsCreatedTotal;
NewInstructions.push_back(I);
})),
SQ(SQ), IsTrulyNegation(IsTrulyNegation_) {}
IsTrulyNegation(IsTrulyNegation_) {}

#if LLVM_ENABLE_STATS
Negator::~Negator() {
Expand Down Expand Up @@ -402,8 +402,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
I->getName() + ".neg", /* HasNUW */ false, IsNSW);
}
case Instruction::Or: {
if (!haveNoCommonBitsSet(I->getOperand(0), I->getOperand(1),
SQ.getWithInstruction(I)))
if (!cast<PossiblyDisjointInst>(I)->isDisjoint())
return nullptr; // Don't know how to handle `or` in general.
std::array<Value *, 2> Ops = getSortedOperandsOfBinOp(I);
// `or`/`add` are interchangeable when operands have no common bits set.
Expand Down Expand Up @@ -539,7 +538,7 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
if (!NegatorEnabled || !DebugCounter::shouldExecute(NegatorCounter))
return nullptr;

Negator N(Root->getContext(), IC.getSimplifyQuery(), LHSIsZero);
Negator N(Root->getContext(), IC.getDataLayout(), LHSIsZero);
std::optional<Result> Res = N.run(Root, IsNSW);
if (!Res) { // Negation failed.
LLVM_DEBUG(dbgs() << "Negator: failed to sink negation into " << *Root
Expand Down
11 changes: 11 additions & 0 deletions llvm/test/Transforms/InstCombine/sub-of-negatible.ll
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,17 @@ define i8 @negation_of_increment_via_or_common_bits_set(i8 %x, i8 %y) {
ret i8 %t2
}

define i8 @negation_of_increment_via_or_disjoint(i8 %x, i8 %y) {
; CHECK-LABEL: @negation_of_increment_via_or_disjoint(
; CHECK-NEXT: [[T1_NEG:%.*]] = xor i8 [[Y:%.*]], -1
; CHECK-NEXT: [[T2:%.*]] = add i8 [[T1_NEG]], [[X:%.*]]
; CHECK-NEXT: ret i8 [[T2]]
;
%t1 = or disjoint i8 %y, 1
%t2 = sub i8 %x, %t1
ret i8 %t2
}

; 'or' of operands with no common bits set is 'add'
define i8 @add_via_or_with_no_common_bits_set(i8 %x, i8 %y) {
; CHECK-LABEL: @add_via_or_with_no_common_bits_set(
Expand Down

0 comments on commit cd865e3

Please sign in to comment.