This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
RFC: using clz for comparing to zero on the tree level.
- From: Andrew Pinski <pinskia at physics dot uc dot edu>
- To: gcc at gcc dot gnu dot org
- Cc: Andrew Pinski <pinskia at physics dot uc dot edu>
- Date: Wed, 7 May 2003 21:35:30 -0400
- Subject: RFC: using clz for comparing to zero on the tree level.
Would it be okay for a patch which transforms some comparisons to
use clz if clz is defined at 0 for SImode or DImode and the target
wants it (these are all are wins for PPC in terms of size and speed).
a==0||b==0 to (clz(a)|clz(b))>>n (if a and b are SImode, then n is
log2(clzsi(0)) or if at DImode log2(clzdi(0)) ).
a==c||b==d to (clz(a^b)|clz(c^d))>>5 or (clz(a+-b)|clz(c+-d))>>5 (if
a, b, c, and d are all SImode or DImode).
a==c&&b==d to clz((a^b)|(c^d))>>5 or clz((a+-b)|(c+-d))>>5 (if a, b, c,
and d are all SImode or DImode).
a==0&&b==0 to (clz(a|b))>>n (if a and b are SImode or DImode).
In fact some optimizations can happen because of these because of the
shifts.
The selection of which operator in the case of the comparisons not
against zero
will be dependent on what the target wants (on PPC for 16 bit unsigned
ints
(upper or lower) can be done with xor and 16 bit signed ints will be
done with add).
The only problem with this approach is that if we have a==0||b==0||c==0
we get ((clz(a)|clz(b))>>n)|(c==0) which is not optimal, the optimal
one would get ((clz(a)|clz(b)|clz(c))>>n).
Another approach would have combine (or some other part of the backend)
do the combine (which gets the problem correct) of
(set (REG:SI RESULT) (EQ:SI (REG:CC0 TEMP) (0))) with (set (REG:CC0
TEMP) (COMAPRE:CC0 (REG:SI A) (const_int 0)))
to (set (REG:SI RESULT) (ASHIFTRT (REG:SI TEMP1) (const_int n))) and
(set (REG:SI TEMP1) (CLZ:SI (REG:SI A))).
I have a patch which uses combine but it depends Segher Boessenkool's
patch that simplifies two insns into two different insn and I heard
from him that some people do not like it.
I also tried a split in the rs6000's machine description but that did
produced two shifts,
not one for the case, a==0||b==0, so that was not optimal.
This there a place in gcc where this could be done "safely" and will
handles all the cases?
Thanks,
Andrew Pinski