private Expr buildPhiOperand(final ExprInfo exprInfo, final Phi phi,
			final Block pred) {
		final Iterator leaves = phi.leaves().iterator();

		final Expr expr = (Expr) exprInfo.prototype().clone();

		expr.visit(new TreeVisitor() {
			public void visitExpr(final StoreExpr expr) {
				throw new RuntimeException();
			}

			public void visitConstantExpr(final ConstantExpr expr) {
				visitLeaf(expr);
			}

			public void visitVarExpr(final VarExpr expr) {
				visitLeaf(expr);
			}

			public void visitLeaf(final Expr expr) {
				if (leaves.hasNext()) {
					Expr leaf = (Expr) leaves.next();

					if (leaf instanceof VarExpr) {
						Assert.isTrue(((VarExpr) leaf).isDef());

						if (leaf.parent() instanceof PhiJoinStmt) {
							final PhiJoinStmt leafPhi = (PhiJoinStmt) leaf
									.parent();

							if (leafPhi.block() == phi.block()) {
								leaf = leafPhi.operandAt(pred);

								if (leaf instanceof VarExpr) {
									leaf = leaf.def();
								}
							}
						}
					}

					Assert.isTrue(leaf != null);

					final Expr copy = (Expr) leaf.clone();

					if (leaf.isDef()) {
						copy.setDef((VarExpr) leaf);
					}

					expr.replaceWith(copy);
				} else {
					throw new RuntimeException();
				}
			}
		});

		expr.setValueNumber(nextValueNumber++);

		return expr;
	}