public void visitStoreExpr(final StoreExpr expr) {
		if (expr.expr() instanceof CheckExpr) {
			// This makes copy propagation more effective after PRE.
			// x := rc(y) --> rc(x := y)
			final CheckExpr rc = (CheckExpr) expr.expr();

			if (replace) {
				final Node parent = expr.parent();

				// x := rc(y) --> x := y
				expr.visit(new ReplaceVisitor(rc, rc.expr()));

				// rc(y) --> rc(x := y)
				rc.visit(new ReplaceVisitor(rc.expr(), expr));

				// x := rc(y) --> rc(x := y)
				parent.visit(new ReplaceVisitor(expr, rc));

				node = rc;

			} else {
				// Don't bother.
				node = null;
			}

			return;
		}

		if (expr.target() instanceof LocalExpr) {
			// If we're assigning into a local variable,

			final int v = expr.valueNumber();
			final int lv = expr.target().valueNumber();
			final int rv = expr.expr().valueNumber();

			int max = v;
			max = Math.max(max, lv);
			max = Math.max(max, rv);
			values.ensureSize(max + 1);

			boolean reffects = false;

			if (replace) {
				sideEffects.reset();
				expr.expr().visit(sideEffects);
				reffects = sideEffects.hasSideEffects();
			}

			final ConstantExpr rexpr = (ConstantExpr) values.get(rv);

			if (rexpr != null) {
				// The entire StoreExpr has a constant value
				if (!replace) {
					node = rexpr;
					values.set(v, node);

				} else if (!reffects && (expr.target().uses().size() == 0)) {
					// Replace the rhs with constant mapped to its value number
					node = new ConstantExpr(rexpr.value(), expr.type());
					node.setValueNumber(v);
					values.set(v, node);
					expr.replaceWith(node);
				}
			}
		}
	}