Skip to content

Commit ff1982d

Browse files
authored
Optimize generated cmm for negated comparisons (#2131)
* Optimize away asr of lsl operations in some situations In some cases, such as comparisons, we can statically know from the cmm code whether it is correct to remove a pair [asr (lsl 1 ..) 1]. This commit introduces that simplification in cmm_helpers.
1 parent 22b6dd4 commit ff1982d

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

backend/cmm_helpers.ml

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,14 @@ let rec mul_int c1 c2 dbg =
290290
add_const (mul_int c (Cconst_int (k, dbg)) dbg) (n * k) dbg
291291
| c1, c2 -> Cop (Cmuli, [c1; c2], dbg)
292292

293+
(* identify cmm operations whose result is guaranteed to be small integers (e.g.
294+
in the range [min_int / 4; max_int / 4]) *)
295+
let guaranteed_to_be_small_int = function
296+
| Cop ((Ccmpi _ | Ccmpf _), _, _) ->
297+
(* integer/float comparisons return either [1] or [0]. *)
298+
true
299+
| _ -> false
300+
293301
let ignore_low_bit_int = function
294302
| Cop
295303
( Caddi,
@@ -315,7 +323,14 @@ let lsr_int c1 c2 dbg =
315323
let asr_int c1 c2 dbg =
316324
match c2 with
317325
| Cconst_int (0, _) -> c1
318-
| Cconst_int (n, _) when n > 0 -> Cop (Casr, [ignore_low_bit_int c1; c2], dbg)
326+
| Cconst_int (n, _) when n > 0 -> (
327+
match ignore_low_bit_int c1 with
328+
(* some operations always return small enough integers that it is safe and
329+
correct to optimise [asr (lsl x 1) 1] into [x]. *)
330+
| Cop (Clsl, [c; Cconst_int (1, _)], _)
331+
when n = 1 && guaranteed_to_be_small_int c ->
332+
c
333+
| c1' -> Cop (Casr, [c1'; c2], dbg))
319334
| _ -> Cop (Casr, [c1; c2], dbg)
320335

321336
let tag_int i dbg =

0 commit comments

Comments
 (0)