This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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
--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]