[llvm] [InstSimplify] Simplify the expression `(a^c)&(a^~c)` to zero (PR #76637)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Jan 2 09:37:18 PST 2024
https://github.com/ChipsSpectre updated https://github.com/llvm/llvm-project/pull/76637
>From ea5f87c65ba90265d8c705d26442244011bfa8e8 Mon Sep 17 00:00:00 2001
From: ChipsSpectre <maximilian.hornung at tum.de>
Date: Tue, 2 Jan 2024 18:28:57 +0100
Subject: [PATCH 1/2] [InstSimplify] Add pre-commit tests for PR75692. NFC.
---
.../Transforms/InstCombine/and-xor-merge.ll | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
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
+}
>From 5766d8e5c72fdaef5b2335fcaaff9ec9d0d2f2fc Mon Sep 17 00:00:00 2001
From: ChipsSpectre <maximilian.hornung at tum.de>
Date: Tue, 2 Jan 2024 18:31:40 +0100
Subject: [PATCH 2/2] [InstSimplify] Fold (X ^ C) & (X ^ ~C) into zero.
---
llvm/lib/Analysis/InstructionSimplify.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index 78a8334763340e..d2baaaf80f8f0c 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, *C2;
+ 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_APInt(C2))) && (*C1 ^ *C2).isAllOnes())
+ 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.
More information about the llvm-commits
mailing list