[llvm] 20167e8 - [InstSimplify] !(X && Y) || X --> true (for poison-safe logical ops)
Sanjay Patel via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 29 07:38:25 PST 2023
Author: Sanjay Patel
Date: 2023-01-29T10:24:52-05:00
New Revision: 20167e8483159536c13b2cda763047cbd6d7d62c
URL: https://github.com/llvm/llvm-project/commit/20167e8483159536c13b2cda763047cbd6d7d62c
DIFF: https://github.com/llvm/llvm-project/commit/20167e8483159536c13b2cda763047cbd6d7d62c.diff
LOG: [InstSimplify] !(X && Y) || X --> true (for poison-safe logical ops)
https://alive2.llvm.org/ce/z/xuvL46
This is the similar to the existing folds added with:
D138853 / f2973327496fc966c4e89597
7dbeb127eaf6
...but with the and/or swapped.
Added:
Modified:
llvm/lib/Analysis/InstructionSimplify.cpp
llvm/test/Transforms/InstSimplify/select-logical.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp
index e2154ca55c3e8..4ca117b6043ed 100644
--- a/llvm/lib/Analysis/InstructionSimplify.cpp
+++ b/llvm/lib/Analysis/InstructionSimplify.cpp
@@ -4621,6 +4621,13 @@ static Value *simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
// Match patterns that end in logical-or.
if (match(TrueVal, m_One())) {
+ // !(X && Y) || X --> true (commuted 2 ways)
+ if (match(Cond, m_Not(m_c_LogicalAnd(m_Specific(FalseVal), m_Value()))))
+ return ConstantInt::getTrue(Cond->getType());
+ // X || !(X && Y) --> true (commuted 2 ways)
+ if (match(FalseVal, m_Not(m_c_LogicalAnd(m_Specific(Cond), m_Value()))))
+ return ConstantInt::getTrue(Cond->getType());
+
// (X && Y) || Y --> Y (commuted 2 ways)
if (match(Cond, m_c_LogicalAnd(m_Specific(FalseVal), m_Value())))
return FalseVal;
diff --git a/llvm/test/Transforms/InstSimplify/select-logical.ll b/llvm/test/Transforms/InstSimplify/select-logical.ll
index 796c7db7cedba..1c11bb8982eb1 100644
--- a/llvm/test/Transforms/InstSimplify/select-logical.ll
+++ b/llvm/test/Transforms/InstSimplify/select-logical.ll
@@ -285,12 +285,11 @@ define i1 @logical_not_or_and_negative1(i1 %x, i1 %y, i1 %z) {
ret i1 %r
}
+; !(x && y) || x --> true
+
define i1 @logical_nand_logical_or_common_op_commute1(i1 %x, i1 %y) {
; CHECK-LABEL: @logical_nand_logical_or_common_op_commute1(
-; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
-; CHECK-NEXT: [[NAND:%.*]] = xor i1 [[AND]], true
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[NAND]], i1 true, i1 [[X]]
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: ret i1 true
;
%and = select i1 %x, i1 %y, i1 false
%nand = xor i1 %and, -1
@@ -300,10 +299,7 @@ define i1 @logical_nand_logical_or_common_op_commute1(i1 %x, i1 %y) {
define <2 x i1> @logical_nand_logical_or_common_op_commute2(<2 x i1> %x, <2 x i1> %y) {
; CHECK-LABEL: @logical_nand_logical_or_common_op_commute2(
-; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i1> [[X:%.*]], <2 x i1> zeroinitializer
-; CHECK-NEXT: [[NAND:%.*]] = xor <2 x i1> [[AND]], <i1 true, i1 true>
-; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[NAND]], <2 x i1> <i1 true, i1 true>, <2 x i1> [[X]]
-; CHECK-NEXT: ret <2 x i1> [[OR]]
+; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%and = select <2 x i1> %y, <2 x i1> %x, <2 x i1> zeroinitializer
%nand = xor <2 x i1> %and, <i1 -1, i1 -1>
@@ -313,10 +309,7 @@ define <2 x i1> @logical_nand_logical_or_common_op_commute2(<2 x i1> %x, <2 x i1
define <2 x i1> @logical_nand_logical_or_common_op_commute3(<2 x i1> %x, <2 x i1> %y) {
; CHECK-LABEL: @logical_nand_logical_or_common_op_commute3(
-; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[Y:%.*]], <2 x i1> zeroinitializer
-; CHECK-NEXT: [[NAND:%.*]] = xor <2 x i1> [[AND]], <i1 true, i1 poison>
-; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[X]], <2 x i1> <i1 true, i1 poison>, <2 x i1> [[NAND]]
-; CHECK-NEXT: ret <2 x i1> [[OR]]
+; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true>
;
%and = select <2 x i1> %x, <2 x i1> %y, <2 x i1> zeroinitializer
%nand = xor <2 x i1> %and, <i1 -1, i1 poison>
@@ -326,10 +319,7 @@ define <2 x i1> @logical_nand_logical_or_common_op_commute3(<2 x i1> %x, <2 x i1
define i1 @logical_nand_logical_or_common_op_commute4(i1 %x, i1 %y) {
; CHECK-LABEL: @logical_nand_logical_or_common_op_commute4(
-; CHECK-NEXT: [[AND:%.*]] = select i1 [[Y:%.*]], i1 [[X:%.*]], i1 false
-; CHECK-NEXT: [[NAND:%.*]] = xor i1 [[AND]], true
-; CHECK-NEXT: [[OR:%.*]] = select i1 [[X]], i1 true, i1 [[NAND]]
-; CHECK-NEXT: ret i1 [[OR]]
+; CHECK-NEXT: ret i1 true
;
%and = select i1 %y, i1 %x, i1 false
%nand = xor i1 %and, -1
@@ -337,6 +327,8 @@ define i1 @logical_nand_logical_or_common_op_commute4(i1 %x, i1 %y) {
ret i1 %or
}
+; TODO: This could fold the same as above (we don't match a partial poison vector as logical op).
+
define <2 x i1> @logical_nand_logical_or_common_op_commute4_poison_vec(<2 x i1> %x, <2 x i1> %y) {
; CHECK-LABEL: @logical_nand_logical_or_common_op_commute4_poison_vec(
; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i1> [[X:%.*]], <2 x i1> <i1 false, i1 poison>
@@ -350,6 +342,8 @@ define <2 x i1> @logical_nand_logical_or_common_op_commute4_poison_vec(<2 x i1>
ret <2 x i1> %or
}
+; negative test - need common operand
+
define i1 @logical_nand_logical_or(i1 %x, i1 %y, i1 %z) {
; CHECK-LABEL: @logical_nand_logical_or(
; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false
More information about the llvm-commits
mailing list