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