<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">