Mercury Bugs - mercury
View Issue Details
0000042mercuryBugpublic2008-02-04 11:012008-10-22 15:35
Reporterwangp 
Assigned Towangp 
PrioritynormalSeverityminorReproducibilityalways
StatusresolvedResolutionfixed 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0000042: bug with LCMC in hlc grades
DescriptionIn the attached test case, a list is converted to a bag then back again.
The input is [1,1,1,2,3,3,4]. The output should be the same.
When the module is compiled with

    mmc -s hlc.gc --optimize-constructor-last-call --no-inlining

the output is just "[1]".
TagsNo tags attached.
Attached Files? bag_to_list.m (665) 2008-02-04 11:01
https://bugs.mercurylang.org/file_download.php?file_id=35&type=bug

Notes
(0000094)
wangp   
2008-03-28 11:26   
This appears to have been fixed by Mark's recent changes.
(0000095)
wangp   
2008-03-28 15:06   
Sorry, I was wrong. The reason it "works" now is that the latest compiler no longer performs the LCMC optimisation on the test case at all.
(0000098)
juliensf   
2008-04-04 17:43   
(Last edited: 2008-04-04 17:44)
The reason that the compiler no longer performs LCMC optimisation is a change in the
behaviour of common structure optimisation:

Compiling with: -O2 --optimize-constructor-last-call --nolining --no-common-struct
gives me the following at stage 135 (which is the last pass that does something meaningful
before the LCMC pass) for the predicate to_list_2.

bag_to_list.to_list_2(TypeInfo_for_T, HeadVar__1, HeadVar__2) :-
  ( % cannot_fail switch on `HeadVar__1'
    % HeadVar__1 has functor list.[]/0
    HeadVar__2 = list.[]
  ;
    % HeadVar__1 has functor list.[|]/2
    HeadVar__1 = list.[V_9 | Xs],
    V_9 = pair.(X - Int),
    (if
      V_10 = 0,
      int.(Int =< V_10)
    then
      bag_to_list.to_list_2(TypeInfo_for_T, Xs, HeadVar__2)
    else
      V_11 = 1,
      NewInt = int.(Int - V_11),
      V_13 = pair.(X - NewInt),
      V_12 = list.[V_13 | Xs],
      bag_to_list.to_list_2(TypeInfo_for_T, V_12, Out0),
      HeadVar__2 = list.[X | Out0]
    )
  ).

Enabling common structure optimisation gives the following:

bag_to_list.to_list_2(TypeInfo_for_T, HeadVar__1, HeadVar__2) :-
  ( % cannot_fail switch on `HeadVar__1'
    % HeadVar__1 has functor list.[]/0
    HeadVar__2 = list.[]
  ;
    % HeadVar__1 has functor list.[|]/2
    HeadVar__1 = list.[V_9 | Xs],
    V_9 = pair.(X - Int),
    (if
      V_10 = 0,
      int.(Int =< V_10)
    then
      bag_to_list.to_list_2(TypeInfo_for_T, Xs, Out)
    else
      V_11 = 1,
      NewInt = int.(Int - V_11),
      V_13 = pair.(X - NewInt),
      V_12 = list.[V_13 | Xs],
      bag_to_list.to_list_2(TypeInfo_for_T, V_12, Out0),
      Out = list.[X | Out0]
    ),
    HeadVar__2 = Out
  ).

The unification HeadVar__2 = Out is introduced in stage 65 by common structure optimisation
and it inhibits LCMC. Compiling with --no-common-struct causes the program to exhibit
the original buggy behaviour reported by Peter Wang.

Since there is no advantage gained by adding the new assignment unification and given
that it inhibits other optimisations this behaviour from --common-struct is also a bug.

(0000147)
wangp   
2008-09-03 17:10   
Fix is here
http://www.cs.mu.oz.au/research/mercury/mailing-lists/mercury-reviews/mercury-reviews.200806/0032.html

but store_at_ref needs to be declared impure first.

Issue History
2008-02-04 11:01wangpNew Issue
2008-02-04 11:01wangpFile Added: bag_to_list.m
2008-03-28 11:26wangpNote Added: 0000094
2008-03-28 11:27wangpStatusnew => resolved
2008-03-28 11:27wangpResolutionopen => fixed
2008-03-28 11:27wangpAssigned To => wangp
2008-03-28 15:06wangpNote Added: 0000095
2008-03-28 15:06wangpAssigned Towangp =>
2008-03-28 15:06wangpStatusresolved => new
2008-04-04 17:43juliensfNote Added: 0000098
2008-04-04 17:44juliensfNote Edited: 0000098
2008-09-03 17:10wangpNote Added: 0000147
2008-10-22 15:35wangpStatusnew => resolved
2008-10-22 15:35wangpAssigned To => wangp