<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/149808>149808</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Wrong stack adjustments around __tls_get_addr on SPARC
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
rorth
</td>
</tr>
</table>
<pre>
On 64-bit Solaris/SPARC, several `libomp` testcases `FAIL` apparently randomly. The failure mode is always the same: the tests `SEGV` like this:
```
Thread 58 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 56 (LWP 56)]
0xffffffff7edcba04 in mmap () from /lib/64/libc.so.1
(gdb)
(gdb)
(gdb) bt
#0 0xffffffff7edcba04 in mmap () from /lib/64/libc.so.1
#1 0xffffffff7edae65c in lmalloc () from /lib/64/libc.so.1
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) display/i $pc
1: x/i $pc
=> 0xffffffff7edcba04 <mmap+16>: bcs 0xffffffff7ecc8230 <_cerror>
0xffffffff7edcba08 <mmap+20>: nop
```
This happens both in `Release` and `Debug` builds, but not in a 1-stage build with `gcc-14`.
It has turned out that `clang` has a bug with thread-local storage: in `libomp.so` there's
```
c56b4: 9c 03 bf ff add %sp, -1, %sp
c56b8: 33 00 00 01 sethi %hi(0x400), %i1
c56bc: b2 06 62 c0 add %i1, 0x2c0, %i1 ! 6c0 <_DYNAMIC+0x5a0>
c56c0: 90 06 80 19 add %i2, %i1, %o0
c56c4: 40 04 9f bf call 1ed5c0 <__tls_get_addr@plt>
c56c8: 01 00 00 00 nop
c56cc: 9c 03 a0 01 inc %sp
```
which creates an unaligned stack. While Solaris `__tls_get_addr` in `libc` doesn't use `%sp` itself, it calls into `slow_tls_get_addr` which does, and also sometimes calls `lmalloc`. The stack corruption also causes the broken backtrace above, which made investigating this difficult.
This is not an issue on Linux/sparc64 where `__tls_get_addr` lives in `ld-linux.so.2` and doesn't use `%sp` at all.
Similarly, all other `call`s in `__kmp_launch_worker` are also wrapped in similar stack adjustments. However, those don't create unaligned stacks, e.g.
```
c5754: 40 04 9e c3 call 1ed260 <__kmp_str_buf_print@plt>
c5758: 94 10 00 19 mov %i1, %o2
c575c: f8 5f 00 00 ldx [ %i4 ], %i4
c5760: 02 cf 00 07 brz %i4, c577c <_ZL19__kmp_launch_workerPv+0x128>
c5764: 9c 03 a0 30 add %sp, 0x30, %sp
```
but always are by 48 bytes.
When building `libomp` with `gcc`, however, none of these adjustments occur, and neither do the `SEGV`s.
I could trace the 1-byte adjustments to `llvm/lib/Target/Sparc/SparcISelLowering.cpp` (`SparcTargetLowering::LowerGlobalTLSAddress`), which has
```
Chain = DAG.getCALLSEQ_START(Chain, 1, 0, DL);
```
changing that to `... (Chain, 0, 0, DL)`, there aren't any 1-byte adjustments any longer and all supported `libomp` tests `PASS`.
However, those stack adjustments remain, but are clearly unnecessary. I could trace them all the way back to
```
commit cb1dca602c436c80c6923e106c9a9d8fc2353e8c
Author: Venkatraman Govindaraju <venkatra@cs.wisc.edu>
Date: Sun Sep 22 06:48:52 2013 +0000
[Sparc] Add support for TLS in sparc.
```
but could not patch submission other than the actual commit, so there's no justification whatsoever. My knowledge of the backend is practically non-existant, so I'm at a loss how to get rid of those adjustments.
@koachan Any suggestions?
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysV11v47oR_TXMyyAGRX1YevCDk2y2AXLb7Tq4i_YloChK4oYiBZKy4_76Yig5dj4u0IcagWNKnOHwzJwzJPdedUbKDclvSH53xafQW7dx1oX-qrbNcfMPA0V2XasAO6u5U56w-92P7c9bwm7By710XAMpqFa1HUZSUAjSB8G99Pj4fvvwiA_5OHInTdBHcNw0dtDHFcBTL6HlSk9OwmAbCcoD1wd-9BB6CZ4PkqTb-Bu9Ro-7b9__RI9avUgIvfIk3RK6JQVd_uj2qXeSN5CX4KSQai8bwG1yDbuH79Ge3cJOdoM0gQdlDbR80mGFbvKb3UEF0SvTQbBwclUAYeXjrx-QF4RVJL8jdEtf2-Wzlo2oOc1AGRgGPuJkwiponR2AsHutasLui2z-KVberhJcjJVdU-PEvx7UIQ5TCv-H5dIE3rvhssgFutED19qK_9HTDRcvwXEhwQc7jrLBLI1O7pWdPLSODxKUMdIhhJij5RlhpbDOTWMAH7h4Iek9onm530b5UfMjYfcKCMtGQeg2Qfev7x6R9I6k377ChKS3iAlhN0lB0m-xOqpa-Pc7F6JETEl6-yykc9bhVLr97LC8cMjom0NjR_hUdcpDz8dRGg-1DT3iSgr6U2rJvYwsMA0-uZP11OG4npRuPFZjPQUwNqAJh-TaB97J-TUcVOjRqhPiOslIQWOd0u1DgJ57CJMzsgE7BQg9DzhTaG6if3zPoZ662UmIxXytreAaM-d4F_k1xzkzeOVtJHEvnSRs7T9sEgBEXtQZms2fSgBNoW6hbeOYNw0AYbkfcV_XCX7PwzfrEq3TFCiNf0m08zL0Klr2irCSvmaUYnHM5io5m4vz4jUDWkDBQNC3hVVckr4yQd-McS5hCRRizvndv_6-_ePhlrAb-ppzuiQ_uhf0Ym8U3ZcUkursnp1Dmn_YMzDiApiMAs2gahEb_AiuNUAim3wJ4jlo_9zJ8MybxpGMjjq8C6Q8-6LJCSwax0v5LRMjIHMe-Bueygh4A_4yhYdeiR6EkzxID9zAZLjGLtDMpFwB_OqVlifBx9r4EGtBzzUjcNRY6Q1h6wCTl_hiXhjnBS91i0ipECHwoEywOMdre_jkd44O_aENEoZrb8HbQQY1SL_4wLVnyUJCzJ0kRg-LwKCqR0vBJ-xF2ENqZ1-kgfpNvXht9xLXmVcdOLYgs5c-qI6H2AKQ1I1qWyVOHWJhuvKRsNyA8n6SYA08KjOhTPmRO1FkcEASfQ2fVnvpTyA21xotUV3ZSSb-GlEegGu9hLJTg9Lc6WNES2uwyNwoAlxrBHlZ5Pn5ZRifNZ-M6J8P1r3IGAd3cobp4FC5GpztZ58Lnrz5PfmArdKvAP5mD9jzcbXQWy-hsXOUcz19rKWYRLnqVl_JyDr_zBYJIn3PFlYsbMH4fXDP9dQ-j06Z8Iky6_yCMlUGSeRLUsXxYPfwnrYM7dDqQlDaEvL2gmi6eQUg-U20zAAb_8L-7G3V4kIxKAMx26-hdv-BZSq7xYlrEXfy78ek-iIdP_ZRjhJWXm6p-CS1nEJKv5Ba-prSS7G9xBvby3KwwozXR8hKqI9B-qWOfvVIDOw3WPXvznMX_SeW4S305yIw1kiwLdLLy8taASvE5E4cNlLFumxsJOL5GHda_wGEnXQDMy9xTnKN8b1zOcuG1vvh7WjyxF0nA55JkXOn_w87qR_tQTplupUY4zbwZFPQ-Ho2Ok3Ahp5u4-i7tjXXT4-7bdM46X3cb3UWiJ5_0Q_htufIsfQO7rbfV50Mt9vHx923fz7vnrY_nwgr4wT0Mncm_Lp7RMfpzQd3ouemm3WHh2W_q9UKLp3QD07mnMSGjcmd6cjN8SsE8bG2ppNukVYNfhpH64JsPp_io8z-2O5250PHJ_5_EglwclgijVXnJAgtUaJgMkYK6T13ePj_lPIhxoO5P_BjVGkI9iNAdhiwkdRJI3hBmcjSQpRUFBVLZUILUfGqKVvB0jyVJZ4Ut_FKgyT6U5oXHhwfuIHvdq9Mwx3_PSEn98srklHhVwflxUo208zDOx7kzMHdZGAnR2B46iDpNkO5yRkwmqSA5KWUzjDF80Z-MxdlfgfbpjkBDa118PS4i0qL7z9qI6I2I4P9ZeRB9OCnelDeY1ObBT703ESouAgT1zDjEu9k9nx4A2MBE6NaJeaLzqHnwVtM4QrgjyO8GHvQsulOJI6wS9NgexsdF0GhEB-R59fyVfnAzWmVB8LWQ-xGoK33qApYsZ0M4FQz-7PvRWEpIpLRF8ux1mFrjuCnrsOWa40n6f1Vs0mbKq34ldwk6zxNaFKx_KrfZKWgZVrIivGMpnldsbLhWUvbnK-LdVpeqQ2jLKdrliQsy1m-yhpWVVWSs7ZMWJq2JKNYm3qFErKyrruKrXuTZFVJyyvNa6l9vAozZuRhbuyEMbwZuw0aXddT50lGtfLBn90EFbTc_HLWdF8Qgjs7mQbeHwLwvBDv0VeT05s-hDFeZNk9YfedCv1Ur4SNOrfIHa4-OvtbCpS7GBrexZfY9xv23wAAAP__1X3EIw">