<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/55651>55651</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
LoadStoreVectorizer wrong logic for zext gep offsets
</td>
</tr>
<tr>
<th>Labels</th>
<td>
miscompilation,
llvm:optimizations
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
nunoplopes
</td>
</tr>
</table>
<pre>
LoadStoreVectorizer is buggy wrt to gep offsets that are zero extended rather than sign extended. See example below that shows the mistake in considering `%src + zext(-1)` contiguous to `%src + 0`
```llvm
; Test: Transforms/LoadStoreVectorizer/X86/vectorize-i8-nested-add.ll
define void @ld_v4i8_add_nuw_operand_orders(i32 %v0, i32 %v1, ptr %src, ptr %dst) {
%bb:
; load %src + zext(-1)
%tmp = add nuw i32 %v0, 4294967295
%tmp1 = add nuw i32 %v1, %tmp
%tmp2 = zext i32 %tmp1 to i64
%tmp3 = gep inbounds ptr %src, 1 x i64 %tmp2
%tmp4 = load i8, ptr %tmp3, align 1
; load %src + 0
%tmp5 = add nuw i32 %v0, %v1
%tmp6 = zext i32 %tmp5 to i64
%tmp7 = gep inbounds ptr %src, 1 x i64 %tmp6
%tmp8 = load i8, ptr %tmp7, align 1
; load %src + 1
%tmp9 = add nuw i32 %v0, 1
%tmp10 = add nuw i32 %tmp9, %v1
%tmp11 = zext i32 %tmp10 to i64
%tmp12 = gep inbounds ptr %src, 1 x i64 %tmp11
%tmp13 = load i8, ptr %tmp12, align 1
; load %src + 2
%tmp14 = add nuw i32 %v0, 2
%tmp15 = add nuw i32 %v1, %tmp14
%tmp16 = zext i32 %tmp15 to i64
%tmp17 = gep inbounds ptr %src, 1 x i64 %tmp16
%tmp18 = load i8, ptr %tmp17, align 1
...
}
=>
define void @ld_v4i8_add_nuw_operand_orders(i32 %v0, i32 %v1, ptr %src, ptr %dst) {
%bb:
; load %src - 1 .. %src + 2
%tmp = add nuw i32 %v0, 4294967295
%tmp1 = add nuw i32 %v1, %tmp
%tmp2 = zext i32 %tmp1 to i64
%tmp3 = gep inbounds ptr %src, 1 x i64 %tmp2
%0 = bitcast ptr %tmp3 to ptr
%1 = load <4 x i8>, ptr %0, align 1
...
}
Transformation doesn't verify!
ERROR: Source is more defined than target
Example:
i32 %v0 = #x00000000 (0)
i32 %v1 = #x00000000 (0)
ptr %src = pointer(non-local, block_id=1, offset=9223336852088022299)
ptr %dst = pointer(non-local, block_id=2, offset=11661997849188)
Source:
i32 %tmp = #xffffffff (4294967295, -1)
i32 %tmp1 = #xffffffff (4294967295, -1)
i64 %tmp2 = #x00000000ffffffff (4294967295)
ptr %tmp3 = pointer(non-local, block_id=1, offset=9223336856382989594)
i8 %tmp4 = poison
i32 %tmp5 = #x00000000 (0)
i64 %tmp6 = #x0000000000000000 (0)
ptr %tmp7 = pointer(non-local, block_id=1, offset=9223336852088022299)
i8 %tmp8 = poison
i32 %tmp9 = #x00000001 (1)
i32 %tmp10 = #x00000001 (1)
i64 %tmp11 = #x0000000000000001 (1)
ptr %tmp12 = pointer(non-local, block_id=1, offset=9223336852088022300)
i8 %tmp13 = poison
i32 %tmp14 = #x00000002 (2)
i32 %tmp15 = #x00000002 (2)
i64 %tmp16 = #x0000000000000002 (2)
ptr %tmp17 = pointer(non-local, block_id=1, offset=9223336852088022301)
i8 %tmp18 = poison
<4 x i8> %tmp19 = < poison, #x00 (0) [based on undef value], #x00 (0), #x00 (0) >
<4 x i8> %tmp20 = < poison, poison, #x00 (0), #x00 (0) >
<4 x i8> %tmp21 = < poison, poison, poison, #x00 (0) >
<4 x i8> %tmp22 = < poison, poison, poison, poison >
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0
Block 1 > size: 9223336856382989596 align: 4 alloc type: 0
Block 2 > size: 35184372088832 align: 4 alloc type: 0
Target:
i32 %tmp = #xffffffff (4294967295, -1)
i32 %tmp1 = #xffffffff (4294967295, -1)
i64 %tmp2 = #x00000000ffffffff (4294967295)
ptr %tmp3 = pointer(non-local, block_id=1, offset=9223336856382989594)
ptr %0 = pointer(non-local, block_id=1, offset=9223336856382989594)
<4 x i8> %1 = UB triggered!
```
cc @regehr @d0k @nikic @RKSimon
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJztWE2PozgQ_TXkYiXyBxA45NDpZC7TMy2le1a7pwiCQ7xNMMIm3T2_fsuQECCQ6Yz6sFotigLGVc_1nguXIZTR--xBBtGTljn_g2_gJH7yHAmFwiKO39FrrpGWKOYZktut4lohvQs0CnKOwFAi_qZ5GvEI5YHegSf0pkiJOK17JuiJc2gF-yzhKOSJfK0w1E6-GjiO9kLp4IUjkaKNTJWIeC7SGFkutqij8g2y6ByGe9MW9cbEoj70GEst4kIWykTYtsWmiRcWvjv-u7j6Jclhf7zF5uiZK22xO_ScB6naynyvLPqlRw-4-6fnwv_hdGssvHEK3jwaB1E0SZLmaBHfipSjgxQRsmycROuDLbw1GK7T4nUtMw7jRWuZA08Y0ROMQtTOARjco1ODmEamc1TRarQiCJr6yJrOj4NSJwyBRtVCyDBLgAQaEu9kRx29z8B8gSA0BKGhViQ29W3fnVLfaXuQXpcy3sqgbU5LcxPAybbEgDkTrt02ZaWpSTaRhrJII9VRgKA343VCbnvbpXfJXHgNvQywaQaJSUvSnKl-sXAb1xmWqCLesnb76Dq9dKe30XXb3t4w3elNdDsE_GG6HUuC-0wNxIA2hPTmAu5Vh9Db5CHdwdiwQITepFAn0Yg9LFHXtD95Gg8L6dLuTSDSn0HkxhQinRwiV5KIXGbRZDI5ijVdnFbRhcWW_8plbwzcJ5Mr0_gfWfmqhzAUehMo3VzzzEDQbJiS82xb7N42kJ6ZvrPI-ANzXlfLQAuZokhylVp0qtEByvb23aJHz-Vq9bgy5fVJFvmGm03FHsoqqvIkqrYKOshjrpuP4LLaKdQzW89MGbxF2Rs-HtDwcF3Q6un4hd1Z19IwkyLVpsR7qUzHidwEidEghKuXtYjApJzfavcDLZ9SxpjrORR7HqaU-n4XGjL1g9C0BU2I6xLfn3q2TzyvRq3-KxG7qpzS2NDdHg9Dt5HBMEKj7DcT8TbHc_JdCDwE0JalTvPfltxlHvU93_Htc1heq_oDtJJpl6rzq9Q519gLy6tJVBfxz8yimpJ3hZLfDZSYAHvn-eLB6Zo2SugQ_Y5Ls5J-Cn-G8SV_wq4IcCzCjVhNj0f7FLiY_65po0AOKdBxadbJT1KA9ChwmQLNhftkdUwGdn-yLAuSoXDKWgSH5czDQMHCC4s2VBi-RYcgKbjlLC7texDqOt8TAcU9EQzFcis2uYo9yPgqJv0gZnXVwKrW4scfq_sl-rb89rj6Cz093z3XQy1-81e6f3_8Pn54vL97QHM4fX2qV_u5ySJkRF6i6lDwEmpqK66qtbkkxy64A-ZIv2eVRROC9EBcLq9uDXSEtj8ATXugmUM8m01NinvwOH4c8rjTqDYH_9e8ds077dU-Hbj7pFRy_ZgjnYs45jmP6s1d_UWlOV-bjdn45zzmu9xcRfjFnFLxIsqe1dcnsZfpKJqxyGd-MNJCJ7z3C9RrLtMYtqoxeMJes9pFNz5DjYo8me20zpRJD_oFfrHQuyKcbOQeGuWHnuo0znL5NyBDUyhVcPORx3Fch4x2Mxwyn2PMeOjA1ouFYRC5G5sw5mGbRoyOkiDkiZrB2mlRuhcK0DORlDtfuFEtO7QcjN3JTIu9-Fl2KtPrLEZiRmFxxw5lBOMpdibh1jHUQz-geBO5BGTh-0AkEwMykXk8ymdl1GERK_MaJZRW585AmY9rnJcRAX5Q6J3MZ2mRyiyBVyw1KjnOSoL_APcXW9M">