diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index d9f89962c100a7..75ccb103936d61 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -1072,39 +1072,6 @@ Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, Value *And1 = Builder.CreateAnd(Lshr, ConstantInt::get(X->getType(), 1)); return replaceInstUsesWith(Zext, And1); } - - // icmp ne A, B is equal to xor A, B when A and B only really have one bit. - // It is also profitable to transform icmp eq into not(xor(A, B)) because - // that may lead to additional simplifications. - if (IntegerType *ITy = dyn_cast(Zext.getType())) { - Value *LHS = Cmp->getOperand(0); - Value *RHS = Cmp->getOperand(1); - - KnownBits KnownLHS = computeKnownBits(LHS, 0, &Zext); - KnownBits KnownRHS = computeKnownBits(RHS, 0, &Zext); - - if (KnownLHS == KnownRHS) { - APInt KnownBits = KnownLHS.Zero | KnownLHS.One; - APInt UnknownBit = ~KnownBits; - if (UnknownBit.countPopulation() == 1) { - Value *Result = Builder.CreateXor(LHS, RHS); - - // Mask off any bits that are set and won't be shifted away. - if (KnownLHS.One.uge(UnknownBit)) - Result = Builder.CreateAnd(Result, - ConstantInt::get(ITy, UnknownBit)); - - // Shift the bit we're testing down to the lsb. - Result = Builder.CreateLShr( - Result, ConstantInt::get(ITy, UnknownBit.countTrailingZeros())); - - if (Cmp->getPredicate() == ICmpInst::ICMP_EQ) - Result = Builder.CreateXor(Result, ConstantInt::get(ITy, 1)); - Result->takeName(Cmp); - return replaceInstUsesWith(Zext, Result); - } - } - } } return nullptr; diff --git a/llvm/test/Transforms/InstCombine/zext.ll b/llvm/test/Transforms/InstCombine/zext.ll index c0275e99c53fd0..d223c94e553e1b 100644 --- a/llvm/test/Transforms/InstCombine/zext.ll +++ b/llvm/test/Transforms/InstCombine/zext.ll @@ -685,3 +685,20 @@ define i16 @zext_icmp_eq0_pow2_use2(i32 %x) { %z = zext i1 %i to i16 ret i16 %z } + +; This used to infinite loop. + +define i8 @zext_icmp_eq_pow2(i8 %y, i8 %x) { +; CHECK-LABEL: @zext_icmp_eq_pow2( +; CHECK-NEXT: [[SHLX:%.*]] = shl i8 [[X:%.*]], 7 +; CHECK-NEXT: [[SHLY:%.*]] = shl i8 -128, [[Y:%.*]] +; CHECK-NEXT: [[C:%.*]] = icmp eq i8 [[SHLX]], [[SHLY]] +; CHECK-NEXT: [[R:%.*]] = zext i1 [[C]] to i8 +; CHECK-NEXT: ret i8 [[R]] +; + %shlx = shl i8 %x, 7 + %shly = shl i8 -128, %y + %c = icmp eq i8 %shlx, %shly + %r = zext i1 %c to i8 + ret i8 %r +}