@@ -391,15 +391,28 @@ let triop ty op e1 e2 e3 =
391391
392392let 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