This patch prevents merging of CALL instructions that that have different REG_CALL_DECL notes attached to them.
On most architectures this is not an important distinction. Usually instruction patterns for calls to different functions reference different SYMBOL_REF-s, so they won't match. On MIPS PIC calls get split into an got_load/*call_internal pair where the latter represents indirect register call w/o SYMBOL_REF attached (until machine_reorg pass). The bugzilla issue had such two internal_call-s merged despite the fact that they had different register usage information assigned by ipa-ra. As per comment form Richard Sandiford, this version compares reg usage for both call instruction instead of shallow comparing the notes. Tests updated accordingly. gcc/ChangeLog: 2019-07-09 Dragan Mladjenovic <dmladjeno...@wavecomp.com> * cfgcleanup.c (old_insns_match_p): Check if used hard regs set is equal for both call instructions. gcc/testsuite/ChangeLog: 2019-07-09 Dragan Mladjenovic <dmladjeno...@wavecomp.com> * gcc.target/mips/cfgcleanup-jalr1.c: New test. * gcc.target/mips/cfgcleanup-jalr2.c: New test. * gcc.target/mips/cfgcleanup-jalr3.c: New test. --- gcc/cfgcleanup.c | 9 +++++++++ gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c | 19 +++++++++++++++++++ gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c | 23 +++++++++++++++++++++++ gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c | 23 +++++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c create mode 100644 gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c create mode 100644 gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 992912c..fca3a08 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "dce.h" #include "dbgcnt.h" #include "rtl-iter.h" +#include "regs.h" #define FORWARDER_BLOCK_P(BB) ((BB)->flags & BB_FORWARDER_BLOCK) @@ -1224,6 +1225,14 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx_insn *i1, rtx_insn *i2) } } } + + HARD_REG_SET i1_used, i2_used; + + get_call_reg_set_usage (i1, &i1_used, call_used_reg_set); + get_call_reg_set_usage (i2, &i2_used, call_used_reg_set); + + if (!hard_reg_set_equal_p (i1_used, i2_used)) + return dir_none; } /* If both i1 and i2 are frame related, verify all the CFA notes diff --git a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c new file mode 100644 index 0000000..24c1826 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips" } */ +/* { dg-skip-if "needs codesize optimization" { *-*-* } { "-O0" "-O1" "-O2" "-O3" } { "" } } */ + +extern void foo (void*); + +extern void bar (void*); + +void +test (void* p) +{ + if (!p) + foo(p); + else + bar(p); +} + +/* { dg-final { scan-assembler-not "\\\.reloc\t1f,R_MIPS_JALR,foo" } } */ +/* { dg-final { scan-assembler-not "\\\.reloc\t1f,R_MIPS_JALR,bar" } } */ diff --git a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c new file mode 100644 index 0000000..9fd75c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr2.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips" } */ +/* { dg-additional-options "-fno-inline -fipa-ra -mcompact-branches=never" } */ +/* { dg-skip-if "needs codesize optimization" { *-*-* } { "-O0" "-O1" "-O2" "-O3" } { "" } } */ + +static int foo (void* p) { __asm__ (""::"r"(p):"$t0"); return 0; } + +static int bar (void* p) { return 1; } + +int +test (void* p) +{ + int res = !p ? foo(p) : bar(p); + + register int tmp __asm__("$t0") = -1; + __asm__ (""::"r"(tmp)); + + return res; +} + +/* { dg-final { scan-assembler "\\\.reloc\t1f,R_MIPS_JALR,foo" } } */ +/* { dg-final { scan-assembler "\\\.reloc\t1f,R_MIPS_JALR,bar" } } */ +/* { dg-final { scan-assembler-not "\\.set\tnomacro\n\tjalr\t\\\$25" } } */ diff --git a/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c new file mode 100644 index 0000000..580c6ec --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/cfgcleanup-jalr3.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-mabicalls -fpic -mno-mips16 -mno-micromips" } */ +/* { dg-additional-options "-fno-inline -fipa-ra -mcompact-branches=never" } */ +/* { dg-skip-if "needs codesize optimization" { *-*-* } { "-O0" "-O1" "-O2" "-O3" } { "" } } */ + +static int foo (void* p) { return 0; } + +static int bar (void* p) { return 1; } + +int +test (void* p) +{ + int res = !p ? foo(p) : bar(p); + + register int tmp __asm__("$t0") = -1; + __asm__ (""::"r"(tmp)); + + return res; +} + +/* { dg-final { scan-assembler-not "\\\.reloc\t1f,R_MIPS_JALR,foo" } } */ +/* { dg-final { scan-assembler-not "\\\.reloc\t1f,R_MIPS_JALR,bar" } } */ +/* { dg-final { scan-assembler "\\.set\tnomacro\n\tjalr\t\\\$25" } } */ -- 1.9.1