<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/61898>61898</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Inline assembly with stack-pointer clobbers not handled as well as it could be -- easy fix
</td>
</tr>
<tr>
<th>Labels</th>
<td>
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
pskocik
</td>
</tr>
</table>
<pre>
Although GCC complains about stack pointer clobbers from inline assembly (declares to have deprecated them), it actually supports them better than clang by:
- forcing a frame pointer
- avoiding the redzone
- restoring the stack pointer based on the frame pointer
This allows stack-allocating inline assembly to work (and stackfreeing inline assembly: as long as just allocated stack space is freed and spills made by the compiler aren't jeopardized) in addition to making inline assembly such as "pushf; pop ..." harmless inside of code that might otherwise want to store a local in the first slot of the red zone (see https://godbolt.org/z/rv3aoK3x8 where gcc has correct codegen but clang doesn't (based on https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108799 by listing the rsp in clobbers)).
I think for clang, this would be an easy fix: simply treat frames with opaque stack pointer adjustments as if they had variably-sized objects:
```
diff --git a/llvm/include/llvm/CodeGen/MachineFrameInfo.h b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
index 7d11d63d4..5cc2045e4 100644
--- a/llvm/include/llvm/CodeGen/MachineFrameInfo.h
+++ b/llvm/include/llvm/CodeGen/MachineFrameInfo.h
@@ -352,7 +352,7 @@ public:
/// This method may be called any time after instruction
/// selection is complete to determine if the stack frame for this function
/// contains any variable sized objects.
- bool hasVarSizedObjects() const { return HasVarSizedObjects; }
+ bool hasVarSizedObjects() const { return HasVarSizedObjects || HasOpaqueSPAdjustment; }
```
This simple change makes the above-listed `pushf;pop ...` code example no longer crash in addition to making code like:
```
void push(void){ __asm volatile("push $0;" ::: "rsp"); }
void loopy(void){
long register rsp __asm("rsp");
void *savedSp; __asm ("mov %1, %0\n" : "=rm"(savedSp): "r"(rsp) );
for(int i=0;i<3;i++){
__asm volatile("push $0;" ::: "rsp");
__asm volatile("push $0;" ::: "rsp");
asm volatile ("mov %1, %0\n" : "=r"(rsp) : "r"(savedSp));
}
}
```
no longer crash (at least with optimization at at least -O1 -- the rsp reading assembly at the start of loopy() actually crashes at -O0 on clang (not gcc) due to https://github.com/llvm/llvm-project/issues/61897).
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy0Vl1v4zoO_TXKC5HAlfPhPOShTZG7g8ViFpjFvg5oibE1lSWvJCeT_voFZSdtemeAxczewnCTSDqkyMNDYoymcUQ7sXoSq-cZDqn1YdfHF6_My6z2-rJ7tKn1Q9PCH_s9KN_1Fo2LgLUfEsSE6gV6b1yiAMr6uqYQ4Rh8B8ZZ4wgwRupqewEhK03KYqAIyUOLJwJNfSCFiTSkljoht0LuwSRAlQa09gJx6HsfUszrUFNiQ6lFB8qia6C-iPJRFM-imN5zOPqgjGsA4Riwo6t712U8eaN5PbUEgfSrd3RdCxSTD9fF-9vVGEmDd3npB8jj-1-tiYDW-nMcz8_5i8LEoB9DkjycfXjh0KDT4_5jIPrBXlE-Akawni8W4dsQE0zINJ2E2KMiMBx_Ig0ZsjfWRuhQE9SX7Drn0FgKgIGckJsE38j3GLR5JS3kFsA4QK1NMnxZDx2-_Mj5OKiWXRFS9kNsj6J8gt73sFgshJTQYugsxQjGRaMJ_BGU18S5S9CZpk3gU0vhbCLBGV1iUxx9AgS-l2U_cqxNiAmi9YlBpqwBp40DF4mgTamPzAN5EPLQeF17mxY-NEIeXoU8hFOJ_u_l9wrOLQWCRiloMYLyIZBK2bGGHNRDmmilPcUxOEJWt8x_NKTUonHDZKgemldjLQp5iK0_f62HZqEaI8qD0aJ8fiiqzXbLSbAmphv_Ys_XvFZOLoDt4j2hPkFqjXthVo--cYUkZtnZD1ZDTYAOCOMFjuY70ySarmdyBcI0EjXC2aQWfI__GT7SGjVzqSOXImfT5AhfoEUNJwwGa3uZR6YG-PobqRTf6m1dTE_-qs3xCPN5w9Ur5MHaUyfkwThlB01vP-y9pj-YeId_oGqNowN7-Mkd_aKF-hcPjh4Yp-k7bPTDg16XerlYrJSSxXJFS3goivVyOZX5fP7LHk43l0_j85sOi2UhlgXMy5UUcr8BIZ9uH8elfqitUbeQA8BIPSEPkKWmo9R6DR1emAkKrc2Vf4FkOgI8coqNiykMiut5gnkDiWQpr7BuZHmnRFyKmhKFjit-pMREm1H4mIyZg8fBvcd9757yLo2twl2uVCK4o9LiqrtQe2-5JP-N4Qvv-DxxTVasSMq7mEBsniBQGoKDv_15Z_kEYvN8y8__ARLEZi82e175nCvnyz8fb8Vyb---EnJichUSqBZdQ6yhlHsYN84TzVkDSINYF1ftvErnuhh1kr5jBnA-iz6314Cx_Yk45yPWvNDPqnN8c-sDtihkxZ9ZbzZP8PUrxg5O3mIylnKEsqaDkMtClE-s5wycHxb8EHshJZ9-H4aMbr3vL3fwN26M3StQw5cPWfuy5dHge8zpSAYU8jHiifSXno2Nro4nOn8CIVcPrIhCrgqx2rvJVXZSlM-hy5DVFYDBxwuMv2ebW7gzCsD0FrIyLoER5TNHwIhyX-b_U-nfX4z_fiuIfxnUe6D_PWz30bkL2btQvjf3Vgs_KYqPPOaZJ4EljOnanZLpzCtmZmOC2-r88wPM57d2GQjz-HYbRDBd9SnkCeHKQPb9NkdmoxR58_xzwc18bPRCVs4nngh4ux6y9n1o8ya1Q71QvnvTdv4374NnoWDtj3GgKORh_VBtN9zCYaZ3pd6WW5zR7mFdFUspl3I9a3daFVRs1xupilJtVsu6WhWbukIsSrkpN5uZ2clClsWykEVVFHK92CJW9eq4rrfVsSzXKJYFdWjsgr3g6WOW7e_YeDWzWJON15E-7LKr9dBEsSxYduLbsWSSpd2nD4NdzsY4u_5psudYteh07jIRzmRtnhp4hpqmkfn8No3MhmB3vxfM6r8BAAD___Ij_uY">