This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]