This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/50341] calls via function pointer wrongly scheduled giving invalid TOC pointer


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50341

Michael Meissner <meissner at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |meissner at gcc dot gnu.org

--- Comment #3 from Michael Meissner <meissner at gcc dot gnu.org> 2011-09-15 18:32:45 UTC ---
>From the example in the bug, it is the 3rd cpu_fprintf, where it decides to
move loading up an address into register 27, and move the load of the address
before the call, since register 27 is preserved across calls.

void cpu_dump_state (struct CPUPPCState *env, FILE *f, fprintf_function
cpu_fprintf,
                     int flags)
{



    int i;

    cpu_fprintf(f, "NIP " "%016" "l" "x" "   LR " "%016" "l" "x" " CTR "
                "%016" "l" "x" " XER " "%016" "l" "x" "\n",
                env->nip, env->lr, env->ctr, env->xer);
    cpu_fprintf(f, "MSR " "%016" "l" "x" " HID0 " "%016" "l" "x" "  HF "
                "%016" "l" "x" " idx %d\n", env->msr, env->spr[(0x3F0)],
                env->hflags, env->mmu_idx);

    cpu_fprintf(f, "TB %08" "u" " %08" "l" "u"

                " DECR %08" "u"

                "\n",
                cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)

                , cpu_ppc_load_decr(env)

                );

These are the insns that are moved before the call:

(insn 1105 153 203 2 (set (reg/f:DI 27 27 [603])
        (const:DI (plus:DI (reg:DI 2 2)
                (high:DI (const:DI (unspec:DI [
                                (symbol_ref/f:DI ("*.LC5") [flags 0x82] 
<var_decl 0xfff931e6360 *.LC5>)
                            ] UNSPEC_TOCREL)))))) 513 {largetoc_high}
     (expr_list:REG_EQUIV (const:DI (plus:DI (reg:DI 2 2)
                (high:DI (const:DI (unspec:DI [
                                (symbol_ref/f:DI ("*.LC5") [flags 0x82] 
<var_decl 0xfff931e6360 *.LC5>)
                            ] UNSPEC_TOCREL)))))
        (nil)))

(insn 1107 161 204 2 (set (reg/f:DI 27 27 [601])
        (lo_sum:DI (reg/f:DI 27 27 [603])
            (const:DI (unspec:DI [
                        (symbol_ref/f:DI ("*.LC5") [flags 0x82]  <var_decl
0xfff931e6360 *.LC5>)
                    ] UNSPEC_TOCREL)))) 514 {largetoc_low}
     (expr_list:REG_EQUIV (symbol_ref/f:DI ("*.LC5") [flags 0x82]  <var_decl
0xfff931e6360 *.LC5>)
        (nil)))

The RTL logic is not looking into the const.

This is triggered by Alan's patch in June:

2011-06-20  Alan Modra  <amodra@gmail.com>

    * config/rs6000/rs6000.c (create_TOC_reference): Wrap high part
    of toc-relative address in CONST.
    (rs6000_delegitimize_address): Recognize changed address.
    (rs6000_legitimize_reload_address): Likewise.
    (rs6000_emit_move): Don't force these constants to memory.
    * config/rs6000/rs6000.md (tls_gd, tls_gd_high): Wrap high part of
    toc-relative address in CONST.
    (tls_ld, tls_ld_high, tls_got_dtprel, tls_got_dtprel_high): Likewise.
    (tls_got_tprel, tls_got_tprel_high, largetoc_high): Likewise.

Now, I anticipate that the patch in 4.7 will be temporary until we are
confident that we have the right solution, but it is better to put a bandaid on
the patch to limit the damage.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]