Skip to content

Commit 848d7af

Browse files
authored
[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%|
1 parent 0cb9816 commit 848d7af

File tree

2 files changed

+49
-25
lines changed

2 files changed

+49
-25
lines changed

llvm/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,31 @@ STATISTIC(NumUDivURemsNarrowedExpanded,
9494
"Number of bound udiv's/urem's expanded");
9595
STATISTIC(NumZExt, "Number of non-negative deductions");
9696

97+
static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) {
98+
if (Constant *C = LVI->getConstant(V, At))
99+
return C;
100+
101+
// TODO: The following really should be sunk inside LVI's core algorithm, or
102+
// at least the outer shims around such.
103+
auto *C = dyn_cast<CmpInst>(V);
104+
if (!C)
105+
return nullptr;
106+
107+
Value *Op0 = C->getOperand(0);
108+
Constant *Op1 = dyn_cast<Constant>(C->getOperand(1));
109+
if (!Op1)
110+
return nullptr;
111+
112+
LazyValueInfo::Tristate Result = LVI->getPredicateAt(
113+
C->getPredicate(), Op0, Op1, At, /*UseBlockValue=*/false);
114+
if (Result == LazyValueInfo::Unknown)
115+
return nullptr;
116+
117+
return (Result == LazyValueInfo::True)
118+
? ConstantInt::getTrue(C->getContext())
119+
: ConstantInt::getFalse(C->getContext());
120+
}
121+
97122
static bool processSelect(SelectInst *S, LazyValueInfo *LVI) {
98123
if (S->getType()->isVectorTy() || isa<Constant>(S->getCondition()))
99124
return false;
@@ -106,7 +131,7 @@ static bool processSelect(SelectInst *S, LazyValueInfo *LVI) {
106131
C = LVI->getConstantOnEdge(S->getCondition(), PN->getIncomingBlock(U),
107132
I->getParent(), I);
108133
else
109-
C = LVI->getConstant(S->getCondition(), I);
134+
C = getConstantAt(S->getCondition(), I, LVI);
110135

111136
auto *CI = dyn_cast_or_null<ConstantInt>(C);
112137
if (!CI)
@@ -1109,30 +1134,6 @@ static bool processAnd(BinaryOperator *BinOp, LazyValueInfo *LVI) {
11091134
return true;
11101135
}
11111136

1112-
1113-
static Constant *getConstantAt(Value *V, Instruction *At, LazyValueInfo *LVI) {
1114-
if (Constant *C = LVI->getConstant(V, At))
1115-
return C;
1116-
1117-
// TODO: The following really should be sunk inside LVI's core algorithm, or
1118-
// at least the outer shims around such.
1119-
auto *C = dyn_cast<CmpInst>(V);
1120-
if (!C) return nullptr;
1121-
1122-
Value *Op0 = C->getOperand(0);
1123-
Constant *Op1 = dyn_cast<Constant>(C->getOperand(1));
1124-
if (!Op1) return nullptr;
1125-
1126-
LazyValueInfo::Tristate Result = LVI->getPredicateAt(
1127-
C->getPredicate(), Op0, Op1, At, /*UseBlockValue=*/false);
1128-
if (Result == LazyValueInfo::Unknown)
1129-
return nullptr;
1130-
1131-
return (Result == LazyValueInfo::True) ?
1132-
ConstantInt::getTrue(C->getContext()) :
1133-
ConstantInt::getFalse(C->getContext());
1134-
}
1135-
11361137
static bool runImpl(Function &F, LazyValueInfo *LVI, DominatorTree *DT,
11371138
const SimplifyQuery &SQ) {
11381139
bool FnChanged = false;

llvm/test/Transforms/CorrelatedValuePropagation/select.ll

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,4 +372,27 @@ define i64 @select_cond_may_undef(i32 %a) {
372372
ret i64 %max
373373
}
374374

375+
define i32 @test_solve_select_at_use(i32 %a, i32 %b, i32 %c) {
376+
; CHECK-LABEL: define i32 @test_solve_select_at_use
377+
; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) {
378+
; CHECK-NEXT: entry:
379+
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
380+
; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[A]], -1
381+
; CHECK-NEXT: br i1 [[COND]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
382+
; CHECK: if.then:
383+
; CHECK-NEXT: ret i32 [[C]]
384+
; CHECK: if.else:
385+
; CHECK-NEXT: ret i32 [[B]]
386+
;
387+
entry:
388+
%cmp = icmp slt i32 %a, 0
389+
%retval = select i1 %cmp, i32 %b, i32 %c
390+
%cond = icmp sgt i32 %a, -1
391+
br i1 %cond, label %if.then, label %if.else
392+
if.then:
393+
ret i32 %retval
394+
if.else:
395+
ret i32 %retval
396+
}
397+
375398
!0 = !{}

0 commit comments

Comments
 (0)