This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Fortran sizetype fix
- To: zack at wolery dot cumb dot org
- Subject: Re: Fortran sizetype fix
- From: craig at jcb-sc dot com
- Date: 14 Jun 2000 23:05:38 -0000
- cc: toon at moene dot indiv dot nluug dot nl, gcc-patches at gcc dot gnu dot org
- cc: craig at jcb-sc dot com
- References: <10004291405.AA14019@vlsi1.ultra.nyu.edu> <20000429095707.K24271@wolery.cumb.org> <20000429120520.L24271@wolery.cumb.org> <390B454C.A8C70EF1@moene.indiv.nluug.nl> <20000429134509.M24271@wolery.cumb.org>
Sorry to have taken so long to get to this! Started looking at it maybe a month
or so ago, but really haven't had the time to re-learn this stuff.
However, I'll make a few suggestions. First, it seems pretty clear that
this code is used only to determine overlapping involving COMPLEX arguments
in procedure (library or SUBROUTINE/FUNCTION) calls or in COMPLEX dest/source
pairs in assignments (as in C1=C2()).
So, before mucking around with the code much and hoping it works at least as
well as it used to, it's probably best for someone to write a bunch of tests
that stress the various cases this code deals with to inhibit incorrect
code generation while making good optimization decisions.
E.g. in C1=C2(), this code tries to answer the question "is it safe to
pass to C2 the address of C1, for the purposes of writing into it the result
of invoking COMPLEX FUNCTION C2, instead of passing the address of a complex
temporary and subsequently copying the temporary into C1?".
So if you can write tests that do things that'll fail if the answer to the
question is "yes" in cases where it should be "no" or "maybe", you'll have
covered some important cases of subtle bugs being introduced as a result of
changing the code.
Offhand, an example of such a test case might look like:
COMPLEX C1, C2, C3, C4
C4 = (1, 2)
C3 = C4
C1 = C2 (C3)
IF (C1 .NE. C4) CALL ABORT
IF (C3 .NE. (3, 4)) CALL ABORT
END
COMPLEX FUNCTION C2 (C)
COMPLEX C
C2 = C
C = (3, 4)
END
The second-to-last line is the key one. It modifies the argument to the
function (allowed in Fortran; think of C2 (C3) as c2(&c3) in C) *after*
assigning the value to be returned in the previous line (which is sorta
like C's "return c;", except the actual return happens when a RETURN or
END statement is executed). The g77/f2c procedure interface mandates
that a complex function have, as its first argument, a "phantom" address
pointing to where the function should write its result (same kinda thing
done for CHARACTER functions). If that address points to part or all of
one of the arguments to the function, that sort of write-result-then-
write-argument behavior will fail, even though it's standard-conforming.
Write similar tests to cover invoking library routines that return complex
results. Make sure they fail when the "is it safe?" question is forced to
always answer "yes". These tests should include testing partial overlap,
in both directions, between the real and imaginary parts of complex
values. (That's because I think libg2c is, or was, perfectly clean in this
regard, while libf2c might not work in one direction of overlap.)
They should also test out COMMON and EQUIVALENCE overlap, not just
argument-based overlap. (That's how C1=C2() might require a temp;
C1 might be in COMMON, visible to C2, so the caller can't pass the
address of C1 as if it was some temp, in case C2 assigns to it and *then*
writes or reads it via COMMON.)
And maybe use the code you're presently having trouble with to guide you
in writing tests of particularly interesting boundary conditions.
Having done that, I suspect it'll be clearer just how to modify the code
to accommodate the other changes that were made. I.e. the research done
into how to write good tests could give people enough insight into the
issues to feel more comfortable modifying the code.
But at least if it isn't clear enough, if bugs are thereby introduced, the
chances are much greater that the results will be either obvious test-suite
failures or (innocuous or noticeable) performance degradation (the case
where the question is answer "no" or "maybe" when it used to be correctly
answered "yes").
(These sorts of tests should be de rigeur for a project like this, IMO.)
If that all seems like too much work, and you can't back out the partial
changes made so far, perhaps it's best to just disable the optimizations by
having the question always answered "maybe" (or "no" -- can't recall if there's
an important difference in that case).
Then, if someone complains about the drop in performance, you can suggest
they fund improvements or something!
Hope this helps.
tq vm, (burley)
>Right - Craig, we are discussing a patch for ICEs in size_binop,
>provoked by code in the Fortran front end.
>
>The problem lies in ffecom_tree_canonize_(ref|ptr)_ both of which do
>something like this:
>
> *offset
> = size_binop (MULT_EXPR,
> TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))),
> convert (sizetype,
> fold (build (MINUS_EXPR, TREE_TYPE (element),
> element,
> TYPE_MIN_VALUE
> (TYPE_DOMAIN
> (TREE_TYPE (array)))))));;
>
>Recently TYPE_SIZE was changed to be bitsizetype instead of sizetype.
>Therefore, size_binop is asked to operate on one bitsizetype value and
>one sizetype value, so it aborts. g77.f-torture/execute/19990325-[01].f
>both trigger the bug.
>
>Changing sizetype to bitsizetype makes this instance of the bug go
>away. However, that's not a complete fix, say the people who
>understand sizetype vs. bitsizetype. Neither they nor I understand
>com.c well enough to know what the complete fix is.