(** Normalization at load time *)
Definition vnormalize (chunk: memory_chunk) (v: aval) :=
match chunk, v with
| _, Vbot => Vbot
| Mint8signed, I i => I (Int.sign_ext 8 i)
| Mint8signed, Uns p n => if zlt n 8 then Uns (provenance v) n else Sgn (provenance v) 8
| Mint8signed, Sgn p n => Sgn (provenance v) (Z.min n 8)
| Mint8signed, _ => Sgn (provenance v) 8
| Mint8unsigned, I i => I (Int.zero_ext 8 i)
| Mint8unsigned, Uns p n => Uns (provenance v) (Z.min n 8)
| Mint8unsigned, _ => Uns (provenance v) 8
| Mint16signed, I i => I (Int.sign_ext 16 i)
| Mint16signed, Uns p n => if zlt n 16 then Uns (provenance v) n else Sgn (provenance v) 16
| Mint16signed, Sgn p n => Sgn (provenance v) (Z.min n 16)
| Mint16signed, _ => Sgn (provenance v) 16
| Mint16unsigned, I i => I (Int.zero_ext 16 i)
| Mint16unsigned, Uns p n => Uns (provenance v) (Z.min n 16)
| Mint16unsigned, _ => Uns (provenance v) 16
| Mint32, (I _ | Uns _ _ | Sgn _ _ | Ifptr _) => v
| Mint32, Ptr p => if Archi.ptr64 then Ifptr p else v
| Mint64, (L _ | Ifptr _) => v
| Mint64, (Uns p _ | Sgn p _) => Ifptr p
| Mint64, Ptr p => if Archi.ptr64 then v else Ifptr p
| Mfloat32, FS f => v
| Mfloat64, F f => v
| Many32, (I _ | Uns _ _ | Sgn _ _ | FS _ | Ifptr _) => v
| Many32, Ptr p => if Archi.ptr64 then Ifptr p else v
| Many64, _ => v
| _, _ => Ifptr (provenance v)
end.

Lemma vnormalize_cast:
forall chunk m b ofs v p,
Mem.load chunk m b ofs = Some v ->
vmatch v (Ifptr p) ->
vmatch v (vnormalize chunk (Ifptr p)).