return LV;
}
+ LatticeVal toLatticeVal(const ValueLatticeElement &V, Type *T) {
+ LatticeVal Res;
+ if (V.isUndefined())
+ return Res;
+
+ if (V.isConstant()) {
+ Res.markConstant(V.getConstant());
+ return Res;
+ }
+ if (V.isConstantRange() && V.getConstantRange().isSingleElement()) {
+ Res.markConstant(
+ ConstantInt::get(T, *V.getConstantRange().getSingleElement()));
+ return Res;
+ }
+ Res.markOverdefined();
+ return Res;
+ }
+
ValueLatticeElement &getParamState(Value *V) {
assert(!V->getType()->isStructTy() && "Should use getStructValueState");
} else {
// Most other parts of the Solver still only use the simpler value
// lattice, so we propagate changes for parameters to both lattices.
- LatticeVal ConcreteArgument = getValueState(*CAI);
- bool ParamChanged =
- getParamState(&*AI).mergeIn(ConcreteArgument.toValueLattice(), DL);
- bool ValueChanged = mergeInValue(&*AI, ConcreteArgument);
+ ValueLatticeElement ConcreteArgument =
+ isa<Argument>(*CAI) ? getParamState(*CAI)
+ : getValueState(*CAI).toValueLattice();
+ bool ParamChanged = getParamState(&*AI).mergeIn(ConcreteArgument, DL);
+ bool ValueChanged =
+ mergeInValue(&*AI, toLatticeVal(ConcreteArgument, AI->getType()));
// Add argument to work list, if the state of a parameter changes but
// ValueState does not change (because it is already overdefined there),
// We have to take changes in ParamState into account, as it is used
%call = call i32 @recursive_f(i32 42)
ret i32 %call
}
+
+define internal i32 @callee6.1(i32 %i) {
+; CHECK-LABEL: define internal i32 @callee6.1(
+; CHECK-NEXT: %res = call i32 @callee6.2(i32 %i)
+; CHECK-NEXT: ret i32 undef
+;
+ %res = call i32 @callee6.2(i32 %i)
+ ret i32 %res
+}
+
+define internal i32 @callee6.2(i32 %i) {
+; CHECK-LABEL: define internal i32 @callee6.2(i32 %i) {
+; CHECK-NEXT: br label %if.then
+
+; CHECK-LABEL: if.then:
+; CHECK-NEXT: ret i32 undef
+;
+ %cmp = icmp ne i32 %i, 0
+ br i1 %cmp, label %if.then, label %if.else
+
+if.then: ; preds = %entry
+ ret i32 1
+
+if.else: ; preds = %entry
+ ret i32 2
+}
+
+define i32 @caller6() {
+; CHECK-LABEL: define i32 @caller6() {
+; CHECK-NEXT: %call.1 = call i32 @callee6.1(i32 30)
+; CHECK-NEXT: %call.2 = call i32 @callee6.1(i32 43)
+; CHECK-NEXT: ret i32 2
+
+ %call.1 = call i32 @callee6.1(i32 30)
+ %call.2 = call i32 @callee6.1(i32 43)
+ %res = add i32 %call.1, %call.2
+ ret i32 %res
+}