@@ -395,27 +395,55 @@ struct
395395 | Le , Some false -> meet_bin (ID. starting ikind (Z. succ l2)) (ID. ending ikind (Z. pred u1))
396396 | _ , _ -> a, b)
397397 | _ -> a, b)
398- | BOr | BXor as op ->
399- if M. tracing then M. tracel " inv" " Unhandled operator %a" d_binop op;
398+ | BOr ->
400399 (* Be careful: inv_exp performs a meet on both arguments of the BOr / BXor. *)
401- a, b
400+ if PrecisionUtil. get_bitfield () then
401+ let a', b' = ID. meet a (ID. logand a c), ID. meet b (ID. logand b c) in
402+ let (cz, co) = ID. to_bitfield ikind c in
403+ let (az, ao) = ID. to_bitfield ikind a' in
404+ let (bz, bo) = ID. to_bitfield ikind b' in
405+ let cDef1 = Z. logand co (Z. lognot cz) in
406+ let aDef0 = Z. logand az (Z. lognot ao) in
407+ let bDef0 = Z. logand bz (Z. lognot bo) in
408+ let az = Z. logand az (Z. lognot (Z. logand bDef0 cDef1)) in
409+ let bz = Z. logand bz (Z. lognot (Z. logand aDef0 cDef1)) in
410+ ID. meet a' (ID. of_bitfield ikind (az, ao)), ID. meet b' (ID. of_bitfield ikind (bz, bo))
411+ else a, b
412+ | BXor ->
413+ (* Be careful: inv_exp performs a meet on both arguments of the BOr / BXor. *)
414+ if PrecisionUtil. get_bitfield () then
415+ let a' = ID. meet a (ID. logxor c b)
416+ in let b' = ID. meet b (ID. logxor a c)
417+ in a', b'
418+ else a,b
402419 | LAnd ->
403420 if ID. to_bool c = Some true then
404421 meet_bin c c
405422 else
406423 a, b
407- | BAnd as op ->
424+ | BAnd ->
408425 (* we only attempt to refine a here *)
409426 let a =
410427 match ID. to_int b with
411428 | Some x when Z. equal x Z. one ->
412429 (match ID. to_bool c with
413430 | Some true -> ID. meet a (ID. of_congruence ikind (Z. one, Z. of_int 2 ))
414431 | Some false -> ID. meet a (ID. of_congruence ikind (Z. zero, Z. of_int 2 ))
415- | None -> if M. tracing then M. tracel " inv " " Unhandled case for operator x %a 1 = %a " d_binop op ID. pretty c; a)
416- | _ -> if M. tracing then M. tracel " inv " " Unhandled case for operator x %a %a = %a " d_binop op ID. pretty b ID. pretty c; a
432+ | None -> a)
433+ | _ -> a
417434 in
418- a, b
435+ if PrecisionUtil. get_bitfield () then
436+ let a', b' = ID. meet a (ID. logor a c), ID. meet b (ID. logor b c) in
437+ let (cz, co) = ID. to_bitfield ikind c in
438+ let (az, ao) = ID. to_bitfield ikind a' in
439+ let (bz, bo) = ID. to_bitfield ikind b' in
440+ let cDef0 = Z. logand cz (Z. lognot co) in
441+ let aDef1 = Z. logand ao (Z. lognot az) in
442+ let bDef1 = Z. logand bo (Z. lognot bz) in
443+ let ao = Z. logand ao (Z. lognot (Z. logand bDef1 cDef0)) in
444+ let bo = Z. logand bo (Z. lognot (Z. logand aDef1 cDef0)) in
445+ ID. meet a' (ID. of_bitfield ikind (az, ao)), ID. meet b' (ID. of_bitfield ikind (bz, bo))
446+ else a, b
419447 | op ->
420448 if M. tracing then M. tracel " inv" " Unhandled operator %a" d_binop op;
421449 a, b
0 commit comments