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

    <tr>
        <th>Summary</th>
        <td>
            SLPVectorizer replaces `add nsw undef` with `add poison`
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            miscompilation,
            llvm:SLPVectorizer,
            llvm:optimizations
      </td>
    </tr>

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

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

<pre>
    SLPVectorizer incorrectly replaces `add nsw undef` with `add poison`. However, `add nsw undef, 0` is undef, not poison, so the transformation is not correct.
Example:
```llvm
; Test: Transforms/SLPVectorizer/X86/vectorize-reorder-alt-shuffle.ll

define void @foo(ptr %c, ptr %d) {
%entry:
  %arrayidx1 = gep inbounds ptr %c, 1 x i64 4
  %0 = load i8, ptr %arrayidx1, align 1
  %conv2 = zext i8 %0 to i32
  %and = and i32 %conv2, 3
  %arrayidx4 = gep inbounds ptr %c, 1 x i64 1
  %1 = load i8, ptr %arrayidx4, align 1
  %conv5 = zext i8 %1 to i32
  %shl6 = shl nsw nuw i32 %conv5, 2
  %arrayidx12 = gep inbounds ptr %c, 1 x i64 2
  %2 = load i8, ptr %arrayidx12, align 1
  %conv13 = zext i8 %2 to i32
  %shl14 = shl nsw nuw i32 %conv13, 2
  %arrayidx17 = gep inbounds ptr %c, 1 x i64 3
  %3 = load i8, ptr %arrayidx17, align 1
  %conv18 = zext i8 %3 to i32
  %shl19 = shl nsw nuw i32 %conv18, 2
  %sub = add nsw i32 undef, %shl6
  %conv27 = sitofp i32 %sub to float, exceptions=ignore
  %div = fdiv float %conv27, undef, exceptions=ignore
  %add.ptr = gep inbounds ptr %d, 4 x i64 -1
  store float %div, ptr %add.ptr, align 4
  %sub32 = add nsw i32 undef, %and
  %conv33 = sitofp i32 %sub32 to float, exceptions=ignore
  %div36 = fdiv float %conv33, undef, exceptions=ignore
  %add.ptr37 = gep inbounds ptr %d, 4 x i64 -2
  store float %div36, ptr %add.ptr37, align 4

; HERE: add nsw undef
  %sub40 = add nsw i32 undef, %shl19

  %conv41 = sitofp i32 %sub40 to float, exceptions=ignore
  %div44 = fdiv float %conv41, undef, exceptions=ignore
  %add.ptr45 = gep inbounds ptr %d, 4 x i64 -3
  store float %div44, ptr %add.ptr45, align 4
  %sub48 = add nsw i32 undef, %shl14
  %conv49 = sitofp i32 %sub48 to float, exceptions=ignore
  %div52 = fdiv float %conv49, undef, exceptions=ignore
  %add.ptr53 = gep inbounds ptr %d, 4 x i64 -4
  store float %div52, ptr %add.ptr53, align 4
  ret void
}
=>
define void @foo(ptr %c, ptr %d) {
%entry:
  %arrayidx4 = gep inbounds ptr %c, 1 x i64 1
  %add.ptr53 = gep inbounds ptr %d, 4 x i64 -4
  %0 = bitcast ptr %arrayidx4 to ptr
  %1 = load <4 x i8>, ptr %0, align 1
  %2 = zext <4 x i8> %1 to <4 x i32>
  %3 = shl nsw nuw <4 x i32> %2, { 2, 2, 2, 3 }
  %4 = and <4 x i32> %2, { 2, 2, 2, 3 }
  %5 = shufflevector <4 x i32> %3, <4 x i32> %4, 1, 2, 7, 0

; And here we have add poison
  %6 = add nsw <4 x i32> poison, %5

  %7 = sitofp <4 x i32> %6 to <4 x float>, exceptions=ignore
  %8 = fdiv <4 x float> %7, poison, exceptions=ignore
  %9 = bitcast ptr %add.ptr53 to ptr
  store <4 x float> %8, ptr %9, align 4
  ret void
}
Transformation doesn't verify!
ERROR: Mismatch in memory

Example:
ptr %c = pointer(non-local, block_id=1, offset=2)
ptr %d = pointer(non-local, block_id=1, offset=32)

Source:
ptr %arrayidx1 = pointer(non-local, block_id=1, offset=6)
i8 %0 = #x00 (0)
i32 %conv2 = #x00000000 (0)
i32 %and = #x00000000 (0)
ptr %arrayidx4 = pointer(non-local, block_id=1, offset=3)
i8 %1 = poison
i32 %conv5 = poison
i32 %shl6 = poison
ptr %arrayidx12 = pointer(non-local, block_id=1, offset=4)
i8 %2 = poison
i32 %conv13 = poison
i32 %shl14 = poison
ptr %arrayidx17 = pointer(non-local, block_id=1, offset=5)
i8 %3 = #x00 (0)
i32 %conv18 = #x00000000 (0)
i32 %shl19 = #x00000000 (0)
i32 %sub = poison
float %conv27 = poison
float %div = poison
ptr %add.ptr = pointer(non-local, block_id=1, offset=28)
i32 %sub32 = #x00000000 (0)     [based on undef value]
float %conv33 = #x00000000 (+0.0)
float %div36 = NaN      [based on undef value]
ptr %add.ptr37 = pointer(non-local, block_id=1, offset=24)
i32 %sub40 = #x00000000 (0)     [based on undef value]
float %conv41 = #x00000000 (+0.0)
float %div44 = NaN      [based on undef value]
ptr %add.ptr45 = pointer(non-local, block_id=1, offset=20)
i32 %sub48 = poison
float %conv49 = poison
float %div52 = poison
ptr %add.ptr53 = pointer(non-local, block_id=1, offset=16)

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >       size: 0 align: 1        alloc type: 0
Block 1 >       size: 135       align: 256      alloc type: 0
Block 2 >       size: 254       align: 65536    alloc type: 0

Target:
ptr %arrayidx4 = pointer(non-local, block_id=1, offset=3)
ptr %add.ptr53 = pointer(non-local, block_id=1, offset=16)
ptr %0 = pointer(non-local, block_id=1, offset=3)
<4 x i8> %1 = < poison, poison, #x00 (0), #x00 (0) >
<4 x i32> %2 = < poison, poison, #x00000000 (0), #x00000000 (0) >
<4 x i32> %3 = < poison, poison, #x00000000 (0), #x00000000 (0) >
<4 x i32> %4 = < poison, poison, #x00000000 (0), #x00000000 (0) >
<4 x i32> %5 = < poison, #x00000000 (0), #x00000000 (0), poison >
<4 x i32> %6 = < poison, poison, poison, poison >
<4 x float> %7 = < poison, poison, poison, poison >
<4 x float> %8 = < poison, poison, poison, poison >
ptr %9 = pointer(non-local, block_id=1, offset=16)

Mismatch in pointer(non-local, block_id=1, offset=22)
Source value: #x80
Target value: poison
```

