From 9666e89d577887cf574507207484a066588fc9ca Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 26 Mar 2021 20:12:55 +0100 Subject: [PATCH] [ValueTracking] Handle shl in isKnownNonEqual() This handles the pattern X != X << C for non-zero X and C and a non-overflowing shift. This establishes parity with the corresponing fold for multiplies. --- llvm/lib/Analysis/ValueTracking.cpp | 16 ++++++++++++++++ llvm/test/Analysis/ValueTracking/known-non-equal.ll | 10 ++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 1c3d5df..6f89ba9 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -2564,6 +2564,19 @@ static bool isNonEqualMul(const Value *V1, const Value *V2, unsigned Depth, return false; } +/// Return true if V2 == V1 << C, where V1 is known non-zero, C is not 0 and +/// the shift is nuw or nsw. +static bool isNonEqualShl(const Value *V1, const Value *V2, unsigned Depth, + const Query &Q) { + if (auto *OBO = dyn_cast(V2)) { + const APInt *C; + return match(OBO, m_Shl(m_Specific(V1), m_APInt(C))) && + (OBO->hasNoUnsignedWrap() || OBO->hasNoSignedWrap()) && + !C->isNullValue() && isKnownNonZero(V1, Depth + 1, Q); + } + return false; +} + static bool isNonEqualPHIs(const PHINode *PN1, const PHINode *PN2, unsigned Depth, const Query &Q) { // Check two PHIs are in same block. @@ -2665,6 +2678,9 @@ static bool isKnownNonEqual(const Value *V1, const Value *V2, unsigned Depth, if (isNonEqualMul(V1, V2, Depth, Q) || isNonEqualMul(V2, V1, Depth, Q)) return true; + if (isNonEqualShl(V1, V2, Depth, Q) || isNonEqualShl(V2, V1, Depth, Q)) + return true; + if (V1->getType()->isIntOrIntVectorTy()) { // Are any known bits in V1 contradictory to known bits in V2? If V1 // has a known zero where V2 has a known one, they must not be equal. diff --git a/llvm/test/Analysis/ValueTracking/known-non-equal.ll b/llvm/test/Analysis/ValueTracking/known-non-equal.ll index 552e5d1..6958b78 100644 --- a/llvm/test/Analysis/ValueTracking/known-non-equal.ll +++ b/llvm/test/Analysis/ValueTracking/known-non-equal.ll @@ -345,10 +345,7 @@ exit: define i1 @shl_nuw(i16 %x) { ; CHECK-LABEL: @shl_nuw( -; CHECK-NEXT: [[NZ:%.*]] = or i16 [[X:%.*]], 2 -; CHECK-NEXT: [[MUL:%.*]] = shl nuw i16 [[NZ]], 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[NZ]], [[MUL]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %nz = or i16 %x, 2 %mul = shl nuw i16 %nz, 1 @@ -358,10 +355,7 @@ define i1 @shl_nuw(i16 %x) { define i1 @shl_nsw(i16 %x) { ; CHECK-LABEL: @shl_nsw( -; CHECK-NEXT: [[NZ:%.*]] = or i16 [[X:%.*]], 2 -; CHECK-NEXT: [[MUL:%.*]] = shl nsw i16 [[NZ]], 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 [[NZ]], [[MUL]] -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: ret i1 false ; %nz = or i16 %x, 2 %mul = shl nsw i16 %nz, 1 -- 2.7.4