diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2024-08-21 16:15:34 +0100 |
---|---|---|
committer | Richard Earnshaw <rearnsha@arm.com> | 2024-09-11 15:51:24 +0100 |
commit | 670cfd5fe6433ee8f2e86eedb197d2523dbb033b (patch) | |
tree | 0cc8be054d9c2e4517d83a29506f5dcf4ef3bb8b /libcpp | |
parent | 09a514fbb67caf7e33a6ceddf524ee21024c33c5 (diff) | |
download | gcc-670cfd5fe6433ee8f2e86eedb197d2523dbb033b.zip gcc-670cfd5fe6433ee8f2e86eedb197d2523dbb033b.tar.gz gcc-670cfd5fe6433ee8f2e86eedb197d2523dbb033b.tar.bz2 |
arm: avoid indirect sibcalls when IP is live [PR116597]
On Arm only r0-r3 (the argument registers) and IP are available for
use as an address for an indirect sibcall. But if all the argument
registers are used and IP is clobbered during the epilogue, or is used
to pass closure information, then there is no spare register to hold
the address and we must reject the sibcall.
arm_function_ok_for_sibcall did try to handle this, but it did this by
examining the function declaration. That doesn't work if the function
has no prototype, or if the prototype has variadic arguments: we must,
instead, look at the list of actuals for the call rather than the list
of formals.
The old code also worked by laying out all the arguments and then
trying to add one more integer argument at the end of the list, but
this missed a corner case where a hole had been left in the argument
register list due to argument alignment.
We fix all of this by now scanning the list of actual values to be
passed and then checking if a core register has been assigned to that
argument. If it has, then we record which registers were assigned.
Once done we then look to see if all the argument registers have been
assigned and only block the sibcall if that is the case. This permits
us to sibcall:
int (*d)(int, ...);
int g(void);
int i () { return d(g(), 2LL);}
because r1 remains free (the 2LL argument is passed in {r2,r3}).
gcc/
PR target/116597
* config/arm/arm.cc (arm_function_ok_for_sibcall): Use the list of
actuals for the call, not the list of formals.
gcc/testsuite/
PR target/116597
* gcc.target/arm/pac-sibcall-2.c: New test.
* gcc.target/arm/pac-sibcall-3.c: New test.
Diffstat (limited to 'libcpp')
0 files changed, 0 insertions, 0 deletions