Skip to content

Commit 1cdf207

Browse files
committed
[bugfix] Correctly propagate poison unboxed args
In some cases, a generated poison values for an unboxed arg was later "transformed" into an available simple pointing to the "invalid" constant for the adequate kind. This could bring problem where a constant value is then passed to a deeper decisions that expects a variant with no constant constructors.
1 parent 3205dd4 commit 1cdf207

File tree

1 file changed

+27
-33
lines changed

1 file changed

+27
-33
lines changed

middle_end/flambda/unboxing/unboxing_epa.ml

Lines changed: 27 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -46,41 +46,43 @@ let type_of_arg_being_unboxed unboxed_arg =
4646
| Generated var -> Some (aux (Simple.var var))
4747
| Added_by_wrapper_at_rewrite_use _ -> prevent_current_unboxing ()
4848

49-
let arg_being_unboxed_of_extra_arg extra_arg =
50-
match (extra_arg : EPA.Extra_arg.t) with
51-
| Already_in_scope simple -> Available simple
52-
| New_let_binding (var, _)
53-
| New_let_binding_with_named_args (var, _) -> Generated var
54-
55-
let extra_arg_of_arg_being_unboxed (unboxer : Unboxers.unboxer)
49+
let unbox_arg (unboxer : Unboxers.unboxer)
5650
~typing_env_at_use arg_being_unboxed =
5751
match arg_being_unboxed with
5852
| Poison ->
59-
EPA.Extra_arg.Already_in_scope (Simple.const unboxer.invalid_const)
53+
let extra_arg =
54+
EPA.Extra_arg.Already_in_scope (Simple.const unboxer.invalid_const)
55+
in
56+
extra_arg, Poison
6057
| Available arg_at_use ->
6158
let arg_type = T.alias_type_of K.value arg_at_use in
6259
begin match unboxer.prove_simple typing_env_at_use arg_type
63-
~min_name_mode:Name_mode.normal with
60+
~min_name_mode:Name_mode.normal with
6461
| Proved simple ->
65-
EPA.Extra_arg.Already_in_scope simple
62+
EPA.Extra_arg.Already_in_scope simple, Available simple
6663
| Invalid ->
67-
EPA.Extra_arg.Already_in_scope (Simple.const unboxer.invalid_const)
64+
let extra_arg =
65+
EPA.Extra_arg.Already_in_scope (Simple.const unboxer.invalid_const)
66+
in
67+
extra_arg, Poison
6868
| Unknown ->
6969
let var = Variable.create unboxer.var_name in
7070
let prim = unboxer.unboxing_prim arg_at_use in
71-
EPA.Extra_arg.New_let_binding (var, prim)
71+
let extra_arg = EPA.Extra_arg.New_let_binding (var, prim) in
72+
extra_arg, Generated var
7273
end
7374
| Generated var ->
7475
let arg_at_use = Simple.var var in
7576
let var = Variable.create unboxer.var_name in
7677
let prim = unboxer.unboxing_prim arg_at_use in
77-
EPA.Extra_arg.New_let_binding (var, prim)
78+
let extra_arg = EPA.Extra_arg.New_let_binding (var, prim) in
79+
extra_arg, Generated var
7880
| Added_by_wrapper_at_rewrite_use { nth_arg; } ->
7981
let var = Variable.create "unboxed_field" in
8082
EPA.Extra_arg.New_let_binding_with_named_args (var, (fun args ->
8183
let arg_simple = List.nth args nth_arg in
8284
unboxer.unboxing_prim arg_simple
83-
))
85+
)), Generated var
8486

8587
(* Helpers for the variant case *)
8688
(* **************************** *)
@@ -166,18 +168,19 @@ let extra_args_for_const_ctor_of_variant
166168
Misc.fatal_errorf "Bad kind for unboxing the constant constructor \
167169
of a variant"
168170

171+
169172
(* Helpers for the number case *)
170173
(* *************************** *)
171174

172175
let compute_extra_arg_for_number kind unboxer epa
173176
rewrite_id ~typing_env_at_use arg_being_unboxed : U.decision =
174-
let extra_arg =
175-
extra_arg_of_arg_being_unboxed unboxer
176-
~typing_env_at_use arg_being_unboxed
177+
let extra_arg, _new_arg_being_unboxed =
178+
unbox_arg unboxer ~typing_env_at_use arg_being_unboxed
177179
in
178180
let epa = Extra_param_and_args.update_param_args epa rewrite_id extra_arg in
179181
Unbox (Number (kind, epa))
180182

183+
181184
(* Recursive descent on decisions *)
182185
(* ****************************** *)
183186

@@ -288,17 +291,16 @@ and compute_extra_args_for_block ~pass
288291
let unboxer =
289292
Unboxers.Field.unboxer ~invalid_const bak ~index:field_nth
290293
in
291-
let new_extra_arg =
292-
extra_arg_of_arg_being_unboxed unboxer
293-
~typing_env_at_use arg_being_unboxed
294+
let new_extra_arg, new_arg_being_unboxed =
295+
unbox_arg unboxer ~typing_env_at_use arg_being_unboxed
294296
in
295297
let epa =
296298
Extra_param_and_args.update_param_args epa rewrite_id new_extra_arg
297299
in
298300
let decision =
299301
compute_extra_args_for_one_decision_and_use ~pass
300302
rewrite_id ~typing_env_at_use
301-
(arg_being_unboxed_of_extra_arg new_extra_arg) decision
303+
new_arg_being_unboxed decision
302304
in
303305
Target_imm.(add one field_nth), { epa; decision; }
304306
) Target_imm.zero fields
@@ -312,17 +314,16 @@ and compute_extra_args_for_closure ~pass
312314
Var_within_closure.Map.mapi
313315
(fun var ({ epa; decision; } : U.field_decision) : U.field_decision ->
314316
let unboxer = Unboxers.Closure_field.unboxer closure_id var in
315-
let new_extra_arg =
316-
extra_arg_of_arg_being_unboxed unboxer
317-
~typing_env_at_use arg_being_unboxed
317+
let new_extra_arg, new_arg_being_unboxed =
318+
unbox_arg unboxer ~typing_env_at_use arg_being_unboxed
318319
in
319320
let epa =
320321
Extra_param_and_args.update_param_args epa rewrite_id new_extra_arg
321322
in
322323
let decision =
323324
compute_extra_args_for_one_decision_and_use ~pass
324325
rewrite_id ~typing_env_at_use
325-
(arg_being_unboxed_of_extra_arg new_extra_arg) decision
326+
new_arg_being_unboxed decision
326327
in
327328
{ epa; decision; }
328329
) vars_within_closure
@@ -404,14 +405,7 @@ and compute_extra_args_for_variant ~pass
404405
let unboxer =
405406
Unboxers.Field.unboxer ~invalid_const bak ~index:field_nth
406407
in
407-
let new_extra_arg =
408-
extra_arg_of_arg_being_unboxed unboxer
409-
~typing_env_at_use arg_being_unboxed
410-
in
411-
let new_arg_being_unboxed =
412-
arg_being_unboxed_of_extra_arg new_extra_arg
413-
in
414-
new_extra_arg, new_arg_being_unboxed
408+
unbox_arg unboxer ~typing_env_at_use arg_being_unboxed
415409
end else begin
416410
EPA.Extra_arg.Already_in_scope (Simple.const invalid_const),
417411
Poison

0 commit comments

Comments
 (0)