Skip to content

Commit

Permalink
Relaxed alignment constraints for memory and array accesses (#748)
Browse files Browse the repository at this point in the history
Co-authored-by: Benjamin Grēgoire <[email protected]>
(cherry picked from commit a5293ba)
  • Loading branch information
vbgl committed Mar 28, 2024
1 parent d637f5e commit c5a7502
Show file tree
Hide file tree
Showing 81 changed files with 1,405 additions and 1,065 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
- Register allocation can print liveness information (enable with `-pliveness`)
([PR #749](https://github.com/jasmin-lang/jasmin/pull/749)).

- Relaxed alignment constraints for memory and array accesses
([PR #748](https://github.com/jasmin-lang/jasmin/pull/748)).

## Bug fixes

- The compiler no longer throws an exception when a required file does not exist
Expand Down
2 changes: 1 addition & 1 deletion compiler/safety/fail/bad_align.jazz
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ fn main(reg u64 pt) -> reg u64 {
reg u64 tmp;

tmp = (u64)[pt + 0];
tmp = (u64)[pt + 1];
tmp = (u64)[#aligned pt + 1];

return tmp;
}
14 changes: 7 additions & 7 deletions compiler/safetylib/safetyAbsExpr.ml
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct

| Pvar x -> mvar_of_var x :: acc

| Pget(access,ws,x,ei) ->
| Pget(_, access,ws,x,ei) ->
abs_sub_arr_range abs (L.unloc x.gv,x.gs) access ws 1 ei @ acc
| Psub (access, ws, len, x, ei) ->
abs_sub_arr_range abs (L.unloc x.gv,x.gs) access ws len ei @ acc
Expand Down Expand Up @@ -606,7 +606,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
| _ -> raise (Binop_not_supported op2)
end

| Pget(access,ws,x,ei) ->
| Pget(_, access,ws,x,ei) ->
begin
match abs_sub_arr_range abs (L.unloc x.gv,x.gs) access ws 1 ei with
| [] -> assert false
Expand Down Expand Up @@ -641,17 +641,17 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct

| Pconst _ | Pbool _ | Parr_init _ | Pvar _ -> None

| Pget(acc,ws,x,e1) ->
| Pget(al,acc,ws,x,e1) ->
remove_if_expr_aux e1
|> map_f (fun ex -> Pget(acc,ws,x,ex))
|> map_f (fun ex -> Pget(al,acc,ws,x,ex))

| Psub(acc,ws,x,len,e1) ->
remove_if_expr_aux e1
|> map_f (fun ex -> Psub(acc,ws,x,len,ex))

| Pload (sz, x, e1) ->
| Pload (al, sz, x, e1) ->
remove_if_expr_aux e1
|> map_f (fun ex -> Pload (sz,x,ex))
|> map_f (fun ex -> Pload (al,sz,x,ex))

| Papp1 (op1, e1) ->
remove_if_expr_aux e1
Expand Down Expand Up @@ -1012,7 +1012,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
| _, Bty _ -> MLvar (loc, Mlocal (Avar ux))
| _, Arr _ -> MLvar (loc, Mlocal (Aarray ux)) end

| Laset (acc, ws, x, ei) ->
| Laset (_, acc, ws, x, ei) ->
begin
match abs_sub_arr_range abs (L.unloc x,Expr.Slocal) acc ws 1 ei with
| [] -> assert false
Expand Down
37 changes: 22 additions & 15 deletions compiler/safetylib/safetyInterpreter.ml
Original file line number Diff line number Diff line change
Expand Up @@ -275,20 +275,26 @@ let safe_var x = match (L.unloc x).v_ty with
let safe_gvar x = match x.gs with
| Expr.Sglob -> []
| Expr.Slocal -> safe_var x.gv


let optional_alignment_check al ws x e acc =
match al with
| Memory_model.Unaligned -> acc
| _ -> AlignedPtr (ws, x, e) :: acc

let rec safe_e_rec safe = function
| Pconst _ | Pbool _ | Parr_init _ -> safe
| Pvar x -> safe_gvar x @ safe

| Pload (ws,x,e) ->
Valid (ws, L.unloc x, e) ::
AlignedPtr (ws, L.unloc x, e) ::
safe_e_rec safe e
| Pload (al, ws,x,e) ->
let x = L.unloc x in
Valid (ws, x, e) ::
optional_alignment_check al ws x e
(safe_e_rec safe e)

| Pget (access, ws, x, e) ->
| Pget (al, access, ws, x, e) ->
in_bound x.gv access ws e 1 @
init_get x access ws e 1 @
arr_aligned (* x.gv *) access ws e @
(if al = Aligned then arr_aligned (* x.gv *) access ws e else []) @
safe

| Psub (access, ws, len, x, e) ->
Expand All @@ -315,14 +321,15 @@ let safe_es = List.fold_left safe_e_rec []
let safe_lval = function
| Lnone _ | Lvar _ -> []

| Lmem(ws, x, e) ->
Valid (ws, L.unloc x, e) ::
AlignedPtr (ws, L.unloc x, e) ::
safe_e_rec [] e
| Lmem(al, ws, x, e) ->
let x = L.unloc x in
Valid (ws, x, e) ::
optional_alignment_check al ws x e
(safe_e_rec [] e)

| Laset(access,ws, x,e) ->
| Laset(al, access,ws, x,e) ->
in_bound x access ws e 1 @
arr_aligned (* x *) access ws e @
(if al = Aligned then arr_aligned (* x *) access ws e else []) @
safe_e_rec [] e

| Lasub(access,ws,len,x,e) ->
Expand Down Expand Up @@ -1451,7 +1458,7 @@ end = struct

and nm_e vs_for = function
| Pconst _ | Pbool _ | Parr_init _ | Pvar _ -> true
| Pget (_,_,_, e)
| Pget (_,_,_,_, e)
| Psub (_,_,_, _, e) -> know_offset vs_for e && nm_e vs_for e
| Pload _ -> false
| Papp1 (_, e) -> nm_e vs_for e
Expand All @@ -1463,7 +1470,7 @@ end = struct

and nm_lv vs_for = function
| Lnone _ | Lvar _ -> true
| Laset (_,_,_,e) | Lasub (_,_,_,_,e) -> know_offset vs_for e
| Laset (_,_,_,_,e) | Lasub (_,_,_,_,e) -> know_offset vs_for e
| Lmem _ -> false

and nm_lvs vs_for lvs = List.for_all (nm_lv vs_for) lvs
Expand Down
22 changes: 11 additions & 11 deletions compiler/safetylib/safetyPreanalysis.ml
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ end = struct
and mk_lval fn lv = match lv with
| Lnone _ -> lv
| Lvar v -> Lvar (mk_v_loc fn v)
| Lmem (ws,ty,e) -> Lmem (ws, mk_v_loc fn ty, mk_expr fn e)
| Laset (acc,ws,v,e) -> Laset (acc,ws, mk_v_loc fn v, mk_expr fn e)
| Lmem (al, ws,ty,e) -> Lmem (al, ws, mk_v_loc fn ty, mk_expr fn e)
| Laset (al,acc,ws,v,e) -> Laset (al,acc,ws, mk_v_loc fn v, mk_expr fn e)
| Lasub (acc,ws,len,v,e) -> Lasub (acc,ws,len, mk_v_loc fn v, mk_expr fn e)

and mk_range fn (dir, e1, e2) = (dir, mk_expr fn e1, mk_expr fn e2)
Expand Down Expand Up @@ -99,10 +99,10 @@ end = struct
and mk_expr fn expr = match expr with
| Pconst _ | Pbool _ | Parr_init _ -> expr
| Pvar v -> Pvar (mk_gvar fn v)
| Pget (acc, ws, v, e) -> Pget (acc, ws, mk_gvar fn v, mk_expr fn e)
| Pget (al, acc, ws, v, e) -> Pget (al, acc, ws, mk_gvar fn v, mk_expr fn e)
| Psub (acc, ws, len, v, e) ->
Psub (acc, ws, len, mk_gvar fn v, mk_expr fn e)
| Pload (ws, v, e) -> Pload (ws, mk_v_loc fn v, mk_expr fn e)
| Pload (al, ws, v, e) -> Pload (al, ws, mk_v_loc fn v, mk_expr fn e)
| Papp1 (op, e) -> Papp1 (op, mk_expr fn e)
| Papp2 (op, e1, e2) -> Papp2 (op, mk_expr fn e1, mk_expr fn e2)
| PappN (op,es) -> PappN (op, List.map (mk_expr fn) es)
Expand Down Expand Up @@ -186,7 +186,7 @@ end = struct
| Psub _ -> dp (* We ignore sub-array copies *)

(* We ignore loads for v, but we compute dependencies of v' in ei *)
| Pload (_,v',ei) -> app_expr dp (L.unloc v') ei ct
| Pload (_, _,v',ei) -> app_expr dp (L.unloc v') ei ct

| Papp1 (_,e1) -> app_expr dp v e1 ct
| Papp2 (_,e1,e2) -> app_expr (app_expr dp v e1 ct) v e2 ct
Expand Down Expand Up @@ -223,7 +223,7 @@ end = struct
end

(* We ignore loads for v, but we compute dependencies of v' in ei *)
| Pload (_,v',ei) ->
| Pload (_, _,v',ei) ->
let dp = app_expr st.dp (L.unloc v') ei st.ct in
acc, { st with dp = dp }

Expand All @@ -249,7 +249,7 @@ end = struct

| Pvar v' -> aux_gv acc v'
(* We ignore loads for v, but we compute dependencies of v' in ei *)
| Pload (_,v',ei) -> aux (aux_v acc v') ei
| Pload (_, _,v',ei) -> aux (aux_v acc v') ei

| Papp1 (_,e1) -> aux acc e1
| Papp2 (_,e1,e2) -> aux (aux acc e1) e2
Expand Down Expand Up @@ -285,7 +285,7 @@ end = struct
| Lvar v -> pa_expr st (L.unloc v) e

(* For memory stores, we are only interested in v and ei *)
| Lmem (_, v, ei) -> pa_expr st (L.unloc v) ei
| Lmem (_, _, v, ei) -> pa_expr st (L.unloc v) ei


let rec flag_mem_lvs v = function
Expand Down Expand Up @@ -484,9 +484,9 @@ end = struct
| Expr.Sglob -> sv
| Expr.Slocal -> Sv.add (L.unloc v.gv) sv
end
| Pget (_,_, v, e) -> collect_vars_e (Sv.add (L.unloc v.gv) sv) e
| Pget (_,_, _, v, e) -> collect_vars_e (Sv.add (L.unloc v.gv) sv) e
| Psub (_,_,_, v, e) -> collect_vars_e (Sv.add (L.unloc v.gv) sv) e
| Pload (_, v, e) -> collect_vars_e (Sv.add (L.unloc v) sv) e
| Pload (_, _, v, e) -> collect_vars_e (Sv.add (L.unloc v) sv) e
| Papp1 (_,e) -> collect_vars_e sv e
| Papp2 (_,e1,e2) -> collect_vars_es sv [e1;e2]
| PappN (_, el) -> collect_vars_es sv el
Expand All @@ -496,7 +496,7 @@ end = struct
let collect_vars_lv sv = function
| Lnone _ -> sv
| Lvar v -> Sv.add (L.unloc v) sv
| Laset (_,_, v, e) | Lasub (_,_,_, v, e) | Lmem (_, v, e) ->
| Laset (_,_,_, v, e) | Lasub (_,_,_, v, e) | Lmem (_, _, v, e) ->
collect_vars_e (Sv.add (L.unloc v) sv) e

let collect_vars_lvs sv = List.fold_left collect_vars_lv sv
Expand Down
18 changes: 9 additions & 9 deletions compiler/src/conv.ml
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ let rec cexpr_of_expr = function
| Pbool b -> C.Pbool b
| Parr_init n -> C.Parr_init (pos_of_int n)
| Pvar x -> C.Pvar (cgvari_of_gvari x)
| Pget (aa,ws, x,e) -> C.Pget (aa, ws, cgvari_of_gvari x, cexpr_of_expr e)
| Pget (al, aa,ws, x,e) -> C.Pget (al, aa, ws, cgvari_of_gvari x, cexpr_of_expr e)
| Psub (aa,ws,len, x,e) ->
C.Psub (aa, ws, pos_of_int len, cgvari_of_gvari x, cexpr_of_expr e)
| Pload (ws, x, e) -> C.Pload(ws, cvari_of_vari x, cexpr_of_expr e)
| Pload (al, ws, x, e) -> C.Pload(al, ws, cvari_of_vari x, cexpr_of_expr e)
| Papp1 (o, e) -> C.Papp1(o, cexpr_of_expr e)
| Papp2 (o, e1, e2) -> C.Papp2(o, cexpr_of_expr e1, cexpr_of_expr e2)
| PappN (o, es) -> C.PappN (o, List.map (cexpr_of_expr) es)
Expand All @@ -96,9 +96,9 @@ let rec expr_of_cexpr = function
| C.Pbool b -> Pbool b
| C.Parr_init n -> Parr_init (int_of_pos n)
| C.Pvar x -> Pvar (gvari_of_cgvari x)
| C.Pget (aa,ws, x,e) -> Pget (aa, ws, gvari_of_cgvari x, expr_of_cexpr e)
| C.Pget (al, aa,ws, x,e) -> Pget (al, aa, ws, gvari_of_cgvari x, expr_of_cexpr e)
| C.Psub (aa,ws,len,x,e) -> Psub (aa, ws, int_of_pos len, gvari_of_cgvari x, expr_of_cexpr e)
| C.Pload (ws, x, e) -> Pload(ws, vari_of_cvari x, expr_of_cexpr e)
| C.Pload (al, ws, x, e) -> Pload(al, ws, vari_of_cvari x, expr_of_cexpr e)
| C.Papp1 (o, e) -> Papp1(o, expr_of_cexpr e)
| C.Papp2 (o, e1, e2) -> Papp2(o, expr_of_cexpr e1, expr_of_cexpr e2)
| C.PappN (o, es) -> PappN (o, List.map (expr_of_cexpr) es)
Expand All @@ -112,16 +112,16 @@ let rec expr_of_cexpr = function
let clval_of_lval = function
| Lnone(loc, ty) -> C.Lnone (loc, cty_of_ty ty)
| Lvar x -> C.Lvar (cvari_of_vari x)
| Lmem (ws, x, e) -> C.Lmem (ws, cvari_of_vari x, cexpr_of_expr e)
| Laset(aa,ws,x,e)-> C.Laset (aa, ws, cvari_of_vari x, cexpr_of_expr e)
| Lmem (al, ws, x, e) -> C.Lmem (al, ws, cvari_of_vari x, cexpr_of_expr e)
| Laset(al, aa,ws,x,e)-> C.Laset (al, aa, ws, cvari_of_vari x, cexpr_of_expr e)
| Lasub(aa,ws,len,x,e)->
C.Lasub (aa, ws, pos_of_int len, cvari_of_vari x, cexpr_of_expr e)

let lval_of_clval = function
| C.Lnone(p, ty) -> Lnone (p, ty_of_cty ty)
| C.Lvar x -> Lvar (vari_of_cvari x)
| C.Lmem(ws,x,e) -> Lmem (ws, vari_of_cvari x, expr_of_cexpr e)
| C.Laset(aa,ws,x,e) -> Laset (aa,ws, vari_of_cvari x, expr_of_cexpr e)
| C.Lmem(al,ws,x,e) -> Lmem (al, ws, vari_of_cvari x, expr_of_cexpr e)
| C.Laset(al, aa,ws,x,e) -> Laset (al, aa,ws, vari_of_cvari x, expr_of_cexpr e)
| C.Lasub(aa,ws,len,x,e) ->
Lasub (aa,ws, int_of_pos len, vari_of_cvari x, expr_of_cexpr e)

Expand Down Expand Up @@ -284,7 +284,7 @@ let prog_of_csprog p =
let to_array ty p t =
let ws, n = array_kind ty in
let get i =
match Warray_.WArray.get p Warray_.AAscale ws t (cz_of_int i) with
match Warray_.WArray.get p Aligned Warray_.AAscale ws t (cz_of_int i) with
| Utils0.Ok w -> z_of_word ws w
| _ -> assert false in
ws, Array.init n get
Expand Down
8 changes: 4 additions & 4 deletions compiler/src/ct_checker_forward.ml
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,12 @@ let rec ty_expr ~(public:bool) env (e:expr) =

| Pvar x -> Env.gget ~public env x

| Pget (_, _, x, i) | Psub (_, _, _, x, i) ->
| Pget (_, _, _, x, i) | Psub (_, _, _, x, i) ->
let env, ty = Env.gget ~public env x in
let env, _ = ty_expr ~public:true env i in
env, ty

| Pload (_, x, i) ->
| Pload (_, _, x, i) ->
let env, _ = Env.get ~public:true env x in
let env, _ = ty_expr ~public:true env i in
env, Secret
Expand Down Expand Up @@ -409,11 +409,11 @@ let ty_lval env x lvl =
match x with
| Lnone _ -> env
| Lvar x -> Env.set env x lvl
| Lmem(_, x, i) ->
| Lmem(_, _, x, i) ->
let env, _ = Env.get ~public:true env x in
let env, _ = ty_expr ~public:true env i in
env
| Laset(_, _, x, i) | Lasub(_, _, _, x, i) ->
| Laset(_, _, _, x, i) | Lasub(_, _, _, x, i) ->
(* x[i] = e is x = x[i <- e] *)
let env, xlvl = Env.get ~public:false env x in
let env, _ = ty_expr ~public:true env i in
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/evaluator.ml
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,10 @@ let pp_val fmt v =
Format.fprintf fmt "@[[";
for i = 0 to ip-2 do
let i = Conv.cz_of_int i in
Format.fprintf fmt "%a;@ " pp_res (WArray.get p AAscale U8 t i);
Format.fprintf fmt "%a;@ " pp_res (WArray.get p Aligned AAscale U8 t i);
done;
if 0 < ip then
pp_res fmt (WArray.get p AAscale U8 t (Conv.cz_of_int (ip-1)));
pp_res fmt (WArray.get p Aligned AAscale U8 t (Conv.cz_of_int (ip-1)));
Format.fprintf fmt "]@]";
| Vword(ws, w) -> pp_word fmt ws w
| Vundef ty -> pp_undef fmt ty
Expand Down
24 changes: 15 additions & 9 deletions compiler/src/latex_printer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,11 @@ let pp_attribute_key fmt s =
then F.fprintf fmt "%s" s
else F.fprintf fmt "%S" s

let pp_aligned fmt = function
| None -> ()
| Some `Aligned -> F.fprintf fmt "%aaligned " sharp ()
| Some `Unaligned -> F.fprintf fmt "%aunaligned " sharp ()

let rec pp_simple_attribute fmt a =
match L.unloc a with
| Aint i -> Z.pp_print fmt i
Expand Down Expand Up @@ -146,9 +151,9 @@ let rec pp_expr_rec prio fmt pe =
match L.unloc pe with
| PEParens e -> pp_expr_rec prio fmt e
| PEVar x -> pp_var fmt x
| PEGet (aa, ws, x, e, len) ->
pp_arr_access fmt aa ws x e len
| PEFetch me -> pp_mem_access fmt me
| PEGet (al, aa, ws, x, e, len) ->
pp_arr_access fmt al aa ws x e len
| PEFetch me -> pp_mem_access fmt me
| PEpack (vs,es) ->
F.fprintf fmt "(%a)[@[%a@]]" pp_svsize vs (pp_list ",@ " pp_expr) es
| PEBool b -> F.fprintf fmt "%s" (if b then "true" else "false")
Expand All @@ -173,13 +178,13 @@ let rec pp_expr_rec prio fmt pe =
F.fprintf fmt "%a ? %a : %a" (pp_expr_rec p) e1 (pp_expr_rec p) e2 (pp_expr_rec p) e3;
optparent fmt prio p ")"

and pp_mem_access fmt (ty,x,e) =
and pp_mem_access fmt (al, ty,x,e) =
let pp_e fmt e =
match e with
| None -> ()
| Some (`Add, e) -> Format.fprintf fmt " + %a" pp_expr e
| Some (`Sub, e) -> Format.fprintf fmt " - %a" pp_expr e in
F.fprintf fmt "%a[%a%a]" (pp_opt (pp_paren pp_ws)) ty pp_var x pp_e e
F.fprintf fmt "%a[%a%a%a]" (pp_opt (pp_paren pp_ws)) ty pp_aligned al pp_var x pp_e e

and pp_type fmt ty =
match L.unloc ty with
Expand All @@ -191,14 +196,15 @@ and pp_type fmt ty =
and pp_ws fmt w = F.fprintf fmt "%a" ptype (string_of_wsize w)
and pp_expr fmt e = pp_expr_rec Pmin fmt e

and pp_arr_access fmt aa ws x e len=
and pp_arr_access fmt al aa ws x e len=
let pp_olen fmt len =
match len with
| None -> ()
| Some len -> Format.fprintf fmt " : %a" pp_expr len in
F.fprintf fmt "%a%s[%a%a%a%a]"
pp_var x
F.fprintf fmt "%a%s[%a%a%a%a%a]"
pp_var x
(if aa = Warray_.AAdirect then "." else "")
pp_aligned (Option.bind len (fun _ -> al))
(pp_opt pp_ws) ws (pp_opt pp_space) ws pp_expr e pp_olen len

let pp_writable = function
Expand Down Expand Up @@ -248,7 +254,7 @@ let pp_lv fmt x =
match L.unloc x with
| PLIgnore -> F.fprintf fmt "_"
| PLVar x -> pp_var fmt x
| PLArray (aa, ws, x, e, len) -> pp_arr_access fmt aa ws x e len
| PLArray (al, aa, ws, x, e, len) -> pp_arr_access fmt al aa ws x e len
| PLMem me -> pp_mem_access fmt me

let pp_eqop fmt op =
Expand Down
2 changes: 2 additions & 0 deletions compiler/src/lexer.mll
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ rule main = parse
| "=" { EQ }
| "==" { EQEQ }
| "!=" { BANGEQ }
| "#unaligned" { UNALIGNED }
| "#aligned" { ALIGNED }

| _ as c { invalid_char (L.of_lexbuf lexbuf) c }
| eof { EOF }
Expand Down
Loading

0 comments on commit c5a7502

Please sign in to comment.