Skip to content

comparison operations on abstract types and max/min are not specialized #7440

@vicuna

Description

@vicuna

Original bug ID: 7440
Reporter: markghayden
Status: acknowledged (set by @xavierleroy on 2017-01-14T15:23:38Z)
Resolution: open
Priority: normal
Severity: feature
Platform: AMD64
OS: MacOS
OS Version: 10.12.2
Version: 4.04.0
Target version: later
Category: middle end (typedtree to clambda)
Duplicate of: #7441 #7442
Related to: #5592
Monitored by: @gasche @ygrek

Bug description

Specialization of integer and floating point comparisons (presumably also char and bool) seems to be brittle.

See the examples below where in many cases the comparison is not specialized and so external C call is made to the runtime comparison routine, losing an easy optimization opportunity to replace C call with assembly.

Also, Pervasives.min/max seem to never be specialized, even when inlined (which they should probably always be). To get specialization, you appear to need to write own functions, with type-casts.

Actual testing was done with 4.05.0 trunk.

(*********************************************************************)

let float_zero = 0.0 ;;

let int_zero = 0 ;;

(* Is specialized
*)
let float_test0 v =
v >= float_zero
;;

(* Is specialized
*)
let int_test0 v =
v >= int_zero
;;

(*********************************************************************)

module AbsFloat : sig type t val zero : t end = struct
type t = float
let zero = 0.0
end

(* Not specialized
*)
let float_test1 v =
v >= AbsFloat.zero
;;

(*********************************************************************)

module AbsInt : sig type t val zero : t end = struct
type t = int
let zero = 0
end

(* Not specialized
*)
let int_test1 v =
v >= AbsInt.zero
;;

(*********************************************************************)

(* Add inline for good measure.
*)
let [@inline] min x y = if x <= y then x else y ;;
let [@inline] max x y = if x >= y then x else y ;;

(* Not specialized
*)
let float_max0 (v0:float) (v1:float) =
max v0 v1
;;

(* Is specialized
*)
let float_max1 (v0:float) (v1:float) =
if v0 >= v1 then v0 else v1
;;

(* Not specialized
*)
let int_max0 (v0:int) (v1:int) =
max v0 v1
;;

(* Is specialized
*)
let int_max1 (v0:int) (v1:int) =
if v0 >= v1 then v0 else v1
;;

(*********************************************************************)

Steps to reproduce

Compile attached ml file with various examples.

File attachments

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions