Skip to content

Commit 3a74831

Browse files
committed
Added unsigned integer comparisons
1 parent 8e27699 commit 3a74831

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+571
-400
lines changed

backend/amd64/emit.ml

+13-18
Original file line numberDiff line numberDiff line change
@@ -756,18 +756,16 @@ let instr_for_floatarithmem (width : Cmm.float_width) op =
756756
| Float32, Ifloatdiv -> I.divss
757757

758758
let cond : Operation.integer_comparison -> X86_ast.condition = function
759-
| Isigned Ceq -> E
760-
| Isigned Cne -> NE
761-
| Isigned Cle -> LE
762-
| Isigned Cgt -> G
763-
| Isigned Clt -> L
764-
| Isigned Cge -> GE
765-
| Iunsigned Ceq -> E
766-
| Iunsigned Cne -> NE
767-
| Iunsigned Cle -> BE
768-
| Iunsigned Cgt -> A
769-
| Iunsigned Clt -> B
770-
| Iunsigned Cge -> AE
759+
| Ceq -> E
760+
| Cne -> NE
761+
| Cle -> LE
762+
| Cgt -> G
763+
| Clt -> L
764+
| Cge -> GE
765+
| Cule -> BE
766+
| Cugt -> A
767+
| Cult -> B
768+
| Cuge -> AE
771769

772770
(* Output an = 0 or <> 0 test. *)
773771

