Skip to content

[InstCombine] simplify average of lsb #95684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 17, 2024
Merged

[InstCombine] simplify average of lsb #95684

merged 7 commits into from
Jun 17, 2024

Conversation

c8ef
Copy link
Contributor

@c8ef c8ef commented Jun 16, 2024

close: #94737
alive2: https://alive2.llvm.org/ce/z/TtauVq https://alive2.llvm.org/ce/z/WF_7mX

In this patch, we combine (X + Y) / 2 into (X & Y) only when both X and Y are less than or equal to 1.

@c8ef c8ef requested a review from nikic as a code owner June 16, 2024 01:20
@llvmbot
Copy link
Member

llvmbot commented Jun 16, 2024

@llvm/pr-subscribers-llvm-transforms

Author: None (c8ef)

Changes

close: #94737
alive2: https://alive2.llvm.org/ce/z/TtauVq

In this patch, we combine ((a % 2) + (b % 2)) / 2 into (a & b & 1).


Full diff: https://github.com/llvm/llvm-project/pull/95684.diff

2 Files Affected:

  • (modified) llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp (+8)
  • (added) llvm/test/Transforms/InstCombine/avg-lsb.ll (+46)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 4a014ab6e044e..bb68aa79ca970 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1284,6 +1284,14 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
     return NewSub;
   }
 
+  // ((X % 2) + (Y % 2)) / 2 --> (X & Y & 1)
+  if (match(Op0,
+            m_Add(m_And(m_Value(X), m_One()), m_And(m_Value(Y), m_One()))) &&
+      match(Op1, m_One())) {
+    Value *And = Builder.CreateAnd(X, Y);
+    return BinaryOperator::CreateAnd(And, ConstantInt::get(And->getType(), 1));
+  }
+
   // (sub nuw X, (Y << nuw Z)) >>u exact Z --> (X >>u exact Z) sub nuw Y
   if (I.isExact() &&
       match(Op0, m_OneUse(m_NUWSub(m_Value(X),
diff --git a/llvm/test/Transforms/InstCombine/avg-lsb.ll b/llvm/test/Transforms/InstCombine/avg-lsb.ll
new file mode 100644
index 0000000000000..e9fdb5bfe8dc9
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/avg-lsb.ll
@@ -0,0 +1,46 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i8 @avg_lsb(i8 %a, i8 %b) {
+; CHECK-LABEL: define i8 @avg_lsb(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = and i8 [[B]], [[A]]
+; CHECK-NEXT:    [[DIV2:%.*]] = and i8 [[TMP1]], 1
+; CHECK-NEXT:    ret i8 [[DIV2]]
+;
+  %rem = and i8 %a, 1
+  %rem1 = and i8 %b, 1
+  %add = add nuw nsw i8 %rem1, %rem
+  %div2 = lshr i8 %add, 1
+  ret i8 %div2
+}
+
+define i8 @avg_lsb_mismatch(i8 %a, i8 %b) {
+; CHECK-LABEL: define i8 @avg_lsb_mismatch(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) {
+; CHECK-NEXT:    [[REM:%.*]] = and i8 [[A]], 1
+; CHECK-NEXT:    [[REM1:%.*]] = and i8 [[B]], 3
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i8 [[REM1]], [[REM]]
+; CHECK-NEXT:    [[DIV2:%.*]] = lshr i8 [[ADD]], 1
+; CHECK-NEXT:    ret i8 [[DIV2]]
+;
+  %rem = and i8 %a, 1
+  %rem1 = and i8 %b, 3
+  %add = add nuw nsw i8 %rem1, %rem
+  %div2 = lshr i8 %add, 1
+  ret i8 %div2
+}
+
+define <2 x i8> @avg_lsb_vector(<2 x i8> %a, <2 x i8> %b) {
+; CHECK-LABEL: define <2 x i8> @avg_lsb_vector(
+; CHECK-SAME: <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i8> [[B]], [[A]]
+; CHECK-NEXT:    [[DIV2:%.*]] = and <2 x i8> [[TMP1]], <i8 1, i8 1>
+; CHECK-NEXT:    ret <2 x i8> [[DIV2]]
+;
+  %rem = and <2 x i8> %a, <i8 1, i8 1>
+  %rem1 = and <2 x i8> %b, <i8 1, i8 1>
+  %add = add nuw nsw <2 x i8> %rem1, %rem
+  %div2 = lshr <2 x i8> %add, <i8 1, i8 1>
+  ret <2 x i8> %div2
+}

dtcxzyw added a commit to dtcxzyw/llvm-opt-benchmark that referenced this pull request Jun 16, 2024
@c8ef c8ef requested review from dtcxzyw and goldsteinn June 16, 2024 08:02
; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[A]], [[B]]
; CHECK-NEXT: [[LSHR:%.*]] = zext i1 [[TMP1]] to i32
; CHECK-NEXT: ret i32 [[LSHR]]
; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if it's a regression.

@c8ef c8ef requested a review from dtcxzyw June 16, 2024 11:39
dtcxzyw added a commit to dtcxzyw/llvm-opt-benchmark that referenced this pull request Jun 16, 2024
@@ -1284,6 +1284,13 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
return NewSub;
}

// Fold (X + Y) / 2 --> (X & Y) iff (X u<= 1) && (Y u<= 1)
if (match(Op0, m_Add(m_Value(X), m_Value(Y))) && match(Op1, m_One()) &&
computeKnownBits(X, 0, &I).countMaxActiveBits() <= 1 &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nikic Can you check compile-time impact of this change? If it is high, I suggest to revert the generalization.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No compile-time impact.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@nikic nikic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@goldsteinn
Copy link
Contributor

LGTM

Copy link
Member

@dtcxzyw dtcxzyw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thank you!

@dtcxzyw dtcxzyw merged commit 1d4e857 into llvm:main Jun 17, 2024
5 of 7 checks passed
@c8ef c8ef deleted the lsb branch June 17, 2024 05:21
@HendrikHuebner
Copy link
Contributor

HendrikHuebner commented Jun 18, 2024

@c8ef I was already assigned to this and had still been planning to work on it. Please ask first before you take issues that are already assigned to someone else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[InstCombine] Failure to simplify average of lsb
6 participants