This patch does the following:
- Fix FIXME on needsStackRealignment: it is now shared between multiple targets, implemented in TargetRegisterInfo, and isn't virtual anymore. This will break out-of-tree targets, silently if they used virtual and with a build error if they used override.
- Factor out canRealignStack as a virtual function on TargetRegisterInfo, by default only looks for the no-realign-stack function attribute.
Multiple targets duplicated the same needsStackRealignment code:
- Aarch64.
- ARM.
- Mips almost: had extra DEBUG diagnostic, which the default implementation now has.
- PowerPC.
- WebAssembly.
- x86 almost: has an extra -force-align-stack option, which the default implementation now has.
The default implementation of needsStackRealignment used to just return false. My current patch changes the behavior by simply using the above shared behavior. This affects:
- AMDGPU
- BPF
- CppBackend
- MSP430
- NVPTX
- Sparc
- SystemZ
- XCore
- Out-of-tree targets
This is a breaking change! make check passes.
The only implementation of the virtual function (besides the slight different in x86) was Hexagon (which did MF.getFrameInfo()->getMaxAlignment() > 8), and potentially some out-of-tree targets. Hexagon now uses the default implementation.
needsStackRealignment was being overwritten in <Target>GenRegisterInfo.inc, to return false as the default also did. That was odd and is now gone.
I'm not sure this diagnostic makes sense: x86, ARM and MIPS implement canRealignStack, and a few places in the codebase check needsStackRealignment as one of a few conditions which are supposed to be commutable (in a chain of logical ors), or as a condition in a chain of logical ands where the call to canRealignStack was hoisted to be done unconditionally. When this happens, the code assumes that calling needsStackRealignment on invalid functions will just return false and the other checks will handle things. Adding report_fatal_error to canRealignStack breaks that assumption.
I wrote a patch (attached) which tries to fix all of these assumptions, but the code still fails on all the same tests. For example, ARM's hasFP check eventually ends up calling canRealignStack to decide whether getFrameRegister should return FP or SP. The basic situation seems to be sensible (if you can't realign the stack then your frame register is the stack pointer), but making this warning a hard-failure breaks the code.
Similar situations occur for other tests.
I think the right thing to do here is to remove this diagnostic: in some cases it makes sense, but only the (sometimes indirect) caller of needsStackRealignment knows whether that's the case or not. We could instead add an isFatal parameter, but that seems icky because the caller can be indirect (e.g. the previous hasFP example).
Turning this into report_fatal_error makes the following tests fail: