https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63390
Bug ID: 63390 Summary: [SH] Hoist/schedule constant pool loads Product: gcc Version: 5.0 Status: UNCONFIRMED Severity: enhancement Priority: P3 Component: target Assignee: unassigned at gcc dot gnu.org Reporter: olegendo at gcc dot gnu.org Target: sh*-*-* The following example resembles a use case where a tagged pointer (1 bit tag in LSB) is tested for nullptr and a function is invoked with the extracted normal pointer: void foo (unsigned int, int); void test (unsigned int* x) { if (__builtin_expect ((*x >> 1) != 0, 1)) foo (*x >> 1, 123456); } -O2 -m4 -ml: mov.l @r4,r4 shlr r4 tst r4,r4 bt .L3 mov.l .L6,r1 <<<< mov.l .L7,r5 <<<< jmp @r1 nop .align 1 .L3: rts nop .L7: Since the pointer is likely to be not nullptr, the function 'foo' is also likely to be executed. Thus it would make sense to hoist the loads for the function call to get better scheduling: mov.l @r4,r4 mov.l .L6,r1 <<<< shlr r4 mov.l .L7,r5 <<<< tst r4,r4 bt .L3 jmp @r1 nop .L3: rts nop .L7: The scheduler doesn't see that because the constant loads remain in the same basic block that contains the function call. Moreover, the constant pool loads are expanded by sh_reorg pass after scheduling (which makes sense). One idea could be to record the expanded constant pool load insns and try to hoist them after sh_reorg and maybe run the scheduler on the modified insn sections.