[llvm] [InstCombine] Fold `trunc nuw (x xor y) to i1` to `x != y` (PR #90408)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 29 02:28:18 PDT 2024
https://github.com/YanWQ-monad updated https://github.com/llvm/llvm-project/pull/90408
>From 606774ef63d246ea227e2320d6ee560b1e6b4dde Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 29 Apr 2024 02:01:25 +0800
Subject: [PATCH 1/5] [InstCombine] Precommit: add tests
---
llvm/test/Transforms/InstCombine/trunc.ll | 33 +++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index e59b2bea6684c0..adcfa115bf375d 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -1054,3 +1054,36 @@ define i8 @drop_both_trunc(i16 %x, i16 %y) {
%res = trunc nuw nsw i16 %and2 to i8
ret i8 %res
}
+
+define i1 @trunc_xor(i8 %x, i8 %y) {
+; CHECK-LABEL: @trunc_xor(
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = trunc i8 [[XOR]] to i1
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %xor = xor i8 %x, %y
+ %r = trunc i8 %xor to i1
+ ret i1 %r
+}
+
+define i1 @trunc_nuw_xor(i8 %x, i8 %y) {
+; CHECK-LABEL: @trunc_nuw_xor(
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = trunc nuw i8 [[XOR]] to i1
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %xor = xor i8 %x, %y
+ %r = trunc nuw i8 %xor to i1
+ ret i1 %r
+}
+
+define <2 x i1> @trunc_nuw_xor_vector(<2 x i8> %x, <2 x i8> %y) {
+; CHECK-LABEL: @trunc_nuw_xor_vector(
+; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = trunc nuw <2 x i8> [[XOR]] to <2 x i1>
+; CHECK-NEXT: ret <2 x i1> [[R]]
+;
+ %xor = xor <2 x i8> %x, %y
+ %r = trunc nuw <2 x i8> %xor to <2 x i1>
+ ret <2 x i1> %r
+}
>From 9951df0f10e706676faa2a45e42b33e02cc59aeb Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 29 Apr 2024 02:02:08 +0800
Subject: [PATCH 2/5] [InstCombine] Fold `trunc nuw (x xor y) to i1` to `x !=
y`
---
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 7 +++++++
llvm/test/Transforms/InstCombine/trunc.ll | 6 ++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index 567b27b4630439..c769c28c90c1a9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -770,6 +770,13 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
return new ICmpInst(ICmpInst::Predicate::ICMP_EQ, X, Zero);
}
}
+
+ if (Trunc.hasNoUnsignedWrap()) {
+ Value *X, *Y;
+ if (match(Src, m_Xor(m_Value(X), m_Value(Y)))) {
+ return new ICmpInst(ICmpInst::ICMP_NE, X, Y);
+ }
+ }
}
Value *A, *B;
diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index adcfa115bf375d..d4e4b1866349c0 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -1068,8 +1068,7 @@ define i1 @trunc_xor(i8 %x, i8 %y) {
define i1 @trunc_nuw_xor(i8 %x, i8 %y) {
; CHECK-LABEL: @trunc_nuw_xor(
-; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = trunc nuw i8 [[XOR]] to i1
+; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%xor = xor i8 %x, %y
@@ -1079,8 +1078,7 @@ define i1 @trunc_nuw_xor(i8 %x, i8 %y) {
define <2 x i1> @trunc_nuw_xor_vector(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @trunc_nuw_xor_vector(
-; CHECK-NEXT: [[XOR:%.*]] = xor <2 x i8> [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = trunc nuw <2 x i8> [[XOR]] to <2 x i1>
+; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret <2 x i1> [[R]]
;
%xor = xor <2 x i8> %x, %y
>From af56ec90bfbd37cd21a9ddec7e4d3bd0444fa6a1 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 29 Apr 2024 11:17:50 +0800
Subject: [PATCH 3/5] [InstCombine] style: remove curly braces
---
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index c769c28c90c1a9..c66884d718cc97 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -773,9 +773,8 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
if (Trunc.hasNoUnsignedWrap()) {
Value *X, *Y;
- if (match(Src, m_Xor(m_Value(X), m_Value(Y)))) {
+ if (match(Src, m_Xor(m_Value(X), m_Value(Y))))
return new ICmpInst(ICmpInst::ICMP_NE, X, Y);
- }
}
}
>From aa2d32852f33ab5b7536559d24f2aab1773dab65 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 29 Apr 2024 17:20:32 +0800
Subject: [PATCH 4/5] [InstCombine] Precommit: add nsw test
---
llvm/test/Transforms/InstCombine/trunc.ll | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index d4e4b1866349c0..c70e15f7908481 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -1076,6 +1076,17 @@ define i1 @trunc_nuw_xor(i8 %x, i8 %y) {
ret i1 %r
}
+define i1 @trunc_nsw_xor(i8 %x, i8 %y) {
+; CHECK-LABEL: @trunc_nsw_xor(
+; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
+; CHECK-NEXT: [[R:%.*]] = trunc nsw i8 [[XOR]] to i1
+; CHECK-NEXT: ret i1 [[R]]
+;
+ %xor = xor i8 %x, %y
+ %r = trunc nsw i8 %xor to i1
+ ret i1 %r
+}
+
define <2 x i1> @trunc_nuw_xor_vector(<2 x i8> %x, <2 x i8> %y) {
; CHECK-LABEL: @trunc_nuw_xor_vector(
; CHECK-NEXT: [[R:%.*]] = icmp ne <2 x i8> [[X:%.*]], [[Y:%.*]]
>From 3b750ba2cd688f255bf522e9f1d4b126015a5c35 Mon Sep 17 00:00:00 2001
From: YanWQ-monad <YanWQmonad at gmail.com>
Date: Mon, 29 Apr 2024 17:28:00 +0800
Subject: [PATCH 5/5] [InstCombine] Also fold for `trunc nsw`
---
llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp | 2 +-
llvm/test/Transforms/InstCombine/trunc.ll | 3 +--
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
index c66884d718cc97..11e31877de38c2 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp
@@ -771,7 +771,7 @@ Instruction *InstCombinerImpl::visitTrunc(TruncInst &Trunc) {
}
}
- if (Trunc.hasNoUnsignedWrap()) {
+ if (Trunc.hasNoUnsignedWrap() || Trunc.hasNoSignedWrap()) {
Value *X, *Y;
if (match(Src, m_Xor(m_Value(X), m_Value(Y))))
return new ICmpInst(ICmpInst::ICMP_NE, X, Y);
diff --git a/llvm/test/Transforms/InstCombine/trunc.ll b/llvm/test/Transforms/InstCombine/trunc.ll
index c70e15f7908481..a180c3d52f6ab1 100644
--- a/llvm/test/Transforms/InstCombine/trunc.ll
+++ b/llvm/test/Transforms/InstCombine/trunc.ll
@@ -1078,8 +1078,7 @@ define i1 @trunc_nuw_xor(i8 %x, i8 %y) {
define i1 @trunc_nsw_xor(i8 %x, i8 %y) {
; CHECK-LABEL: @trunc_nsw_xor(
-; CHECK-NEXT: [[XOR:%.*]] = xor i8 [[X:%.*]], [[Y:%.*]]
-; CHECK-NEXT: [[R:%.*]] = trunc nsw i8 [[XOR]] to i1
+; CHECK-NEXT: [[R:%.*]] = icmp ne i8 [[X:%.*]], [[Y:%.*]]
; CHECK-NEXT: ret i1 [[R]]
;
%xor = xor i8 %x, %y
More information about the llvm-commits
mailing list