[m-rev.] Re: --optimize-dups bug

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Nov 14 12:24:28 AEDT 2006


On 14-Nov-2006, Ian MacLarty <maclarty at csse.unimelb.edu.au> wrote:
> The following code results in a non-terminating executable when compiled
> at -O2 in grade asm_fast.gc with ROTD 2006-11-12.

Here is the fix; I will commit it after bootcheck.

Zoltan.

Fix a bug reported by Ian.

compiler/peephole.m:
	Document the restriction on the application of the patterns concerning
	assignments to redoips.

compiler/opt_util.m:
	Fix the bug in the utility predicate used by peephole.m.

tests/hard_coded/opt_dup_bug.{m,exp}:
	The test case provided by Ian, with an explanation of the bug.

tests/hard_coded/Mmakefile:
tests/hard_coded/Mercury.options:
	Enable the new test case, and run it with the options that expose the
	bug if it exists.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.156
diff -u -b -r1.156 opt_util.m
--- compiler/opt_util.m	1 Nov 2006 02:31:09 -0000	1.156
+++ compiler/opt_util.m	14 Nov 2006 01:06:05 -0000
@@ -57,7 +57,8 @@
 
     % Find the next assignment to the redoip of the frame whose address
     % is given by the base addresses in the second argument, provided
-    % it is guaranteed to be reached from here.
+    % it is guaranteed to be reached from here, and guaranteed not to be
+    % reached from anywhere else by a jump.
     %
 :- pred next_assign_to_redoip(list(instruction)::in, list(lval)::in,
     list(instruction)::in, code_addr::out, list(instruction)::out,
@@ -411,6 +412,11 @@
         Uinstr = mkframe(_, _)
     ->
         fail
+
+    ;
+        Uinstr = label(_)
+    ->
+        fail
     ;
         can_instr_branch_away(Uinstr, CanBranchAway),
         (
Index: compiler/peephole.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/peephole.m,v
retrieving revision 1.94
diff -u -b -r1.94 peephole.m
--- compiler/peephole.m	1 Nov 2006 02:31:09 -0000	1.94
+++ compiler/peephole.m	14 Nov 2006 01:05:26 -0000
@@ -213,8 +213,11 @@
 
     % If a `mkframe' is followed by an assignment to its redoip slot,
     % with the instructions in between containing only straight-line code,
-    % we can delete the assignment and instead just set the redoip
-    % directly in the `mkframe'.
+    % and no labels, we can delete the assignment and instead just set
+    % the redoip directly in the `mkframe'. (If the code between the
+    % mkframe and the redoip contains a label, then we need to keep the
+    % redoip assign, in case we reach it via the label and not from the
+    % mkframe above.
     %
     %   mkframe(NFI, _)             =>  mkframe(NFI, Redoip)
     %   <straightline instrs>           <straightline instrs>
@@ -336,8 +339,8 @@
     Instrs = [store_ticket(Lval) - Comment | Instrs2].
 
     % If an assignment to a redoip slot is followed by another, with
-    % the instructions in between containing only straight-line code,
-    % we can delete one of the asignments:
+    % the instructions in between containing only straight-line code
+    % without labels, we can delete one of the asignments:
     %
     %   assign(redoip(Fr), Redoip1) =>  assign(redoip(Fr), Redoip2)
     %   <straightline instrs>           <straightline instrs>
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
Index: tests/hard_coded/Mercury.options
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mercury.options,v
retrieving revision 1.22
diff -u -b -r1.22 Mercury.options
--- tests/hard_coded/Mercury.options	8 Nov 2006 10:14:46 -0000	1.22
+++ tests/hard_coded/Mercury.options	14 Nov 2006 01:09:54 -0000
@@ -45,6 +45,7 @@
 MCFLAGS-no_inline_builtins =	--no-inline-builtins
 MCFLAGS-no_warn_singleton =	--halt-at-warn
 MCFLAGS-nondet_copy_out =	--no-inlining --nondet-copy-out
+MCFLAGS-opt_dup_bug	=	-O2 --optimize-dups --optimize-frames
 MCFLAGS-redoip_clobber	=	--no-inlining
 MCFLAGS-rnd		=	-O6
 MCFLAGS-split_c_files	=	--trace rep
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.301
diff -u -b -r1.301 Mmakefile
--- tests/hard_coded/Mmakefile	9 Nov 2006 00:47:25 -0000	1.301
+++ tests/hard_coded/Mmakefile	14 Nov 2006 01:13:04 -0000
@@ -15,6 +15,7 @@
 	boyer \
 	brace \
 	builtin_inst_rename \
+	c_write_string \
 	cc_and_non_cc_test \
 	cc_multi_bug \
 	cc_nondet_disj \
@@ -35,7 +36,6 @@
 	curry \
 	curry2 \
 	cut_test \
-	c_write_string \
 	cycles \
 	cycles2 \
 	deconstruct_arg \
@@ -65,8 +65,8 @@
 	existential_float \
 	existential_reordering \
 	existential_reordering_class \
-	existential_types_test \
 	existential_type_switch_opt \
+	existential_types_test \
 	expand \
 	export_test \
 	external_unification_pred \
@@ -109,6 +109,7 @@
 	impure_init_and_final \
 	impure_prune \
 	initialise_decl \
+	int_fold_up_down \
 	integer_test \
 	intermod_c_code \
 	intermod_foreign_type \
@@ -117,7 +118,6 @@
 	intermod_pragma_clause \
 	intermod_type_qual \
 	intermod_unused_args \
-	int_fold_up_down \
 	join_list \
 	list_series_int \
 	loop_inv_test \
@@ -134,13 +134,14 @@
 	no_fully_strict \
 	no_inline \
 	no_inline_builtins \
+	no_warn_singleton \
 	nonascii \
 	nondet_copy_out \
 	nondet_ctrl_vn \
-	no_warn_singleton \
-	nullary_ho_func \
 	null_char \
+	nullary_ho_func \
 	one_member \
+	opt_dup_bug \
 	ppc_bug \
 	pprint_test \
 	pprint_test2 \
@@ -152,9 +153,9 @@
 	pretty_printing \
 	prince_frameopt \
 	print_stream \
+	promise_equiv_with_svars \
 	promise_equivalent_clauses \
 	promise_equivalent_solutions_test \
-	promise_equiv_with_svars \
 	pure_mutable \
 	qual_adv_test \
 	qual_basic_test \
@@ -204,13 +205,13 @@
 	test_cord \
 	test_imported_no_tag \
 	test_promise_impure_implicit \
-	time_test \
 	tim_qual1 \
+	time_test \
 	trace_goal_1 \
 	trace_goal_2 \
 	trace_goal_3 \
-	transform_value \
 	trans_intermod_user_equality \
+	transform_value \
 	transitive_inst_type \
 	trigraphs \
 	tuple_test \
Index: tests/hard_coded/opt_dup_bug.exp
===================================================================
RCS file: tests/hard_coded/opt_dup_bug.exp
diff -N tests/hard_coded/opt_dup_bug.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/opt_dup_bug.exp	14 Nov 2006 01:17:03 -0000
@@ -0,0 +1,3 @@
+"a"
+"b"
+"c"
Index: tests/hard_coded/opt_dup_bug.m
===================================================================
RCS file: tests/hard_coded/opt_dup_bug.m
diff -N tests/hard_coded/opt_dup_bug.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/opt_dup_bug.m	14 Nov 2006 01:12:47 -0000
@@ -0,0 +1,42 @@
+% This is a regression test for a bug reported by Ian on 14 Nov 2006.
+% The bug manifests itself only if all three of --optimize-dups,
+% --optimize-frames and --optimize-peep are turned on, as they are
+% at the default optimization level. The bug was actually in peephole
+% optimization; the other two optimizations just created the circumstances
+% that tickled the bug. The bug is shown in this diff, created using
+% --debug-opt:
+%
+% -       mkframe(pred opt_dup_bug.t/2-0, 0, no, do_fail)
+% +       mkframe(pred opt_dup_bug.t/2-0, 0, no, local_8)
+%                 late setup
+%  local_14:
+% -       redoip_slot(maxfr) := code_addr_const(opt_dup_bug_t_2_0_i8)
+% -               hijack redoip to effect resume point
+%
+% The transformation is correct for code that enters the code above at the top,
+% but for code that enters by jumping to local_14, it changes the semantics of
+% the program, yielding an infinite loop.
+
+:- module opt_dup_bug.
+:- interface.
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module solutions.
+
+main(!IO) :-
+    solutions(t("2"), Solutions),
+    io.write_list(Solutions, "\n", io.write, !IO),
+    io.nl(!IO).
+
+:- pred t(string, string).
+:- mode t(in, out) is nondet.
+
+t("2", "a").
+t("2", "b").
+t("2", "c").
+t("3", "b").
+t("3", "c").
+t("4", "c").
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to:       mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions:          mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------



More information about the reviews mailing list