Skip to content

Commit e1c12d7

Browse files
committed
weaken asr
1 parent cc28415 commit e1c12d7

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

backend/cmm_helpers.ml

+12-2
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,21 @@ let rec lsr_int c1 c2 dbg =
398398
and asr_int c1 c2 dbg =
399399
match c1, c2 with
400400
| c1, Cconst_int (0, _) -> c1
401-
| c1, Cconst_int (n, _) when n > 0 -> (
401+
| c1, Cconst_int (n, _) when 0 < n && n < arch_bits -> (
402402
match ignore_low_bit_int c1 with
403+
| Cop (Casr, [c; Cconst_int (n', _)], _) when 0 <= n' && n' < arch_bits ->
404+
asr_const c (Int.min (n + n') (arch_bits - 1)) dbg
405+
| Cop (Clsr, [c; Cconst_int (n', _)], _) when 0 < n' && n' < arch_bits ->
406+
(* If the inner unsigned shift is guaranteed positive, then we know the
407+
sign bit is 0 and we can weaken this operation to a logical shift *)
408+
lsr_const c (n + n') dbg
409+
| Cop (Cor, [inner; Cconst_int (x, _)], _) when n <= Sys.int_size ->
410+
let inner = asr_const inner n dbg in
411+
let x = x asr n in
412+
if x = 0 then inner else Cop (Cor, [inner; Cconst_int (x, dbg)], dbg)
413+
| Cop (Clsl, [c; Cconst_int (1, _)], _)
403414
(* some operations always return small enough integers that it is safe and
404415
correct to optimise [asr (lsl x 1) 1] into [x]. *)
405-
| Cop (Clsl, [c; Cconst_int (1, _)], _)
406416
when n = 1 && guaranteed_to_be_small_int c ->
407417
c
408418
| Cop (Cor, [inner; Cconst_int (x, _)], _) when n < Sys.int_size ->

0 commit comments

Comments
 (0)