[llvm] 4444a7e - [InstSimplify] Simplify the expression `(a^c)&(a^~c)` to zero and (a^c) | (a^~c) to minus one (#76637)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 3 03:01:06 PST 2024
Author: ChipsSpectre
Date: 2024-01-03T12:01:02+01:00
New Revision: 4444a7e89a1e1c750f25e1673d54627a56fe0f9f
URL: https://github.com/llvm/llvm-project/commit/4444a7e89a1e1c750f25e1673d54627a56fe0f9f
DIFF: https://github.com/llvm/llvm-project/commit/4444a7e89a1e1c750f25e1673d54627a56fe0f9f.diff
LOG: [InstSimplify] Simplify the expression `(a^c)&(a^~c)` to zero and (a^c) | (a^~c) to minus one (#76637)
Changes the InstSimplify pass of the LLVM optimizer, such that the
aforementioned expression is reduced to zero if c2==~c1.
Alive2: https://alive2.llvm.org/ce/z/xkQiid
Fixes https://github.com/llvm/llvm-project/issues/75692.
Added:
Modified:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstCombine/and-xor-merge.ll
llvm/test/Transforms/InstCombine/or-xor.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 78a8334763340e..241bdd81b75a97 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2204,6 +2204,13 @@ static Value *simplifyAndInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
match(Op1, m_c_Xor(m_Specific(Or), m_Specific(Y))))
return Constant::getNullValue(Op0->getType());
+ const APInt *C1;
+ Value *A;
+ // (A ^ C) & (A ^ ~C) -> 0
+ if (match(Op0, m_Xor(m_Value(A), m_APInt(C1))) &&
+ match(Op1, m_Xor(m_Specific(A), m_SpecificInt(~*C1))))
+ return Constant::getNullValue(Op0->getType());
+
if (Op0->getType()->isIntOrIntVectorTy(1)) {
if (std::optional<bool> Implied = isImpliedCondition(Op0, Op1, Q.DL)) {
// If Op0 is true implies Op1 is true, then Op0 is a subset of Op1.
@@ -2473,6 +2480,11 @@ static Value *simplifyOrInst(Value *Op0, Value *Op1, const SimplifyQuery &Q,
if (Value *V = threadBinOpOverPHI(Instruction::Or, Op0, Op1, Q, MaxRecurse))
return V;
+ // (A ^ C) | (A ^ ~C) -> -1, i.e. all bits set to one.
+ if (match(Op0, m_Xor(m_Value(A), m_APInt(C1))) &&
+ match(Op1, m_Xor(m_Specific(A), m_SpecificInt(~*C1))))
+ return Constant::getAllOnesValue(Op0->getType());
+
if (Op0->getType()->isIntOrIntVectorTy(1)) {
if (std::optional<bool> Implied =
isImpliedCondition(Op0, Op1, Q.DL, false)) {
diff --git a/llvm/test/Transforms/InstCombine/and-xor-merge.ll b/llvm/test/Transforms/InstCombine/and-xor-merge.ll
index 543336468ff0a6..e6df4e32bae361 100644
--- a/llvm/test/Transforms/InstCombine/and-xor-merge.ll
+++ b/llvm/test/Transforms/InstCombine/and-xor-merge.ll
@@ -40,3 +40,42 @@ define i32 @PR38781(i32 %a, i32 %b) {
%and = and i32 %b.lobit.not, %a.lobit.not
ret i32 %and
}
+
+; (a ^ 4) & (a ^ ~4) -> 0
+define i32 @PR75692_1(i32 %x) {
+; CHECK-LABEL: @PR75692_1
+; CHECK-NEXT: ret i32 0
+;
+ %t2 = xor i32 %x, 4
+ %t3 = xor i32 %x, -5
+ %t4 = and i32 %t2, %t3
+ ret i32 %t4
+}
+
+; (a ^ 4) & (a ^ 3) is not zero
+define i32 @PR75692_2(i32 %x) {
+; CHECK-LABEL: @PR75692_2
+; CHECK-NEXT: %t2 = xor i32 %x, 4
+; CHECK-NEXT: %t3 = xor i32 %x, -4
+; CHECK-NEXT: %t4 = and i32 %t2, %t3
+; CHECK-NEXT: ret i32 %t4
+;
+ %t2 = xor i32 %x, 4
+ %t3 = xor i32 %x, -4
+ %t4 = and i32 %t2, %t3
+ ret i32 %t4
+}
+
+; (a ^ 4) & (b ^ ~4) is not zero, since a != b is possible
+define i32 @PR75692_3(i32 %x, i32 %y) {
+; CHECK-LABEL: @PR75692_3
+; CHECK-NEXT: %t2 = xor i32 %x, 4
+; CHECK-NEXT: %t3 = xor i32 %y, -5
+; CHECK-NEXT: %t4 = and i32 %t2, %t3
+; CHECK-NEXT: ret i32 %t4
+;
+ %t2 = xor i32 %x, 4
+ %t3 = xor i32 %y, -5
+ %t4 = and i32 %t2, %t3
+ ret i32 %t4
+}
diff --git a/llvm/test/Transforms/InstCombine/or-xor.ll b/llvm/test/Transforms/InstCombine/or-xor.ll
index 1d35332d061bbc..361aab6c21e278 100644
--- a/llvm/test/Transforms/InstCombine/or-xor.ll
+++ b/llvm/test/Transforms/InstCombine/or-xor.ll
@@ -1055,3 +1055,42 @@ define i8 @or_nand_xor_common_op_commute3_use3(i8 %x, i8 %y, i8 %z) {
%r = or i8 %xor, %nand
ret i8 %r
}
+
+; (a ^ 4) & (a ^ ~4) -> -1
+define i32 @PR75692_1(i32 %x) {
+; CHECK-LABEL: @PR75692_1(
+; CHECK-NEXT: ret i32 -1
+;
+ %t2 = xor i32 %x, 4
+ %t3 = xor i32 %x, -5
+ %t4 = or i32 %t2, %t3
+ ret i32 %t4
+}
+
+; (a ^ 4) & (a ^ 3) is not -1
+define i32 @PR75692_2(i32 %x) {
+; CHECK-LABEL: @PR75692_2
+; CHECK-NEXT: %t2 = xor i32 %x, 4
+; CHECK-NEXT: %t3 = xor i32 %x, -4
+; CHECK-NEXT: %t4 = or i32 %t2, %t3
+; CHECK-NEXT: ret i32 %t4
+;
+ %t2 = xor i32 %x, 4
+ %t3 = xor i32 %x, -4
+ %t4 = or i32 %t2, %t3
+ ret i32 %t4
+}
+
+; (a ^ 4) & (b ^ ~4) is not -1, since a != b is possible
+define i32 @PR75692_3(i32 %x, i32 %y) {
+; CHECK-LABEL: @PR75692_3
+; CHECK-NEXT: %t2 = xor i32 %x, 4
+; CHECK-NEXT: %t3 = xor i32 %y, -5
+; CHECK-NEXT: %t4 = or i32 %t2, %t3
+; CHECK-NEXT: ret i32 %t4
+;
+ %t2 = xor i32 %x, 4
+ %t3 = xor i32 %y, -5
+ %t4 = or i32 %t2, %t3
+ ret i32 %t4
+}
More information about the llvm-commits
mailing list