Index: llvm/lib/Analysis/InstructionSimplify.cpp =================================================================== --- llvm/lib/Analysis/InstructionSimplify.cpp +++ llvm/lib/Analysis/InstructionSimplify.cpp @@ -2219,6 +2219,14 @@ match(Op1, m_c_Xor(m_Specific(Or), m_Specific(Y)))) return Constant::getNullValue(Op0->getType()); + if (Op0->getType()->isIntOrIntVectorTy(1)) { + // A&B -> A where A implies B + if (isImpliedCondition(Op0, Op1, Q.DL).getValueOr(false)) + return Op0; + if (isImpliedCondition(Op1, Op0, Q.DL).getValueOr(false)) + return Op1; + } + return nullptr; } @@ -2451,6 +2459,14 @@ if (Value *V = ThreadBinOpOverPHI(Instruction::Or, Op0, Op1, Q, MaxRecurse)) return V; + if (Op0->getType()->isIntOrIntVectorTy(1)) { + // A|B -> B where A implies B + if (isImpliedCondition(Op0, Op1, Q.DL).getValueOr(false)) + return Op1; + if (isImpliedCondition(Op1, Op0, Q.DL).getValueOr(false)) + return Op0; + } + return nullptr; } Index: llvm/test/Transforms/InstSimplify/and-icmps-same-ops.ll =================================================================== --- llvm/test/Transforms/InstSimplify/and-icmps-same-ops.ll +++ llvm/test/Transforms/InstSimplify/and-icmps-same-ops.ll @@ -1214,9 +1214,7 @@ define i1 @ult_uge_swap(i8 %a, i8 %b) { ; CHECK-LABEL: @ult_uge_swap( ; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i8 [[B]], [[A]] -; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP1]], [[CMP2]] -; CHECK-NEXT: ret i1 [[AND]] +; CHECK-NEXT: ret i1 [[CMP1]] ; %cmp1 = icmp ult i8 %a, %b %cmp2 = icmp uge i8 %b, %a Index: llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll =================================================================== --- llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll +++ llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll @@ -3,11 +3,8 @@ define i1 @or_implied(i8 %x, i1 %c) { ; CHECK-LABEL: @or_implied( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0 -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X]], 1 -; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[C:%.*]] -; CHECK-NEXT: [[OR:%.*]] = or i1 [[AND]], [[CMP2]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 1 +; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp = icmp eq i8 %x, 0 %cmp2 = icmp ne i8 %x, 1 @@ -18,11 +15,8 @@ define i1 @or_implied_comm1(i8 %x, i1 %c) { ; CHECK-LABEL: @or_implied_comm1( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0 -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X]], 1 -; CHECK-NEXT: [[AND:%.*]] = and i1 [[CMP]], [[C:%.*]] -; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP2]], [[AND]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 1 +; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp = icmp eq i8 %x, 0 %cmp2 = icmp ne i8 %x, 1 @@ -33,11 +27,8 @@ define i1 @or_implied_comm2(i8 %x, i1 %c) { ; CHECK-LABEL: @or_implied_comm2( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0 -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X]], 1 -; CHECK-NEXT: [[AND:%.*]] = and i1 [[C:%.*]], [[CMP]] -; CHECK-NEXT: [[OR:%.*]] = or i1 [[AND]], [[CMP2]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 1 +; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp = icmp eq i8 %x, 0 %cmp2 = icmp ne i8 %x, 1 @@ -48,11 +39,8 @@ define i1 @or_implied_comm3(i8 %x, i1 %c) { ; CHECK-LABEL: @or_implied_comm3( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], 0 -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X]], 1 -; CHECK-NEXT: [[AND:%.*]] = and i1 [[C:%.*]], [[CMP]] -; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP2]], [[AND]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[X:%.*]], 1 +; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp = icmp eq i8 %x, 0 %cmp2 = icmp ne i8 %x, 1 Index: llvm/test/Transforms/InstSimplify/or-icmps-same-ops.ll =================================================================== --- llvm/test/Transforms/InstSimplify/or-icmps-same-ops.ll +++ llvm/test/Transforms/InstSimplify/or-icmps-same-ops.ll @@ -1213,10 +1213,8 @@ define i1 @ult_ne_swap(i8 %a, i8 %b) { ; CHECK-LABEL: @ult_ne_swap( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[B]], [[A]] -; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp ne i8 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ult i8 %a, %b %cmp2 = icmp ne i8 %b, %a @@ -1226,10 +1224,8 @@ define i1 @ult_ule_swap(i8 %a, i8 %b) { ; CHECK-LABEL: @ult_ule_swap( -; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i8 [[A:%.*]], [[B:%.*]] -; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i8 [[B]], [[A]] -; CHECK-NEXT: [[OR:%.*]] = or i1 [[CMP1]], [[CMP2]] -; CHECK-NEXT: ret i1 [[OR]] +; CHECK-NEXT: [[CMP2:%.*]] = icmp uge i8 [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: ret i1 [[CMP2]] ; %cmp1 = icmp ult i8 %a, %b %cmp2 = icmp uge i8 %b, %a