Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -4563,6 +4563,14 @@ return TrueVal; } + if (auto *C = dyn_cast(FalseVal)) + if (C->isNullValue()) { + // !(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 FalseVal; + } + if (match(FalseVal, m_ZeroInt())) { // (X || Y) && (X || !Y) --> X (commuted 8 ways) if (match(Cond, m_c_LogicalOr(m_Value(X), m_Not(m_Value(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, @@ -188,10 +179,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 +192,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 +204,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, @@ -230,18 +212,19 @@ ret <3 x i1> %r } +; TODO: this can be false ; vector case !(X || Y) && X --> false define <3 x i1> @logical_or_not_and_vector1_poison1(<3 x i1> %x, <3 x i1> %y) { ; CHECK-LABEL: @logical_or_not_and_vector1_poison1( ; 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: [[R:%.*]] = select <3 x i1> [[NOT]], <3 x i1> [[X]], <3 x i1> zeroinitializer ; CHECK-NEXT: ret <3 x i1> [[R]] ; %l.and = select <3 x i1> %x, <3 x i1> , <3 x i1> %y %not = xor <3 x i1> %l.and, - %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> + %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> ret <3 x i1> %r } @@ -249,10 +232,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,