[llvm] [InstCombine] Remove `sub nuw C_Mask, X` -> `xor X, C_Mask` canoncalization (PR #122607)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Jan 11 13:30:14 PST 2025
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff 8a1174f06cb69c92290a2231ede0e2a8e8460e0c 8ee0ed1e361809d2cfb3c59ab777b2351c1ab191 --extensions cpp,h -- llvm/include/llvm/IR/PatternMatch.h llvm/lib/Analysis/InstructionSimplify.cpp llvm/lib/Analysis/ValueTracking.cpp llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
``````````
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index f6af0dcb65..f8e2cf05cd 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2155,8 +2155,8 @@ static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
// ((X | Y) ^ Y ) & ((X | Y) ^ X) --> 0
BinaryOperator *Or;
if (match(Op0, m_c_XorLike(m_Value(X),
- m_CombineAnd(m_BinOp(Or),
- m_c_Or(m_Deferred(X), m_Value(Y))))) &&
+ m_CombineAnd(m_BinOp(Or), m_c_Or(m_Deferred(X),
+ m_Value(Y))))) &&
match(Op1, m_c_XorLike(m_Specific(Or), m_Specific(Y))))
return Constant::getNullValue(Op0->getType());
@@ -5097,7 +5097,8 @@ static Value *simplifyGEPInst(Type *SrcTy, Value *Ptr,
}
// gep (gep V, C), (xor V, -1) -> C-1
if (match(Indices.back(),
- m_XorLike(m_PtrToInt(m_Specific(StrippedBasePtr)), m_AllOnes())) &&
+ m_XorLike(m_PtrToInt(m_Specific(StrippedBasePtr)),
+ m_AllOnes())) &&
!BasePtrOffset.isOne()) {
auto *CI = ConstantInt::get(GEPTy->getContext(), BasePtrOffset - 1);
return ConstantExpr::getIntToPtr(CI, GEPTy);
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
index e24fbc3ca9..9e907eaa73 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp
@@ -2671,8 +2671,8 @@ Instruction *InstCombinerImpl::visitSub(BinaryOperator &I) {
const APInt *ShAmt;
Type *Ty = I.getType();
unsigned BitWidth = Ty->getScalarSizeInBits();
- if (match(Op1, m_AShr(m_Value(A), m_APInt(ShAmt))) &&
- Op1->hasNUses(2) && *ShAmt == BitWidth - 1 &&
+ if (match(Op1, m_AShr(m_Value(A), m_APInt(ShAmt))) && Op1->hasNUses(2) &&
+ *ShAmt == BitWidth - 1 &&
match(Op0, m_OneUse(m_c_XorLike(m_Specific(A), m_Specific(Op1))))) {
// B = ashr i32 A, 31 ; smear the sign bit
// sub (xor A, B), B ; flip bits if negative and subtract -1 (add 1)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index ced3677431..1f574ff9d7 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2056,9 +2056,9 @@ static Instruction *foldComplexAndOrPatterns(BinaryOperator &I,
// (~(A & B) | C) & ~(C & (A ^ B)) --> (A ^ B ^ C) | ~(A | C) is invalid.
if (Opcode == Instruction::Or && Op0->hasOneUse() &&
match(Op1, m_OneUse(m_Not(m_CombineAnd(
- m_Value(Y),
- m_c_BinOp(Opcode, m_Specific(C),
- m_c_XorLike(m_Specific(A), m_Specific(B)))))))) {
+ m_Value(Y), m_c_BinOp(Opcode, m_Specific(C),
+ m_c_XorLike(m_Specific(A),
+ m_Specific(B)))))))) {
// X = ~(A | B)
// Y = (C | (A ^ B)
Value *Or = cast<BinaryOperator>(X)->getOperand(0);
@@ -2684,7 +2684,8 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
// (A ^ B) & ((B ^ C) ^ A) -> (A ^ B) & ~C
if (match(Op0, m_XorLike(m_Value(A), m_Value(B))) &&
- match(Op1, m_XorLike(m_XorLike(m_Specific(B), m_Value(C)), m_Specific(A)))) {
+ match(Op1,
+ m_XorLike(m_XorLike(m_Specific(B), m_Value(C)), m_Specific(A)))) {
Value *NotC = Op1->hasOneUse()
? Builder.CreateNot(C)
: getFreelyInverted(C, C->hasOneUse(), &Builder);
@@ -3623,7 +3624,8 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
Value *X, *Y;
const APInt *CV;
- if (match(&I, m_c_Or(m_OneUse(m_XorLike(m_Value(X), m_APInt(CV))), m_Value(Y))) &&
+ if (match(&I,
+ m_c_Or(m_OneUse(m_XorLike(m_Value(X), m_APInt(CV))), m_Value(Y))) &&
!CV->isAllOnes() && MaskedValueIsZero(Y, *CV, 0, &I)) {
// (X ^ C) | Y -> (X | Y) ^ C iff Y & C == 0
// The check for a 'not' op is for efficiency (if Y is known zero --> ~X).
@@ -3732,16 +3734,18 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
// (A ^ B) | ((B ^ C) ^ A) -> (A ^ B) | C
if (match(Op0, m_XorLike(m_Value(A), m_Value(B))))
- if (match(Op1,
- m_c_XorLike(m_c_XorLike(m_Specific(B), m_Value(C)), m_Specific(A))) ||
- match(Op1, m_c_XorLike(m_c_XorLike(m_Specific(A), m_Value(C)), m_Specific(B))))
+ if (match(Op1, m_c_XorLike(m_c_XorLike(m_Specific(B), m_Value(C)),
+ m_Specific(A))) ||
+ match(Op1, m_c_XorLike(m_c_XorLike(m_Specific(A), m_Value(C)),
+ m_Specific(B))))
return BinaryOperator::CreateOr(Op0, C);
// ((B ^ C) ^ A) | (A ^ B) -> (A ^ B) | C
if (match(Op1, m_XorLike(m_Value(A), m_Value(B))))
- if (match(Op0,
- m_c_XorLike(m_c_XorLike(m_Specific(B), m_Value(C)), m_Specific(A))) ||
- match(Op0, m_c_XorLike(m_c_XorLike(m_Specific(A), m_Value(C)), m_Specific(B))))
+ if (match(Op0, m_c_XorLike(m_c_XorLike(m_Specific(B), m_Value(C)),
+ m_Specific(A))) ||
+ match(Op0, m_c_XorLike(m_c_XorLike(m_Specific(A), m_Value(C)),
+ m_Specific(B))))
return BinaryOperator::CreateOr(Op1, C);
if (Instruction *DeMorgan = matchDeMorgansLaws(I, *this))
@@ -3881,9 +3885,10 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
// ((A & B) ^ B) | ((A & B) ^ A) -> A ^ B
// (B ^ (A & B)) | (A ^ (A & B)) -> A ^ B
const auto TryXorOpt = [&](Value *Lhs, Value *Rhs) -> Instruction * {
- if (match(Lhs, m_c_XorLike(m_And(m_Value(A), m_Value(B)), m_Deferred(A))) &&
- match(Rhs,
- m_c_XorLike(m_And(m_Specific(A), m_Specific(B)), m_Specific(B)))) {
+ if (match(Lhs,
+ m_c_XorLike(m_And(m_Value(A), m_Value(B)), m_Deferred(A))) &&
+ match(Rhs, m_c_XorLike(m_And(m_Specific(A), m_Specific(B)),
+ m_Specific(B)))) {
return BinaryOperator::CreateXor(A, B);
}
return nullptr;
@@ -4083,7 +4088,7 @@ static Instruction *foldXorToXor(BinaryOperator &I,
// (A | B) ^ (A & B) -> A ^ B
// (A | B) ^ (B & A) -> A ^ B
if (match(&I, m_c_XorLike(m_And(m_Value(A), m_Value(B)),
- m_c_Or(m_Deferred(A), m_Deferred(B)))))
+ m_c_Or(m_Deferred(A), m_Deferred(B)))))
return BinaryOperator::CreateXor(A, B);
// (A | ~B) ^ (~A | B) -> A ^ B
@@ -4091,7 +4096,7 @@ static Instruction *foldXorToXor(BinaryOperator &I,
// (~A | B) ^ (A | ~B) -> A ^ B
// (B | ~A) ^ (A | ~B) -> A ^ B
if (match(&I, m_XorLike(m_c_Or(m_Value(A), m_Not(m_Value(B))),
- m_c_Or(m_Not(m_Deferred(A)), m_Deferred(B)))))
+ m_c_Or(m_Not(m_Deferred(A)), m_Deferred(B)))))
return BinaryOperator::CreateXor(A, B);
// (A & ~B) ^ (~A & B) -> A ^ B
@@ -4099,7 +4104,7 @@ static Instruction *foldXorToXor(BinaryOperator &I,
// (~A & B) ^ (A & ~B) -> A ^ B
// (B & ~A) ^ (A & ~B) -> A ^ B
if (match(&I, m_XorLike(m_c_And(m_Value(A), m_Not(m_Value(B))),
- m_c_And(m_Not(m_Deferred(A)), m_Deferred(B)))))
+ m_c_And(m_Not(m_Deferred(A)), m_Deferred(B)))))
return BinaryOperator::CreateXor(A, B);
// For the remaining cases we need to get rid of one of the operands.
@@ -4261,11 +4266,12 @@ static Instruction *visitMaskedMerge(BinaryOperator &I,
InstCombiner::BuilderTy &Builder) {
Value *B, *X, *D;
Value *M;
- if (!match(&I, m_c_XorLike(m_Value(B),
- m_OneUse(m_c_And(
- m_CombineAnd(m_c_XorLike(m_Deferred(B), m_Value(X)),
- m_Value(D)),
- m_Value(M))))))
+ if (!match(&I, m_c_XorLike(
+ m_Value(B),
+ m_OneUse(m_c_And(
+ m_CombineAnd(m_c_XorLike(m_Deferred(B), m_Value(X)),
+ m_Value(D)),
+ m_Value(M))))))
return nullptr;
Value *NotM;
@@ -4690,7 +4696,7 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
// (X | Y) ^ M -> (X ^ M) ^ Y
// (X | Y) ^ M -> (Y ^ M) ^ X
if (match(&I, m_c_XorLike(m_OneUse(m_DisjointOr(m_Value(X), m_Value(Y))),
- m_Value(M)))) {
+ m_Value(M)))) {
if (Value *XorAC = simplifyXorInst(X, M, SQ.getWithInstruction(&I)))
return BinaryOperator::CreateXor(XorAC, Y);
@@ -4703,7 +4709,7 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
// calls in there are unnecessary as SimplifyDemandedInstructionBits should
// have already taken care of those cases.
if (match(&I, m_c_XorLike(m_c_And(m_Not(m_Value(M)), m_Value()),
- m_c_And(m_Deferred(M), m_Value())))) {
+ m_c_And(m_Deferred(M), m_Value())))) {
if (isGuaranteedNotToBeUndef(M))
return BinaryOperator::CreateDisjointOr(Op0, Op1);
else
@@ -4877,15 +4883,15 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
Value *A, *B, *C;
// (A ^ B) ^ (A | C) --> (~A & C) ^ B -- There are 4 commuted variants.
if (match(&I, m_c_XorLike(m_OneUse(m_XorLike(m_Value(A), m_Value(B))),
- m_OneUse(m_c_Or(m_Deferred(A), m_Value(C))))))
- return BinaryOperator::CreateXor(
- Builder.CreateAnd(Builder.CreateNot(A), C), B);
+ m_OneUse(m_c_Or(m_Deferred(A), m_Value(C))))))
+ return BinaryOperator::CreateXor(Builder.CreateAnd(Builder.CreateNot(A), C),
+ B);
// (A ^ B) ^ (B | C) --> (~B & C) ^ A -- There are 4 commuted variants.
if (match(&I, m_c_XorLike(m_OneUse(m_XorLike(m_Value(A), m_Value(B))),
- m_OneUse(m_c_Or(m_Deferred(B), m_Value(C))))))
- return BinaryOperator::CreateXor(
- Builder.CreateAnd(Builder.CreateNot(B), C), A);
+ m_OneUse(m_c_Or(m_Deferred(B), m_Value(C))))))
+ return BinaryOperator::CreateXor(Builder.CreateAnd(Builder.CreateNot(B), C),
+ A);
// (A & B) ^ (A ^ B) -> (A | B)
if (match(Op0, m_And(m_Value(A), m_Value(B))) &&
@@ -4903,7 +4909,8 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
return BinaryOperator::CreateNot(Builder.CreateAnd(A, B));
// (~A & B) ^ A --> A | B -- There are 4 commuted variants.
- if (match(&I, m_c_XorLike(m_c_And(m_Not(m_Value(A)), m_Value(B)), m_Deferred(A))))
+ if (match(&I,
+ m_c_XorLike(m_c_And(m_Not(m_Value(A)), m_Value(B)), m_Deferred(A))))
return BinaryOperator::CreateOr(A, B);
// (~A | B) ^ A --> ~(A & B)
@@ -4932,7 +4939,7 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
// (A & B) ^ (A | C) --> A ? ~B : C -- There are 4 commuted variants.
if (I.getType()->isIntOrIntVectorTy(1) &&
match(&I, m_c_XorLike(m_OneUse(m_LogicalAnd(m_Value(A), m_Value(B))),
- m_OneUse(m_LogicalOr(m_Value(C), m_Value(D)))))) {
+ m_OneUse(m_LogicalOr(m_Value(C), m_Value(D)))))) {
bool NeedFreeze = isa<SelectInst>(Op0) && isa<SelectInst>(Op1) && B == D;
if (B == C || B == D)
std::swap(A, B);
@@ -4961,10 +4968,11 @@ Instruction *InstCombinerImpl::visitXor(BinaryOperator &I) {
// (X ^ C) ^ Y --> (X ^ Y) ^ C
// Just like we do in other places, we completely avoid the fold
// for constantexprs, at least to avoid endless combine loop.
- if (match(&I, m_c_XorLike(m_OneUse(m_XorLike(m_CombineAnd(m_Value(X),
- m_Unless(m_ConstantExpr())),
- m_ImmConstant(C1))),
- m_Value(Y))))
+ if (match(&I, m_c_XorLike(
+ m_OneUse(m_XorLike(
+ m_CombineAnd(m_Value(X), m_Unless(m_ConstantExpr())),
+ m_ImmConstant(C1))),
+ m_Value(Y))))
return BinaryOperator::CreateXor(Builder.CreateXor(X, Y), C1);
if (Instruction *R = reassociateForUses(I, Builder))
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index a02789cd05..d3d571573f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -1662,8 +1662,8 @@ Instruction *InstCombinerImpl::foldICmpXorShiftConst(ICmpInst &Cmp,
return nullptr;
Value *X;
const APInt *ShiftC;
- if (!match(Xor, m_OneUse(m_c_XorLike(m_Value(X),
- m_AShr(m_Deferred(X), m_APInt(ShiftC))))))
+ if (!match(Xor, m_OneUse(m_c_XorLike(
+ m_Value(X), m_AShr(m_Deferred(X), m_APInt(ShiftC))))))
return nullptr;
uint64_t Shift = ShiftC->getLimitedValue();
Type *XType = X->getType();
@@ -4363,7 +4363,8 @@ static bool isMaskOrZero(const Value *V, bool Not, const SimplifyQuery &Q,
return match(V, m_c_XorLike(m_Value(X), m_Neg(m_Deferred(X))));
// (X ^ (X - 1)) is a Mask
else
- return match(V, m_c_XorLike(m_Value(X), m_Add(m_Deferred(X), m_AllOnes())));
+ return match(V,
+ m_c_XorLike(m_Value(X), m_Add(m_Deferred(X), m_AllOnes())));
case Instruction::Select:
// c ? Mask0 : Mask1 is a Mask.
return isMaskOrZero(I->getOperand(1), Not, Q, Depth) &&
@@ -5721,12 +5722,13 @@ static Instruction *foldICmpPow2Test(ICmpInst &I,
if ((Pred == ICmpInst::ICMP_UGE || Pred == ICmpInst::ICMP_ULT) &&
match(Op0, m_OneUse(m_c_XorLike(m_Add(m_Specific(Op1), m_AllOnes()),
- m_Specific(Op1))))) {
+ m_Specific(Op1))))) {
A = Op1;
CheckIs = Pred == ICmpInst::ICMP_UGE;
} else if ((Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_ULE) &&
- match(Op1, m_OneUse(m_c_XorLike(m_Add(m_Specific(Op0), m_AllOnes()),
- m_Specific(Op0))))) {
+ match(Op1,
+ m_OneUse(m_c_XorLike(m_Add(m_Specific(Op0), m_AllOnes()),
+ m_Specific(Op0))))) {
A = Op0;
CheckIs = Pred == ICmpInst::ICMP_ULE;
}
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 27ce207de0..5320a3271e 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -1140,8 +1140,7 @@ static Instruction *foldSelectCtlzToCttz(ICmpInst *ICI, Value *TrueVal,
std::swap(TrueVal, FalseVal);
Value *Ctlz;
- if (!match(FalseVal,
- m_XorLike(m_Value(Ctlz), m_SpecificInt(BitWidth - 1))))
+ if (!match(FalseVal, m_XorLike(m_Value(Ctlz), m_SpecificInt(BitWidth - 1))))
return nullptr;
if (!match(Ctlz, m_Intrinsic<Intrinsic::ctlz>()))
``````````
</details>
https://github.com/llvm/llvm-project/pull/122607
More information about the llvm-commits
mailing list