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

    <tr>
        <th>Summary</th>
        <td>
            AArch64 GlobalISel bug with byval Arguments
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            backend:AArch64,
            globalisel
      </td>
    </tr>

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

    <tr>
      <th>Reporter</th>
      <td>
          lenary
      </td>
    </tr>
</table>

<pre>
    Related to #62137, the same issue comes up with GlobalISel:

If you run `llvm/test/CodeGen/Generic/2010-11-04-BigByval.ll` through llc with the default target set to `aarch64`, and globalisel enabled, then you get an error when EXPENSIVE_CHECKS is enabled.

The difference here is that the `AArch64::ADJCALLSTACKDOWN` and `AArch64::ADJCALLSTACKUP` instructions (which also represent moving the `sp` for the call) also cannot be nested, and the `memcpy` for a large byval argument is inserted by target-independent code, as far as I can see. In this case, AArch64CallLowering inserts the call stack adjustments, and then a `G_MEMCPY` is inserted by `CallLowering::ValueHandler::copyArgumentMemory` (which is in `llvm/lib/CodeGen/GlobalISel/CallLowering.cpp` and therefore target-independent). Later, the `G_MEMCPY` will be legalised to become a libcall, which ends up nesting the ADJCALLSTACKDOWN/UP instructions, which is invalid. 

I'm less sure of what the fix is here, given the fact that, unlike in ISelLowering (which has a very long target-specific function to handle lowering arguments), globalisel mixes a lot more target-independent code and structure into the process, making it not very easy to work out where the fix could be applied with the current structure. I wonder if the fix might possibly come from a few other approaches:
- Maybe a pre-globalisel LLVM IR pass to turn `byval` arguments into copies and pointer arguments, before we build any Machine IR.
- Maybe for simple function calls, like memcpy, which don't need to move `sp`, `ADJCALLSTACKDOWN`/`ADJCALLSTACKUP` don't need to be emitted at all, which would prevent the inner nesting?
- Maybe legalisation to a libcall should know when it's in a `ADJCALLSTACKDOWN`/`ADJCALLSTACKUP` sequence and try to hoist the inserted call before the region? This is difficult/dangerous because any reads of `sp` inside the region are not necessarily the same as reads of `sp` outside the region.
- Maybe there's a nicer way to handle `byval` arguments in the target-independent globalisel code?
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyUVl1z27gO_TX0CyYemXLk-MEPrhOnvk16M03be_epQ1GQxIYitfyw63-_A8pfSbM7sy_JjEwCB8A5BxTeq8YgLtj1B3Z9OxIxtNYtNBrh9qPSVvvFF9QiYAXBAuN5wSf5jPEVhBbBiw5BeR8RpO3QQ-xhp0IL99qWQm-eUbN8ybJblh3-bmrY2wguGmBFpvW2Y3wd0AfG1ytb4T0axtf3aNApyfiaZ5PsajK5yqZXH1TzYb8Veqw1KzIIrbOxaUFrOeQkQBXWIuoAQbgGA3gMCXaRCeFkW0xZkRF2YSpoEkTlUQMaUWqsDlWZhJCuCwPonHWwo693_3-6-_y8-X73Y_XxbvXpGZQ_3hxflviVcKi6RodGIrToqEcQWhESRlZky-WAJl-yfLm8_c9q-fDw_HW5-nT73_99puII4D-d-_ZEp5TxwUUZlDUeGL_ZtUq2ILS34LB36NEE6OxWmeaY2fd0sbYufZBCa8bnwxUpjLEBSgSDPgztIByHmx12st8fbwvQ1GIoaSIgXBM7SqY8gUJHfCn3hzFcKVNhj6aiE9JWmCJ7qIWjfxvKDB5xDBsDoVUepPDp0KH-ldD6we7QUSFDfH_CDz4I-QKi-hl9IBD-ArgBQdjvfzzePa6e_khNew2RFdll-KHV34WO-FGYSqMbvkjb75eHKh-xsy514tTzFPSC0VqVrwl91gNfX-Yby74_DjwQVWrr8J2-MT4fw4MI6I7ae1PWTmlNs9PYJFYnvZZIsqRhqXKY9QoGwGiqpFYa9ZEevxGRr789vSLZ-X4qeCu0qsbwSt-MzzrQ6D346BBsDbsj8Wv1i-5RlRSoUVs0ww9ChqQP-hyNVi9I7aR2ncZ-anUrPAjYotuDtoR86JXvUapaSaijSWCp_jaNEPQxyJGnnvF5gnD2gE79QgqsLUnm3Rkk7qZJDR2h-pQJNtXQOyvRpw514iURNQDpKSFF4fcEaGfdC9gYyFEox6Er0kZd0fRE32uF1dnQZHSOUp8yjmEDO2sqdKDqU4BONW2A3nqvSr1PZgy1sx0IqHEHlqhFwZ0VskV_MuUreBR7ygu9w6uLdjw8fH-EzRfohfcEPESX-J30ngh7bOXQAml7Rf0zFfRWmUDpzs1eQTkQe4dQRqUrEGYPj0K2yiBsvoxfoyGD8arrNZ6nSfRNkRI7DmZ0omNlDeOzAAYH4nd2e7Y7OkZm-rvPMr5-88NgrG_DlQjYqUCWIQK8EtIuja53uKUx0TyUMeiOwmL5-nVtB32KI0VP2gTfplAvxu6GhaMC47NkLOJf4vf4Z0zLJ9mKS9RrrfJHgAf7S2kPk6EfHDbKGpav4Su5sPJpjykZNa3nSpgGnY2ebEVEj2mIDkXlSean5aKMV9VlQBAOkxQMkkSEU3p_fj4I_04MG8ObIG8oEgYXmZFkjZLoYCf2F5L_O6qmiO9I-4L6aUPl61G1yKt5PhcjXEyKm8n0JptcF6N2Mc9mk7qYziY1z4uSy2mBAmWd5TdFNpPzYqQWPON5Np1MJ_l0PinGIkc5lbxGOc-qbDpj0ww7oegls-3G1jWj9IZa0NvqZqRFidqnBxnnpZAvaCpa_4e3AOeMrxjnZ8T06fp25BYU7qqMjWfTTCsf_DlBUEHj4hDj4nkGZWwGtxk2-XHH-VF0etGG0Cez4GvG140KbSzH0qYNd1h0lLJ39idK4kiqwzO-TqX8FQAA__-RPnf7">