[llvm] [InstCombine] simplify average of lsb (PR #95684)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 16 03:26:09 PDT 2024
https://github.com/c8ef updated https://github.com/llvm/llvm-project/pull/95684
>From 3734ce9d7391f16781440d5d84df5ffa5fcef814 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 16 Jun 2024 09:17:02 +0800
Subject: [PATCH 1/6] simplify average of lsb
---
.../InstCombine/InstCombineShifts.cpp | 8 ++++
llvm/test/Transforms/InstCombine/avg-lsb.ll | 46 +++++++++++++++++++
2 files changed, 54 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/avg-lsb.ll
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
+}
>From 3530da30f3171f44fd5623d9a1a341b685eb60f0 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 16 Jun 2024 14:45:05 +0800
Subject: [PATCH 2/6] Fold ((X % 2) + (Y % 2)) / 2 --> (X & Y & 1) iff (X u<=
1) && (Y u<= 1)
---
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 9 +++++----
llvm/test/Transforms/InstCombine/avg-lsb.ll | 8 ++++----
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index bb68aa79ca970..66e6a8c9921ef 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -12,6 +12,7 @@
#include "InstCombineInternal.h"
#include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
@@ -1284,10 +1285,10 @@ 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())) {
+ // Fold ((X % 2) + (Y % 2)) / 2 --> (X & Y & 1) 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 &&
+ computeKnownBits(Y, 0, &I).countMaxActiveBits() <= 1) {
Value *And = Builder.CreateAnd(X, Y);
return BinaryOperator::CreateAnd(And, ConstantInt::get(And->getType(), 1));
}
diff --git a/llvm/test/Transforms/InstCombine/avg-lsb.ll b/llvm/test/Transforms/InstCombine/avg-lsb.ll
index e9fdb5bfe8dc9..23a47166bf2fe 100644
--- a/llvm/test/Transforms/InstCombine/avg-lsb.ll
+++ b/llvm/test/Transforms/InstCombine/avg-lsb.ll
@@ -4,8 +4,8 @@
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: [[REM:%.*]] = and i8 [[A]], 1
+; CHECK-NEXT: [[DIV2:%.*]] = and i8 [[REM]], [[B]]
; CHECK-NEXT: ret i8 [[DIV2]]
;
%rem = and i8 %a, 1
@@ -34,8 +34,8 @@ define i8 @avg_lsb_mismatch(i8 %a, i8 %b) {
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: [[REM:%.*]] = and <2 x i8> [[A]], <i8 1, i8 1>
+; CHECK-NEXT: [[DIV2:%.*]] = and <2 x i8> [[REM]], [[B]]
; CHECK-NEXT: ret <2 x i8> [[DIV2]]
;
%rem = and <2 x i8> %a, <i8 1, i8 1>
>From c076cc6eca83055742d13379c5b7df6e57197b0f Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 16 Jun 2024 14:46:26 +0800
Subject: [PATCH 3/6] fix comment
---
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index 66e6a8c9921ef..a383458e8bfe0 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1285,7 +1285,7 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
return NewSub;
}
- // Fold ((X % 2) + (Y % 2)) / 2 --> (X & Y & 1) iff (X u<= 1) && (Y u<= 1)
+ // Fold (X + Y) / 2 --> (X & Y & 1) 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 &&
computeKnownBits(Y, 0, &I).countMaxActiveBits() <= 1) {
>From 0979c62fd22f5444006705f781c6deef9fdbb55e Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 16 Jun 2024 14:48:31 +0800
Subject: [PATCH 4/6] remove unused include
---
llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index a383458e8bfe0..bef3c06b2ee95 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -12,7 +12,6 @@
#include "InstCombineInternal.h"
#include "llvm/Analysis/InstructionSimplify.h"
-#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/Transforms/InstCombine/InstCombiner.h"
>From 6369dec6f0196be18db264ce8463405decc9f007 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 16 Jun 2024 15:00:13 +0800
Subject: [PATCH 5/6] regen test
---
llvm/test/Transforms/InstCombine/lshr.ll | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll
index 60f03733ebd99..276a1345becb4 100644
--- a/llvm/test/Transforms/InstCombine/lshr.ll
+++ b/llvm/test/Transforms/InstCombine/lshr.ll
@@ -1391,8 +1391,8 @@ define i8 @not_signbit_trunc(i16 %x) {
define i2 @bool_add_lshr(i1 %a, i1 %b) {
; CHECK-LABEL: @bool_add_lshr(
; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[LSHR:%.*]] = zext i1 [[TMP1]] to i2
-; CHECK-NEXT: ret i2 [[LSHR]]
+; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i2
+; CHECK-NEXT: ret i2 [[TMP2]]
;
%zext.a = zext i1 %a to i2
%zext.b = zext i1 %b to i2
@@ -1437,8 +1437,8 @@ define i2 @bool_add_ashr(i1 %a, i1 %b) {
define <2 x i8> @bool_add_lshr_vec(<2 x i1> %a, <2 x i1> %b) {
; CHECK-LABEL: @bool_add_lshr_vec(
; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[LSHR:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>
-; CHECK-NEXT: ret <2 x i8> [[LSHR]]
+; CHECK-NEXT: [[TMP2:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>
+; CHECK-NEXT: ret <2 x i8> [[TMP2]]
;
%zext.a = zext <2 x i1> %a to <2 x i8>
%zext.b = zext <2 x i1> %b to <2 x i8>
@@ -1453,9 +1453,8 @@ define i32 @bool_add_lshr_uses(i1 %a, i1 %b) {
; CHECK-NEXT: call void @use(i32 [[ZEXT_A]])
; CHECK-NEXT: [[ZEXT_B:%.*]] = zext i1 [[B:%.*]] to i32
; CHECK-NEXT: call void @use(i32 [[ZEXT_B]])
-; 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]]
+; CHECK-NEXT: ret i32 [[TMP1]]
;
%zext.a = zext i1 %a to i32
call void @use(i32 %zext.a)
@@ -1473,9 +1472,8 @@ define i32 @bool_add_lshr_uses2(i1 %a, i1 %b) {
; CHECK-NEXT: call void @use(i32 [[ZEXT_B]])
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]
; CHECK-NEXT: call void @use(i32 [[ADD]])
-; 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]]
+; CHECK-NEXT: ret i32 [[TMP1]]
;
%zext.a = zext i1 %a to i32
%zext.b = zext i1 %b to i32
@@ -1496,8 +1494,8 @@ define i32 @bool_add_lshr_uses3(i1 %a, i1 %b) {
; CHECK-NEXT: call void @use(i32 [[ZEXT_B]])
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]
; CHECK-NEXT: call void @use(i32 [[ADD]])
-; CHECK-NEXT: [[LSHR:%.*]] = lshr i32 [[ADD]], 1
-; CHECK-NEXT: ret i32 [[LSHR]]
+; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]
+; CHECK-NEXT: ret i32 [[TMP1]]
;
%zext.a = zext i1 %a to i32
call void @use(i32 %zext.a)
>From 84f194839fa297a5c90b916b0633e61f19e543c9 Mon Sep 17 00:00:00 2001
From: c8ef <c8ef at outlook.com>
Date: Sun, 16 Jun 2024 18:25:52 +0800
Subject: [PATCH 6/6] x & y
---
.../InstCombine/InstCombineShifts.cpp | 5 ++--
llvm/test/Transforms/InstCombine/lshr.ll | 24 +++++++++----------
2 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
index bef3c06b2ee95..7f2dcbfe8ea7f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
@@ -1284,12 +1284,11 @@ Instruction *InstCombinerImpl::visitLShr(BinaryOperator &I) {
return NewSub;
}
- // Fold (X + Y) / 2 --> (X & Y & 1) iff (X u<= 1) && (Y u<= 1)
+ // 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 &&
computeKnownBits(Y, 0, &I).countMaxActiveBits() <= 1) {
- Value *And = Builder.CreateAnd(X, Y);
- return BinaryOperator::CreateAnd(And, ConstantInt::get(And->getType(), 1));
+ return BinaryOperator::CreateAnd(X, Y);
}
// (sub nuw X, (Y << nuw Z)) >>u exact Z --> (X >>u exact Z) sub nuw Y
diff --git a/llvm/test/Transforms/InstCombine/lshr.ll b/llvm/test/Transforms/InstCombine/lshr.ll
index 276a1345becb4..01e07985ba6ab 100644
--- a/llvm/test/Transforms/InstCombine/lshr.ll
+++ b/llvm/test/Transforms/InstCombine/lshr.ll
@@ -1390,9 +1390,9 @@ define i8 @not_signbit_trunc(i16 %x) {
define i2 @bool_add_lshr(i1 %a, i1 %b) {
; CHECK-LABEL: @bool_add_lshr(
-; CHECK-NEXT: [[TMP1:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i2
-; CHECK-NEXT: ret i2 [[TMP2]]
+; CHECK-NEXT: [[LSHR1:%.*]] = and i1 [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[LSHR:%.*]] = zext i1 [[LSHR1]] to i2
+; CHECK-NEXT: ret i2 [[LSHR]]
;
%zext.a = zext i1 %a to i2
%zext.b = zext i1 %b to i2
@@ -1436,9 +1436,9 @@ define i2 @bool_add_ashr(i1 %a, i1 %b) {
define <2 x i8> @bool_add_lshr_vec(<2 x i1> %a, <2 x i1> %b) {
; CHECK-LABEL: @bool_add_lshr_vec(
-; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT: [[TMP2:%.*]] = zext <2 x i1> [[TMP1]] to <2 x i8>
-; CHECK-NEXT: ret <2 x i8> [[TMP2]]
+; CHECK-NEXT: [[LSHR1:%.*]] = and <2 x i1> [[A:%.*]], [[B:%.*]]
+; CHECK-NEXT: [[LSHR:%.*]] = zext <2 x i1> [[LSHR1]] to <2 x i8>
+; CHECK-NEXT: ret <2 x i8> [[LSHR]]
;
%zext.a = zext <2 x i1> %a to <2 x i8>
%zext.b = zext <2 x i1> %b to <2 x i8>
@@ -1453,8 +1453,8 @@ define i32 @bool_add_lshr_uses(i1 %a, i1 %b) {
; CHECK-NEXT: call void @use(i32 [[ZEXT_A]])
; CHECK-NEXT: [[ZEXT_B:%.*]] = zext i1 [[B:%.*]] to i32
; CHECK-NEXT: call void @use(i32 [[ZEXT_B]])
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: [[LSHR:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]
+; CHECK-NEXT: ret i32 [[LSHR]]
;
%zext.a = zext i1 %a to i32
call void @use(i32 %zext.a)
@@ -1472,8 +1472,8 @@ define i32 @bool_add_lshr_uses2(i1 %a, i1 %b) {
; CHECK-NEXT: call void @use(i32 [[ZEXT_B]])
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]
; CHECK-NEXT: call void @use(i32 [[ADD]])
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: [[LSHR:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]
+; CHECK-NEXT: ret i32 [[LSHR]]
;
%zext.a = zext i1 %a to i32
%zext.b = zext i1 %b to i32
@@ -1494,8 +1494,8 @@ define i32 @bool_add_lshr_uses3(i1 %a, i1 %b) {
; CHECK-NEXT: call void @use(i32 [[ZEXT_B]])
; CHECK-NEXT: [[ADD:%.*]] = add nuw nsw i32 [[ZEXT_A]], [[ZEXT_B]]
; CHECK-NEXT: call void @use(i32 [[ADD]])
-; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]
-; CHECK-NEXT: ret i32 [[TMP1]]
+; CHECK-NEXT: [[LSHR:%.*]] = and i32 [[ZEXT_A]], [[ZEXT_B]]
+; CHECK-NEXT: ret i32 [[LSHR]]
;
%zext.a = zext i1 %a to i32
call void @use(i32 %zext.a)
More information about the llvm-commits
mailing list