This is the mail archive of the java@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

5.1.3 Jacks failures on s390


Hello,

I've analyzed the 5.1.3-dtl-1 Jacks failure on s390 a bit.
The problem is this code:

  case (((long)Double.POSITIVE_INFINITY == 0x7fffffffffffffffL) ? 1 : 0):

where the conditional is supposed to be constant-folded to 1.

Now, converting an Inf value to integer is undefined in C, 
but apparently defined to yield the largest integer of the
type in Java.  It looks like this piece of code in 
java/typeck.c:convert() is supposed to handle this:

      if (! flag_unsafe_math_optimizations
          && ! flag_emit_class_files
          && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE
          && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT)
        return fold (convert_ieee_real_to_integer (type, expr));
      else
        return fold (convert_to_integer (type, expr));

The routine convert_ieee_real_to_integer generates a conditional
that handles all these special cases.  Unfortunately, when compiling
to a class file, it is not actually called, but the regular gcc
back-end convert_to_integer is called instead, which in this
case simply wraps the Inf into a FIX_TRUNC_EXPR.

When this is later passed through fold, it is handled by
fold_convert (fold-const.c).  However, it would appear that
this routine treats Inf values in a somewhat peculiar manner.
It first calls REAL_VALUE_TO_INT to convert it to a pair of
two HOST_WIDE_INTs, and subsequently truncates the result
to fit into the target type's precision.

Now, REAL_VALUE_TO_INT tries to handle the conversion in a
IEEE conformant manner and returns the largest positive
number representable in a pair of HOST_WIDE_INTs.

What happens at this point depends on the host system.
On a host with 32-bit HOST_WIDE_INT like Intel, this
number just happens to be the largest positive number
representable in a Java long.  However, on a host with
64-bit HOST_WIDE_INT like s390, we get a much larger
number which is subsequently truncated to 0xffff...
or -1.  This is of course not what Java expects ...

Now I'm wondering who's at fault here:

- Apparently the Java front-end doesn't trust the gcc back-end
  to handle these conversions in a manner conformant to the
  Java specifications.  Why does it do so anyway if 
  -femit-class-files is given?

- What should fold_convert to with Inf values?  While C doesn't
  expect any particular value, the current behaviour does appear
  to be quite odd.

Any ideas how to best fix this?

Thanks,
Ulrich

-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de


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