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

    <tr>
        <th>Summary</th>
        <td>
            [InstCombine] Unsound integer-to-pointer coercion
        </td>
    </tr>

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

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

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

<pre>
    If a pointer is stored in memory, `%v3` returns `poison`, while `%v4` returns the pointer value in the original program.
Introducing the cast in the target program is unsound as `%v3` is `poison` and `%v4` becomes `poison`.

Alive2: [https://alive2.llvm.org/ce/z/FW5zqi](https://alive2.llvm.org/ce/z/FW5zqi)

```llvm
declare void @use(...) nofree memory(read)

@use = constant ? bytes, exec, align 8

define ptr @f5(ptr %p, i1 %cond) {
#0:
  br i1 %cond, label %bb1, label %bb2

bb2:
  %v2 = load ptr, ptr %p, align 8
  call void @use(...ptr %v2) nofree memory(read)
  br label %merge

bb1:
  %v1 = load i64, ptr %p, align 4
  call void @use(...i64 %v1) nofree memory(read)
  br label %merge

merge:
  %v3 = load i64, ptr %p, align 4
  call void @use(...i64 %v3) nofree memory(read)
  %v4 = load ptr, ptr %p, align 8
 ret ptr %v4
}
=>
declare void @use(...) nofree memory(read)

@use = constant ? bytes, exec, align 8

define ptr @f5(ptr %p, i1 %cond) {
#0:
 br i1 %cond, label %bb1, label %bb2

bb2:
  %v2 = load ptr, ptr %p, align 8
  call void @use(...ptr %v2) nofree memory(read)
  br label %merge

bb1:
  %v1 = load i64, ptr %p, align 4
  call void @use(...i64 %v1) nofree memory(read)
  br label %merge

merge:
  %v3 = load i64, ptr %p, align 4
  call void @use(...i64 %v3) nofree memory(read)
  %v4.cast = int2ptr i64 %v3 to ptr
  ret ptr %v4.cast
}
Transformation doesn't verify!

ERROR: Target is more poisonous than source

Example:
ptr %p = pointer(non-local, block_id=1, offset=0) / Address=#x0000000000000008
i1 %cond = #x1 (1)

Source:
  >> Jump to %bb1
i64 %v1 = poison
Function returned
  >> Jump to %merge
i64 %v3 = poison
Function  returned
ptr %v4 = pointer(non-local, block_id=4, offset=0) / Address=#x0000000000000001

SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >    size: 0 align: 4        alloc type: 0   alive: false    address: 0
Block 1 >    size: 11        align: 8        alloc type: 0   alive: true     address: 8      const
Contents:
1: pointer(non-local, block_id=4, offset=0), byte offset=1
*: pointer(non-local, block_id=4, offset=0), byte offset=0

Block 2 >    size: 0 align: 8        alloc type: 0   alive: true     address: 8
Contents:
1: pointer(non-local, block_id=4, offset=0), byte offset=1
*: pointer(non-local, block_id=4, offset=0), byte offset=0

Block 3 >    size: 0 align: 8        alloc type: 0   alive: true     address: 8
Contents:
1: pointer(non-local, block_id=4, offset=0), byte offset=1
*: pointer(non-local, block_id=4, offset=0), byte offset=0

Block 4 >    size: 0 align: 1        alloc type: 0   alive: true     address: 1
Contents:
1: pointer(non-local, block_id=4, offset=0), byte offset=1
*: pointer(non-local, block_id=4, offset=0), byte offset=0

Block 5 >    size: 0 align: 8        alloc type: 0   alive: true     address: 8
Contents:
1: pointer(non-local, block_id=4, offset=0), byte offset=1
*: pointer(non-local, block_id=4, offset=0), byte offset=0

Block 6 >    size: 0 align: 2        alloc type: 0   alive: true     address: 2
Contents:
1: pointer(non-local, block_id=4, offset=0), byte offset=1
*: pointer(non-local, block_id=4, offset=0), byte offset=0


Target:
  >> Jump to %bb1
i64 %v1 = poison
Function  returned
  >> Jump to %merge
i64 %v3 = poison
Function  returned
ptr %v4.cast = poison
Source value: pointer(non-local, block_id=4, offset=0) / Address=#x0000000000000001
Target value: poison
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWF9z4jYQ_zTiRQMjy38wDzw4gGfS5o6ZJDedPnVkewG1skQlmQv59B3JxkB6pQm9PuQmGSbY0v75-bcr77LMGL6WAFMU36B4PmCN3Sg93UKlVSlUoQaFqvbT2xVmeKu4tKAxN9hYpaHCXOIaaqX3iM4wSgii8S5ECcEabKOlcWtbxY2SfnOGv264gINkdCppN9A72DHRgDPuFpXmay6ZwFut1prVI0SyW2m1qpqSy7WXKZmxB3nL9BrsQdqBbaRRjawwM2cY-Tk8zGR1hqyAUtVwLuScI5Jlgu-AojDDKL7ZWLs1KMwQzRHNmd8aCbGrR0qvEc1LQDR_RjTPf4mf_-QoniOavlWJTlrPDqD_OFlEsgpKwTTgneIVRhFpDCCajkYjRCdYqpUG6EOUamDV0ZIXxiic41JJY5m0GIU5LvYWjIsVPEHpvpnga4nTVquCFZeAt1Y7b6sY0dRf03jrZHngLkslnR-MxjdOi4bEPSnJMC70mcgMC1aAcAtFEby4p61Hd9Fpu9BQj1goVjkQTuXU_xErxiUT4u-8dNI7epkgD7UHU4NewwFOcAonOMLhSfRtONEFODyJWjtXwmkvTwCF3wlQ-G-A_Dl5bTC0O5Ed8847Gs_d_3COwsW7y-KPJP6xknjky4fzyKWlzlOvj63yEXKyZznsdfpEftRMmpXSNbNcSVwpMBLRscU70Hy1RzRoH3Rxf7-8d2XjsS1S3OBaaV_4jJKqcWWQSWxUo8uOm8UTq7eiY-fAggfbVUtEU6nkUKiSCcdOIVT5x2-8QuHcJ6NarQxYFM6JT2aa46yqNBjjTh8Nn8j5n0u7Y3Z7R07KraRBf-weWoSHkIULFC7wT029dYR1B4FkfV4c8LoiSrK8kaXnqa39UP2DkUOGHKPxbTOndvoAvZKi6AqKumA-LL_czxb40-LT8v5X_PCYPS4O77SrPiT7vPw8vFvOsjt8c7ec_fzQ8nvj0GLiCSITw58d75ggMvEHwd1E_kaoEtv99nR7529WTBhwC4en8vud4eCF4SA4tZxetmx188KwU_BvYkSymZIWpDXtc7hXzlUR8QJ7C8dVHwGafT-DpA1pywi9RPU1hLxXIsIPIloioktEBG8lIni_RMQfGdESkVwigr6VCPoeiXB9j29j_msb8L_2Acfmrldom5d2ynAtK6_rEro279RTC6H_GT-opmE1CSdsANNgHI7TSRKMx4PNdJIyFkARTcoVSSCa0LIIaRIFFQ2DaFXAgE8poTEJaBLQOAnGI8rihLCKhCmL0qhkKCJQMy76scKAG9PANKBRlAQD34gbP_ehVMJX7HcRpSieD_TUKQ2LZm1QRAQ31hzNWG6FHxjdSmNnqi64BBTP8ZduzuLYXIMeWjU8THRKBbrkSg4aLabns481t5umGJWqRjT3U432a7jV6ncoLaK5R2YQzTvouyn9KwAA__9RgIER">