Closed
Description
When a local variable requires alignment higher than 16, Clang/LLVM appears to use r30
to hold the stack pointer on entry to the function.
As a callee-saved register, the value of r30
is saved; however, the AIX ABI requires that callee-saved (a.k.a. "non-volatile") registers are saved from highest to lowest, meaning that r31
should also be saved. The save of r31
does not appear to be done (with optimization enabled) as required.
When the ABI rule is violated, the value of r31
can be corrupted during EH unwinding.
Source (<stdin>
):
struct A { char x alignas(32); };
void g(void *);
void f() {
A a;
g(&a);
}
Compiler invocation:
clang++ --target=powerpc64-ibm-aix -O -Xclang -disable-llvm-passes -S -o - -xc++ -
Compiler output (partial):
._Z1fv:
# %bb.0:
mflr 0
std 30, -16(1)
mr 30, 1
std 0, 16(1)
clrldi 0, 1, 59
subfic 0, 0, -192
stdux 1, 1, 0
addi 3, 1, 128
bl ._Z1gPv[PR]
nop
mr 1, 30
ld 0, 16(1)
ld 30, -16(1)
mtlr 0
blr
Compiler version info (clang++ -v
):
clang version 19.0.0git (https://github.com/llvm/llvm-project.git 91db7add6d72d411a50c1d7265e7d115d6e4a882)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /opt/wandbox/clang-head/bin
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Candidate multilib: .;@m64
Selected multilib: .;@m64