diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/llvm/lib/Analysis/InstructionSimplify.cpp @@ -2219,6 +2219,15 @@ match(Op1, m_c_Xor(m_Specific(Or), m_Specific(Y)))) return Constant::getNullValue(Op0->getType()); + if (Op0->getType()->isIntOrIntVectorTy(1)) { + // Op0&Op1 -> Op0 where Op0 implies Op1 + if (isImpliedCondition(Op0, Op1, Q.DL).getValueOr(false)) + return Op0; + // Op0&Op1 -> Op1 where Op1 implies Op0 + if (isImpliedCondition(Op1, Op0, Q.DL).getValueOr(false)) + return Op1; + } + return nullptr; } @@ -2451,6 +2460,15 @@ if (Value *V = ThreadBinOpOverPHI(Instruction::Or, Op0, Op1, Q, MaxRecurse)) return V; + if (Op0->getType()->isIntOrIntVectorTy(1)) { + // Op0|Op1 -> Op1 where Op0 implies Op1 + if (isImpliedCondition(Op0, Op1, Q.DL).getValueOr(false)) + return Op1; + // Op0|Op1 -> Op0 where Op1 implies Op0 + if (isImpliedCondition(Op1, Op0, Q.DL).getValueOr(false)) + return Op0; + } + return nullptr; } diff --git a/llvm/test/Transforms/InstSimplify/and-icmps-same-ops.ll b/llvm/test/Transforms/InstSimplify/and-icmps-same-ops.ll --- a/llvm/test/Transforms/InstSimplify/and-icmps-same-ops.ll +++ b/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 diff --git a/llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll b/llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll --- a/llvm/test/Transforms/InstSimplify/and-or-implied-cond.ll +++ b/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 diff --git a/llvm/test/Transforms/InstSimplify/or-icmps-same-ops.ll b/llvm/test/Transforms/InstSimplify/or-icmps-same-ops.ll --- a/llvm/test/Transforms/InstSimplify/or-icmps-same-ops.ll +++ b/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