This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[fortran,patch] Fix LEADZ/TRAILZ
- From: FX <fxcoudert at gmail dot com>
- To: Fortran List <fortran at gcc dot gnu dot org>, gcc-patches at gcc dot gnu dot org
- Cc: stevenb dot gcc at gmail dot com
- Date: Wed, 20 May 2009 00:23:32 +0200
- Subject: [fortran,patch] Fix LEADZ/TRAILZ
The current implementation of LEADZ/TRAILZ has the following bugs:
1. Simplification of LEADZ for negative arguments is wrong (it
should always give 0)
2. When calling leadz or trailz on a type smaller than "int", we
should cast to the unsigned type of the same size before casting to
"unsigned int"; that is, for example, we should do:
__builtin_clz ((unsigned int) (unsigned short) short_value)
instead of
__builtin_clz ((unsigned int) short_value)
Otherwise, for negative values, we get wrong results.
3. In the translation of these intrisics, kinds <= 4 yield a call
to __builtin_clz(), kind = 8 calls __builtin_clzl() and kind = 16
calls __builtin_clzll(). This is wrong, as there is no such hard-wired
correspondance of integer kinds and C types. In particular, on x86_64,
integer(kind=16) is larger than "long long int", and thus no builtin
is available!
The attached patch solves all these issues, by 1. special-casing
negatives args in LEADZ simplification; 2. performing the correct
double cast; 3. choosing the right builtin based on type size, and
call adequate new library functions (_gfortran_clz128 /
_gfortran_ctz128).
Bootstrapped and regtested on x86_64-linux, comes with testcases. OK
to commit?
FX
PS: could the reviewer (or another maintainer) please double check
that I've done the correct modification to libgfortran/gfortran.map?
Attachment:
leadz_trailz.ChangeLog
Description: Binary data
Attachment:
leadz_trailz.diff
Description: Binary data