The recent changes for the new code models tickled a latent bug in the GCC 4.6
and 4.7 compilers with the AIX calling sequence (PR 50341).  When you call a
function indirectly, the compiler has to save the current function's TOC
pointer that is in r2 on the stack frame, and then load the new function's TOC
pointer before doing the call.  If the indirect function that you are calling
has the same TOC value as the current function, the code will run, but if the
indirection function has a different TOC (for example it is in the main
program, and the indirect call is in a shared library), the wrong address will
be used.

The existing code did this by doing a split after reload has finished.
Scheduling after reload then moves the load of the new TOC.  These patches for
GCC 4.6 and GCC 4.7 disable the splits so that the load of the new TOC is
always next to the bctrl instruction, preventing the compiler from moving the
load.  Ideally, we can eventually tackle the underlying problem that we did not
have the right dependencies to prevent the scheduler from moving the new TOC
load before the use.

[gcc-4.6]
2011-09-15  Alan Modra  <amo...@gmail.com>
            Michael Meissner  <meiss...@linux.vnet.ibm.com>

        PR target/50341
        * config/rs6000/rs6000.md (call_indirect_aix32): Do not split the
        load of the indirect function's TOC from the call to prevent the
        compiler from moving the load of the new TOC above code that
        references the current function's TOC.
        (call_indirect_aix64): Ditto.
        (call_value_indirect_aix32): Ditto.
        (call_value_indirect_aix64): Ditto.
        (call_indirect_nonlocal_aix32_internal): Ditto.
        (call_indirect_nonlocal_aix32): Ditto.
        (call_indirect_nonlocal_aix64_internal): Ditto.
        (call_indirect_nonlocal_aix64): Ditto.
        (call_value_indirect_nonlocal_aix32_internal): Ditto.
        (call_value_indirect_nonlocal_aix32): Ditto.
        (call_value_indirect_nonlocal_aix64_internal): Ditto.
        (call_value_indirect_nonlocal_aix64): Ditto.


[gcc-4.7]
2011-09-15  Alan Modra  <amo...@gmail.com>
            Michael Meissner  <meiss...@linux.vnet.ibm.com>

        PR target/50341
        * config/rs6000/rs6000.md (call_indirect_aix<ptrsize>): Do not
        split the load of the indirect function's TOC from the call to
        prevent the compiler from moving the load of the new TOC above
        code that references the current function's TOC.
        (call_indirect_aix<ptrsize>_internal): Ditto.
        (call_indirect_aix<ptrsize>_nor11): Ditto.
        (call_indirect_aix<ptrsize>_internal2): Ditto.
        (call_value_indirect_aix<ptrsize>): Ditto.
        (call_value_indirect_aix<ptrsize>_internal): Ditto.
        (call_value_indirect_aix<ptrsize>_nor11): Ditto.
        (call_value_indirect_aix<ptrsize>_internal2): Ditto.

I have bootstraped both compilers for C, C++, and Fortran.  There were no
differences in the make check output.

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meiss...@linux.vnet.ibm.com     fax +1 (978) 399-6899

Reply via email to