Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -4563,6 +4563,11 @@ } if (match(FalseVal, m_ZeroInt())) { + // !(X || Y) && X --> false (commuted 2 ways) + if (match(Cond, m_Not(m_LogicalOr(m_Value(X), m_Value(Y)))) && + (TrueVal == X || TrueVal == Y)) + return ConstantInt::getFalse(Cond->getType()); + // (X || Y) && (X || !Y) --> X (commuted 8 ways) if (match(Cond, m_c_LogicalOr(m_Value(X), m_Not(m_Value(Y)))) && match(TrueVal, m_c_LogicalOr(m_Specific(X), m_Specific(Y)))) Index: llvm/test/Transforms/InstSimplify/select-logical.ll =================================================================== --- llvm/test/Transforms/InstSimplify/select-logical.ll +++ llvm/test/Transforms/InstSimplify/select-logical.ll @@ -127,10 +127,7 @@ define i1 @or_not_and(i1 %x, i1 %y) { ; CHECK-LABEL: @or_not_and( -; CHECK-NEXT: [[L_AND:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[L_AND]], true -; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT]], i1 [[X]], i1 false -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %l.and = or i1 %x, %y %not = xor i1 %l.and, true @@ -142,10 +139,7 @@ define <2 x i1> @or_not_and_vector(<2 x i1> %x, <2 x i1> %y) { ; CHECK-LABEL: @or_not_and_vector( -; CHECK-NEXT: [[L_AND:%.*]] = or <2 x i1> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[L_AND]], -; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT]], <2 x i1> [[X]], <2 x i1> zeroinitializer -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %l.and = or <2 x i1> %x, %y %not = xor <2 x i1> %l.and, @@ -157,10 +151,7 @@ define <2 x i1> @or_not_and_vector_poison1(<2 x i1> %x, <2 x i1> %y) { ; CHECK-LABEL: @or_not_and_vector_poison1( -; CHECK-NEXT: [[L_AND:%.*]] = or <2 x i1> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[L_AND]], -; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT]], <2 x i1> [[X]], <2 x i1> zeroinitializer -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %l.and = or <2 x i1> %x, %y %not = xor <2 x i1> %l.and, @@ -172,10 +163,7 @@ define <2 x i1> @or_not_and_vector_poison2(<2 x i1> %x, <2 x i1> %y) { ; CHECK-LABEL: @or_not_and_vector_poison2( -; CHECK-NEXT: [[L_AND:%.*]] = or <2 x i1> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor <2 x i1> [[L_AND]], -; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[NOT]], <2 x i1> [[X]], <2 x i1> -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %l.and = or <2 x i1> %x, %y %not = xor <2 x i1> %l.and, @@ -188,10 +176,7 @@ define i1 @logical_or_not_and(i1 %x, i1 %y) { ; CHECK-LABEL: @logical_or_not_and( -; CHECK-NEXT: [[L_AND:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[L_AND]], true -; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT]], i1 [[X]], i1 false -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %l.and = select i1 %x, i1 true, i1 %y %not = xor i1 %l.and, true @@ -204,10 +189,7 @@ define i1 @logical_or_not_and_comute_or(i1 %x, i1 %y) { ; CHECK-LABEL: @logical_or_not_and_comute_or( -; CHECK-NEXT: [[L_AND:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[L_AND]], true -; CHECK-NEXT: [[R:%.*]] = select i1 [[NOT]], i1 [[Y]], i1 false -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %l.and = select i1 %x, i1 true, i1 %y %not = xor i1 %l.and, true @@ -219,10 +201,7 @@ define <3 x i1> @logical_or_not_and_vector1(<3 x i1> %x, <3 x i1> %y) { ; CHECK-LABEL: @logical_or_not_and_vector1( -; CHECK-NEXT: [[L_AND:%.*]] = select <3 x i1> [[X:%.*]], <3 x i1> , <3 x i1> [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor <3 x i1> [[L_AND]], -; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[NOT]], <3 x i1> [[X]], <3 x i1> zeroinitializer -; CHECK-NEXT: ret <3 x i1> [[R]] +; CHECK-NEXT: ret <3 x i1> zeroinitializer ; %l.and = select <3 x i1> %x, <3 x i1> , <3 x i1> %y %not = xor <3 x i1> %l.and, @@ -249,10 +228,7 @@ define <3 x i1> @logical_or_not_and_vector1_poison2(<3 x i1> %x, <3 x i1> %y) { ; CHECK-LABEL: @logical_or_not_and_vector1_poison2( -; CHECK-NEXT: [[L_AND:%.*]] = select <3 x i1> [[X:%.*]], <3 x i1> , <3 x i1> [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor <3 x i1> [[L_AND]], -; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[NOT]], <3 x i1> [[X]], <3 x i1> zeroinitializer -; CHECK-NEXT: ret <3 x i1> [[R]] +; CHECK-NEXT: ret <3 x i1> zeroinitializer ; %l.and = select <3 x i1> %x, <3 x i1> , <3 x i1> %y %not = xor <3 x i1> %l.and, @@ -264,10 +240,7 @@ define <3 x i1> @logical_or_not_and_vector1_poison3(<3 x i1> %x, <3 x i1> %y) { ; CHECK-LABEL: @logical_or_not_and_vector1_poison3( -; CHECK-NEXT: [[L_AND:%.*]] = select <3 x i1> [[X:%.*]], <3 x i1> , <3 x i1> [[Y:%.*]] -; CHECK-NEXT: [[NOT:%.*]] = xor <3 x i1> [[L_AND]], -; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[NOT]], <3 x i1> [[X]], <3 x i1> -; CHECK-NEXT: ret <3 x i1> [[R]] +; CHECK-NEXT: ret <3 x i1> zeroinitializer ; %l.and = select <3 x i1> %x, <3 x i1> , <3 x i1> %y %not = xor <3 x i1> %l.and,