@@ -856,14 +854,11 @@ let emit_test i ~(taken : X86_ast.condition -> unit) = function
856854
| Iinttest cmp ->
857855
I.cmp (arg i 1) (arg i 0);
858856
taken (cond cmp)
859-
| Iinttest_imm
860-
(((Isigned Ceq | Isigned Cne | Iunsigned Ceq | Iunsigned Cne) as cmp), 0)
861-
->
857+
| Iinttest_imm (((Ceq | Cne) as cmp), 0) ->
862858
output_test_zero i.arg.(0);
863859
taken (cond cmp)
864860
| Iinttest_imm
865-
( (( Isigned (Ceq | Cne | Clt | Cgt | Cle | Cge)
866-
| Iunsigned (Ceq | Cne | Clt | Cgt | Cle | Cge) ) as cmp),
861+
( ((Ceq | Cne | Clt | Cgt | Cle | Cge | Cult | Cugt | Cule | Cuge) as cmp),
867862
n ) ->
868863
I.cmp (int n) (arg i 0);
869864
taken (cond cmp)
@@ -2023,7 +2018,7 @@ let emit_instr ~first ~fallthrough i =
20232018
I.mov (addressing (Ibased (semaphore_sym, Global, 2)) WORD i 0) (res16 i 0);
20242019
(* If the semaphore is 0, then the result is 0, otherwise 1. *)
20252020
I.cmp (int 0) (res16 i 0);
2026-
I.set (cond (Iunsigned Cne)) (res8 i 0);
2021+
I.set (cond Cne) (res8 i 0);
20272022
I.movzx (res8 i 0) (res i 0)
20282023
| Lop Dls_get ->
20292024
if Config.runtime5

backend/amd64/proc.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ let operation_supported = function
627627
| Ccsel _
628628
| Cbswap _
629629
| Cclz _ | Cctz _
630-
| Ccmpi _ | Caddv | Cadda | Ccmpa _
630+
| Ccmpi _ | Caddv | Cadda
631631
| Cnegf _ | Cabsf _ | Caddf _ | Csubf _ | Cmulf _ | Cdivf _ | Cpackf32
632632
| Ccmpf _
633633
| Craise _

backend/amd64/simd_selection.ml

+26-28
Original file line numberDiff line numberDiff line change
@@ -649,34 +649,32 @@ let vectorize_operation (width_type : Vectorize_utils.Width_in_bits.t)
649649
| W8 -> None
650650
in
651651
Option.bind op (fun op -> instr op |> make_default ~arg_count ~res_count)
652-
| Icomp (Isigned intcomp) -> (
653-
match intcomp with
654-
| Ceq ->
655-
let op =
656-
match width_type with
657-
| W128 -> assert false
658-
| W64 -> pcmpeqq
659-
| W32 -> pcmpeqd
660-
| W16 -> pcmpeqw
661-
| W8 -> pcmpeqb
662-
in
663-
instr op |> make_default ~arg_count ~res_count
664-
| Cgt ->
665-
let op =
666-
match width_type with
667-
| W128 -> assert false
668-
| W64 -> pcmpgtq
669-
| W32 -> pcmpgtd
670-
| W16 -> pcmpgtw
671-
| W8 -> pcmpgtb
672-
in
673-
instr op |> make_default ~arg_count ~res_count
674-
| Cne | Clt | Cle | Cge ->
675-
None
676-
(* These instructions seem to not have a simd counterpart yet, could
677-
also implement as a combination of other instructions if needed in
678-
the future *))
679-
| Idiv | Imod | Iclz _ | Ictz _ | Ipopcnt | Icomp (Iunsigned _) -> None
652+
| Icomp Ceq ->
653+
let op =
654+
match width_type with
655+
| W128 -> assert false
656+
| W64 -> pcmpeqq
657+
| W32 -> pcmpeqd
658+
| W16 -> pcmpeqw
659+
| W8 -> pcmpeqb
660+
in
661+
instr op |> make_default ~arg_count ~res_count
662+
| Icomp Cgt ->
663+
let op =
664+
match width_type with
665+
| W128 -> assert false
666+
| W64 -> pcmpgtq
667+
| W32 -> pcmpgtd
668+
| W16 -> pcmpgtw
669+
| W8 -> pcmpgtb
670+
in
671+
instr op |> make_default ~arg_count ~res_count
672+
(* These instructions seem to not have a simd counterpart yet, could also
673+
implement as a combination of other instructions if needed in the
674+
future *)
675+
| Icomp (Cne | Clt | Cle | Cge | Cugt | Cult | Cule | Cuge)
676+
| Idiv | Imod | Iclz _ | Ictz _ | Ipopcnt ->
677+
None
680678
in
681679
match List.hd cfg_ops with
682680
| Move -> Operation.Move |> make_default ~arg_count ~res_count

backend/arm64/emit.ml

+10-12
Original file line numberDiff line numberDiff line change
@@ -603,18 +603,16 @@ let emit_stack_realloc () =
603603

604604
let cond_for_comparison :
605605
integer_comparison -> Arm64_ast.Instruction_name.Cond.t = function
606-
| Isigned Ceq -> EQ
607-
| Isigned Cne -> NE
608-
| Isigned Cle -> LE
609-
| Isigned Cge -> GE
610-
| Isigned Clt -> LT
611-
| Isigned Cgt -> GT
612-
| Iunsigned Ceq -> EQ
613-
| Iunsigned Cne -> NE
614-
| Iunsigned Cle -> LS
615-
| Iunsigned Cge -> CS
616-
| Iunsigned Clt -> CC
617-
| Iunsigned Cgt -> HI
606+
| Ceq -> EQ
607+
| Cne -> NE
608+
| Cle -> LE
609+
| Cge -> GE
610+
| Clt -> LT
611+
| Cgt -> GT
612+
| Cule -> LS
613+
| Cuge -> CS
614+
| Cult -> CC
615+
| Cugt -> HI
618616

619617
let instr_for_int_operation = function
620618
| Iadd -> I.ADD

backend/arm64/proc.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ let operation_supported : Cmm.operation -> bool = function
417417
| Capply _ | Cextcall _ | Cload _ | Calloc _ | Cstore _
418418
| Caddi | Csubi | Cmuli | Cmulhi _ | Cdivi | Cmodi
419419
| Cand | Cor | Cxor | Clsl | Clsr | Casr
420-
| Ccmpi _ | Caddv | Cadda | Ccmpa _
420+
| Ccmpi _ | Caddv | Cadda
421421
| Cnegf Float64 | Cabsf Float64 | Caddf Float64
422422
| Csubf Float64 | Cmulf Float64 | Cdivf Float64
423423
| Creinterpret_cast (Int_of_value | Value_of_int |

backend/branch_relaxation.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ module Make (T : Branch_relaxation_intf.S) = struct
9191
| None -> next
9292
| Some l ->
9393
instr_cons
94-
(Lcondbranch (Iinttest_imm (Isigned Cmm.Ceq, n), l))
94+
(Lcondbranch (Iinttest_imm (Ceq, n), l))
9595
arg [||] next ~available_before:None ~available_across:None
9696
in
9797
let rec fixup did_fix pc instr =

backend/cfg/cfg.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ let dump_terminator' ?(print_reg = Printreg.reg) ?(res = [||]) ?(args = [||])
318318
| Int_test { lt; eq; gt; is_signed; imm } ->
319319
let cmp =
320320
Printf.sprintf " %s%s"
321-
(if is_signed then "s" else "u")
321+
(match is_signed with Signed -> "s" | Unsigned -> "u")
322322
(match imm with None -> second_arg | Some i -> " " ^ Int.to_string i)
323323
in
324324
fprintf ppf "if%s <%s goto %a%s" first_arg cmp Label.format lt sep;

backend/cfg/cfg_intf.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ module S = struct
6868
{ lt : Label.t; (** if x < y (resp. x < n) goto [lt] label *)
6969
eq : Label.t; (** if x = y (resp. x = n) goto [eq] label *)
7070
gt : Label.t; (** if x > y (resp. x > n) goto [gt] label *)
71-
is_signed : bool;
71+
is_signed : Scalar.Signedness.t;
7272
imm : int option
7373
}
7474

backend/cfg/cfg_to_linear.ml

+15-27
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,6 @@ let basic_to_linear (i : _ Cfg.instruction) ~next =
5151
let desc = Cfg_to_linear_desc.from_basic i.desc in
5252
to_linear_instr ~like:i desc ~next
5353

54-
let mk_int_test ~lt ~eq ~gt : Cmm.integer_comparison =
55-
match eq, lt, gt with
56-
| true, false, false -> Ceq
57-
| false, true, false -> Clt
58-
| false, false, true -> Cgt
59-
| false, true, true -> Cne
60-
| true, true, false -> Cle
61-
| true, false, true -> Cge
62-
| true, true, true -> assert false
63-
| false, false, false -> assert false
64-
6554
(* Certain "unordered" outcomes of float comparisons are not expressible as a
6655
single Cmm.float_comparison operator, or a disjunction of disjoint
6756
Cmm.float_comparison operators. For example, for float_test { lt = L0; eq =
@@ -278,8 +267,8 @@ let linearize_terminator cfg_with_layout (func : string) start
278267
#8677 *)
279268
let can_emit_Lcondbranch3 =
280269
match is_signed, imm with
281-
| false, Some 1 -> true
282-
| false, Some _ | false, None | true, _ -> false
270+
| Unsigned, Some n -> n = 1
271+
| Unsigned, None | Signed, _ -> false
283272
in
284273
if Label.Set.cardinal cond_successor_labels = 2 && can_emit_Lcondbranch3
285274
then
@@ -295,21 +284,20 @@ let linearize_terminator cfg_with_layout (func : string) start
295284
let init = branch_or_fallthrough [] last in
296285
( Label.Set.fold
297286
(fun lbl acc ->
298-
let cond =
299-
mk_int_test ~lt:(Label.equal lt lbl) ~eq:(Label.equal eq lbl)
287+
match
288+
Scalar.Integer_comparison.create is_signed
289+
~lt:(Label.equal lt lbl) ~eq:(Label.equal eq lbl)
300290
~gt:(Label.equal gt lbl)
301-
in
302-
let comp =
303-
match is_signed with
304-
| true -> Operation.Isigned cond
305-
| false -> Operation.Iunsigned cond
306-
in
307-
let test =
308-
match imm with
309-
| None -> Operation.Iinttest comp
310-
| Some n -> Operation.Iinttest_imm (comp, n)
311-
in
312-
L.Lcondbranch (test, lbl) :: acc)
291+
with
292+
| Error false -> assert false
293+
| Error true -> L.Lbranch lbl :: acc
294+
| Ok comp ->
295+
let test =
296+
match imm with
297+
| None -> Operation.Iinttest comp
298+
| Some n -> Operation.Iinttest_imm (comp, n)
299+
in
300+
L.Lcondbranch (test, lbl) :: acc)
313301
cond_successor_labels init,
314302
None )
315303
| _ -> assert false)

backend/cfg/simplify_terminator.ml

+9-6
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,14 @@ let simplify_switch (block : C.basic_block) labels =
5656
assert (Label.equal labels.(n) ln);
5757
assert (len = n + k);
5858
let desc =
59-
C.Int_test { is_signed = false; imm = Some n; lt = l0; eq = ln; gt = ln }
59+
C.Int_test
60+
{ is_signed = Unsigned; imm = Some n; lt = l0; eq = ln; gt = ln }
6061
in
6162
block.terminator <- { block.terminator with desc }
6263
| [(l0, m); (l1, 1); (l2, _)] when Label.equal l0 l2 ->
6364
let desc =
64-
C.Int_test { is_signed = false; imm = Some m; lt = l0; eq = l1; gt = l0 }
65+
C.Int_test
66+
{ is_signed = Unsigned; imm = Some m; lt = l0; eq = l1; gt = l0 }
6567
in
6668
block.terminator <- { block.terminator with desc }
6769
| [(l0, 1); (l1, 1); (l2, n)] ->
@@ -70,7 +72,8 @@ let simplify_switch (block : C.basic_block) labels =
7072
assert (Label.equal labels.(2) l2);
7173
assert (len = n + 2);
7274
let desc =
73-
C.Int_test { is_signed = false; imm = Some 1; lt = l0; eq = l1; gt = l2 }
75+
C.Int_test
76+
{ is_signed = Unsigned; imm = Some 1; lt = l0; eq = l1; gt = l2 }
7477
in
7578
block.terminator <- { block.terminator with desc }
7679
| _ -> ()
@@ -104,9 +107,9 @@ let evaluate_terminator ~(reg : Reg.t) ~(const : nativeint)
104107
then
105108
let const' = Nativeint.of_int const' in
106109
let result =
107-
if is_signed
108-
then Nativeint.compare const const'
109-
else Nativeint.unsigned_compare const const'
110+
match is_signed with
111+
| Signed -> Nativeint.compare const const'
112+
| Unsigned -> Nativeint.unsigned_compare const const'
110113
in
111114
if result < 0 then Some lt else if result > 0 then Some gt else Some eq
112115
else None)

backend/cfg_selectgen.ml

+18-24
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ module Make (Target : Cfg_selectgen_target_intf.S) = struct
6666
(* avoid reordering *)
6767
(* The remaining operations are simple if their args are *)
6868
| Cload _ | Caddi | Csubi | Cmuli | Cmulhi _ | Cdivi | Cmodi | Cand | Cor
69-
| Cxor | Clsl | Clsr | Casr | Ccmpi _ | Caddv | Cadda | Ccmpa _ | Cnegf _
70-
| Cclz _ | Cctz _ | Cpopcnt | Cbswap _ | Ccsel _ | Cabsf _ | Caddf _
71-
| Csubf _ | Cmulf _ | Cdivf _ | Cpackf32 | Creinterpret_cast _
72-
| Cstatic_cast _ | Ctuple_field _ | Ccmpf _ | Cdls_get ->
69+
| Cxor | Clsl | Clsr | Casr | Ccmpi _ | Caddv | Cadda | Cnegf _ | Cclz _
70+
| Cctz _ | Cpopcnt | Cbswap _ | Ccsel _ | Cabsf _ | Caddf _ | Csubf _
71+
| Cmulf _ | Cdivf _ | Cpackf32 | Creinterpret_cast _ | Cstatic_cast _
72+
| Ctuple_field _ | Ccmpf _ | Cdls_get ->
7373
List.for_all is_simple_expr args)
7474
| Cifthenelse _ | Cswitch _ | Ccatch _ | Cexit _ -> false
7575

