aboutsummaryrefslogtreecommitdiffstats
path: root/x86/CSE2depsproof.v
blob: 37e16dfedce2a217c6ecda5054fe62c454b181f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
Require Import Coqlib Maps Errors Integers Floats Lattice Kildall.
Require Import AST Linking.
Require Import Memory Registers Op RTL Maps.

Require Import Globalenvs Values.
Require Import Linking Values Memory Globalenvs Events Smallstep.
Require Import Registers Op RTL.
Require Import CSE2 CSE2deps.
Require Import Lia.

Section SOUNDNESS.
  Variable F V : Type.
  Variable genv: Genv.t F V.
  Variable sp : val.

Section MEMORY_WRITE.
  Variable m m2 : mem.
  Variable chunkw chunkr : memory_chunk.
  Variable base : val.
  
  Variable addrw addrr valw valr : val.
  Hypothesis STORE : Mem.storev chunkw m addrw valw = Some m2.
  Hypothesis READ : Mem.loadv chunkr m addrr = Some valr.

  Section INDEXED_AWAY.
  Variable ofsw ofsr : Z.
  Hypothesis ADDRW : eval_addressing genv sp
                       (Aindexed ofsw) (base :: nil) = Some addrw. 
  Hypothesis ADDRR : eval_addressing genv sp
                       (Aindexed ofsr) (base :: nil) = Some addrr.

  Lemma load_store_away1 :
    forall RANGEW : 0 <= ofsw <= Ptrofs.modulus - largest_size_chunk,
    forall RANGER : 0 <= ofsr <= Ptrofs.modulus - largest_size_chunk,
    forall SWAPPABLE :    ofsw + size_chunk chunkw <= ofsr
                       \/ ofsr + size_chunk chunkr <= ofsw,
    Mem.loadv chunkr m2 addrr = Some valr.
  Proof.
    intros.
    
    pose proof (max_size_chunk chunkr) as size_chunkr_bounded.
    pose proof (max_size_chunk chunkw) as size_chunkw_bounded.
    try change (Ptrofs.modulus - largest_size_chunk) with 4294967288 in *.
    try change (Ptrofs.modulus - largest_size_chunk) with 18446744073709551608 in *.
    destruct addrr ; simpl in * ; try discriminate.
    unfold eval_addressing in *.
    destruct Archi.ptr64 eqn:PTR64; destruct base; simpl in *; try discriminate.
    rewrite PTR64 in *.
    
    inv ADDRR.
    inv ADDRW.
    rewrite <- READ.
    eapply Mem.load_store_other with (chunk := chunkw) (v := valw) (b := b).
    exact STORE.
    right.
 
    all: try (destruct (Ptrofs.unsigned_add_either i0
                (Ptrofs.of_int (Int.repr ofsr))) as [OFSR | OFSR];
              rewrite OFSR).
    all: try (destruct (Ptrofs.unsigned_add_either i0
                (Ptrofs.of_int64 (Int64.repr ofsr))) as [OFSR | OFSR];
              rewrite OFSR).
    all: try (destruct (Ptrofs.unsigned_add_either i0
                (Ptrofs.of_int (Int.repr ofsw))) as [OFSW | OFSW];
              rewrite OFSW).
    all: try (destruct (Ptrofs.unsigned_add_either i0
                (Ptrofs.of_int64 (Int64.repr ofsw))) as [OFSW | OFSW];
              rewrite OFSW).
    
    all: unfold Ptrofs.of_int64.
    all: unfold Ptrofs.of_int.
   

    all: repeat rewrite Int.unsigned_repr by (change Int.max_unsigned with 4294967295; lia).
    all: repeat rewrite Ptrofs.unsigned_repr by (change Ptrofs.max_unsigned with 4294967295; lia).
    all: repeat rewrite Int64.unsigned_repr by (change Int64.max_unsigned with 18446744073709551615; lia).
    all: repeat rewrite Ptrofs.unsigned_repr by (change Ptrofs.max_unsigned with 18446744073709551615; lia).

    all: try change Ptrofs.modulus with 4294967296.
    all: try change Ptrofs.modulus with 18446744073709551616.
   
    all: intuition lia.
  Qed.
  
  Theorem load_store_away :
    can_swap_accesses_ofs ofsr chunkr ofsw chunkw = true ->
    Mem.loadv chunkr m2 addrr = Some valr.
  Proof.
    intro SWAP.
    unfold can_swap_accesses_ofs in SWAP.
    repeat rewrite andb_true_iff in SWAP.
    repeat rewrite orb_true_iff in SWAP.
    repeat rewrite Z.leb_le in SWAP.
    apply load_store_away1.
    all: tauto.
  Qed.
  End INDEXED_AWAY.

  Section DIFFERENT_GLOBALS.
    Variable ofsw ofsr : ptrofs.
    Hypothesis symw symr : ident.
    Hypothesis ADDRW : eval_addressing genv sp
                                       (Aglobal symw ofsw) nil = Some addrw. 
    Hypothesis ADDRR : eval_addressing genv sp
                                       (Aglobal symr ofsr) nil = Some addrr.

    Lemma ptr64_cases:
      forall {T : Type},
      forall b : bool,
      forall x y : T,
        (if b then (if b then x else y) else (if b then y else x)) = x.
    Proof.
      destruct b; reflexivity.
    Qed.

    Lemma load_store_diff_globals :
      symw <> symr ->
      Mem.loadv chunkr m2 addrr = Some valr.
    Proof.
      intros.
      unfold eval_addressing in *.
      simpl in *.
      rewrite ptr64_cases in ADDRR.
      rewrite ptr64_cases in ADDRW.
      unfold Genv.symbol_address in *.
      unfold Genv.find_symbol in *.
      destruct ((Genv.genv_symb genv) ! symw) as [bw |] eqn:SYMW; inv ADDRW.
      2: simpl in STORE; discriminate.
      destruct ((Genv.genv_symb genv) ! symr) as [br |] eqn:SYMR; inv ADDRR.
      2: simpl in READ; discriminate.
      assert (br <> bw).
      {
        intro EQ.
        subst br.
        assert (symr = symw).
        {
          eapply Genv.genv_vars_inj; eauto.
        }
        congruence.
      }
      rewrite <- READ.
      eapply Mem.load_store_other with (chunk := chunkw) (v := valw) (b := bw).
      - exact STORE.
      - left. assumption.
    Qed.
  End DIFFERENT_GLOBALS.

  Section SAME_GLOBALS.
    Variable ofsw ofsr : ptrofs.
    Hypothesis sym : ident.
    Hypothesis ADDRW : eval_addressing genv sp
                                       (Aglobal sym ofsw) nil = Some addrw. 
    Hypothesis ADDRR : eval_addressing genv sp
                                       (Aglobal sym ofsr) nil = Some addrr.
    
  Lemma load_store_glob_away1 :
    forall RANGEW : 0 <= (Ptrofs.unsigned ofsw) <= Ptrofs.modulus - largest_size_chunk,
    forall RANGER : 0 <= (Ptrofs.unsigned ofsr) <= Ptrofs.modulus - largest_size_chunk,
    forall SWAPPABLE : (Ptrofs.unsigned ofsw) + size_chunk chunkw <= (Ptrofs.unsigned ofsr)
                    \/ (Ptrofs.unsigned ofsr) + size_chunk chunkr <= (Ptrofs.unsigned ofsw),
    Mem.loadv chunkr m2 addrr = Some valr.
  Proof.
    intros.
    
    pose proof (max_size_chunk chunkr) as size_chunkr_bounded.
    pose proof (max_size_chunk chunkw) as size_chunkw_bounded.
    unfold largest_size_chunk in size_chunkr_bounded, size_chunkw_bounded.
    try change (Ptrofs.modulus - largest_size_chunk) with 4294967288 in *.
    try change (Ptrofs.modulus - largest_size_chunk) with 18446744073709551608 in *.
    unfold eval_addressing, eval_addressing32, eval_addressing64 in *.
    destruct Archi.ptr64 eqn:PTR64.

    {
      unfold Genv.symbol_address in *.
      inv ADDRR.
      inv ADDRW.
      destruct (Genv.find_symbol genv sym).
      2: discriminate.
      
      rewrite <- READ.
      eapply Mem.load_store_other with (chunk := chunkw) (v := valw) (b := b).
      exact STORE.
      right.
      tauto.
    }

    {
      unfold Genv.symbol_address in *.
      inv ADDRR.
      inv ADDRW.
      destruct (Genv.find_symbol genv sym).
      2: discriminate.
      
      rewrite <- READ.
      eapply Mem.load_store_other with (chunk := chunkw) (v := valw) (b := b).
      exact STORE.
      right.
      tauto.
    }
  Qed.

  Lemma load_store_glob_away :
    (can_swap_accesses_ofs (Ptrofs.unsigned ofsr) chunkr (Ptrofs.unsigned ofsw) chunkw) = true ->
    Mem.loadv chunkr m2 addrr = Some valr.
  Proof.
    intro SWAP.
    unfold can_swap_accesses_ofs in SWAP.
    repeat rewrite andb_true_iff in SWAP.
    repeat rewrite orb_true_iff in SWAP.
    repeat rewrite Z.leb_le in SWAP.
    apply load_store_glob_away1.
    all: tauto.
  Qed.
  End SAME_GLOBALS.
End MEMORY_WRITE.
End SOUNDNESS.


Section SOUNDNESS.
  Variable F V : Type.
  Variable genv: Genv.t F V.
  Variable sp : val.

Lemma may_overlap_sound:
  forall m m' : mem,
  forall chunk addr args chunk' addr' args' v a a' vl rs,
    (eval_addressing genv sp addr (rs ## args)) = Some a ->
    (eval_addressing genv sp addr' (rs ## args')) = Some a' ->
    (may_overlap chunk addr args chunk' addr' args') = false ->
    (Mem.storev chunk m a v) = Some m' ->
    (Mem.loadv chunk' m  a') = Some vl ->
    (Mem.loadv chunk' m' a') = Some vl.
Proof.
  intros until rs.
  intros ADDR ADDR' OVERLAP STORE LOAD.
  destruct addr; destruct addr'; try discriminate.
  { (* Aindexed / Aindexed *)
  destruct args as [ | base [ | ]]. 1,3: discriminate.
  destruct args' as [ | base' [ | ]]. 1,3: discriminate.
  simpl in OVERLAP.
  destruct (peq base base'). 2: discriminate.
  subst base'.
  destruct (can_swap_accesses_ofs z0 chunk' z chunk) eqn:SWAP.
  2: discriminate.
  simpl in *.
  eapply load_store_away; eassumption.
  }
  { (* Aglobal / Aglobal *)
    destruct args. 2: discriminate.
    destruct args'. 2: discriminate.
    simpl in *.
    destruct (peq i i1).
    {
      subst i1.
      rewrite negb_false_iff in OVERLAP.
      eapply load_store_glob_away; eassumption.
    }
    eapply load_store_diff_globals; eassumption.
  }
Qed.

End SOUNDNESS.