diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp index 73320b556f825..be9843503298f 100644 --- a/llvm/lib/Analysis/ValueTracking.cpp +++ b/llvm/lib/Analysis/ValueTracking.cpp @@ -278,7 +278,16 @@ static bool isKnownNonZero(const Value *V, const APInt &DemandedElts, bool llvm::isKnownNonNegative(const Value *V, const SimplifyQuery &SQ, unsigned Depth) { - return computeKnownBits(V, SQ, Depth).isNonNegative(); + if (computeKnownBits(V, SQ, Depth).isNonNegative()) + return true; + + Value *X, *Y; + if (match(V, m_NSWSub(m_Value(X), m_Value(Y)))) + if (std::optional result = + isImpliedByDomCondition(ICmpInst::ICMP_SLE, Y, X, SQ.CxtI, SQ.DL)) + return *result; + + return false; } bool llvm::isKnownPositive(const Value *V, const SimplifyQuery &SQ, diff --git a/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll b/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll new file mode 100644 index 0000000000000..279a6de4125ed --- /dev/null +++ b/llvm/test/Transforms/InstCombine/sub-after-sle-is-non-negative.ll @@ -0,0 +1,53 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s +define void @test_as_arg(i8 %a, i8 %b) { +; CHECK-LABEL: define void @test_as_arg( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) { +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], [[B]] +; CHECK-NEXT: br i1 [[CMP]], label %[[COND_END:.*]], label %[[COND_FALSE:.*]] +; CHECK: [[COND_FALSE]]: +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[CONV:%.*]] = zext nneg i8 [[SUB]] to i16 +; CHECK-NEXT: call void @subroutine(i16 [[CONV]]) +; CHECK-NEXT: br label %[[COND_END]] +; CHECK: [[COND_END]]: +; CHECK-NEXT: ret void +; + %cmp = icmp sgt i8 %a, %b + br i1 %cmp, label %cond.end, label %cond.false + +cond.false: + %sub = sub nsw i8 %b, %a + %conv = sext i8 %sub to i16 + call void @subroutine(i16 %conv) + br label %cond.end + +cond.end: + ret void +} + +declare void @subroutine(i16) + +define i16 @test_as_retval(i8 %a, i8 %b) { +; CHECK-LABEL: define i16 @test_as_retval( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]]) { +; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i8 [[A]], [[B]] +; CHECK-NEXT: br i1 [[CMP]], label %[[COND_TRUE:.*]], label %[[COND_FALSE:.*]] +; CHECK: [[COND_TRUE]]: +; CHECK-NEXT: ret i16 0 +; CHECK: [[COND_FALSE]]: +; CHECK-NEXT: [[SUB:%.*]] = sub nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[CONV:%.*]] = zext nneg i8 [[SUB]] to i16 +; CHECK-NEXT: ret i16 [[CONV]] +; + %cmp = icmp sgt i8 %a, %b + br i1 %cmp, label %cond.true, label %cond.false + +cond.true: + ret i16 0 + +cond.false: + %sub = sub nsw i8 %b, %a + %conv = sext i8 %sub to i16 + ret i16 %conv +} pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy