Skip to content

[PPC][AIX] Local variable needing higher alignment shows r31 not saved with r30 as required by ABI #96411

Closed
@hubert-reinterpretcast

Description

@hubert-reinterpretcast

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions