This is the mail archive of the
mailing list for the GCC project.
Re: [PATCH] Fix ICE in fold-const.c
- From: Andrew Pinski <pinskia at physics dot uc dot edu>
- To: Roger Sayle <roger at eyesopen dot com>
- Cc: gcc-patches at gcc dot gnu dot org, Andrew Pinski <pinskia at physics dot uc dot edu>
- Date: Mon, 17 May 2004 00:00:27 -0400
- Subject: Re: [PATCH] Fix ICE in fold-const.c
- References: <Pine.LNX.email@example.com>
On May 16, 2004, at 21:59, Roger Sayle wrote:
On Sun, 16 May 2004, Andrew Pinski wrote:
I do not have a testcase for this patch as it cannot happen in C or
C++ or Java as you convert the (bool)(a) into a != 0.
The ICE can happens when !(bool)a is passed to fold because fold will
use STRIP_SIGNED_NOPS which removes the cast to bool which causes an
ICE in invert_truthvalue.
Could you provide some more details? Firstly, if correctly written
front-ends (such as C, C++ or Java) make the conversion explicit,
which language front-end is it that needs to be fixed :>
The front-ends are correctly converting it to be ! (a == 0) when passed
to fold, the problem comes into play when trying to do a combine pass
for tree-ssa, so combining c_1 = ! d_2 and d_2 = (bool)a_3 which gives
! (bool)a_3 and then passing that to fold which I assumed to do the
right thing. a is not of type boolean_type at all but integer_type.
Secondly, which ICE in invert_truthvalue is getting tripped. The
STRIP_SIGNED_NOPS macro does precisely that, remove no-op casts
that don't affect the value/mode of the argument only the type.
Hence what is it about "a" in "!(bool)a" that's triggering the ICE
if "(bool)" is a no-op cast?
The ICE that the type of a is not of a boolean_type but is of
integer_type. STRIP_SIGN_NOPS strips when the modes are the same which
only happens on powerpc-darwin where bools are the same size (mode)
of ints unlike every other target where bools are the same size (mode)
of chars. So this will not cause an ICE on most targets.
A cast to bool can't be a NOP_EXPR if it's argument isn't guaranteed
to be one or zero valued. Which is why C, C++ and Java go the safe
route of making the "!= 0" explicit, which will then be removed by
fold if it can determine that the argument really is zero/one valued.
It is not a NOP_EXPR but a CONVERT_EXPR which STRIP_SIGN_NOPS still
strips. Maybe the other fix is to remove the check for CONVERT_EXPR
in STRIP_NOPS and STRIP_SIGN_NOPS as by definition CONVERT_EXPR is
like NOP_EXPR but can create code.
Clearly one of the invariants required by the middle-end's constant
folder isn't being satisfied and without more information, it's
difficult to determine if your proposed patch is the correct fix.