Trunk miscompiles libjava
Andrew Haley
aph@cambridge.redhat.com
Thu May 23 11:30:00 GMT 2002
Boehm, Hans writes:
> On Linux/IA64, and probably other platforms, the trunk gcc miscompiles the isWhiteSpace() method in libjava/java/lang/Character. Apparently the bit-wise & in a return is the problem. This is a regression from 3.1. It fails with the current CVS and failed with the one from a few days ago.
>
> Reduced test case (only isWhitespace is miscompiled, the rest is scaffolding):
>
> class mychar {
> public static boolean isWhitespace(char ch)
> {
> int attr = readChar(ch);
> return (((1 << attr) & 0x7000) != 0);
> }
>
>
> private static char readChar(char ch) {
> if (ch < 128) return (char) 9;
> return 9999;
> }
>
> public static void main(String[] argv) {
> if (isWhitespace('4'))
> System.out.println("FAIL 1");
> if (isWhitespace('a'))
> System.out.println("FAIL 2");
> }
> }
>
> Offending RTL instruction (partial diff of trunk (-) against 3.1 output (+)):
>
> (insn 57 56 59 (set (reg:DI 359)
> - (zero_extend:DI (subreg:QI (reg:SI 355) 0))) -1 (nil)
> + (and:DI (subreg:DI (reg:SI 355) 0)
> + (const_int 1 [0x1]))) -1 (nil)
> (nil))
>
> In both 3.1 and the trunk, the code in the return is compiled as a
> variable right shift of 0x7000. In the 3.1 version, this is anded
> against 0x1. In the trunk version the and is dropped.
It's the old problem that bites us all the time. fold() is doing
conversions that are legal C but not legal java.
It's caused by this patch:
revision 1.195
date: 2002/04/18 10:39:20; author: jakub; state: Exp; lines: +43 -0
* fold-const.c (fold) [NOP_EXPR]: Convert (T)(x&c) into ((T)x&(T)c)
for integer constant c (if x has unsigned type or sign bit is not
set in c). This folds the zero/sign extension into the bit-wise and
operation.
* gcc.c-torture/compile/20020415-1.c: New.
I don't think there's anything wrong with this patch, but it causes
breakage on systems that have a boolean type smaller than int.
I intend to dig deeper tomorrow.
Andrew.
More information about the Java
mailing list