This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix a type mismatch in fold-const
- From: Roger Sayle <roger at eyesopen dot com>
- To: Andrew Pinski <pinskia at physics dot uc dot edu>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sun, 24 Apr 2005 09:41:28 -0600 (MDT)
- Subject: Re: [PATCH] Fix a type mismatch in fold-const
On Sun, 24 Apr 2005, Andrew Pinski wrote:
>
> * fold-const.c (fold_binary): Convert the new operands for the
> "(A * C) - (B * C) -> (A-B) * C" conversion.
> Likewise for the "(A * C1) - (A * C2) -> A * (C1-C2)" conversion.
This is OK for mainline.
However, there's also a latent overflow issues in the original code
that needs to be addressed. This is that I don't think these
transformations can be applied with integral types and flag_trapv.
For example, with signed types "(A * C)" or "(B * C)" may overflow and
cause a trap, where the transformed expression "(A-B) * C" doesn't.
The simple case is A = B = MAX_INT and C > 1.
I've made my head hurt going through the other cases, that may
induce overflow in one type and not in the other. In your example,
"(long)((unsigned)(a) * 4) - (long)((unsigned)(b) * 4)" we convert
two unsigned multiplications which have defined semantics on overflow,
into "(a-b)*4" whose multiplication has undefined semantics on overflow.
However, I've so far failed to come up with a case where the expression
is undefined afterwards, where it wasn't undefined before. If anyone
else can, it's simple enough to check that types match or flag_wrapv.
Any chance I could ask you to add a flag_trapv check as a follow-up?
I appreciate this is a pre-existing bug (and one I missed last time
I modified this code!), but it makes sense to fix it now after you've
made me think so hard about this transformation.
Many thanks in advance,
Roger
--