Mercurial > hg > index.cgi
view test/runtests @ 418:3832a68d83ef
Fix internal compiler error on "var2 = var1 + 1" patterns
This appears to be the correct fix. It was provided by Tormod Volden
(debian.tormod@gmail.com). The final commit is substantially different from
Tormod's submission mostly due to housecleaning (removing the old patches
and updating the README). Tormod's comments follow.
The original addhi_mem_1 "insn" instruction pattern /matches/ two
memory operands, just with the /constraint/ that these are the same
location. A pattern match tells the compiler "you should be able to use
this, but you might have to work on it to meet the constraints". For
typical constraints on registers the compiler can add "reloads", moving
stuff between registers or from memory, until the constraints are met
and the instruction can be used. However, in this case, no amount of
reloads can make two memory locations the same if they already weren't,
so the compiler breaks down and cries "unable to generate reloads".
It seems this issue only appears if optimization is enabled. The proof
is in gcc's reload.c and is left as an exercise to the reader.
Limiting the matching pattern to identical memory operands avoids
these situations, while allowing the common "var++" cases.
References:
The pattern/constraints difference is explained in
https://gcc.gnu.org/onlinedocs/gccint/Simple-Constraints.html#index-other-register-constraints-3335
author | William Astle <lost@l-w.ca> |
---|---|
date | Tue, 29 Mar 2016 21:21:49 -0600 |
parents | 3413a88f4d09 |
children | 3cd8aa013b88 |
line wrap: on
line source
#!/usr/bin/perl # # This program will execute all programs in the "tests" directory. Each # program is expected to produce output as follows on stdout: # # each line begins with a test name followed by whitespace followed by # PASS, FAIL, or SKIP. # # stderr is not redirected during testing. Any test that might spam stderr # is encouraged to redirect it somewhere useful. # # After each test script exits, a report indicating number passed, failed, # and skipped is presented, or if the script failed to run. # # Once all tests have been run, a report showing the grand total number of # tests performed, passed, failed, and skipped. # # Each test can be in any programming language that is appropriate for # the task. # # Each test can assume the current directory is the root of the source tree. use File::Basename; $testdir = dirname($0) . '/tests'; opendir DH, $testdir; while ($fe = readdir DH) { next if ($fe =~ /^\./); next if ($fe =~ /~$/); $fn = $testdir . '/' . $fe; open P,"$fn|"; while (<P>) { chomp; ($tn, $ts) = split /\s+/; $testresults{$fe}{$tn} = $ts; if ($ts eq 'PASS') { $testspassed += 1; $testresults{$fe}{'..passed'} += 1; } elsif ($ts eq 'FAIL') { $testsfailed += 1; $testresults{$fe}{'..failed'} =+ 1; } elsif ($ts eq 'SKIP') { $testsskipped += 1; $testresults{$fe}{'..skipped'} += 1; } else { $testsunknown += 1; $testresults{$fe}{'..unknown'} += 1; } $teststotal += 1; $testresults{$fe}{'..total'} += 1; } close P; $fdn = $fe; $fdn =~ s/\..+?$//; $rline = sprintf("%-25.25s: %d/%d (%d skipped, %d unknown, %d failed)", $fdn, $testresults{$fe}{'..passed'}, $testresults{$fe}{'..total'}, $testresults{$fe}{'..skipped'}, $testresults{$fe}{'..unknown'}, $testresults{$fe}{'..failed'}); print "$rline\n"; } closedir DH; print sprintf("\n===================\nTotal: %d/%d (%d skipped, %d unknown, %d failed)\n", $testspassed, $teststotal, $testsskipped, $testsunknown, $testsfailed); if ($testspassed < $teststotal) { print "\nThe following tests either failed or were otherwise dubious:\n"; foreach $i (keys %testresults) { $fdn = $i; $fdn =~ s/\..+?$//; foreach $j (keys %{ $testresults{$i} }) { next if $j =~ /^\./; if ($testresults{$i}{$j} ne 'PASS') { print "$fdn/$j: $testresults{$i}{$j}\n"; } } } exit 1; } exit 0;