https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69984
--- Comment #9 from Edmar Wienskoski <edmar at freescale dot com> --- Ok. Thanks for the clarification. The comparison is made with an unsigned variable, but gcc is certain that this variable cannot have (legally) a value that cannot be represented in an int. That is why C = (long) ((int)A) * ((int)B)) generates the same code as: C = A * B but C = (unsigned long) ((int)A) * ((int)B)) does not. The assignment is made after the computation of the expression, therefore just assigning something to "C", does not change what gcc can infer from the right side, and by consequence what can be known from "C" While on the second case, the type cast is not implicit in the assignment but it is part of the expression itself, and that changes the range of values the expression can take. Lots of thanks for your time.