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 @@ -1095,7 +1095,7 @@ // RHS from matchSelectPattern returns the negation part of abs pattern. // If the negate has an NSW flag we can assume the sign bit of the result // will be 0 because that makes abs(INT_MIN) undefined. - if (Q.IIQ.hasNoSignedWrap(cast(RHS))) + if (match(RHS, m_NSWSub(m_ZeroInt(), m_Specific(LHS)))) MaxHighZeros = 1; } @@ -5624,7 +5624,7 @@ // then the result of abs(X) is [0..SIGNED_MAX], // otherwise it is [0..SIGNED_MIN], as -SIGNED_MIN == SIGNED_MIN. Lower = APInt::getNullValue(BitWidth); - if (cast(RHS)->hasNoSignedWrap()) + if (match(RHS, m_NSWSub(m_ZeroInt(), m_Specific(LHS)))) Upper = APInt::getSignedMaxValue(BitWidth) + 1; else Upper = APInt::getSignedMinValue(BitWidth) + 1; diff --git a/llvm/test/Transforms/InstSimplify/icmp-abs-nabs.ll b/llvm/test/Transforms/InstSimplify/icmp-abs-nabs.ll --- a/llvm/test/Transforms/InstSimplify/icmp-abs-nabs.ll +++ b/llvm/test/Transforms/InstSimplify/icmp-abs-nabs.ll @@ -404,7 +404,12 @@ ; We can't fold this to false unless both subs have nsw. define i1 @abs_sub_sub_missing_nsw(i32 %x, i32 %y) { ; CHECK-LABEL: @abs_sub_sub_missing_nsw( -; CHECK-NEXT: ret i1 false +; CHECK-NEXT: [[A:%.*]] = sub i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[B:%.*]] = sub nsw i32 [[Y]], [[X]] +; CHECK-NEXT: [[C:%.*]] = icmp sgt i32 [[A]], -1 +; CHECK-NEXT: [[D:%.*]] = select i1 [[C]], i32 [[A]], i32 [[B]] +; CHECK-NEXT: [[E:%.*]] = icmp slt i32 [[D]], 0 +; CHECK-NEXT: ret i1 [[E]] ; %a = sub i32 %x, %y %b = sub nsw i32 %y, %x