[llvm] [InstCombine] Simplify a complex OR to XOR (PR #75129)
Fujun Han via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 13 21:59:36 PST 2023
https://github.com/Peter9606 updated https://github.com/llvm/llvm-project/pull/75129
>From 04075a441185b558f1f253cb2194b983f63ed0be Mon Sep 17 00:00:00 2001
From: Peter Han <fujun.han at iluvatar.com>
Date: Thu, 14 Dec 2023 13:48:58 +0800
Subject: [PATCH 1/2] [InstCombine][NFC]Pre-commit test for add-constant to
xor-constant.
Signed-off-by: Peter Han <fujun.han at iluvatar.com>
---
llvm/test/Transforms/InstCombine/and.ll | 37 +++++++++++++++++++++++--
1 file changed, 35 insertions(+), 2 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index 79857f3efbc18b..be797c1d1d5e8c 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -395,8 +395,8 @@ define i8 @test27(i8 %A) {
define i32 @ashr_lowmask(i32 %x) {
; CHECK-LABEL: @ashr_lowmask(
-; CHECK-NEXT: [[TMP1:%.*]] = lshr i32 [[X:%.*]], 24
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: [[A:%.*]] = lshr i32 [[X:%.*]], 24
+; CHECK-NEXT: ret i32 [[A]]
;
%a = ashr i32 %x, 24
%r = and i32 %a, 255
@@ -2711,3 +2711,36 @@ define i32 @canonicalize_and_sub_power2_or_zero_multiuse_nofold(i32 %x, i32 %y)
%and = and i32 %val, %p2
ret i32 %and
}
+
+define i32 @add_constant_equal_with_the_top_bit_of_demandedbits_pass(i32 %x) {
+; CHECK-LABEL: @add_constant_equal_with_the_top_bit_of_demandedbits_pass(
+; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 16
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 24
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %add = add i32 %x, 16
+ %and = and i32 %add, 24
+ ret i32 %and
+}
+
+define i32 @add_constant_equal_with_the_top_bit_of_demandedbits_fail1(i32 %x) {
+; CHECK-LABEL: @add_constant_equal_with_the_top_bit_of_demandedbits_fail1(
+; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 8
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 24
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %add = add i32 %x, 8
+ %and = and i32 %add, 24
+ ret i32 %and
+}
+
+define i32 @add_constant_equal_with_the_top_bit_of_demandedbits_fail2(i32 %x) {
+; CHECK-LABEL: @add_constant_equal_with_the_top_bit_of_demandedbits_fail2(
+; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 24
+; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 24
+; CHECK-NEXT: ret i32 [[AND]]
+;
+ %add = add i32 %x, 24
+ %and = and i32 %add, 24
+ ret i32 %and
+}
>From a553aa3f782ca86d11ac4a20e4333bc9e65feead Mon Sep 17 00:00:00 2001
From: Peter Han <fujun.han at iluvatar.com>
Date: Thu, 14 Dec 2023 13:58:07 +0800
Subject: [PATCH 2/2] [InstCombine]Change (and x, c) to (xor x, c) iff c is
constant and c equals the top bit of the demanded bits.
Signed-off-by: Peter Han <fujun.han at iluvatar.com>
---
.../InstCombine/InstCombineSimplifyDemanded.cpp | 10 ++++++++++
llvm/test/Transforms/InstCombine/and.ll | 4 ++--
2 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
index 046ce9d1207e8e..a54446a9aad270 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
@@ -552,6 +552,16 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
if (DemandedFromOps.isSubsetOf(LHSKnown.Zero))
return I->getOperand(1);
+ // (add X, C) --> (xor X, C) IFF C is equal to the top bit of the DemandMask
+ {
+ Value *X;
+ const APInt *C;
+ if (match(I, m_Add(m_Value(X), m_APInt(C))) &&
+ C->isOneBitSet(DemandedMask.getBitWidth() -
+ DemandedMask.countLeadingZeros() - 1))
+ return Builder.CreateXor(X, ConstantInt::get(VTy, *C));
+ }
+
// Otherwise just compute the known bits of the result.
bool NSW = cast<OverflowingBinaryOperator>(I)->hasNoSignedWrap();
Known = KnownBits::computeForAddSub(true, NSW, LHSKnown, RHSKnown);
diff --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index be797c1d1d5e8c..e5b4ecbf56e3af 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -2714,8 +2714,8 @@ define i32 @canonicalize_and_sub_power2_or_zero_multiuse_nofold(i32 %x, i32 %y)
define i32 @add_constant_equal_with_the_top_bit_of_demandedbits_pass(i32 %x) {
; CHECK-LABEL: @add_constant_equal_with_the_top_bit_of_demandedbits_pass(
-; CHECK-NEXT: [[ADD:%.*]] = add i32 [[X:%.*]], 16
-; CHECK-NEXT: [[AND:%.*]] = and i32 [[ADD]], 24
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 24
+; CHECK-NEXT: [[AND:%.*]] = xor i32 [[TMP1]], 16
; CHECK-NEXT: ret i32 [[AND]]
;
%add = add i32 %x, 16
More information about the llvm-commits
mailing list