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

    <tr>
        <th>Summary</th>
        <td>
            [InstCombine] Replacement of binop with binop-of-shuffle incorrectly adds extra poison value
        </td>
    </tr>

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

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

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

<pre>
    
The following IR is a minimal repro when run with `opt -passes=instcombine`:
```llvm
define i8 @src(<2 x i8> %x, <2 x i8> %y) {
  %xsplat = shufflevector <2 x i8> %x, <2 x i8> poison, <2 x i32> <i32 1, i32 0>
  %vv = mul <2 x i8> %xsplat, %y
  %m = mul <2 x i8> %x, %y   ;  <<<< Note that %m is later replaced with %vv in the output
  %msplat = shufflevector <2 x i8> %m, <2 x i8> poison, <2 x i32> <i32 0, i32 0>
  %res = add <2 x i8> %vv, %msplat
  %vget_lane = extractelement <2 x i8> %res, i64 1
  ret i8 %vget_lane
}
```
Which on 17.x or trunk will give:
```llvm
define i8 @src(<2 x i8> %x, <2 x i8> %y) {
  %xsplat = shufflevector <2 x i8> %x, <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
 %vv = mul <2 x i8> %xsplat, %y
  %msplat = shufflevector <2 x i8> %vv, <2 x i8> poison, <2 x i32> <i32 poison, i32 0>
  %res = add <2 x i8> %vv, %msplat
  %vget_lane = extractelement <2 x i8> %res, i64 1
  ret i8 %vget_lane
}
```
However, this is not correct, because the added poisoned values end up observed in the final output. First, in InstCombine, the masks in the shuffle are first replaced with `poison` due to not being observed in the final `extractelement`. After that we run into this code  in `InstCombineSimplifyDemanded.cpp`:
https://github.com/llvm/llvm-project/blob/d8278b682386f51dfba204849c624672a3df40c7/llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp#L1866-L1880

This is what replaces the `mul <2 x i8> %x, %y` with `mul <2 x i8> %xsplat, %y` (`m_ZeroMask` also matches poison). However in doing so, it introduces the extra poison from `%xsplat`, meaning that `%msplat` has both its elements poisoned, which ends up propagating to `%vget_lane`.

Here is a Godbolt link showing the test case on 16.x, 17.x, and trunk:
https://godbolt.org/z/5eeT7x4s3

And also an Alive2 example showing the bad transformation with a counter-example:
https://alive2.llvm.org/ce/z/RpBJEN

The code was first introduced in 3b090ff2bdb2828b53d6fec9c06b9d52fed09f42, which a bisect shows is when this first started repro'ing

I have verified that this still repros on latest trunk, 2de269a641e4ffbb7a44e559c4c0a91bb66df823

For priority/triage: this bug was found by a fuzzer meant to test SIMD codegen. It was not from manually written code
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzUV0Fv2zwS_TX0ZRCDomRaPviQxPV-WbQ9tAUW2EtBiiOLDUUKJGUn_fULUnLiJJvddrGXAoYti5qZxzdvZigRgj5YxC1Z3ZDVbiHG2Dm_vUH7Q9uwkE49bgndEXr9rUNonTHupO0B7r6ADiCg11b3woDHwTs4dWjBjxZOOnZAOHVDhKtBhICBlDttQ2xcL7VFwikpryfP6Tp_jDn20y2FrbYIugZS0eAbwmpS3jJ4AF2T8gMQtnog7BZe33wkbANkfTN5gfxcGIyIQModhG5sW4NHbKLzb2zfOhycDs5e3i5Zfri81SWDIq2kC0rKDxcRj8ccrR_N2xgZTPaYwD7b9O-bnJ8GAFLepK_bpw98dhEhdmmDyYkOYEREn_JhRINqzkQGpS3EDsGNcRjjZexfZaj_XYboOwx5DDmcUOpNkONx3vAE65LXA8bvRljMtvgQvWgiGuzRxjduPIYcnFdQnH14jFlSF65mBa53r6Q4_f1Hp5sOnIVivXwA5yH60d7DSRsDB33EP17Cz8uvsvS_yvhXkc5Z_n9A_ZME9Zc74RF9chQ7HVK9Whehcd5jkwmV2IgxYK5UoRSqeeOo4CjMiAHQKhgHcDKgP6I6l3WrrTBzcS9hr33I_rSFOxvi7dx2c2CEXoT7cLacMwXCJy8-xNfdg9OZfE5BjQjRZdQS0yT49zgIpy_5JJwu4bpNvSm3qxPmQaFtdBMVjVMIyQnh9ALxV90PRrePO-yFVaiWzTBcDo8uxiGkf2xP2P6gYzfKZeN6wva5Fqefq8G7H5nhvTROErZXNVvXktesrHm7KlQrBaNVXW0aziq-ZqJUbUWb9YUfney-eWFD63wfCNu_YHb_31Cz8mNRc371sajrWQ_n0TpJ4ZSImbkPmUzC6X-cCSkj5xz9QqFyCqkNcdp__yd690mE-3RPmOCgF7HpMDzV2WYJs1pTUpRLuQ4uSyqmtHmnxjPMnOrZElrv-oTnOTzPc6BHYZOTaVrl9f68Dp0IIF3sQMcAs2TCk_ST-Sn3YrQqJPUP3g3iIGJ26GZ3z0XI6fKS4L_Q43Re-ZtT0pkIRtt7CN10mElbiBgiNCJgbvd8mSlObT_9Cqum1v-e7CavS-cPhO1_ErZfIX5bP1ShvIRxbdXEtbBwbfQRGeCD6AeDL6BIkaLNMhNRu_k8JaBxo43or2ard9CI7HqZZDsjanCG9WW4-fuHzy-1h1PpnUSYq_8pubmmS0k3tG2ZVJLVrJarUvEWm01DudyoFWtR0U1bseccCZA6YBPzpmZho52qfIoQovAR1XRqJGyt7eES0x104ohwRK9bjWpSTDYPMY3ebBZSotJhJ8Q5N-wWmELGN4JXBVZtK-VaVBWuVpumaqjYFFJyrtqavcjK3nkYvHZex0fC9tFrcUjUThHleJiocaNVIB9BQDv-_Ik-6zkm8WUIX-8-7TKRB7RLuIvZKHXJXA69sKMw5hFOXseINj-5UNtSbcqNWOC2WNO6YAWv14tuy-t2zSsmmORFvVKNRC7asuClapgsq2Kht4yyirKCM1ZU1XopN6IoJa9VvVnTuqxIRbEX2jyJYKFDGHFbM7piCyMkmpCP_IxZPEFeJIylNwC_zQ1TjodAKmp0iOHZS9TR5HeFy8632sGXqWnlwelakNq6YRJtvrxy7dV5ymg7TzvzmAZceNk88oxbjN5sf7ux502krpw3-a8AAAD__4GR6po">