From: Zhongyunde Date: Wed, 26 Apr 2023 07:52:28 +0000 (+0800) Subject: [InstSimplify] with logical ops: (X & Y) == -1 ? X : -1 --> -1 X-Git-Tag: upstream/17.0.6~10389 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f9478f729e68af4d32f20a93382f94744141d4a3;p=platform%2Fupstream%2Fllvm.git [InstSimplify] with logical ops: (X & Y) == -1 ? X : -1 --> -1 Use simplifySelectWithICmpEq to handle the implied equalities from the icmp-and, then both of ICMP_NE and ICMP_EQ will be addressed including vector type. (X & Y) == -1 ? X : -1 --> -1 (commuted 2 ways) (X & Y) != -1 ? -1 : X --> -1 (commuted 2 ways) This is a supplement to the icmp-or scenario on D148986. Reviewed By: nikic Differential Revision: https://reviews.llvm.org/D149229 --- diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp index 57cfef4e..d4639f6 100644 --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -4549,12 +4549,12 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal, Q, MaxRecurse)) return V; - // select(X | Y == 0 ? X : 0) --> 0 (commuted 2 ways) Value *X; Value *Y; + // select((X | Y) == 0 ? X : 0) --> 0 (commuted 2 ways) if (match(CmpLHS, m_Or(m_Value(X), m_Value(Y))) && match(CmpRHS, m_Zero())) { - // X | Y == 0 implies X == 0 and Y == 0. + // (X | Y) == 0 implies X == 0 and Y == 0. if (Value *V = simplifySelectWithICmpEq(X, CmpRHS, TrueVal, FalseVal, Q, MaxRecurse)) return V; @@ -4562,16 +4562,18 @@ static Value *simplifySelectWithICmpCond(Value *CondVal, Value *TrueVal, MaxRecurse)) return V; } - } - if (Pred == ICmpInst::Predicate::ICMP_EQ) { - Value *X; - Value *Y; - // select(X & Y == -1, X or Y, X & Y) -> X & Y - if (match(CondVal, m_ICmp(Pred, m_Specific(FalseVal), m_AllOnes())) && - match(FalseVal, m_And(m_Value(X), m_Value(Y))) && - (TrueVal == X || TrueVal == Y)) - return FalseVal; + // select((X & Y) == -1 ? X : -1) --> -1 (commuted 2 ways) + if (match(CmpLHS, m_And(m_Value(X), m_Value(Y))) && + match(CmpRHS, m_AllOnes())) { + // (X & Y) == -1 implies X == -1 and Y == -1. + if (Value *V = simplifySelectWithICmpEq(X, CmpRHS, TrueVal, FalseVal, Q, + MaxRecurse)) + return V; + if (Value *V = simplifySelectWithICmpEq(Y, CmpRHS, TrueVal, FalseVal, Q, + MaxRecurse)) + return V; + } } return nullptr; diff --git a/llvm/test/Transforms/InstSimplify/select_or_and.ll b/llvm/test/Transforms/InstSimplify/select_or_and.ll index 63ab7cd..6bb7fbf 100644 --- a/llvm/test/Transforms/InstSimplify/select_or_and.ll +++ b/llvm/test/Transforms/InstSimplify/select_or_and.ll @@ -147,10 +147,7 @@ define i32 @select_and_4(i32 %x, i32 %y) { ; select(Y & X != -1, Y, Y & X) define i32 @select_and_not_1(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_not_1( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[AND]], -1 -; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[Y]] -; CHECK-NEXT: ret i32 [[RET]] +; CHECK-NEXT: ret i32 [[Y:%.*]] ; %and = and i32 %y, %x %cmp = icmp eq i32 %and, -1 @@ -161,10 +158,7 @@ define i32 @select_and_not_1(i32 %x, i32 %y) { ; select(Y & X != -1, Y, Y & X) define i32 @select_and_not_2(i32 %x, i32 %y) { ; CHECK-LABEL: @select_and_not_2( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[Y:%.*]], [[X:%.*]] -; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[AND]], -1 -; CHECK-NEXT: [[RET:%.*]] = select i1 [[CMP]], i32 [[Y]], i32 [[AND]] -; CHECK-NEXT: ret i32 [[RET]] +; CHECK-NEXT: ret i32 [[Y:%.*]] ; %and = and i32 %y, %x %cmp = icmp ne i32 %and, -1 @@ -186,13 +180,10 @@ define i32 @select_and_not_3(i32 %x, i32 %y) { ret i32 %ret } -; TODO: https://alive2.llvm.org/ce/z/1ILbih +; https://alive2.llvm.org/ce/z/1ILbih define i32 @select_icmp_and_eq(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_and_eq( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], -1 -; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[A]], i32 -1 -; CHECK-NEXT: ret i32 [[COND]] +; CHECK-NEXT: ret i32 -1 ; %and = and i32 %a, %b %tobool = icmp eq i32 %and, -1 @@ -202,10 +193,7 @@ define i32 @select_icmp_and_eq(i32 %a, i32 %b) { define i32 @select_icmp_and_eq_commuted(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_and_eq_commuted( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[AND]], -1 -; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 [[B]], i32 -1 -; CHECK-NEXT: ret i32 [[COND]] +; CHECK-NEXT: ret i32 -1 ; %and = and i32 %a, %b %tobool = icmp eq i32 %and, -1 @@ -216,10 +204,7 @@ define i32 @select_icmp_and_eq_commuted(i32 %a, i32 %b) { ; https://alive2.llvm.org/ce/z/HfYXvx define <2 x i16> @select_icmp_and_eq_vec(<2 x i16> %a, <2 x i16> %b) { ; CHECK-LABEL: @select_icmp_and_eq_vec( -; CHECK-NEXT: [[AND:%.*]] = and <2 x i16> [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq <2 x i16> [[AND]], -; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[TOBOOL]], <2 x i16> [[A]], <2 x i16> -; CHECK-NEXT: ret <2 x i16> [[COND]] +; CHECK-NEXT: ret <2 x i16> ; %and = and <2 x i16> %a, %b %tobool = icmp eq <2 x i16> %and, @@ -230,10 +215,7 @@ define <2 x i16> @select_icmp_and_eq_vec(<2 x i16> %a, <2 x i16> %b) { ; The ne should also be macthed define i32 @select_icmp_and_ne(i32 %a, i32 %b) { ; CHECK-LABEL: @select_icmp_and_ne( -; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[AND]], -1 -; CHECK-NEXT: [[COND:%.*]] = select i1 [[TOBOOL]], i32 -1, i32 [[A]] -; CHECK-NEXT: ret i32 [[COND]] +; CHECK-NEXT: ret i32 -1 ; %and = and i32 %a, %b %tobool = icmp ne i32 %and, -1