Skip to content

[InstCombine] Unsound integer-to-pointer coercion #124461

Description

@pedroclobo

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

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    llvm:instcombineCovers the InstCombine, InstSimplify and AggressiveInstCombine passes

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions