Fix COND_EXPR foldings that are not happening
Paolo Bonzini
bonzini@gnu.org
Tue Jun 8 15:48:00 GMT 2004
This patch fixes two problems with foldings of COND_EXPRs that "should"
be happening but actually are not.
The first is that fold looks for (A OP B ? A : C), but not for the
similar expression (A OP B ? C : A). This for example means that we do
produce an ABS_EXPR for (x > 0 ? x : -x), but not for (x < 0 ? -x : x).
Currently, phiopt handles that in the end, but fixing this will be
useful both at -O0 and when my patch is finished that bases phiopt on
fold. This is easily done by rewriting the missing template to the one
that is handled (using invert_truthvalue).
Some care is needed to avoid infinite loops. fold tries to invert the
expression if the "then" arm is simpler than the "else" arm: well, after
tree-ssa has been merged (but also before), I'd consider gcc to be
broken if it is still true that having a constant in the "then" arm
produces worse code than having it in the "else" arm. This is also not
helping canonicalization in any way (COND_EXPRs are not always
canonicalized, IIRC they can even keep a TRUTH_NOT_EXPR in the condition
for example).
What did happen was that inverting the arms triggered other foldings:
so, I replaced the inversion with the actual rewritings that it actually
caused to happen, that is, A ? 1 : B to A || B, or A ? 0 : B to !A && B.
The second problem is a missing optimization for (A & N ? N : 0) where N
is a power-of-two. This could be converted to A & N, and indeed fold
includes code to do so: but since the first operand of a COND_EXPR is a
truth value, A & N has already been folded by fold_single_bit_test to
either (A < 0) or to (A >> log2 N) & 1.
The easiest way to fix this is to reconstruct the BIT_AND_EXPR, A & N
(looking into the condition for a variable and supposing that it must be
A), call fold_single_bit_test again, and check that the results matches
the condition in the COND_EXPR. Failure to find A & N will cause the
condition not to be folded, but will not produce incorrect code.
Bootstrapped/regtested i686-pc-linux-gnu. Ok for mainline?
Paolo
gcc/ChangeLog:
2004-06-06 Paolo Bonzini <bonzini@gnu.org>
* fold-const.c (find_only_var): New function.
(fold) <COND_EXPR>: Fold (A OP B) ? C : A, A ? 1 : B,
A ? B : 0. Do not try to invert the two arms of a
COND_EXPR. Fix bitrot in the transformation of
(A & N) ? N : 0 to A & N, where N is power of two.
gcc/testsuite/gcc.dg/Paolo Bonzini
2004-06-06 Paolo Bonzini <bonzini@gnu.org>
* 20040606-1.c: New.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: fold-cond-expr-adjust-for-tree-ssa.patch
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20040608/bc531de3/attachment.ksh>
More information about the Gcc-patches
mailing list