cc @regehr @cilkplus @davemgreen @RKSimon
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJy9WduO4jgQ_ZrwYoES2wnhgYemYTTSznSvuntXu0-rkBjIToijONCXr9-yc3Nu3KZ3EAqJ7TquOi67qsiaB-_z52-__8n8jKfhB0tRGPs8TeE5ekcpSyLPZwIZjukFAYrFKzrEAdvAM3oNs13ZkfBQ8BgeJugrf2VHlhr4visFbaYUDUXdEPOsFIcnwVG2YyhLvVhseLr3spDHcrwcVig2McylYd6t3rx9EjGD3OXPAJx_o-i4L5rIAr0wkcEY9FJCCgN_aZgMz3-5DlyPZdM4ZTwNWDr2omwsdofNJmKTKCpA1RW0D2OGjjwMkEHNDecGdpMsRQa2fWlJcR8YeIaM6aKQxTaLs_S9UhrJMV6aeu9h8GYhgyzRliWwCGsODAmkI1roDYUORVQTNZVIxL0Aha42bQUp27wo3MbI0sR8Hh-xEv1gbxmI5lgZRyHBumZxoEbJX-ipRCUq6bGAXmaBrop1xgI6bIHdtsDqWiB2kaOGwY3yxPjwqptiS3jctxj4Mlt0WXxuNfCwMRZpW4N7rbHoKXMsMmjP9DJ79GUl5-yZnrDHbdtD-u2ZnbTHbdsjDuvcJYuTRQ6uDpNiwduenpsuwoxvkhJd4oA-G7Auk6LszWeJPG0EjAWDeMo0mCA8KoyNvFEyNbiUrjQ4DQNKTxSHAysRSAharMS4olTAscTqaUEHfTFyzHolaJMtgk_yBVu7RRch_XQRfB1hxBmgjJDrKSPD7tskDQ-TRpwubWTaIa6OHV9XTysZO5pRrMEuNc95ozXTYSuWqdXPMjWvY5nSAZapdT3L1L6QZTLMMqVdlqk96J7UPUsgbVM3G6DOvY664rzuoW52PXXFYXmeOjpMnY271Nmkh7qUZSr1KDxruix9dmmQ1f-XoNwQ3m9mp0pu1mHmeyLr5AVyreW515tKGOReQbqSj9pYsz9eaamQLlilFGUjxK6SXi0-6qGrMVJBKz-eLhDOA1l5AdFy1RQUrfKsmyHsQhuVrua5bBdMeVOnVW1Zq0Ke5pl66zS8A-V2DFz2laGdd2RIy_xrLZzGdm7OVOf5Ut3OsdgI0x0dHW0l8j2eL-3p3enWW7wlq2ZUvlFpdRpq1uuOlX833THf3D1T6nnU7PKt_dKsiALOBKg8hbEsDTfvBi78efX09PgkY9b3UMBYfwf7De3ZnsOe1vhuF0_lNlYmAiFxJusiN-bxOOK-F0lF13D34x_QjCyVq_DNRjAwawk-M2vABDfBkBonvz7zQ-p3dGxWS9dO4lRzlEWPRDEweTPhFrtm3a_VO9qg_NM7tKyWhgd2zrCbeGqZUBFRbUS9vhnqrAojva9Tr9ykIG0piE8pWNQ9_Rpa9KyK05tUtFsqkkvcoChpzvpBXdWcH1pUM7qFrfJiuL8sSvro0QqNq7ez26MlGd4DSH4Me7H2BAsQHE4qcUJHLzoww172GEVIL5iBF-akpqiZuiuJB-8BXTRdO8m_jQjaQwQ1P5GIogi4gogi3b-RCGrfRkSf3xaJ-6DnFln6kOf2nAqdkHqLrpbTjiKPfzzdr9D31ffHp7_R88vdy0rLlm_6KvGHx4fxt8f7u29oAT-_PVdxaiFVQ9JNVvkaQUrzIcMYtKlgL2-togtaYDjK3pN8hA5h9UBYxK4ECyiZGp2Dwj1QMulsQTm2TZxBqCIT8dKtZLo_Kv9sSPtsHygT_59Uq1sWqH1L9OxRz24bcaTTgqoyopvsXwDciicD7ScmIb9iEvorJrF7JrkGulbqxCTOSUvadx2gRsHxeVDujVBl7fE5p6teZlwdVuqEP0_1i9gFJ45cK9fUD5y6Tw8Z1UsfXSffl_94pGzLdqm888PoRxIdhLwPoHDdb1PGYvn09NtzuOfxKJiTYEZm3igLs4i13ohd_xZsdEij-S7LEiGPSfwFvlsYd1hPfL6HB_WGKv8ZJyn_F-aCx1CIA5Nvp2zbscloN7eCgFAXvg7dzNZTjC0MJ9l6ajG4TGfrUeStWSTmkAMYGO9DAehJGKkK0cD53wYYq8nIXeuVV6uXQ9m7Dz-8vPiFXns5CufYxNi0MbFM7FrOxDFnto1BIdN2puvABQLZ3gujiQSZ8HQ7SufKpvVhK6AzCkUm6k5PCAgzjCl9Ad87ZDuezuNDzJOIJ0yMFANzZf5_kCz_cw">