Proof with (try discriminate).
intros. set (delta := dst - src) in *. unfold shift_memcpy_eq in H.
destruct e as [l strict rhs] eqn:E.
destruct rhs as [op vl | chunk addr vl]...
destruct addr...
try (rename i into ofs).
set (i1 := Ptrofs.unsigned ofs) in *. set (j := i1 + delta) in *.
destruct (zle src i1)...
destruct (zle (i1 + size_chunk chunk) (src + sz))...
destruct (zeq (delta mod align_chunk chunk) 0)...
destruct (zle 0 j)...
destruct (zle j Ptrofs.max_unsigned)...
simpl in H; inv H.
assert (LD: forall v,
Mem.loadv chunk m (Vptr sp ofs) = Some v ->
Mem.loadv chunk m' (Vptr sp (Ptrofs.repr j)) = Some v).
{
simpl; intros. rewrite Ptrofs.unsigned_repr by omega.
unfold j, delta. eapply load_memcpy; eauto.
apply Zmod_divide; auto. generalize (align_chunk_pos chunk); omega.
}
inv H2.
+ inv H3. exploit eval_addressing_Ainstack_inv; eauto. intros [E1 E2].
simpl in E2; rewrite Ptrofs.add_zero_l in E2. subst a.
apply eq_holds_strict. econstructor. rewrite eval_addressing_Ainstack.
simpl. rewrite Ptrofs.add_zero_l. eauto.
apply LD; auto.
+ inv H4. exploit eval_addressing_Ainstack_inv; eauto. intros [E1 E2].
simpl in E2; rewrite Ptrofs.add_zero_l in E2. subst a.
apply eq_holds_lessdef with v; auto.
econstructor. rewrite eval_addressing_Ainstack. simpl. rewrite Ptrofs.add_zero_l. eauto.
apply LD; auto.
Qed.

Lemma add_memcpy_eqs_charact:
forall e' src sz delta eqs2 eqs1,
In e' (add_memcpy_eqs src sz delta eqs1 eqs2) ->
In e' eqs2 \/ exists e, In e eqs1 /\ shift_memcpy_eq src sz delta e = Some e'.