This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [g77 testsuite]
Richard Henderson wrote:
> On Wed, Jul 18, 2001 at 10:23:22PM +0200, Toon Moene wrote:
> > The nice thing is - this actually fails for i686-pc-linux-gnu (and
> > probably a lot of other targets).
>
> It fails because in C, a shift larger than the operand size is
> undefined, and the rtl shift operators inherit that. This is a
> Good Thing, because that's how most hardware actually works.
> If such overflow is defined in Fortran, the front end will have
> to add extra code for this.
Hmmm, that's not how I read it. This is the implementation of ISHFT in
the Fortran frontend (line 4549ff of f/com.c):
case FFEINTRIN_impISHFT:
{
tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1));
tree arg2_tree = ffecom_save_tree (convert (integer_type_node,
ffecom_expr
(arg2)));
tree uns_type
= ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt];
expr_tree
= ffecom_3 (COND_EXPR, tree_type,
ffecom_truth_value
(ffecom_2 (GE_EXPR, integer_type_node,
arg2_tree,
integer_zero_node)),
ffecom_2 (LSHIFT_EXPR, tree_type,
arg1_tree,
arg2_tree),
convert (tree_type,
ffecom_2 (RSHIFT_EXPR, uns_type,
convert (uns_type, arg1_tree),
ffecom_1 (NEGATE_EXPR,
integer_type_node,
arg2_tree))));
...
In words, this says: Test the if count against zero. If it is larger,
do an LSHIFT_EXPR of the shiftee, else do an RSHIFT_EXPR of (unsigned)
the shiftee. According to tree.def, RSHIFT_EXPR on an unsigned quantity
should do a logical shift, i.e., with zero-fill. Perhaps the way the
conversion to unsigned is done doesn't work.
> That said, I think a better test is
>
> I = 0
> I = NOT(I)
> IF (ISHIFT(I, -BIT_SIZE(I)+1) .NE. 1) CALL ABORT
> I = 1
> I = ISHIFT(I, BIT_SIZE(I)-1)
> IF (I .EQ. 0) CALL ABORT
> IF (ISHIFT(I, 1) .NE. 0) CALL ABORT
>
> since your test checks that BIT_SIZE is at least as large
> as the integer, but doesn't check that it is not larger.
Perhaps even a still better one is:
INTEGER I, IC
I = 1
IC = 1
DO WHILE (ISHFT(I, IC) .NE. 0)
IC = IC + 1
ENDDO
IF (IC .NE. BIT_SIZE(I)) CALL ABORT
END
and mutatis mutandis the other way around (Note: ISHFT, not ISHIFT).
--
Toon Moene - mailto:toon@moene.indiv.nluug.nl - phoneto: +31 346 214290
Saturnushof 14, 3738 XG Maartensdijk, The Netherlands
Maintainer, GNU Fortran 77: http://gcc.gnu.org/onlinedocs/g77_news.html
Join GNU Fortran 95: http://g95.sourceforge.net/ (under construction)