[pulse][arith] change bit shifts by a constant factor into multiplications

Summary:
When we don't know the value being shifted it may help to translate
bit-shifting into multiplication by a constant as it might surface
linear terms, eg `x<<1` is `2*x`.

Reviewed By: skcho

Differential Revision: D27464847

fbshipit-source-id: 9b3b5f0d0
master
Jules Villard 4 years ago committed by Facebook GitHub Bot
parent 8e9bc54c4a
commit 8602b709ef

@ -647,6 +647,24 @@ module Term = struct
zero
| (BitShiftLeft (t1, t2) | BitShiftRight (t1, t2)) when is_zero t2 ->
t1
| BitShiftLeft (t', Const q) | BitShiftRight (t', Const q) -> (
match Q.to_int q with
| None ->
(* overflows or otherwise undefined, propagate puzzlement *)
Const Q.undef
| Some i -> (
if i >= 64 then (* assume 64-bit or fewer architecture *) zero
else if i < 0 then (* this is undefined, maybe we should report a bug here *)
Const Q.undef
else
let factor = Const Q.(of_int 1 lsl i) in
match[@warning "-8"] t with
| BitShiftLeft _ ->
simplify_shallow_ (Mult (t', factor))
| BitShiftRight _ ->
simplify_shallow_ (Div (t', factor)) ) )
| (BitShiftLeft (t1, t2) | BitShiftRight (t1, t2)) when is_zero t2 ->
t1
| And (t1, t2) when is_zero t1 || is_zero t2 ->
(* [false ∧ t = t ∧ false = false] *) zero
| And (t1, t2) when is_non_zero_const t1 ->

@ -155,3 +155,17 @@ void FP_ints_are_not_rationals_ok() {
*p = 42;
}
}
void shift_equal_mult_by_power_of_two_ok(int x) {
if (x << 1 != mult(2, x)) {
int* p = nullptr;
*p = 42;
}
}
void shift_by_too_much_ok(int x) {
if (x << 64 != 0 || x >> 4000 != 0) {
int* p = nullptr;
*p = 42;
}
}

Loading…
Cancel
Save