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

    <tr>
        <th>Summary</th>
        <td>
            unexpected memcmp folding for sizes close to SIZE_MAX
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

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

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

<pre>
    Code in the `memcmp` folder copied below results in unexpected folding when the third argument to the call, `Len`, is close to `SIZE_MAX`(*).  When the multiplication by 8 overflows to a value that's less than the position of the first mismatched character in the two constant arrays the result of the call ends up folded to zero when nonzero is expected.
```
  // memcmp(S1,S2,N/8)==0 -> (*(intN_t*)S1 != *(intN_t*)S2)==0
  // TODO: The case where both inputs are constants does not need to be limited
  // to legal integers or equality comparison. See block below this.
  if (DL.isLegalInteger(Len * 8) && isOnlyUsedInZeroEqualityComparison(CI)) {
    IntegerType *IntType = IntegerType::get(CI->getContext(), Len * 8);
    unsigned PrefAlignment = DL.getPrefTypeAlignment(IntType);
    ...
```
A test case that reproduces this and that aborts at runtime is below.

[*] The text in the C standard suggests `memcmp` calls with `n` in excess of the sizes of the arrays are undefined but I'm fairly sure that's unintended.  In any case, the overflow can easily be prevented and the folder changed to behave consistently in all cases when the arrays differ in prior characters.
```
$ cat a.c && /build/llvm-clang-gcc/bin/clang -O2 -S -emit-llvm -o/dev/stdout a.c
void abort (void);
int memcmp (const void*, const void*, __SIZE_TYPE__);

const char a[] = "123456789", b[] = "123456780";

int main (void)
{
  if (memcmp (a, b, ~0LU / 8 + 2) == 0)
    abort ();
}
; ModuleID = 'a.c'
source_filename = "a.c"
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@a = dso_local local_unnamed_addr constant [10 x i8] c"123456789\00", align 1
@b = dso_local local_unnamed_addr constant [10 x i8] c"123456780\00", align 1

; Function Attrs: noreturn nounwind uwtable
define dso_local i32 @main() local_unnamed_addr #0 {
entry:
  tail call void @abort() #2
  unreachable
}

; Function Attrs: noreturn
declare dso_local void @abort() local_unnamed_addr #1

attributes #0 = { noreturn nounwind uwtable "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { noreturn "frame-pointer"="none" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #2 = { noreturn nounwind }

!llvm.module.flags = !{!0, !1}
!llvm.ident = !{!2}

!0 = !{i32 1, !"wchar_size", i32 4}
!1 = !{i32 7, !"uwtable", i32 2}
!2 = !{!"clang version 15.0.0 (https://github.com/llvm/llvm-project.git 6efda5e6d6531ced6e35ccb3f6499ca13b8edb60)"}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzlV0uP2zYQ_jX2hZAgUbZsH3zYV4AFkqbApujjYlAiZbORSJWPtd1f3xlSku3NtkiB3goYNMkZzovfDEeV5uftg-aCSEXcQZBZmXWiq7seJqTRLReG1LqXgpNKtPpIjLC-dRb5vRKnXtQOaMgp1Z4cDyLKcQdpOGFm7zuhHHE67NasbWf0AbV8FApGXEhL6lZbgUyw9fL829Pu090vgbqe0bsZ3aSE_DxK7kC97FtZMye1ItWZrIl-FaYB6yzKYOSVtR5NYG5GV5a0wlpcxfO9tjKc1E1YN9JYRzppO-bqA_hSH5hh4JUZY-KOGmKgrGPgCTOGnW3Yj6EY5aBvRChuie9j5Dha86cwOoZFaRUW4O8Yt3SWPc6yO3Q1_sKSkBn9AD8y3ARdv-QQqBcKww-wD0HZzIpH-GUkmRVPZIzTWir3w87FmL3ksJ8DE3mHRi8i3uj88vnx86y4I1-CS3ArYLsRpNLuAPHoPVw9g_UYD0u4FhZ8c0SJ6HElSCs7Ce69EQ20VuxZC3Kc2AtjiTZE_OFZK90ZJHY9M9JqlZIXARpbXX8dQAdosukoTTbo8OPHVNqPKO45SoM9wBQ6SzBAMCnhB9H-rNrzT1bwZ_UbhP9p0PcwqYODD88YDzy0uh_VEDII_nLuBYqFZZxCSK9IECz47YULcvA-YP6ggeHkwsVsEOTXps2KKyVeWblXELkfjWjuWpiHhEEl4CKIwn3UM9FA6GDKW1lp-j6g7ogTgPFwnZgVgNzeaO5rYUNoCVM8ElilDd4wsHjlZCcQreEORslxXN4jkJaPASbo6ZgrDwRhwRkkv_X7Pai1tzUF08SSowQ4wRJrAB4VpxqTdEglK_8U02JIOASdV1w0EoNVeUfgzlYdaZg07RmUmauM9wohBtw8xWsE_87Be7wJlDnWC9gE3cxKkACw7Y14hQCD_BgQMVVAKB77Ed0H9hrxLy3ocHAUHMDkRw32UgIHw7lsmlhLeiO1uZQX-_5lzegCJMFVpPWIYUieysuWw3_bvnZJ3YI5yb6ukSABwB_CDkk-U5K8kERA9iXISRINRC5eYbSOax_ERj2vWvJ435hOuLqGE8RvKD9IDdlOIs8dBvGbjd0u1O0vv_74tNtdC4pj5EfXCUPwAHJiZaI5LRbLcrWGLMH6Rqr3yRmSb2UGE5lU1-ZH8iWJY624OMKiCnyCVk_Zx58wtPB-zOg9oSH_Q00k2SQL02oK0o1fq8dhUtyTT5BMrXgerV5hkOkq0q32pha7RrZCsU6MjgUWGlkcvJPCEc4ca9kZb2lgEkkHtUUkPV1lMCloGHCZ3y5xVi7CkMhx0qzxUE7XiVrjpBzPAO0lR3du9TsD7-pk4Gld7oDRq69KH1XSSuVPyV756dQwLjIWjnCrd1CyobyHcecVust3jHNzeT7hdvOMnIhc4yXXNwBYPmTZgAKGxY7kk4rqP1GR_b2K6So_eFWH9uDOOWPxJVTaCOcNPuBeHSVUBn90rGpFPBRL0pVtsqAETEZoRsy8Z-2MFtnltYEyYs74kAyYc0y2saEIWYoxRgwO4uAsHTm9MoJBXk3mXHD5HS6NHkD5MNcuvKf1fSdu4sdAvoTSDFUw-odIWt3_fQQRZ40BgUmvsWKbkOWPMEKzBNWaIkMnAX340Cev0DRpkxwld4eJMxvYlE6cYX0PbWgCrdyFwRk_igKA1F8TePtclFR5rM0JvjcT-3rgjUmR1L2fSJASCSTXDb0RDFwTdmKCWlKfQMgDTJqTNXHWdac4seEVihMaZ6f1apQJLfWNxr1Qwsg6kMeLvY1y_m2Uvyeo_9No0X_A5NvMoTk-oWkXanvatGxvh9qYY-LSPHy9wH9-OTmckXzs4SZm-q347IoDi0Y-yAP7j_hU7sZI40cS0BfXevI3h1eXw2N5upyk1yfprWHAFrsH6IksVol8mWZphu_dwbke60Xs3_fQs_kqhT596EPGdgQQ8jsgJAUGUoqGs6Uoebks8lrwUhTLuq6KplxsNjXLi2oteFWGB5ZemTX2QHO-Lfim2LC5k64V26tvzOEVHz81G-ilYqM4fT2On45zb9rtvzMeltJaj8j8sFys1uX8sKVVtRGLsuaLTVGU5arKKa3KTVZWnJflspy3DFpjuw3dMFXiSIII9Gv5OJdbmkF1WmQlpctyQdOqLrJNTrN1uc42KwDEIhPwSLRpgIw2-7nZBpMqv7dAbKG_tBcis-FDQWxjgzRn3h202XZWQJGeB83bYPlfdi26dQ">