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;
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;
; 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
; 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
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
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
; 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]], <i16 -1, i16 -1>
-; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[TOBOOL]], <2 x i16> [[A]], <2 x i16> <i16 -1, i16 -1>
-; CHECK-NEXT: ret <2 x i16> [[COND]]
+; CHECK-NEXT: ret <2 x i16> <i16 -1, i16 -1>
;
%and = and <2 x i16> %a, %b
%tobool = icmp eq <2 x i16> %and, <i16 -1, i16 -1>
; 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