@@ -121,9 +121,9 @@ module Make (Target : Cfg_selectgen_target_intf.S) = struct
121121
| Cprobe_is_enabled _ -> EC.coeffect_only Arbitrary
122122
| Ctuple_field _ | Caddi | Csubi | Cmuli | Cmulhi _ | Cdivi | Cmodi
123123
| Cand | Cor | Cxor | Cbswap _ | Ccsel _ | Cclz _ | Cctz _ | Cpopcnt
124-
| Clsl | Clsr | Casr | Ccmpi _ | Caddv | Cadda | Ccmpa _ | Cnegf _
125-
| Cabsf _ | Caddf _ | Csubf _ | Cmulf _ | Cdivf _ | Cpackf32
126-
| Creinterpret_cast _ | Cstatic_cast _ | Ccmpf _ ->
124+
| Clsl | Clsr | Casr | Ccmpi _ | Caddv | Cadda | Cnegf _ | Cabsf _
125+
| Caddf _ | Csubf _ | Cmulf _ | Cdivf _ | Cpackf32 | Creinterpret_cast _
126+
| Cstatic_cast _ | Ccmpf _ ->
127127
EC.none
128128
in
129129
EC.join from_op (EC.join_list_map args effects_of)
@@ -156,20 +156,13 @@ module Make (Target : Cfg_selectgen_target_intf.S) = struct
156156
let select_condition (arg : Cmm.expression) : Operation.test * Cmm.expression
157157
=
158158
match arg with
159-
| Cop (Ccmpi cmp, [arg1; Cconst_int (n, _)], _)
160-
when is_immediate_test (Isigned cmp) n ->
161-
Iinttest_imm (Isigned cmp, n), arg1
159+
| Cop (Ccmpi cmp, [arg1; Cconst_int (n, _)], _) when is_immediate_test cmp n
160+
->
161+
Iinttest_imm (cmp, n), arg1
162162
| Cop (Ccmpi cmp, [Cconst_int (n, _); arg2], _)
163-
when is_immediate_test (Isigned (Cmm.swap_integer_comparison cmp)) n ->
164-
Iinttest_imm (Isigned (Cmm.swap_integer_comparison cmp), n), arg2
165-
| Cop (Ccmpi cmp, args, _) -> Iinttest (Isigned cmp), Ctuple args
166-
| Cop (Ccmpa cmp, [arg1; Cconst_int (n, _)], _)
167-
when is_immediate_test (Iunsigned cmp) n ->
168-
Iinttest_imm (Iunsigned cmp, n), arg1
169-
| Cop (Ccmpa cmp, [Cconst_int (n, _); arg2], _)
170-
when is_immediate_test (Iunsigned (Cmm.swap_integer_comparison cmp)) n ->
171-
Iinttest_imm (Iunsigned (Cmm.swap_integer_comparison cmp), n), arg2
172-
| Cop (Ccmpa cmp, args, _) -> Iinttest (Iunsigned cmp), Ctuple args
163+
when is_immediate_test (Cmm.swap_integer_comparison cmp) n ->
164+
Iinttest_imm (Cmm.swap_integer_comparison cmp, n), arg2
165+
| Cop (Ccmpi cmp, args, _) -> Iinttest cmp, Ctuple args
173166
| Cop (Ccmpf (width, cmp), args, _) -> Ifloattest (width, cmp), Ctuple args
174167
| Cop (Cand, [arg1; Cconst_int (1, _)], _) -> Ioddtest, arg1
175168
| _ -> Itruetest, arg
@@ -245,8 +238,10 @@ module Make (Target : Cfg_selectgen_target_intf.S) = struct
245238
| [arg; Cconst_int (n, _)] when is_immediate (Operation.Icomp cmp) n ->
246239
SU.basic_op (Intop_imm (Icomp cmp, n)), [arg]
247240
| [Cconst_int (n, _); arg]
248-
when is_immediate (Operation.Icomp (SU.swap_intcomp cmp)) n ->
249-
SU.basic_op (Intop_imm (Icomp (SU.swap_intcomp cmp), n)), [arg]
241+
when is_immediate (Operation.Icomp (Scalar.Integer_comparison.swap cmp)) n
242+
->
243+
( SU.basic_op (Intop_imm (Icomp (Scalar.Integer_comparison.swap cmp), n)),
244+
[arg] )
250245
| _ -> SU.basic_op (Intop (Icomp cmp)), args
251246

252247
(* Default instruction selection for operators *)
@@ -353,10 +348,9 @@ module Make (Target : Cfg_selectgen_target_intf.S) = struct
353348
| Cctz { arg_is_non_zero } ->
354349
SU.basic_op (Intop (Ictz { arg_is_non_zero })), args
355350
| Cpopcnt -> SU.basic_op (Intop Ipopcnt), args
356-
| Ccmpi comp -> select_arith_comp (Isigned comp) args
351+
| Ccmpi comp -> select_arith_comp comp args
357352
| Caddv -> select_arith_comm Iadd args
358353
| Cadda -> select_arith_comm Iadd args
359-
| Ccmpa comp -> select_arith_comp (Iunsigned comp) args
360354
| Ccmpf (w, comp) -> SU.basic_op (Floatop (w, Icompf comp)), args
361355
| Ccsel _ ->
362356
let cond, ifso, ifnot = three_args () in

0 commit comments

Comments
 (0)