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

    <tr>
        <th>Summary</th>
        <td>
            Misoptimization (possibly in MemCpyOpt) results in no output
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            llvm:optimizations
      </td>
    </tr>

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

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

<pre>
    The following test case produces no output at O2 when "B" is expected. We've bisected this issue to commit f5446b769a7929806f72256fccd4826d66502e59:

```
  commit f5446b769a7929806f72256fccd4826d66502e59
  Author: Olle Fredriksson [fredriksson.olle@gmail.com](mailto:fredriksson.olle@gmail.com)
  Date:   Wed Apr 21 22:48:28 2021 +0200

      [MemCpyOpt] Allow variable lengths in memcpy optimizer

      This makes the memcpy-memcpy and memcpy-memset optimizations work for
      variable sizes as long as they are equal, relaxing the old restriction
      that they are constant integers. If they're not equal, the old
      requirement that they are constant integers with certain size
      restrictions is used.

      The implementation works by pushing the length tests further down in the
      code, which reveals some places where it's enough that the lengths are
      equal (but not necessarily constant).

      Differential Revision: https://reviews.llvm.org/D100870
```

Steps to reproduce:

```
$ cat test.cpp
#include <string.h>
#include <stdio.h>

void testcase(const char *path, char *name)
{
  if (name)
  {
    *name = 0;
  }
  char tmp[260];
  int pos = (int)strlen(path) - 1;
  int pos2 = sizeof(tmp) - 1;
  bool loop = true;
  while (pos >= 0 && pos2 >= 0 && loop)
  {
    switch (path[pos])
    {
      case '\\':
      case '/':
        memcpy(name, tmp + pos2 + 1, sizeof(tmp) - pos2 - 1);
        name[sizeof(tmp) - pos2 - 1] = 0;
        loop = false;
        break;
      default:
        tmp[pos2--] = path[pos--];
        break;
    }
  }
}
int main(void)
{
  char name[260];
  testcase("A/B", name);
  printf("%s\n", name);

  return 1;
}
$ clang -O2 test.cpp
$ ./a.out # "B" is the expected output

$ clang -O1 test.cpp
$ ./a.out
B
$
```

A couple of things I noticed:

  1. Moving tmp to global scope seems to workaround this issue.

  2. A zero length memcpy is possible, if the input begins with a "/".

Thanks in advance for any help on this.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJyVVktv4zYQ_jXyZRBDpvw8-GDHG2APiwXaBXqmpJHFRhJVkrI3_fX9SFuyHGfT1lAUkUPO45tnqvO37Y-SqdBVpc-qOZJj6yiTlqk1Ou8yttRo0p1rO0fS0XdB55IbioTY44-UJf7ZcuY4n9IfHInViSlVNuyQK0FX1nZMTlOm61o5Khbz-TJdLTdytRGbdbwsVkIslkWW5fO1WObL5SIWvNhEyS6KD1Hcv5fx9QlL-t_srtd2nSu1AXP6XlVML4Zzo16t1TBqsS9uyylA4WgeH2upqimkRYtDJNZ-5TTuf3pUDPIO0rGXRoAnp11rSMxICGzN13iJNYkYO5HYxyKOxxZT-EGpb1w_t2_fWwcNaOddRSdplEyhf8XN0ZVAuaGa66x9I906Vau_2Tzy-uH9UctXeNXB7ZcLT9d7sslHO5Zdz0k6pRtLZ21eESlmzHBQw0KgJWmp0ogiGfiDpWHivzpZReKZDFfyZ4gxiNZVjg3rjMo89zFPVyLOhusZRDvZOBjo-MjGTulrEciINdAb7W4irpzH3AyIynDNjfs3znRWrqSMjZNA01t0z2jQ1sc0dRYh_xHETKpuqyAxIBeAs5S-UdvZsgfg4reQb5aKzmDPUK7PjfckFmOemc7Zm3cuVVZCkRPLypLVNbK0kj5HkZOwSDlggoRsdHcsB2uHEIHRY64BNcTdOkVqexgbBisLj1ZvAzgI5A-MPKiigMDGKXD4jU_Keh8iyEvnWusTV7zggaaKz3ZaVad6qs0RW4dZHK9X8YcpfXn_7ri1vlwYvpagzwtBJOYoWC4gOc3att9NVJNVXc4UJc_ec81xWkbJl4_JudJjaniftMoDV18OAVOAhLJSGoC2a6UrvU_6dSNrHrI-Wu17uFThIb6jIqdvdOovQ5EDxVGyvx06DKXOC3F1i1ogYDfq0O0YopdabcN1SFLBZzAYXsfyouaGnmj2eEeESz7QdYGzXsDD0VTrCkmt23DWmY5HRAQkct-LCQp8CSZgvcTTC7jf9Jx-BYRF_iG-e60Xe3AINXczAmt8gS6dCkEfLZ79g49k9yHdx-N7Il3L3eCfZ4-xr8RX3fEx87uPCAW6Bwq6Jft7poHXYv_JJVTx986-_AacCyQ4P5BTw_L13W7Ohewq92DaJVq8yKenXuAN1rD3H_iPYnD4HD58FKHh-TDzufJR9IfAvQLyELmj3MIo4WuGHyk84H263M62SGBXXE5GYoG4eG5-cbi_Yth1phkF880CXzIqiUr8hHnmfeGY0xSqyCmGHoRAMh51fDXtx53rUHRXmUZ8Z5_xvWztB8on5XCHUtyhnZD2XQ9VzNJXX61Vxvm7wkg0m9I3fQotBoGMGnqsdIoSbTPdokcz2rrf9Q1JGt014wntXZkXU9oRhgjdd6rrlIDjiB-r0PQ9-Cr0YhQUPx-mfFTNtY1KCu5B2ok7zj9K2byGcUXmJ9lkfvg0mD3eqOSqJd0ElaaTfJvkm2QjJ065irfflB1PI9ea49V487xuExIyDZ0aGRFkDLPrpDPV9r47HaFml16mtRffoq7_ntB2_oSLsQzAWHws5su1mJTb1WaTy7nMNrxerdYJ52uR56nIC06S2XJdTCqZcmW3CHcYHpgmu7sxyqOyOEzUFlOfiHFLoCPONlMwXq3EfJYuYky0SYJpksM02TfPidkG7dLuaEGsFAaHG1ECi2PDHCSDvwxT7lab2ig7CXZsgxH_AIbdgm4">