From a444fe07dd27580a3e8199831a27f5faa90a423e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 17 Jan 2023 16:22:57 +0100 Subject: [PATCH] [CVP] Handle use-site conditions in domain-based folds As a side-effect, this switchem them to use getConstantRange() rather than getPredicateAt(). getPredicateAt() is not supposed to be more powerful than getConstantRange() for non-equality comparisons (as long as block values are used). --- .../Scalar/CorrelatedValuePropagation.cpp | 42 +++++++--------------- .../CorrelatedValuePropagation/cond-at-use.ll | 16 +++++---- 2 files changed, 23 insertions(+), 35 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index 24d8ccb..89f03c9 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -692,26 +692,13 @@ static bool processCallSite(CallBase &CB, LazyValueInfo *LVI) { return true; } -static bool isNonNegative(Value *V, LazyValueInfo *LVI, Instruction *CxtI) { - Constant *Zero = ConstantInt::get(V->getType(), 0); - auto Result = LVI->getPredicateAt(ICmpInst::ICMP_SGE, V, Zero, CxtI, - /*UseBlockValue=*/true); - return Result == LazyValueInfo::True; -} - -static bool isNonPositive(Value *V, LazyValueInfo *LVI, Instruction *CxtI) { - Constant *Zero = ConstantInt::get(V->getType(), 0); - auto Result = LVI->getPredicateAt(ICmpInst::ICMP_SLE, V, Zero, CxtI, - /*UseBlockValue=*/true); - return Result == LazyValueInfo::True; -} - enum class Domain { NonNegative, NonPositive, Unknown }; -Domain getDomain(Value *V, LazyValueInfo *LVI, Instruction *CxtI) { - if (isNonNegative(V, LVI, CxtI)) +static Domain getDomain(const Use &U, LazyValueInfo *LVI) { + ConstantRange CR = LVI->getConstantRangeAtUse(U); + if (CR.isAllNonNegative()) return Domain::NonNegative; - if (isNonPositive(V, LVI, CxtI)) + if (CR.icmp(ICmpInst::ICMP_SLE, APInt::getNullValue(CR.getBitWidth()))) return Domain::NonPositive; return Domain::Unknown; } @@ -906,10 +893,9 @@ static bool processSRem(BinaryOperator *SDI, LazyValueInfo *LVI) { }; std::array Ops; - for (const auto I : zip(Ops, SDI->operands())) { - Operand &Op = std::get<0>(I); - Op.V = std::get<1>(I); - Op.D = getDomain(Op.V, LVI, SDI); + for (const auto &[Op, U] : zip(Ops, SDI->operands())) { + Op.V = U; + Op.D = getDomain(U, LVI); if (Op.D == Domain::Unknown) return false; } @@ -964,10 +950,9 @@ static bool processSDiv(BinaryOperator *SDI, LazyValueInfo *LVI) { }; std::array Ops; - for (const auto I : zip(Ops, SDI->operands())) { - Operand &Op = std::get<0>(I); - Op.V = std::get<1>(I); - Op.D = getDomain(Op.V, LVI, SDI); + for (const auto &[Op, U] : zip(Ops, SDI->operands())) { + Op.V = U; + Op.D = getDomain(U, LVI); if (Op.D == Domain::Unknown) return false; } @@ -1038,7 +1023,7 @@ static bool processAShr(BinaryOperator *SDI, LazyValueInfo *LVI) { return true; } - if (!isNonNegative(SDI->getOperand(0), LVI, SDI)) + if (!LRange.isAllNonNegative()) return false; ++NumAShrsConverted; @@ -1057,9 +1042,8 @@ static bool processSExt(SExtInst *SDI, LazyValueInfo *LVI) { if (SDI->getType()->isVectorTy()) return false; - Value *Base = SDI->getOperand(0); - - if (!isNonNegative(Base, LVI, SDI)) + const Use &Base = SDI->getOperandUse(0); + if (!LVI->getConstantRangeAtUse(Base).isAllNonNegative()) return false; ++NumSExt; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll b/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll index 2b25195..6270ca8 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll @@ -425,9 +425,11 @@ define i16 @srem_narrow(i16 %x) { define i16 @srem_convert(i16 %x) { ; CHECK-LABEL: @srem_convert( -; CHECK-NEXT: [[SREM:%.*]] = srem i16 [[X:%.*]], 42 +; CHECK-NEXT: [[X_NONNEG:%.*]] = sub i16 0, [[X:%.*]] +; CHECK-NEXT: [[SREM1:%.*]] = urem i16 [[X_NONNEG]], 42 +; CHECK-NEXT: [[SREM1_NEG:%.*]] = sub i16 0, [[SREM1]] ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[X]], 0 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SREM]], i16 24 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SREM1_NEG]], i16 24 ; CHECK-NEXT: ret i16 [[SEL]] ; %srem = srem i16 %x, 42 @@ -438,9 +440,11 @@ define i16 @srem_convert(i16 %x) { define i16 @sdiv_convert(i16 %x) { ; CHECK-LABEL: @sdiv_convert( -; CHECK-NEXT: [[SREM:%.*]] = sdiv i16 [[X:%.*]], 42 +; CHECK-NEXT: [[X_NONNEG:%.*]] = sub i16 0, [[X:%.*]] +; CHECK-NEXT: [[SREM1:%.*]] = udiv i16 [[X_NONNEG]], 42 +; CHECK-NEXT: [[SREM1_NEG:%.*]] = sub i16 0, [[SREM1]] ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i16 [[X]], 0 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SREM]], i16 24 +; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[SREM1_NEG]], i16 24 ; CHECK-NEXT: ret i16 [[SEL]] ; %srem = sdiv i16 %x, 42 @@ -503,7 +507,7 @@ define i16 @umin_elide(i16 %x) { define i16 @ashr_convert(i16 %x, i16 %y) { ; CHECK-LABEL: @ashr_convert( -; CHECK-NEXT: [[ASHR:%.*]] = ashr i16 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[ASHR:%.*]] = lshr i16 [[X:%.*]], [[Y:%.*]] ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i16 [[X]], 0 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[ASHR]], i16 24 ; CHECK-NEXT: ret i16 [[SEL]] @@ -516,7 +520,7 @@ define i16 @ashr_convert(i16 %x, i16 %y) { define i32 @sext_convert(i16 %x) { ; CHECK-LABEL: @sext_convert( -; CHECK-NEXT: [[EXT:%.*]] = sext i16 [[X:%.*]] to i32 +; CHECK-NEXT: [[EXT:%.*]] = zext i16 [[X:%.*]] to i32 ; CHECK-NEXT: [[CMP:%.*]] = icmp sge i16 [[X]], 0 ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[EXT]], i32 24 ; CHECK-NEXT: ret i32 [[SEL]] -- 2.7.4