Skip to content

Commit be26390

Browse files
redianthusfilipeom
authored andcommitted
add some shortcuts on relop based on physical equality
1 parent a46d23c commit be26390

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

src/smtml/expr.ml

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -391,15 +391,28 @@ let triop ty op e1 e2 e3 =
391391

392392
let raw_relop ty op hte1 hte2 = make (Relop (ty, op, hte1, hte2)) [@@inline]
393393

394-
let rec relop ty op hte1 hte2 =
394+
let rec relop ty (op : Ty.Relop.t) hte1 hte2 =
395+
let both_phys_eq = phys_equal hte1 hte2 in
396+
let can_be_shortcuted =
397+
match ty with
398+
| Ty.Ty_bool | Ty_bitv _ | Ty_int | Ty_unit -> both_phys_eq
399+
| Ty_fp _ | Ty_app | Ty_list | Ty_real | Ty_regexp | Ty_roundingMode
400+
| Ty_none | Ty_str ->
401+
false
402+
in
395403
match (op, view hte1, view hte2) with
404+
| (Eq | Le | Ge | LeU | GeU), _, _ when can_be_shortcuted -> value True
405+
| (Ne | Lt | Gt | LtU | GtU), _, _ when can_be_shortcuted -> value False
396406
| op, Val v1, Val v2 -> value (if Eval.relop ty op v1 v2 then True else False)
397-
| Ty.Relop.Ne, Val (Real v), _ | Ne, _, Val (Real v) ->
407+
| Ne, Val (Real v), _ | Ne, _, Val (Real v) ->
398408
if Float.is_nan v || Float.is_infinite v then value True
409+
else if both_phys_eq then value False
399410
else raw_relop ty op hte1 hte2
400411
| _, Val (Real v), _ | _, _, Val (Real v) ->
401412
if Float.is_nan v || Float.is_infinite v then value False
402-
else raw_relop ty op hte1 hte2
413+
else
414+
(* TODO: it is possible to add a shortcut when `both_phys_eq` *)
415+
raw_relop ty op hte1 hte2
403416
| Eq, _, Val Nothing | Eq, Val Nothing, _ -> value False
404417
| Ne, _, Val Nothing | Ne, Val Nothing, _ -> value True
405418
| Eq, _, Val (App (`Op "symbol", [ Str _ ]))
@@ -411,16 +424,21 @@ let rec relop ty op hte1 hte2 =
411424
| ( Eq
412425
, Symbol ({ ty = Ty_fp prec1; _ } as s1)
413426
, Symbol ({ ty = Ty_fp prec2; _ } as s2) )
414-
when prec1 = prec2 && Symbol.equal s1 s2 ->
427+
when both_phys_eq || (prec1 = prec2 && Symbol.equal s1 s2) ->
415428
raw_unop Ty_bool Not (raw_unop (Ty_fp prec1) Is_nan hte1)
416429
| Eq, Ptr { base = b1; offset = os1 }, Ptr { base = b2; offset = os2 } ->
417-
if Bitvector.equal b1 b2 then relop Ty_bool Eq os1 os2 else value False
430+
if both_phys_eq then value True
431+
else if Bitvector.equal b1 b2 then relop Ty_bool Eq os1 os2
432+
else value False
418433
| Ne, Ptr { base = b1; offset = os1 }, Ptr { base = b2; offset = os2 } ->
419-
if Bitvector.equal b1 b2 then relop Ty_bool Ne os1 os2 else value True
434+
if both_phys_eq then value False
435+
else if Bitvector.equal b1 b2 then relop Ty_bool Ne os1 os2
436+
else value True
420437
| ( (LtU | LeU)
421438
, Ptr { base = b1; offset = os1 }
422439
, Ptr { base = b2; offset = os2 } ) ->
423-
if Bitvector.equal b1 b2 then relop ty op os1 os2
440+
if both_phys_eq then value True
441+
else if Bitvector.equal b1 b2 then relop ty op os1 os2
424442
else
425443
let b1 = Value.Bitv b1 in
426444
let b2 = Value.Bitv b2 in

0 commit comments

Comments
 (0)