Remark in_remove:
forall (A: Type) (eq: forall (x y: A), {x=y}+{x<>y}) x y l,
In y (List.remove eq x l) <-> x <> y /\ In y l.

(* Specifications: *)
Lemma forget_reg_charact:
forall n rd r v,
wf_numbering n ->
In r (PMap.get v (forget_reg n rd)) -> r <> rd /\ In r (PMap.get v n.(num_val)).
Lemma update_reg_charact:
forall n rd vd r v,
wf_numbering n ->
In r (PMap.get v (update_reg n rd vd)) ->
PTree.get r (PTree.set rd vd n.(num_reg)) = Some v.
Lemma rhs_eval_to_inj:
forall valu ge sp m rh v1 v2,
rhs_eval_to valu ge sp m rh v1 -> rhs_eval_to valu ge sp m rh v2 -> v1 = v2.
Lemma add_rhs_holds:
forall valu1 ge sp rs m n rd rh rs',
numbering_holds valu1 ge sp rs m n ->
rhs_eval_to valu1 ge sp m rh (rs'#rd) ->
wf_rhs n.(num_next) rh ->
(forall r, r <> rd -> rs'#r = rs#r) ->
exists valu2, numbering_holds valu2 ge sp rs' m (add_rhs n rd rh).
Lemma add_op_holds:
forall valu1 ge sp rs m n op (args: list reg) v dst,
numbering_holds valu1 ge sp rs m n ->
eval_operation ge sp op rs##args m = Some v ->
exists valu2, numbering_holds valu2 ge sp (rs#dst <- v) m (add_op n dst op args).
Lemma add_load_holds:
forall valu1 ge sp rs m n addr (args: list reg) a chunk v dst,
numbering_holds valu1 ge sp rs m n ->
eval_addressing ge sp addr rs##args = Some a ->
Mem.loadv chunk m a = Some v ->
exists valu2, numbering_holds valu2 ge sp (rs#dst <- v) m (add_load n dst chunk addr args).
Lemma set_unknown_holds:
forall valu ge sp rs m n r v,
numbering_holds valu ge sp rs m n ->
numbering_holds valu ge sp (rs#r <- v) m (set_unknown n r).
Lemma set_res_unknown_holds:
forall valu ge sp rs m n r v,
numbering_holds valu ge sp rs m n ->
numbering_holds valu ge sp (regmap_setres r v rs) m (set_res_unknown n r).
Lemma kill_eqs_charact:
forall pred l strict r eqs,
In (Eq l strict r) (kill_eqs pred eqs) ->
pred r = false /\ In (Eq l strict r) eqs.
Lemma kill_equations_hold:
forall valu ge sp rs m n pred m',
numbering_holds valu ge sp rs m n ->
(forall r v,
pred r = false ->
rhs_eval_to valu ge sp m r v ->
rhs_eval_to valu ge sp m' r v) ->
numbering_holds valu ge sp rs m' (kill_equations pred n).
Lemma kill_all_loads_hold:
forall valu ge sp rs m n m',
numbering_holds valu ge sp rs m n ->
numbering_holds valu ge sp rs m' (kill_all_loads n).
Lemma kill_loads_after_store_holds:
forall valu ge sp rs m n addr args a chunk v m' bc approx ae am,
numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m n ->
eval_addressing ge (Vptr sp Ptrofs.zero) addr rs##args = Some a ->
Mem.storev chunk m a v = Some m' ->
genv_match bc ge ->
bc sp = BCstack ->
ematch bc rs ae ->
approx = VA.State ae am ->
numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m'
(kill_loads_after_store approx n chunk addr args).
Lemma store_normalized_range_sound:
forall bc chunk v,
vmatch bc v (store_normalized_range chunk) ->
Val.lessdef (Val.load_result chunk v) v.
Lemma add_store_result_hold:
forall valu1 ge sp rs m' n addr args a chunk m src bc ae approx am,
numbering_holds valu1 ge sp rs m' n ->
eval_addressing ge sp addr rs##args = Some a ->
Mem.storev chunk m a rs#src = Some m' ->
ematch bc rs ae ->
approx = VA.State ae am ->
exists valu2, numbering_holds valu2 ge sp rs m' (add_store_result approx n chunk addr args src).
Lemma kill_loads_after_storebytes_holds:
forall valu ge sp rs m n dst b ofs bytes m' bc approx ae am sz,
numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m n ->
pmatch bc b ofs dst ->
Mem.storebytes m b (Ptrofs.unsigned ofs) bytes = Some m' ->
genv_match bc ge ->
bc sp = BCstack ->
ematch bc rs ae ->
approx = VA.State ae am ->
length bytes = nat_of_Z sz -> sz >= 0 ->
numbering_holds valu ge (Vptr sp Ptrofs.zero) rs m'
(kill_loads_after_storebytes approx n dst sz).
Lemma load_memcpy:
forall m b1 ofs1 sz bytes b2 ofs2 m' chunk i v,
Mem.loadbytes m b1 ofs1 sz = Some bytes ->
Mem.storebytes m b2 ofs2 bytes = Some m' ->
Mem.load chunk m b1 i = Some v ->
ofs1 <= i -> i + size_chunk chunk <= ofs1 + sz ->
(align_chunk chunk | ofs2 - ofs1) ->
Mem.load chunk m' b2 (i + (ofs2 - ofs1)) = Some v.
Lemma shift_memcpy_eq_wf:
forall src sz delta e e' next,
shift_memcpy_eq src sz delta e = Some e' ->
wf_equation next e ->
wf_equation next e'.