From 848d7af956442fbf08310cc2d094035802fbe6ea Mon Sep 17 00:00:00 2001 From: Yingwei Zheng Date: Sat, 6 Jan 2024 02:32:57 +0800 Subject: [CVP] Improve the value solving of select at use (#76700) This patch improves the value solving of select at use if the condition is an icmp and we know the result of comparison from `LVI->getPredicateAt`. Compile-time impact: http://llvm-compile-time-tracker.com/compare.php?from=7e405eb722e40c79b7726201d0f76b5dab34ba0f&to=3c315b1ddcb0ad82554b33f08b9356679fae4bb7&stat=instructions:u |stage1-O3|stage1-ReleaseThinLTO|stage1-ReleaseLTO-g|stage1-O0-g|stage2-O3|stage2-O0-g|stage2-clang| |--|--|--|--|--|--|--| |-0.01%|+0.01%|-0.00%|-0.00%|-0.08%|+0.02%|-0.01%| --- .../Scalar/CorrelatedValuePropagation.cpp | 51 +++++++++++----------- .../CorrelatedValuePropagation/select.ll | 23 ++++++++++ 2 files changed, 49 insertions(+), 25 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp index c44d374..9235850 100644 --- a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +++ b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -94,6 +94,31 @@ STATISTIC(NumUDivURemsNarrowedExpanded, "Number of bound udiv's/urem's expanded"); STATISTIC(NumZExt, "Number of non-negative deductions"); +static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) { + if (Constant *C = LVI->getConstant(V, At)) + return C; + + // TODO: The following really should be sunk inside LVI's core algorithm, or + // at least the outer shims around such. + auto *C = dyn_cast(V); + if (!C) + return nullptr; + + Value *Op0 = C->getOperand(0); + Constant *Op1 = dyn_cast(C->getOperand(1)); + if (!Op1) + return nullptr; + + LazyValueInfo::Tristate Result = LVI->getPredicateAt( + C->getPredicate(), Op0, Op1, At, /*UseBlockValue=*/false); + if (Result == LazyValueInfo::Unknown) + return nullptr; + + return (Result == LazyValueInfo::True) + ? ConstantInt::getTrue(C->getContext()) + : ConstantInt::getFalse(C->getContext()); +} + static bool processSelect(SelectInst *S, LazyValueInfo *LVI) { if (S->getType()->isVectorTy() || isa(S->getCondition())) return false; @@ -106,7 +131,7 @@ static bool processSelect(SelectInst *S, LazyValueInfo *LVI) { C = LVI->getConstantOnEdge(S->getCondition(), PN->getIncomingBlock(U), I->getParent(), I); else - C = LVI->getConstant(S->getCondition(), I); + C = getConstantAt(S->getCondition(), I, LVI); auto *CI = dyn_cast_or_null(C); if (!CI) @@ -1109,30 +1134,6 @@ static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) { return true; } - -static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) { - if (Constant *C = LVI->getConstant(V, At)) - return C; - - // TODO: The following really should be sunk inside LVI's core algorithm, or - // at least the outer shims around such. - auto *C = dyn_cast(V); - if (!C) return nullptr; - - Value *Op0 = C->getOperand(0); - Constant *Op1 = dyn_cast(C->getOperand(1)); - if (!Op1) return nullptr; - - LazyValueInfo::Tristate Result = LVI->getPredicateAt( - C->getPredicate(), Op0, Op1, At, /*UseBlockValue=*/false); - if (Result == LazyValueInfo::Unknown) - return nullptr; - - return (Result == LazyValueInfo::True) ? - ConstantInt::getTrue(C->getContext()) : - ConstantInt::getFalse(C->getContext()); -} - static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT, const SimplifyQuery &SQ) { bool FnChanged = false; diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/select.ll b/llvm/test/Transforms/CorrelatedValuePropagation/select.ll index 28a8516..9842328 100644 --- a/llvm/test/Transforms/CorrelatedValuePropagation/select.ll +++ b/llvm/test/Transforms/CorrelatedValuePropagation/select.ll @@ -372,4 +372,27 @@ define i64 @select_cond_may_undef(i32 %a) { ret i64 %max } +define i32 @test_solve_select_at_use(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: define i32 @test_solve_select_at_use +; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0 +; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[A]], -1 +; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] +; CHECK: if.then: +; CHECK-NEXT: ret i32 [[C]] +; CHECK: if.else: +; CHECK-NEXT: ret i32 [[B]] +; +entry: + %cmp = icmp slt i32 %a, 0 + %retval = select i1 %cmp, i32 %b, i32 %c + %cond = icmp sgt i32 %a, -1 + br i1 %cond, label %if.then, label %if.else +if.then: + ret i32 %retval +if.else: + ret i32 %retval +} + !0 = !{} -- cgit v1.1