If the long-calls feature flags is enabled, disable use of the jal instruction. Instead of that call a function by by first loading its address into a register, and then using the contents of that register.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
2 nits: We should warn/error in LLVM on mixing abicalls and long calls (abicalls overrides long calls). We should make sure clang warns but doesn't error.
Second is about 64bit support, inlined,
lib/Target/Mips/MipsISelLowering.cpp | ||
---|---|---|
3024 ↗ | (On Diff #105736) | Nit:// FIXME: Add support for 64 bit symbols. |
We should warn/error in LLVM on mixing abicalls and long calls
Do you know why gcc does not warn in this case? Moreover gcc -mabicalls -mlong-calls generates jalr not jal instructions. Is it a bug in gcc?
lib/Target/Mips/MipsISelLowering.cpp | ||
---|---|---|
3024 ↗ | (On Diff #105736) |
How can I force compiler to generate the jal instruction to jump to 64-bit symbol? I.e. it looks like with -mabi=64 the compiler always uses the jalr instruction. |
Do you know why gcc does not warn in this case?
GCC's manual says that -mlong-calls has no effect on code that uses -mabicalls. I'm assuming it's a deficiency in the MIPS backend of GCC not to identify this case and report it.
Moreover gcc -mabicalls -mlong-calls generates jalr not jal instructions. Is it a bug in gcc?
This looks like it's some optimization kicking in to store function addresses only in the GOT in the case of static code that uses abicalls and long-calls. I'll have a further look tomorrow about this.
lib/Target/Mips/MipsISelLowering.cpp | ||
---|---|---|
3024 ↗ | (On Diff #105736) | You need to use the static relocation model and turn off abicalls (target feature +noabicalls). The N64 abi defaults to PIC as synthesizing the address of a symbol is quite expensive, so PIC is preferred for that abi. |
Ok, I've followed up on intermixing -mabicalls and -mlong-calls, and I
was wrong. It's the GCC manual I believe is somewhat misleading.
In the basic case of -mabicalls & -mlong-calls, they don't work together
as abicalls code is pic and long-calls is static only.
However, the MIPS non-PIC ABI specification[1] also mixing static
and pic code, cpic. In this case, when code is produced with -mno-shared,
calls to locally defined functions do not have to go through the GOT,
and are either 'jal' or a long call sequence. Calls to functions which
are not locally defined use the GOT and jalr as normal.
Until we get proper support for -mshared / -mno-shared, we should only
allow -mlong-calls with -mno-abicalls.
lib/Target/Mips/MipsISelLowering.cpp | ||
---|---|---|
3024 ↗ | (On Diff #105736) | That check should also test that abicalls are not being used. |
I think a warning shown by the Clang in case of mixed long-calls and 'abicalls` options will be enough. If user gets warning from the front-end and one more warning or even an error from the backend, it might looks messy. Additional option - we can silently ignore long-calls in the backend if no +noabicalls feature flag is provided. Like we ignore long-calls in case of PIC.
- Handle jumps to 64-bit symbols in case of long-calls option
- Ignore long-calls option if abi calls is used
Warning generation in case of mixed usage of -mlong-calls and -mabicalls options will be implemented in the Clang by a separate commit.
LGTM with slight tweak and addition to test cases.
test/CodeGen/Mips/long-calls.ll | ||
---|---|---|
9–12 ↗ | (On Diff #106534) | Add -target-abi n64 to the lines here, and add n32 runlines. |