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