[m-rev.] diff: Make most_specific_rval handle mkword_hole.

Peter Wang novalazy at gmail.com
Wed May 22 14:57:41 AEST 2013


dupelim.most_specific_rval did not handle the `mkword_hole' option that
was added to the `rval' type.

compiler/dupelim.m:
	Fix the bug.

tests/valid/Mmakefile:
tests/valid/dupelim_mkword_hole.m:
	Add test case.

diff --git a/compiler/dupelim.m b/compiler/dupelim.m
index 3afe74a..4794831 100644
--- a/compiler/dupelim.m
+++ b/compiler/dupelim.m
@@ -975,6 +975,7 @@ most_specific_lval(LvalA, LvalB, Lval) :-
 :- pred most_specific_rval(rval::in, rval::in, rval::out) is semidet.
 
 most_specific_rval(RvalA, RvalB, Rval) :-
+    require_complete_switch [RvalA]
     (
         RvalA = lval(LvalA),
         RvalB = lval(LvalB),
@@ -985,6 +986,7 @@ most_specific_rval(RvalA, RvalB, Rval) :-
         unexpected($module, $pred, "var")
     ;
         ( RvalA = mkword(_, _)
+        ; RvalA = mkword_hole(_)
         ; RvalA = const(_)
         ; RvalA = mem_addr(_)
         ),
diff --git a/tests/valid/Mmakefile b/tests/valid/Mmakefile
index 62f01f1..afddc8f 100644
--- a/tests/valid/Mmakefile
+++ b/tests/valid/Mmakefile
@@ -95,6 +95,7 @@ OTHER_PROGS= \
 	det_string_switch \
 	det_switch \
 	double_vn \
+	dupelim_mkword_hole \
 	easy_nondet_test \
 	easy_nondet_test_2 \
 	empty_bound_inst_list \
diff --git a/tests/valid/dupelim_mkword_hole.m b/tests/valid/dupelim_mkword_hole.m
new file mode 100644
index 0000000..8543a62
--- /dev/null
+++ b/tests/valid/dupelim_mkword_hole.m
@@ -0,0 +1,99 @@
+% dupelim.m did not handle mkword_hole case leading to:
+%
+% predicate `ll_backend.dupelim.process_elim_labels'/11:
+% Unexpected: blocks with same standard form don't antiunify
+
+:- module dupelim_mkword_hole.
+:- interface.
+
+:- import_module bool.
+:- import_module io.
+
+:- type foo
+    --->    foo.
+
+:- type value
+    --->    object(object).
+
+:- type object
+    --->    some [T] object(T).
+
+:- pred p1(foo::in, object::in, value::in, bool::out, io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module list.
+:- import_module require.
+
+:- type thing
+    --->    f1
+    ;       f2
+    ;       f3
+    ;       f4
+    ;       f5
+    ;       f6
+    ;       f7
+    ;       f8(int, int)
+    ;       f9(int, int, int)
+    ;       struct(struct). % direct arg functor
+
+:- type struct
+    --->    struct(string, int).
+
+%-----------------------------------------------------------------------------%
+
+p1(Foo, X, object(Y), Res, !IO) :-
+    ( get_thing(X, struct(_)) ->
+        p2(Foo, X, Y, Res, !IO)
+    ;
+        unexpected($module, $pred)
+    ).
+
+:- pred p2(foo::in, object::in, object::in, bool::out, io::di, io::uo) is det.
+
+p2(Foo, X, Y, Res, !IO) :-
+    ( get_thing(X, struct(_)) ->
+        p3(Foo, X, Z),
+        ( Z = [] ->
+            Res = no
+        ; get_thing(Y, struct(_)) ->
+            Res = yes
+        ;
+            Res = no
+        )
+    ; get_thing(X, struct(_)) ->
+        ( get_thing(Y, struct(_)) ->
+            Res = yes
+        ;
+            Res = no
+        )
+    ;
+        Res = no
+    ).
+
+:- pred p3(foo::in, object::in, list(int)::out) is det.
+
+p3(Foo, X, Z) :-
+    p4(Foo, X, Y),
+    (
+        Y = [],
+        Z = []
+    ;
+        Y = [_ | _],
+        Z = [1]
+    ).
+
+:- pragma no_inline(p4/3).
+:- pred p4(foo, object, list(int)).
+:- mode p4(in, in, out) is det.
+
+p4(_, _, []).
+
+:- pred get_thing(object, T).
+:- mode get_thing(in, out) is semidet.
+
+get_thing(object(T0), T) :-
+    dynamic_cast(T0, T).




More information about the reviews mailing list