http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50729
Bug #: 50729 Summary: Silent code gen fault: Value range propagation seems to propagate values across narrowing/widening Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization AssignedTo: unassig...@gcc.gnu.org ReportedBy: mgret...@sourceware.org Target: arm*-*-* Created attachment 25497 --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=25497 Executable test case. The attached executable test rtest.c fails when compiled and executed as follows: $ arm-none-eabi-gcc rtest.c -O2 -o rtest.axf $ ~ramrad01/public/qemu-arm rtest.axf 1616 20019 FAIL!! The test consists of two identical functions f0a and f0b which are compiled with different optimization levels, and produce different results at -O0 and -O2. Investigations lead me to believe that VRP is at fault - initially because the issue goes away if you compile -O2 -fdisable-tree-vrp1 -fdisable-tree-vrp2. The attached cutdown testcase (rtest-cutdown.c) when compiled as follows produces the attached tree dumps. $ arm-none-eabi-gcc rtest-cutdown.c -O2 -o rtest.axf -fdump-tree-all Looking at the difference between the two attached trees indicates that before VRP1 the tree looked something like: int8_t temp_1; uint64_t D.6414; short unsigned int D.6416; temp_1_27 = (int8_t) D.6414_26; D.6416_33 = (short unsigned int) temp_1_27; [note short unsigned int is 16-bits] VRP1's analysis finds the following: D.6414_26: [0, 4611686018427388031] temp_1_27: VARYING After VRP1 this bit of tree is transformed into: int8_t temp_1; uint64_t D.6414; short unsigned int D.6416; temp_1_27 = (int8_t) D.6414_26; D.6416_33 = (short unsigned int) D.6414_26; That is D.6416_33 is now assigned directly from D.6414_26 instead of going through temp_1_27. [Similar replacements of temp_1_27 by D.6414_26 occur throughout the example but this particular case serves its purpose]. This is incorrect as it stops the 64-bit value D6414_26 being narrowed to an 8-bit signed value before being widened to a 16-bit, now it just gets narrowed from 64-bits to 16-bits.