diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp index 20c13de33f818..5e23514bf5ae0 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCasts.cpp @@ -904,19 +904,18 @@ Instruction *InstCombinerImpl::transformZExtICmp(ICmpInst *Cmp, // zext (X == 0) to i32 --> (X>>1)^1 iff X has only the 2nd bit set. // zext (X != 0) to i32 --> X iff X has only the low bit set. // zext (X != 0) to i32 --> X>>1 iff X has only the 2nd bit set. - if (Op1CV->isZero() && Cmp->isEquality() && - (Cmp->getOperand(0)->getType() == Zext.getType() || - Cmp->getPredicate() == ICmpInst::ICMP_NE)) { - // If Op1C some other power of two, convert: - KnownBits Known = computeKnownBits(Cmp->getOperand(0), 0, &Zext); + if (Op1CV->isZero() && Cmp->isEquality()) { // Exactly 1 possible 1? But not the high-bit because that is // canonicalized to this form. + KnownBits Known = computeKnownBits(Cmp->getOperand(0), 0, &Zext); APInt KnownZeroMask(~Known.Zero); - if (KnownZeroMask.isPowerOf2() && - (Zext.getType()->getScalarSizeInBits() != - KnownZeroMask.logBase2() + 1)) { - uint32_t ShAmt = KnownZeroMask.logBase2(); + uint32_t ShAmt = KnownZeroMask.logBase2(); + bool IsExpectShAmt = KnownZeroMask.isPowerOf2() && + (Zext.getType()->getScalarSizeInBits() != ShAmt + 1); + if (IsExpectShAmt && + (Cmp->getOperand(0)->getType() == Zext.getType() || + Cmp->getPredicate() == ICmpInst::ICMP_NE || ShAmt == 0)) { Value *In = Cmp->getOperand(0); if (ShAmt) { // Perform a logical shr by shiftamt. diff --git a/llvm/test/Transforms/InstCombine/zext.ll b/llvm/test/Transforms/InstCombine/zext.ll index 00147bb523f47..f595638ba9e30 100644 --- a/llvm/test/Transforms/InstCombine/zext.ll +++ b/llvm/test/Transforms/InstCombine/zext.ll @@ -749,10 +749,11 @@ define i64 @zext_icmp_ne_bool_1(ptr %ptr) { ret i64 %len } +; https://alive2.llvm.org/ce/z/k7qosS define i32 @zext_icmp_eq0_no_shift(ptr %ptr ) { ; CHECK-LABEL: @zext_icmp_eq0_no_shift( ; CHECK-NEXT: [[X:%.*]] = load i8, ptr [[PTR:%.*]], align 1, !range [[RNG1:![0-9]+]] -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[X]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = xor i8 [[X]], 1 ; CHECK-NEXT: [[RES:%.*]] = zext i8 [[TMP1]] to i32 ; CHECK-NEXT: ret i32 [[RES]] ;