<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/96411>96411</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            [PPC][AIX] Local variable needing higher alignment shows r31 not saved with r30 as required by ABI
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            backend:PowerPC
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          hubert-reinterpretcast
      </td>
    </tr>
</table>

<pre>
    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>`):
```cpp
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
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysVt2P2zYM_2uUF8KGLX8kechDPprtgA47rMVW7KWQJcbWTpE8fTjp_vpBdi6XtLcOBzQIElv8kfyRoigy52SrEVek2pBqN2PBd8auutCg9YlFqT3a3qLnzPlZY8SX1R8damCgDGcKBmYlaxSCxb-DtOiAKdnqI2oPnWw7tOA7piGvCd3CVjHdErp___73X4D1PTLrwBsIDoHUmS0yUmdxoTNKgO8QnGf8CXoz8gCjAbW3XyIkSg9Bcy-NTkm2I9l6-l07YMCZUoiJYwMKsNhK59FGClFtYCogmMONT-lgxJJiA5054fCCXj98gvXm4SVC3zF_74DQBUufUpYCoVQbnQxGMS8VEkoJXV4JOGAWJ0dwsOY4pcj5GI8yJ3Q-Oj0i01K3k5-RYh4pus4EJYApZ6C5WEnhYzc9XsMZscKgA238JcnRfoMgjMbI9SR9B6b38ij_YTF_gDpuoohcmXuOVNylddz2MR8xF0FhzNkgY6BR8bXMjlQ409E3N9aG3qMAEWyM7t3PEPRJaiF1e-eI0GL6wgcTLB8ZkzojxdZ5ITUp3sU3uiTFs0KdTV_e99OK8zZwD2sg8w3wjlk4T3XJHKGLgo7aGyDzHSk2t74HIwW0hC7GB0LXE_JGeIhs6DJanlYB1sCuGBi1Ca3ZrWZ0dE_19YC35thLhRakHgwft-bbKKdXPh2lDaEbSBLPbIueFLvenND2vC4T2RwTJs-Q_ArJpxENiZAu7nOi1HBMeuYcOkg-QGIggeTMn829jasJvg8-7lLPrJdMvbo302v6-c_8MLxIaQGEVk2TZtc1uHyOB2Uhu19zXkCRxWJLYkNZ5NHVvZad_idU_q36tP66MldWCQkXTPypvkK40BwknwAXHkv6jZNwnrTzCXYnZkJIKK7SnC7u5Y2CmKT2cSDV5vE3Uu3u5dr0r0c8miu-8qa-H7D633T6m01olH1bZQxoXewuUh_M5RTfle3wXwf5psSvRvJlmqVZK8dK67zvXdSje0L3rfRdaFJujoTuY21f_pLemr-Q-zRqLXPRzJkQtZhTUeY5qzKeizmtK5yLPK9EjSVbLOg1Bx8vZ2oN50X9uS6ToJ-0OelESR3OSavDBddZZAKORqCK6N44eZ5ED9r5eE-InbRRROje9J7Q_Ylp0ZgzofsxyKRDJgjdN1JPinsTtIitU0jBPMJP2y3IydhzV4jGgrMxVNnEJHBO6P5C9YUi3efZj7d5SdEHVMhjT_8R_LZXZsegvIxaxRrS2ETL7FiXX7n8HuhaSDOxKsSyWLIZrvJ5vsyWy6LKZ92q5AWfl3R-KBaiKSucV4zN85Jl87pczJtmJlc0o2VWU0qLoqrytMSK5_VBLA8VKxZ5ScoMj0yqNFZaamw7k84FXC3rMs9nijWo3DhVUdow_oRakGL9GNvz4zaOBdVuZldjlTahdaTMlHTevVjz0qtxLHt83MYuUG3WD59ItYP394OXRoxX6PO09TJ-uc6cHNgiHweBaegYb35bZLe3PDRf4p0-C1at3nauCN2PMbtYEWPYw4r-GwAA__8E1fnX">