http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49543
Summary: Cast move causes incorrect code and numerical results Product: gcc Version: 4.6.0 Status: UNCONFIRMED Severity: major Priority: P3 Component: middle-end AssignedTo: unassig...@gcc.gnu.org ReportedBy: acarm...@mathworks.com Created attachment 24606 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24606 Folded and unfolded expressions calculate different results Overview -------- In the following example, "Data" is a 32-bit int, and "tmp" is a 64-bit int. with gcc -ansi -pedantic the following line: tmp = (int64_T)(Data - 1) * 1805715409L; /* 32-bit subtraction */ is compiled as tmp = ((int64_T)Data - 1) * 1805715409L; /* 64-bit subtraction */ This changes the numerical result if Data-1 overflowed. If the code was not folded, as in this example: int32_T hoist; hoist = Data - 1; tmp = (int64_T)hoist * 1805715409L; the result in tmp is computed correctly. The attached file cast_move_bug.c demonstrates this and has copiling instructions. The attached file cast_move_bug.s shows that the location of the up-cast to 64 with cltq instruction moved to *before* the subtraction (compared to the unfolded version). Triggering ---------- The bug was observed on all versions of gcc up to 4.6.0 on 64-bit Linux. When -pedantic *IS NOT* specified, the bug is triggered only with -O0. Under -O1 and above the bug is not triggered. When -pedantic *IS* specified, the bug is triggered under all optimization levels: -O0 through -O3. g++ 4.3.2 and 4.4.3 do not exhibit this bug. Claim ----- The up-cast to 64-bit was incorrectly moved inside the parentheses, violating the effect of parenthesization on type sizes, and causing the subtraction to become 64-bit. Fix request ----------- MathWorks requests the fix to be back-ported to 4.5 - a reasonably current, and stable release within our customer community.