diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -994,30 +994,25 @@ bool ShiftAmtIsConstant = Known.isConstant(); bool MaxShiftAmtIsOutOfRange = Known.getMaxValue().uge(BitWidth); - if (ShiftAmtIsConstant) { - Known = KF(Known2, Known); - - // If the known bits conflict, this must be an overflowing left shift, so - // the shift result is poison. We can return anything we want. Choose 0 for - // the best folding opportunity. - if (Known.hasConflict()) - Known.setAllZero(); + // Use the KF callback to get an initial knownbits approximation. + Known = KF(Known2, Known); + // If the known bits conflict, this must be an overflowing left shift, so + // the shift result is poison. + if (Known.hasConflict()) { + Known.resetAll(); return; } + if (ShiftAmtIsConstant) + return; + // If the shift amount could be greater than or equal to the bit-width of the // LHS, the value could be poison, but bail out because the check below is // expensive. // TODO: Should we just carry on? - if (MaxShiftAmtIsOutOfRange) { - Known.resetAll(); + if (MaxShiftAmtIsOutOfRange) return; - } - - // It would be more-clearly correct to use the two temporaries for this - // calculation. Reusing the APInts here to prevent unnecessary allocations. - Known.resetAll(); // If we know the shifter operand is nonzero, we can sometimes infer more // known bits. However this is expensive to compute, so be lazy about it and @@ -1232,10 +1227,6 @@ }; computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Depth, Q, KF); - // Trailing zeros of a right-shifted constant never decrease. - const APInt *C; - if (match(I->getOperand(0), m_APInt(C))) - Known.Zero.setLowBits(C->countTrailingZeros()); break; } case Instruction::LShr: { @@ -1244,10 +1235,6 @@ }; computeKnownBitsFromShiftOperator(I, DemandedElts, Known, Known2, Depth, Q, KF); - // Leading zeros of a left-shifted constant never decrease. - const APInt *C; - if (match(I->getOperand(0), m_APInt(C))) - Known.Zero.setHighBits(C->countLeadingZeros()); break; } case Instruction::AShr: { diff --git a/llvm/test/Transforms/InstSimplify/icmp-constant.ll b/llvm/test/Transforms/InstSimplify/icmp-constant.ll --- a/llvm/test/Transforms/InstSimplify/icmp-constant.ll +++ b/llvm/test/Transforms/InstSimplify/icmp-constant.ll @@ -772,7 +772,12 @@ define i1 @ne_shl_by_constant_produces_poison(i8 %x) { ; CHECK-LABEL: @ne_shl_by_constant_produces_poison( -; CHECK-NEXT: ret i1 true +; CHECK-NEXT: [[ZX:%.*]] = zext i8 [[X:%.*]] to i16 +; CHECK-NEXT: [[XOR:%.*]] = xor i16 [[ZX]], 32767 +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i16 [[ZX]], [[XOR]] +; CHECK-NEXT: [[POISON:%.*]] = shl nsw i16 [[SUB]], 2 +; CHECK-NEXT: [[CMP:%.*]] = icmp ne i16 [[POISON]], 1 +; CHECK-NEXT: ret i1 [[CMP]] ; %zx = zext i8 %x to i16 ; zx = 0x00xx %xor = xor i16 %zx, 32767 ; xor = 0x7fyy @@ -784,7 +789,11 @@ define i1 @eq_shl_by_constant_produces_poison(i8 %x) { ; CHECK-LABEL: @eq_shl_by_constant_produces_poison( -; CHECK-NEXT: ret i1 false +; CHECK-NEXT: [[CLEAR_HIGH_BIT:%.*]] = and i8 [[X:%.*]], 127 +; CHECK-NEXT: [[SET_NEXT_HIGH_BITS:%.*]] = or i8 [[CLEAR_HIGH_BIT]], 112 +; CHECK-NEXT: [[POISON:%.*]] = shl nsw i8 [[SET_NEXT_HIGH_BITS]], 3 +; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[POISON]], 15 +; CHECK-NEXT: ret i1 [[CMP]] ; %clear_high_bit = and i8 %x, 127 ; 0x7f %set_next_high_bits = or i8 %clear_high_bit, 112 ; 0x70