[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