Skip to content

Commit 4ed7355

Browse files
committed
[IPSCCP] Use ParamState for arguments at call sites.
We currently use integer ranges to merge concrete function arguments. We use the ParamState range for those, but we only look up concrete values in the regular state. For concrete function arguments that are themselves arguments of the containing function, we can use the param state directly and improve the precision in some cases. Besides improving the results in some cases, this is also a small step towards switching to ValueLatticeElement, by allowing D60582 to be a NFC. Reviewers: efriedma, davide Reviewed By: efriedma Differential Revision: https://reviews.llvm.org/D71836
1 parent d42d5eb commit 4ed7355

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

llvm/lib/Transforms/Scalar/SCCP.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,24 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
507507
return LV;
508508
}
509509

510+
LatticeVal toLatticeVal(const ValueLatticeElement &V, Type *T) {
511+
LatticeVal Res;
512+
if (V.isUndefined())
513+
return Res;
514+
515+
if (V.isConstant()) {
516+
Res.markConstant(V.getConstant());
517+
return Res;
518+
}
519+
if (V.isConstantRange() && V.getConstantRange().isSingleElement()) {
520+
Res.markConstant(
521+
ConstantInt::get(T, *V.getConstantRange().getSingleElement()));
522+
return Res;
523+
}
524+
Res.markOverdefined();
525+
return Res;
526+
}
527+
510528
ValueLatticeElement &getParamState(Value *V) {
511529
assert(!V->getType()->isStructTy() && "Should use getStructValueState");
512530

@@ -1329,10 +1347,12 @@ void SCCPSolver::visitCallSite(CallSite CS) {
13291347
} else {
13301348
// Most other parts of the Solver still only use the simpler value
13311349
// lattice, so we propagate changes for parameters to both lattices.
1332-
LatticeVal ConcreteArgument = getValueState(*CAI);
1333-
bool ParamChanged =
1334-
getParamState(&*AI).mergeIn(ConcreteArgument.toValueLattice(), DL);
1335-
bool ValueChanged = mergeInValue(&*AI, ConcreteArgument);
1350+
ValueLatticeElement ConcreteArgument =
1351+
isa<Argument>(*CAI) ? getParamState(*CAI)
1352+
: getValueState(*CAI).toValueLattice();
1353+
bool ParamChanged = getParamState(&*AI).mergeIn(ConcreteArgument, DL);
1354+
bool ValueChanged =
1355+
mergeInValue(&*AI, toLatticeVal(ConcreteArgument, AI->getType()));
13361356
// Add argument to work list, if the state of a parameter changes but
13371357
// ValueState does not change (because it is already overdefined there),
13381358
// We have to take changes in ParamState into account, as it is used

llvm/test/Transforms/SCCP/ip-constant-ranges.ll

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,41 @@ entry:
196196
%call = call i32 @recursive_f(i32 42)
197197
ret i32 %call
198198
}
199+
200+
define internal i32 @callee6.1(i32 %i) {
201+
; CHECK-LABEL: define internal i32 @callee6.1(
202+
; CHECK-NEXT: %res = call i32 @callee6.2(i32 %i)
203+
; CHECK-NEXT: ret i32 undef
204+
;
205+
%res = call i32 @callee6.2(i32 %i)
206+
ret i32 %res
207+
}
208+
209+
define internal i32 @callee6.2(i32 %i) {
210+
; CHECK-LABEL: define internal i32 @callee6.2(i32 %i) {
211+
; CHECK-NEXT: br label %if.then
212+
213+
; CHECK-LABEL: if.then:
214+
; CHECK-NEXT: ret i32 undef
215+
;
216+
%cmp = icmp ne i32 %i, 0
217+
br i1 %cmp, label %if.then, label %if.else
218+
219+
if.then: ; preds = %entry
220+
ret i32 1
221+
222+
if.else: ; preds = %entry
223+
ret i32 2
224+
}
225+
226+
define i32 @caller6() {
227+
; CHECK-LABEL: define i32 @caller6() {
228+
; CHECK-NEXT: %call.1 = call i32 @callee6.1(i32 30)
229+
; CHECK-NEXT: %call.2 = call i32 @callee6.1(i32 43)
230+
; CHECK-NEXT: ret i32 2
231+
232+
%call.1 = call i32 @callee6.1(i32 30)
233+
%call.2 = call i32 @callee6.1(i32 43)
234+
%res = add i32 %call.1, %call.2
235+
ret i32 %res
236+
}

0 commit comments

Comments
 (0)