Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -4555,9 +4555,16 @@ if (match(TrueVal, m_One()) && match(FalseVal, m_ZeroInt())) return Cond; - // (X || Y) && (X || !Y) --> X (commuted 8 ways) Value *X, *Y; + if (match(Cond, m_LogicalOr(m_Value(X), m_Value(Y)))) { + auto *C = dyn_cast(TrueVal); + // (X || Y) ? false : X --> false (commuted 2 ways) + if (C && C->isNullValue() && (X == FalseVal || Y == FalseVal)) + return TrueVal; + } + 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)))) && match(TrueVal, m_c_LogicalOr(m_Specific(X), m_Specific(Y)))) return X; Index: llvm/test/Transforms/InstSimplify/select-logical.ll =================================================================== --- llvm/test/Transforms/InstSimplify/select-logical.ll +++ llvm/test/Transforms/InstSimplify/select-logical.ll @@ -198,46 +198,40 @@ } -; another way for !(X || Y) && X --> false +; (X || Y) ? false && X --> false define i1 @logical_not_or_and_case2(i1 %x, i1 %y) { ; CHECK-LABEL: @logical_not_or_and_case2( -; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 false, i1 [[X]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %or = or i1 %x, %y %r = select i1 %or, i1 false, i1 %x ret i1 %r } -; another way for !(X || Y) && Y --> false +; (X || Y) ? false && X --> false define i1 @logical_not_or_and_case3(i1 %x, i1 %y) { ; CHECK-LABEL: @logical_not_or_and_case3( -; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 false, i1 [[Y]] -; CHECK-NEXT: ret i1 [[R]] +; CHECK-NEXT: ret i1 false ; %or = or i1 %x, %y %r = select i1 %or, i1 false, i1 %y ret i1 %r } -; vector case !(X || Y) && X --> false +; vector case (X || Y) ? false && X --> false define <2 x i1> @logical_not_or_and_vector2(<2 x i1> %x, <2 x i1> %y) { ; CHECK-LABEL: @logical_not_or_and_vector2( -; CHECK-NEXT: [[OR:%.*]] = or <2 x i1> [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[OR]], <2 x i1> zeroinitializer, <2 x i1> [[X]] -; CHECK-NEXT: ret <2 x i1> [[R]] +; CHECK-NEXT: ret <2 x i1> zeroinitializer ; %or = or <2 x i1> %x, %y %r = select <2 x i1> %or, <2 x i1> , <2 x i1> %x ret <2 x i1> %r } -; vector case !(X || Y) && X --> false +; vector poison case (X || Y) ? false && X --> false define <2 x i1> @logical_not_or_and_vector2_poison(<2 x i1> %x, <2 x i1> %y) { ; CHECK-LABEL: @logical_not_or_and_vector2_poison(