Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
hubert-reinterpretcast opened this issue Jun 22, 2024 · 2 comments · Fixed by #100182

Comments

@hubert-reinterpretcast
Copy link
Collaborator

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
@llvmbot
Copy link
Collaborator

llvmbot commented Jun 22, 2024

@llvm/issue-subscribers-backend-powerpc

Author: Hubert Tong (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 (&lt;stdin&gt;):

struct A { char x alignas(32); };

void g(void *);
void f() {
  A a;
  g(&amp;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

@chenzheng1030 chenzheng1030 self-assigned this Jun 24, 2024
@chenzheng1030 chenzheng1030 removed their assignment Jul 2, 2024
@syzaara syzaara self-assigned this Jul 15, 2024
@syzaara
Copy link
Contributor

syzaara commented Jul 23, 2024

Posted PR for review: #100182

@syzaara syzaara closed this as completed in d07f106 Aug 7, 2024
TIFitis pushed a commit that referenced this issue Aug 8, 2024
When the base pointer r30 is used to hold the stack pointer, r30 is
spilled in the prologue. On AIX registers are saved from highest to
lowest, so r31 also needs to be saved.

Fixes #96411
llvmbot pushed a commit to llvmbot/llvm-project that referenced this issue Aug 13, 2024
When the base pointer r30 is used to hold the stack pointer, r30 is
spilled in the prologue. On AIX registers are saved from highest to
lowest, so r31 also needs to be saved.

Fixes llvm#96411

(cherry picked from commit d07f106)
tru pushed a commit to llvmbot/llvm-project that referenced this issue Aug 15, 2024
When the base pointer r30 is used to hold the stack pointer, r30 is
spilled in the prologue. On AIX registers are saved from highest to
lowest, so r31 also needs to be saved.

Fixes llvm#96411

(cherry picked from commit d07f106)
kstoimenov pushed a commit to kstoimenov/llvm-project that referenced this issue Aug 15, 2024
When the base pointer r30 is used to hold the stack pointer, r30 is
spilled in the prologue. On AIX registers are saved from highest to
lowest, so r31 also needs to be saved.

Fixes llvm#96411
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants