diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 6f89ba9b53155..39d8f9b9509e3 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2655,6 +2655,20 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth, Depth + 1, Q); break; } + case Instruction::Shl: { + // Same as multiplies, with the difference that we don't need to check + // for a non-zero multiply. Shifts always multiply by non-zero. + auto *OBO1 = cast(O1); + auto *OBO2 = cast(O2); + if ((!OBO1->hasNoUnsignedWrap() || !OBO2->hasNoUnsignedWrap()) && + (!OBO1->hasNoSignedWrap() || !OBO2->hasNoSignedWrap())) + break; + + if (O1->getOperand(1) == O2->getOperand(1)) + return isKnownNonEqual(O1->getOperand(0), O2->getOperand(0), + Depth + 1, Q); + break; + } case Instruction::SExt: case Instruction::ZExt: if (O1->getOperand(0)->getType() == O2->getOperand(0)->getType()) diff --git a/llvm/test/Analysis/ValueTracking/known-non-equal.ll b/llvm/test/Analysis/ValueTracking/known-non-equal.ll index 6958b78b045ab..0942045516460 100644 --- a/llvm/test/Analysis/ValueTracking/known-non-equal.ll +++ b/llvm/test/Analysis/ValueTracking/known-non-equal.ll @@ -406,13 +406,7 @@ define i1 @shl_op_may_be_zero(i16 %x) { define i1 @shl_shl_nuw(i8 %B, i8 %shift) { ; CHECK-LABEL: @shl_shl_nuw( -; CHECK-NEXT: [[A:%.*]] = add i8 [[B:%.*]], 1 -; CHECK-NEXT: [[A_OP:%.*]] = shl nuw i8 [[A]], [[SHIFT:%.*]] -; CHECK-NEXT: [[B_OP:%.*]] = shl nuw i8 [[B]], [[SHIFT]] -; CHECK-NEXT: [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3 -; CHECK-NEXT: [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %A = add i8 %B, 1 %A.op = shl nuw i8 %A, %shift @@ -425,13 +419,7 @@ define i1 @shl_shl_nuw(i8 %B, i8 %shift) { define i1 @shl_shl_nsw(i8 %B, i8 %shift) { ; CHECK-LABEL: @shl_shl_nsw( -; CHECK-NEXT: [[A:%.*]] = add i8 [[B:%.*]], 1 -; CHECK-NEXT: [[A_OP:%.*]] = shl nsw i8 [[A]], [[SHIFT:%.*]] -; CHECK-NEXT: [[B_OP:%.*]] = shl nsw i8 [[B]], [[SHIFT]] -; CHECK-NEXT: [[A_OP2:%.*]] = mul nuw i8 [[A_OP]], 3 -; CHECK-NEXT: [[B_OP2:%.*]] = mul nuw i8 [[B_OP]], 3 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[A_OP2]], [[B_OP2]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %A = add i8 %B, 1 %A.op = shl nsw i8 %A, %shift