<div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace"><font size="2">Hello,<br><br>So, I have this testcase:<br><br>    void f(int n, int x[]) {<br>      if (n < 0)<br>        return;<br><br>      int a[n];<br><br>      for (int i = 0; i < n; i++)<br>        a[i] = x[n - i - 1];<br><br>      for (int i = 0; i < n; i++)<br>        x[i] = a[i] + 1;<br>    }<br><br>that, compiled with -O1/-Os for AArch64 and X86, generates machine code, which<br>fails to properly restore the stack pointer upon function return.<br><br>The testcase allocates a VLA, thus clang generates calls to `llvm.stacksave` and<br>`llvm.stackrestore`. The latter call is lowered to `mov sp, x2`, however this<br>move does not affect decisions made by the shrink wrapping pass, as the<br>instruction does not use or define a callee-saved register.<br><br>The end effect is that placement of register save/restore code is such that<br>along a certain path, the callee-saved registers and the stack pointer are<br>restored, but then the stack pointer is overwritten with an incorrect value.<br><br>I've "fixed" this by modifying `ShrinkWrap::useOrDefCSROrFI` to explicitly check<br>for the stack pointer register (using<br>`TLI.<wbr>getStackPointerRegisterToSaveR<wbr>estore`) and also to ignore tall call<br>instructions (`isCall() && isReturn()`), since they implictly use SP (for<br>AArch{32,64} at least).<br><br>Does this look correct? Are there alternatives?<br><br>Shouldn't `ShrinkWrap::useOrDefCSROrFI` also check whether or not<br>`MachineInstr::Frame{Setup,<wbr>Destroy}` flags are set?<br><br>In that case, I suppose an alternative slution would be to ensure that<br>`llvm.{stacksave,stackrestore} are ultimately lowered to `MachineInstr`s, which<br>have these flags set, perhaps by custom lowering of<br>ISD::{STACKSAVE,STACKRESTORE} to pseudo-instructions? That'd involve changes to<br>each backend, where shrink wrapping is enabled, although it looks least hackish.<br><br>Comments?<br><br>Thanks and best regards,<br>Momchil Velikov<br><br><br></font></div></div>