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.

Reply via email to