From: YunQiang Su Date: Mon, 15 Jan 2024 01:28:51 +0000 (+0800) Subject: MIPS: avoid $gp store if global_pointer is not $gp X-Git-Tag: basepoints/gcc-15~1967 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b503c8787503943c2738058828c3d0037d024fea;p=thirdparty%2Fgcc.git MIPS: avoid $gp store if global_pointer is not $gp $GP is used for expanding GOT load, but in the afterward passes, a temporary register is tried to replace $gp. If sucess, we have no need to store and reload $gp. The example of failure is that the function calls a preemtive function. We shouldn't use $GP for any other purpose in the code we generate. If a user's inline asm code clobbers $GP, it's their duty to save and restore $GP. gcc * config/mips/mips.cc (mips_compute_frame_info): If another register is used as global_pointer, mark $GP live false. gcc/testsuite * gcc.target/mips/mips.exp (mips_option_groups): Add -mxgot/-mno-xgot options. * gcc.target/mips/xgot-n32-avoid-gp.c: New test. * gcc.target/mips/xgot-n32-need-gp.c: New test. --- diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index e752019b5e27..30e99811ff65 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -11353,6 +11353,8 @@ mips_compute_frame_info (void) in, which is why the global_pointer field is initialised here and not earlier. */ cfun->machine->global_pointer = mips_global_pointer (); + if (cfun->machine->global_pointer != GLOBAL_POINTER_REGNUM) + df_set_regs_ever_live (GLOBAL_POINTER_REGNUM, false); offset = frame->args_size + frame->cprestore_size; diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp index 9f8d533cfa57..e028bc93b40f 100644 --- a/gcc/testsuite/gcc.target/mips/mips.exp +++ b/gcc/testsuite/gcc.target/mips/mips.exp @@ -266,6 +266,7 @@ set mips_option_groups { stack-protector "-fstack-protector" stdlib "REQUIRES_STDLIB" unaligned-access "-m(no-|)unaligned-access" + xgot "-m(no-|)xgot" } for { set option 0 } { $option < 32 } { incr option } { diff --git a/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c b/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c new file mode 100644 index 000000000000..3f52fc5a765f --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/xgot-n32-avoid-gp.c @@ -0,0 +1,11 @@ +/* Check if we skip store and load gp if there is no stub function call. */ +/* { dg-options "-mips64r2 -mxgot -mabi=n32 -fPIC" } */ + +extern int a; +int +foo () +{ + return a; +} +/* { dg-final { scan-assembler-not "\tsd\t\\\$28," } } */ +/* { dg-final { scan-assembler-not "\tld\t\\\$28," } } */ diff --git a/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c b/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c new file mode 100644 index 000000000000..631409cb7fe0 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/xgot-n32-need-gp.c @@ -0,0 +1,11 @@ +/* We cannot skip store and load gp if there is stub function call. */ +/* { dg-options "-mips64r2 -mxgot -mabi=n32 -fPIC" } */ + +extern int f(); +int +foo () +{ + return f(); +} +/* { dg-final { scan-assembler "\tsd\t\\\$28," } } */ +/* { dg-final { scan-assembler "\tld\t\\\$28," } } */