Index: llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2899,12 +2899,34 @@ BinaryOperator *Add, const APInt &C) { Value *Y = Add->getOperand(1); + Value *X = Add->getOperand(0); + + // We have two cases to handle here: + // 1- (zext i1 X + zext i1 Y) == 1 --> xor i1 X, Y + // 2- (zext i1 X + zext i1 Y) == 0 --> !(or i1 X, Y) + if (Cmp.isEquality()) { + if (match(Add, m_c_Add(m_OneUse(m_ZExt(m_Value(X))), + m_OneUse(m_ZExt(m_Value(Y))))) && + X->getType()->isIntOrIntVectorTy(1) && + Y->getType()->isIntOrIntVectorTy(1) && (C.isZero() || C.isOne())) { + Value *Cond = Builder.getFalse(); + // Case 1: + if (C.isOne()) { + Cond = Builder.CreateXor(X, Y); + } else { + // Case 2: + Cond = Builder.CreateNot(Builder.CreateOr(X, Y)); + } + return replaceInstUsesWith(Cmp, Cond); + } + return nullptr; + } + const APInt *C2; - if (Cmp.isEquality() || !match(Y, m_APInt(C2))) + if (!match(Y, m_APInt(C2))) return nullptr; // Fold icmp pred (add X, C2), C. - Value *X = Add->getOperand(0); Type *Ty = Add->getType(); const CmpInst::Predicate Pred = Cmp.getPredicate(); Index: llvm/test/Transforms/InstCombine/icmp-add.ll =================================================================== --- llvm/test/Transforms/InstCombine/icmp-add.ll +++ llvm/test/Transforms/InstCombine/icmp-add.ll @@ -5,6 +5,36 @@ ; PR1949 +define i1 @cvt_icmp_1_to_xor(i1 %arg, i1 %arg1) { +; CHECK-LABEL: @cvt_icmp_1_to_xor( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[I4:%.*]] = xor i1 [[ARG1:%.*]], [[ARG:%.*]] +; CHECK-NEXT: ret i1 [[I4]] +; +bb: + %i = zext i1 %arg to i32 + %i2 = zext i1 %arg1 to i32 + %i3 = add nuw nsw i32 %i2, %i + %i4 = icmp eq i32 %i3, 1 + ret i1 %i4 +} + +define i1 @cvt_icmp_0_to_nor(i1 %arg, i1 %arg1) { +; CHECK-LABEL: @cvt_icmp_0_to_nor( +; CHECK-NEXT: bb: +; CHECK-NEXT: [[TMP0:%.*]] = or i1 [[ARG1:%.*]], [[ARG:%.*]] +; CHECK-NEXT: [[I4:%.*]] = xor i1 [[TMP0]], true +; CHECK-NEXT: ret i1 [[I4]] +; +bb: + %i = zext i1 %arg to i32 + %i2 = zext i1 %arg1 to i32 + %i3 = add nuw nsw i32 %i2, %i + %i4 = icmp eq i32 %i3, 0 + ret i1 %i4 +} + + define i1 @test1(i32 %a) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: [[C:%.*]] = icmp ugt i32 [[A:%.*]], -5