[llvm] [InstCombine] Optimize 'xor-and-select' sequence to 'or' for bool (PR #66394)
Qi Hu via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 14 10:59:43 PDT 2023
https://github.com/Qi-Hu updated https://github.com/llvm/llvm-project/pull/66394:
>From 09947d0237c2d0c2320b74666291929ce0cb501e Mon Sep 17 00:00:00 2001
From: Qi Hu <qi.hu at huawei.com>
Date: Wed, 13 Sep 2023 18:33:51 -0400
Subject: [PATCH] [InstCombine] Optimize 'xor-and/or-select' sequence to 'or'
for bool
xor-and-select -> or : https://alive2.llvm.org/ce/z/52ZT62
xor-or-select -> or : https://alive2.llvm.org/ce/z/CHCJQd
---
.../InstCombine/InstCombineSelect.cpp | 20 +++++++++++++++++++
.../InstCombine/fold-xor-and-select-i1.ll | 14 +++++++++++++
.../InstCombine/fold-xor-or-select-i1.ll | 14 +++++++++++++
3 files changed, 48 insertions(+)
create mode 100644 llvm/test/Transforms/InstCombine/fold-xor-and-select-i1.ll
create mode 100644 llvm/test/Transforms/InstCombine/fold-xor-or-select-i1.ll
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index e2965e7a5703976..ba06f35cbdda555 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -3112,6 +3112,26 @@ Instruction *InstCombinerImpl::foldSelectOfBools(SelectInst &SI) {
return SelectInst::Create(FalseVal, One, AndV);
}
+ // select (~b & a), a, b -> or a, b
+ // only for scalar types
+ if (match(CondVal, m_c_And(m_Not(m_Specific(FalseVal)), m_Specific(TrueVal))) &&
+ TrueVal->getType()->isIntegerTy(1) &&
+ FalseVal->getType()->isIntegerTy(1) &&
+ CondVal->getType()->isIntegerTy(1) &&
+ CondVal->hasOneUse()) {
+ return BinaryOperator::CreateOr(TrueVal, FalseVal);
+ }
+
+ // select (~b | a), a, b -> or a, b
+ // only for scalar types
+ if (match(CondVal, m_c_Or(m_Not(m_Specific(FalseVal)), m_Specific(TrueVal))) &&
+ TrueVal->getType()->isIntegerTy(1) &&
+ FalseVal->getType()->isIntegerTy(1) &&
+ CondVal->getType()->isIntegerTy(1) &&
+ CondVal->hasOneUse()) {
+ return BinaryOperator::CreateOr(TrueVal, FalseVal);
+ }
+
if (match(FalseVal, m_Zero()) || match(TrueVal, m_One())) {
Use *Y = nullptr;
bool IsAnd = match(FalseVal, m_Zero()) ? true : false;
diff --git a/llvm/test/Transforms/InstCombine/fold-xor-and-select-i1.ll b/llvm/test/Transforms/InstCombine/fold-xor-and-select-i1.ll
new file mode 100644
index 000000000000000..a5870a3ce9d973f
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fold-xor-and-select-i1.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i1 @max_if(i1 %a, i1 %b) {
+; CHECK-LABEL: define i1 @max_if
+; CHECK-SAME: (i1 [[A:%.*]], i1 [[B:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[A]], [[B]]
+; CHECK-NEXT: ret i1 [[TMP1]]
+;
+ %1 = xor i1 %b, true
+ %cmp = and i1 %1, %a
+ %2 = select i1 %cmp, i1 %a, i1 %b
+ ret i1 %2
+}
diff --git a/llvm/test/Transforms/InstCombine/fold-xor-or-select-i1.ll b/llvm/test/Transforms/InstCombine/fold-xor-or-select-i1.ll
new file mode 100644
index 000000000000000..22e696bd96d291e
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/fold-xor-or-select-i1.ll
@@ -0,0 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+define i1 @max_if(i1 %a, i1 %b) {
+; CHECK-LABEL: define i1 @max_if
+; CHECK-SAME: (i1 [[A:%.*]], i1 [[B:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[A]], [[B]]
+; CHECK-NEXT: ret i1 [[TMP1]]
+;
+ %1 = xor i1 %b, true
+ %cmp = or i1 %1, %a
+ %2 = select i1 %cmp, i1 %a, i1 %b
+ ret i1 %2
+}
More information about the llvm-commits
mailing list