@@ -398,11 +398,21 @@ let rec lsr_int c1 c2 dbg =
398
398
and asr_int c1 c2 dbg =
399
399
match c1, c2 with
400
400
| c1 , Cconst_int (0 , _ ) -> c1
401
- | c1 , Cconst_int (n , _ ) when n > 0 -> (
401
+ | c1 , Cconst_int (n , _ ) when 0 < n && n < arch_bits -> (
402
402
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 , _)], _)
403
414
(* some operations always return small enough integers that it is safe and
404
415
correct to optimise [asr (lsl x 1) 1] into [x]. *)
405
- | Cop (Clsl , [c; Cconst_int (1 , _)], _)
406
416
when n = 1 && guaranteed_to_be_small_int c ->
407
417
c
408
418
| Cop (Cor, [inner ; Cconst_int (x , _ )], _ ) when n < Sys. int_size ->
0 commit comments