This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug tree-optimization/50729] New: Silent code gen fault: Value range propagation seems to propagate values across narrowing/widening
- From: "mgretton at sourceware dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Fri, 14 Oct 2011 13:39:36 +0000
- Subject: [Bug tree-optimization/50729] New: Silent code gen fault: Value range propagation seems to propagate values across narrowing/widening
- Auto-submitted: auto-generated
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: unassigned@gcc.gnu.org
ReportedBy: mgretton@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.