-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CVP] Improve the value solving of select at use #76700
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Yingwei Zheng (dtcxzyw) ChangesThis patch improves the value solving of select at use if the condition is an icmp and we know the result of comparison from Compile-time impact: http://llvm-compile-time-tracker.com/compare.php?from=7e405eb722e40c79b7726201d0f76b5dab34ba0f&to=3c315b1ddcb0ad82554b33f08b9356679fae4bb7&stat=instructions:u
Full diff: https://github.com/llvm/llvm-project/pull/76700.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp
index c44d3748a80d8b..9235850de92f3e 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<CmpInst>(V);
+ if (!C)
+ return nullptr;
+
+ Value *Op0 = C->getOperand(0);
+ Constant *Op1 = dyn_cast<Constant>(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<Constant>(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<ConstantInt>(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<CmpInst>(V);
- if (!C) return nullptr;
-
- Value *Op0 = C->getOperand(0);
- Constant *Op1 = dyn_cast<Constant>(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 28a8516a910280..9842328db70209 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 = !{}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Hi @nikic! I think I have figured out how to fix the regression caused by this patch. Here is the reduced IR:
After further investigation I have found The debug output shows that we hit a cycle and exit early. But I think at least we can infer some information from the idom llvm-project/llvm/lib/Analysis/LazyValueInfo.cpp Lines 712 to 737 in 4b9bbd3
DomTree info is unavailable for LVI because the analysis is also used by |
This issue is on my todo list for next week, as it's also needed for #73662 (comment). My tentative plan was to add a new value lattice state to represent cycles, which will mostly get treated as overdefined, but can be preserved for pass-through operations. |
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%|
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