[MLton] Patch ready

Matthew Fluet fluet at tti-c.org
Sun Feb 11 13:37:14 PST 2007

>>> The new regression/widechar.sml reveals another bug in the compiler. 
>>> There's a type-check failure in the SSA pass:
>>>> Type error: Ssa.TypeCheck.coerce
>>>> {from = word32 vector, to = word8 vector}
>>>> Type error: analyze raised exception unhandled exception: TypeError
>>>> unhandled exception: TypeError
>>> I have no idea where to begin to debug this.
>> I suggest running the compiler with '-verbose 3 -show-types true 
>> -type-check true'; that should reveal which SSA pass is yielding the 
>> type error.  Then run with '-keep-pass ZZZ' for the relevant pass.
> I've shrunk the problem code down to:
>> fun tst0 s = print (s ^ "\n");
>> val _ = WideChar.fromCString "test"
>> val x = WideChar.contains "" #"a"
> If any one of the statements is removed, it compiles!
> The point of the crash is:
>>             typeCheck starting
>>                checkScopes starting
>>                checkScopes finished in 0.01 + 0.00 (0% GC)
>> Type error: Ssa.TypeCheck.coerce
>> {from = word32 vector, to = word8 vector}
>> Type error: analyze raised exception unhandled exception: TypeError
>>             typeCheck raised in 0.01 + 0.00 (0% GC)
>>          ssaSimplify raised in 0.90 + 0.00 (0% GC)
>>       pre codegen raised in 12.14 + 4.10 (25% GC)
>>    Compile SML raised in 12.14 + 4.10 (25% GC)
>> MLton raised in 12.14 + 4.10 (25% GC)
>> unhandled exception: TypeError
> I'm not sure I see the problem in the SSA pass. There's a lot of output.

I should have suggested '-verbose 2' rather than '-verbose 3'; with the 
former, it should be pretty clear that the type-checking pass after 
constant propagation is raising the TypeError.  That lays the blame on 
constant propagation itself.

It still took a little digging to find the error.  I used a SML/NJ 
compiled version of mlton, because it gives '-trace <strings>' argument 
which can be used to instruct the compiler to print out tracing 
information.  (Browsing the source code, you'll see occurrences of 
wrapping (interesting) functions with Trace.trace; the string argument 
to Trace.trace is what is passed on the command line to '-trace' to 
trace that function.  You can also use the 'make traced' target of the 
top-level Makefile to get a mlton compiled version of mlton with tracing 
enabled.)  Since the Analyze.analyze function raised in the SSA 
type-checker, I traced "Analyze.loopStatement" and 
"Analyze.loopTransfer".  This identified a Goto transfer that failed to 
type-check, which I inspected in the .constantPropagation.post.ssa file 
(saved with '-keep-pass constantPropagation').  It quickly became 
apparent that a global word32 vector corresponding to the empty string 
was being passed to a block expecting a word8 vector.  Looking at the 
.constantPropagation.pre.ssa file, I saw that there were both globals 
corresponding to the empty string at 8 bits and at 32 bits.

Without too much more trouble, I discovered that WordXVector.equals was 
comparing the elements of the vectors to determine equality, but was 
ignoring the element size.  Thus, the empty vector at 8 bits was being 
judged equal to the empty vector at 32 bits.  The constantPropagation 
pass tries to combines all equal constants, so it was trying to use the 
same empty vector for both 8-bits and 32-bits -- leading to the type error.

I believe that we would have also gotten a bug by combining any constant 
vectors with the same elements, but at different element sizes.

I've checked in the fix, which ensures that WordXVector.equals returns 
true only if the two vectors have the same elementSize and the same 

More information about the MLton mailing list