[m-rev.] for post-commit review: Fix handling of unifications in float_regs pass.
Peter Wang
novalazy at gmail.com
Tue Oct 29 17:41:14 AEDT 2013
The float_regs.m pass did not consider `deconstruct' unifications which
actually further instantiate the LHS, and inadvertently changed the inst
of a variable on the RHS from being previously bound to free, e.g.
E = e(X, _), % X ground
F = f(1, _, _),
F = f(_, X, _), % X free
compiler/float_regs.m:
Only change the uni_mode of the variable on the RHS of the
deconstruction if it goes from free to bound.
tests/valid/Mmakefile:
tests/valid/bug301.m:
Add test case.
---
compiler/float_regs.m | 20 ++++++++++++++------
tests/valid/Mmakefile | 1 +
tests/valid/bug301.m | 31 +++++++++++++++++++++++++++++++
3 files changed, 46 insertions(+), 6 deletions(-)
create mode 100644 tests/valid/bug301.m
diff --git a/compiler/float_regs.m b/compiler/float_regs.m
index cd59452..f2c3f30 100644
--- a/compiler/float_regs.m
+++ b/compiler/float_regs.m
@@ -794,7 +794,7 @@ insert_reg_wrappers_unify_goal(GoalExpr0, GoalInfo0, Goal, !InstMap, !Info,
inst_expand(ModuleInfo, CellVarInst0, CellVarInst),
(
get_arg_insts(CellVarInst, ConsId, Arity, ArgInsts),
- list.map_corresponding(uni_mode_set_rhs_final_inst,
+ list.map_corresponding(uni_mode_set_rhs_final_inst(ModuleInfo),
ArgInsts, UniModes0, UniModes),
UniModes \= UniModes0
->
@@ -993,12 +993,20 @@ rebuild_cell_bound_inst_arg(InstMap, Var, ArgInst0, ArgInst) :-
ArgInst = VarInst
).
-:- pred uni_mode_set_rhs_final_inst(mer_inst::in, uni_mode::in, uni_mode::out)
- is det.
+:- pred uni_mode_set_rhs_final_inst(module_info::in, mer_inst::in,
+ uni_mode::in, uni_mode::out) is det.
-uni_mode_set_rhs_final_inst(RF, UniMode0, UniMode) :-
- UniMode0 = ((LI - RI0) -> (LF - _RF0)),
- UniMode = ((LI - RI0) -> (LF - RF)).
+uni_mode_set_rhs_final_inst(ModuleInfo, ArgInst, UniMode0, UniMode) :-
+ UniMode0 = ((LI - RI) -> (LF - RF)),
+ % Only when deconstructing to produce the right variable.
+ (
+ inst_is_free(ModuleInfo, RI),
+ inst_is_bound(ModuleInfo, RF)
+ ->
+ UniMode = ((LI - RI) -> (LF - ArgInst))
+ ;
+ UniMode = UniMode0
+ ).
%-----------------------------------------------------------------------------%
diff --git a/tests/valid/Mmakefile b/tests/valid/Mmakefile
index 6793540..93de66d 100644
--- a/tests/valid/Mmakefile
+++ b/tests/valid/Mmakefile
@@ -79,6 +79,7 @@ OTHER_PROGS= \
bug190 \
bug257b \
bug300 \
+ bug301 \
builtin_false \
call_failure \
common_struct_bug \
diff --git a/tests/valid/bug301.m b/tests/valid/bug301.m
new file mode 100644
index 0000000..b41564c
--- /dev/null
+++ b/tests/valid/bug301.m
@@ -0,0 +1,31 @@
+% The compiler aborted in the float_reg.m pass due to mishandling of
+% deconstruction unifications.
+%
+% Software Error: hlds.instmap: predicate `hlds.instmap.merge_instmapping_delta_2'/9:
+% Unexpected: merge_instmapping_delta_2: error merging var 5
+
+:- module bug301.
+:- interface.
+
+:- type e
+ ---> e(string, int).
+
+:- type f
+ ---> f(int, string, int).
+
+:- pred mk(e::in, f::out) is det.
+
+:- implementation.
+
+mk(E, F) :-
+ E = e(X, _),
+ F = f(1, _, _),
+ F = f(_, X, _),
+ ( X = "" ->
+ F = f(_, _, 3)
+ ;
+ F = f(_, _, -3)
+ ).
+
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sts=4 sw=4 et
--
1.7.4.4
More information about the reviews
mailing list