@@ -74,9 +74,46 @@ let wsize_of_ty ty = match ty with
74
74
(* Expression Linearization *)
75
75
(* ***************************)
76
76
77
+ let remove_Owi2 o =
78
+ match o with
79
+ | E. Owi2 (sg , sz , o ) ->
80
+ begin match o with
81
+ | E. WIadd -> E. Oadd (Op_w sz)
82
+ | E. WImul -> E. Omul (Op_w sz)
83
+ | E. WIsub -> E. Osub (Op_w sz)
84
+ | E. WImod -> E. Omod (sg, Op_w sz)
85
+ | E. WIdiv -> E. Odiv (sg, Op_w sz)
86
+ | E. WIshr -> if sg = Signed then E. Oasr (Op_w sz) else E. Olsr sz
87
+ | E. WIshl -> E. Olsl (Op_w sz)
88
+ | E. WIeq -> E. Oeq (Op_w sz)
89
+ | E. WIneq -> E. Oneq (Op_w sz)
90
+ | E. WIlt -> E. Olt (E. Cmp_w (sg, sz))
91
+ | E. WIle -> E. Ole (E. Cmp_w (sg, sz))
92
+ | E. WIgt -> E. Ogt (E. Cmp_w (sg, sz))
93
+ | E. WIge -> E. Oge (E. Cmp_w (sg, sz))
94
+ end
95
+ | _ -> o
96
+
97
+ let rec remove_Owi1 sg o e =
98
+ match o with
99
+ | E. WIwint_of_int sz -> Papp1 (E. Oword_of_int sz, e)
100
+ | E. WIint_of_wint sz -> Papp1 (E. Oint_of_word (sg, sz), e)
101
+ | E. WIword_of_wint _ -> remove_Owi e
102
+ | E. WIwint_of_word _ -> remove_Owi e
103
+ | E. WIwint_ext (szo , szi ) ->
104
+ let o = if sg = Signed then E. Osignext (szo, szi) else E. Ozeroext (szo, szi) in
105
+ Papp1 (o, e)
106
+ | E. WIneg sz -> Papp1 (E. Oneg (Op_w sz), e)
107
+
108
+ and remove_Owi e =
109
+ match e with
110
+ | Papp1 (E. Owi1(sg , o ), e ) -> remove_Owi1 sg o e
111
+ | Papp2 (o , e1 , e2 ) -> Papp2 (remove_Owi2 o, e1, e2)
112
+ | _ -> e
113
+
77
114
let op1_to_abs_unop op1 = match op1 with
78
115
| E. Oneg _ -> Some Texpr1. Neg
79
- | E. Oword_of_int _ | E. Oint_of_word _ | E. Ozeroext _ -> assert false
116
+ | E. Oword_of_int _ | E. Oint_of_word _ | E. Ozeroext _ | E. Owi1 _ -> assert false
80
117
| _ -> None
81
118
82
119
type shift_kind =
@@ -108,10 +145,10 @@ let op2_to_abs_binop op2 = match op2 with
108
145
| E. Omul _ -> AB_Arith Texpr1. Mul
109
146
| E. Osub _ -> AB_Arith Texpr1. Sub
110
147
111
- | E. Omod (Cmp_w ( Signed, _ ) ) -> AB_Unknown
148
+ | E. Omod (Signed, _ ) -> AB_Unknown
112
149
| E. Omod _ -> AB_Arith Texpr1. Mod
113
150
114
- | E. Odiv (Cmp_w ( Signed, _ ) ) -> AB_Unknown
151
+ | E. Odiv (Signed, _ ) -> AB_Unknown
115
152
| E. Odiv _ -> AB_Arith Texpr1. Div
116
153
117
154
| E. Olsr _ -> AB_Wop (Wshift Unsigned_right )
@@ -133,6 +170,7 @@ let op2_to_abs_binop op2 = match op2 with
133
170
| E. Ovadd (_, _) | E. Ovsub (_, _) | E. Ovmul (_, _)
134
171
| E. Ovlsr (_ , _ ) | E. Ovlsl (_ , _ ) | E. Ovasr (_ , _ ) -> AB_Unknown
135
172
173
+ | E. Owi2 _ -> assert false
136
174
137
175
(* Return lin_expr mod 2^n *)
138
176
let expr_pow_mod n lin_expr =
@@ -313,14 +351,16 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
313
351
314
352
| Pconst c -> Some (Z. of_string (Z. to_string c))
315
353
354
+ | Papp1 (E. Owi1(sg , o ), e ) -> aeval_cst_zint abs (remove_Owi1 sg o e)
355
+
316
356
| Papp1 (E. Oneg Op_int, e ) ->
317
357
Option. map Z. neg (aeval_cst_zint abs e)
318
358
319
359
| Papp1 (E. Oint_of_word _ , e ) ->
320
360
aeval_cst_zint abs e
321
361
(* No need to check for overflows because we do not allow word operations. *)
322
362
323
- | Papp2 (Oadd Op_int, e1 , e2 ) ->
363
+ | Papp2 (E. Oadd Op_int, e1 , e2 ) ->
324
364
obind2 (fun x y -> Some (Z. add x y))
325
365
(aeval_cst_zint abs e1) (aeval_cst_zint abs e2)
326
366
@@ -332,7 +372,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
332
372
obind2 (fun x y -> Some (Z. mul x y))
333
373
(aeval_cst_zint abs e1) (aeval_cst_zint abs e2)
334
374
335
- | Papp2 (Odiv Cmp_int , e1 , e2 ) ->
375
+ | Papp2 (Odiv (Unsigned, Op_int) , e1 , e2 ) ->
336
376
obind2 (fun x y -> Some (Z. div x y))
337
377
(aeval_cst_zint abs e1) (aeval_cst_zint abs e2)
338
378
@@ -354,6 +394,8 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
354
394
let rec aeval_cst_w abs e = match e with
355
395
| Pvar x -> aeval_cst_var abs x
356
396
397
+ | Papp1 (E. Owi1(sg , o ), e ) -> aeval_cst_w abs (remove_Owi1 sg o e)
398
+
357
399
| Papp1 (E. Oword_of_int ws , e ) ->
358
400
let c_e = aeval_cst_zint abs e in
359
401
let pws = Z. pow (Z. of_int 2 ) (int_of_ws ws) in
@@ -426,7 +468,8 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
426
468
427
469
| Pload _ -> raise Expr_contain_load
428
470
429
- | Pif (_ ,_ ,e1 ,e2 ) | Papp2 (_ , e1 , e2 ) -> aux (aux acc e1) e2 in
471
+ | Pif (_,_,e1,e2) (* FIXME: why the condition is not added ? *)
472
+ | Papp2 (_ , e1 , e2 ) -> aux (aux acc e1) e2 in
430
473
431
474
try PtVars (aux [] e) with Expr_contain_load -> PtTopExpr
432
475
@@ -451,9 +494,11 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
451
494
check_is_int x;
452
495
Mtexpr. var (mvar_of_var x)
453
496
454
- | Papp1 (E. Oint_of_word sz ,e1 ) ->
497
+ | Papp1 (E. Owi1(sg , o ), e1 ) -> linearize_iexpr abs (remove_Owi1 sg o e1)
498
+
499
+ | Papp1 (E. Oint_of_word(s , sz ),e1 ) ->
455
500
let abs_expr1 = linearize_wexpr abs e1 in
456
- wrap_if_overflow abs abs_expr1 Unsigned (int_of_ws sz)
501
+ wrap_if_overflow abs abs_expr1 s (int_of_ws sz)
457
502
458
503
| Papp1 (op1 , e1 ) ->
459
504
begin match op1_to_abs_unop op1 with
@@ -463,7 +508,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
463
508
| None -> raise (Unop_not_supported op1) end
464
509
465
510
| Papp2 (op2 , e1 , e2 ) ->
466
- begin match op2_to_abs_binop op2 with
511
+ begin match op2_to_abs_binop (remove_Owi2 op2) with
467
512
| AB_Arith absop ->
468
513
Mtexpr. (binop absop
469
514
(linearize_iexpr abs e1)
@@ -486,6 +531,8 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
486
531
let lin = Mtexpr. var (mvar_of_var x) in
487
532
wrap_if_overflow abs lin Unsigned (int_of_ws ws_e)
488
533
534
+ | Papp1 (E. Owi1(sg , o ), e1 ) -> linearize_wexpr abs (remove_Owi1 sg o e1)
535
+
489
536
| Papp1 (E. Oword_of_int sz ,e1 ) ->
490
537
assert (ty_expr e1 = tint);
491
538
let abs_expr1 = linearize_iexpr abs e1 in
@@ -505,7 +552,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
505
552
| None -> raise (Unop_not_supported op1) end
506
553
507
554
| Papp2 (op2 , e1 , e2 ) ->
508
- begin match op2_to_abs_binop op2 with
555
+ begin match op2_to_abs_binop (remove_Owi2 op2) with
509
556
| AB_Arith Texpr1. Mod
510
557
| AB_Arith Texpr1. Mul as absop ->
511
558
let lin = Mtexpr. (binop (abget absop)
@@ -521,7 +568,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
521
568
522
569
(* If the expression overflows, we try to rewrite differently *)
523
570
if linexpr_overflow abs lin Unsigned ws_out then
524
- let alt_lin = match e2 with
571
+ let alt_lin = match remove_Owi e2 with
525
572
| Papp1 (E. Oword_of_int sz , Pconst z ) ->
526
573
let z = mpqf_of_z z in
527
574
let mz = Mpqf. add (Mpqf. neg z) (mpq_pow (int_of_ws sz)) in
@@ -658,6 +705,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
658
705
|> map_f (fun ex -> Papp1 (op1,ex))
659
706
660
707
| Papp2 (op2 , e1 , e2 ) ->
708
+ let op2 = remove_Owi2 op2 in
661
709
begin match remove_if_expr_aux e1 with
662
710
| Some _ as e_opt -> map_f (fun ex -> Papp2 (op2, ex, e2)) e_opt
663
711
| None -> remove_if_expr_aux e2
@@ -692,7 +740,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
692
740
| E. Op_int -> E. Cmp_int
693
741
| E. Op_w ws -> E. Cmp_w (Unsigned , ws) in
694
742
695
- match op2 with
743
+ match remove_Owi2 op2 with
696
744
| E. Obeq | E. Oand | E. Oor | E. Oadd _ | E. Omul _ | E. Osub _
697
745
| E. Odiv _ | E. Omod _ | E. Oland _ | E. Olor _
698
746
| E. Oror _ | E. Orol _
@@ -707,11 +755,12 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
707
755
708
756
| Ovadd (_, _) | Ovsub (_, _) | Ovmul (_, _)
709
757
| Ovlsr (_ , _ ) | Ovlsl (_ , _ ) | Ovasr (_ , _ ) -> assert false
758
+ | Owi2 _ -> assert false
710
759
711
760
let swap_op2 op e1 e2 =
712
761
match op with
713
- | E. Ogt _ -> e2, e1
714
- | E. Oge _ -> e2, e1
762
+ | E. Ogt _ | E. Owi2 ( _ , _ , E. WIgt) -> e2, e1
763
+ | E. Oge _ | E. Owi2 ( _ , _ , E. WIge) -> e2, e1
715
764
| _ -> e1, e2
716
765
717
766
let rec bexpr_to_btcons_aux : AbsDom.t -> Prog.expr -> btcons =
@@ -744,7 +793,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
744
793
| None -> raise Bop_not_supported end
745
794
| _ -> assert false end
746
795
747
- | Papp2 (op2 , e1 , e2 ) -> begin match op2 with
796
+ | Papp2 (op2 , e1 , e2 ) -> begin match remove_Owi2 op2 with
748
797
| E. Oadd _ | E. Omul _ | E. Osub _
749
798
| E. Odiv _ | E. Omod _ | E. Oland _ | E. Olor _
750
799
| E. Oror _ | E. Orol _
@@ -761,9 +810,12 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
761
810
| E. Oor -> BOr ( aux e1, aux e2 )
762
811
763
812
| E. Oeq _ | E. Oneq _ | E. Olt _ | E. Ole _ | E. Ogt _ | E. Oge _ ->
764
- match remove_if_expr_aux e with
813
+ begin match remove_if_expr_aux e with
765
814
| Some (ty ,eb ,el ,er ) -> aux (Pif (ty,eb,el,er))
766
- | None -> flat_bexpr_to_btcons abs op2 e1 e2 end
815
+ | None -> flat_bexpr_to_btcons abs op2 e1 e2
816
+ end
817
+ | E. Owi2 _ -> assert false
818
+ end
767
819
768
820
| PappN (Ocombine_flags c , [ eof ; ecf ; esf ; ezf ]) ->
769
821
begin match c with
@@ -1061,7 +1113,7 @@ module AbsExpr (AbsDom : AbsNumBoolType) = struct
1061
1113
apply_offset_expr abs outv info y o
1062
1114
else aeval_top_offset abs outv
1063
1115
1064
- | Some outv , Papp2 (op2 ,el ,er ) -> begin match op2,el with
1116
+ | Some outv , Papp2 (op2 ,el ,er ) -> begin match remove_Owi2 op2, el with
1065
1117
| E. Oadd ( E. Op_w U64), Pvar y ->
1066
1118
if valid_offset_var abs ws_o y then
1067
1119
apply_offset_expr abs outv info y er
0 commit comments