diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -5260,10 +5260,19 @@ bool IsZext0 = isa(ICmp.getOperand(0)); bool IsZext1 = isa(ICmp.getOperand(1)); - // If we have mismatched casts, treat the zext of a non-negative source as - // a sext to simulate matching casts. Otherwise, we are done. - // TODO: Can we handle some predicates (equality) without non-negative? if (IsZext0 != IsZext1) { + // If X and Y and both i1 + // (icmp eq/ne (zext X) (sext Y)) + // eq -> (icmp eq (or X, Y), 0) + // ne -> (icmp ne (or X, Y), 0) + if (ICmp.isEquality() && X->getType()->isIntOrIntVectorTy(1) && + Y->getType()->isIntOrIntVectorTy(1)) + return new ICmpInst(ICmp.getPredicate(), Builder.CreateOr(X, Y), + Constant::getNullValue(X->getType())); + + // If we have mismatched casts, treat the zext of a non-negative source as + // a sext to simulate matching casts. Otherwise, we are done. + // TODO: Can we handle some predicates (equality) without non-negative? if ((IsZext0 && isKnownNonNegative(X, DL, 0, &AC, &ICmp, &DT)) || (IsZext1 && isKnownNonNegative(Y, DL, 0, &AC, &ICmp, &DT))) IsSignedExt = true; diff --git a/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll b/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll --- a/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll +++ b/llvm/test/Transforms/InstCombine/icmp-ext-ext.ll @@ -384,9 +384,8 @@ define i1 @zext_eq_sext(i1 %a, i1 %b) { ; CHECK-LABEL: @zext_eq_sext( -; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[A:%.*]] to i32 -; CHECK-NEXT: [[CONV3_NEG:%.*]] = sext i1 [[B:%.*]] to i32 -; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp eq i32 [[CONV]], [[CONV3_NEG]] +; CHECK-NEXT: [[TMP1:%.*]] = or i1 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TOBOOL4:%.*]] = xor i1 [[TMP1]], true ; CHECK-NEXT: ret i1 [[TOBOOL4]] ; %conv = zext i1 %a to i32 @@ -410,10 +409,8 @@ define <2 x i1> @zext_ne_sext(<2 x i1> %a, <2 x i1> %b) { ; CHECK-LABEL: @zext_ne_sext( -; CHECK-NEXT: [[CONV:%.*]] = zext <2 x i1> [[A:%.*]] to <2 x i8> -; CHECK-NEXT: [[CONV3_NEG:%.*]] = sext <2 x i1> [[B:%.*]] to <2 x i8> -; CHECK-NEXT: [[TOBOOL4:%.*]] = icmp ne <2 x i8> [[CONV3_NEG]], [[CONV]] -; CHECK-NEXT: ret <2 x i1> [[TOBOOL4]] +; CHECK-NEXT: [[TMP1:%.*]] = or <2 x i1> [[B:%.*]], [[A:%.*]] +; CHECK-NEXT: ret <2 x i1> [[TMP1]] ; %conv = zext <2 x i1> %a to <2 x i8> %conv3.neg = sext <2 x i1> %b to <2 x i8>