Issue 176685
Summary Miscompilation during memcpy-to-load conversion which reads uninitialized bytes as poison
Labels new issue
Assignees
Reporter sairam2661
    **Fuzzer Generated Test**
**Reproducer**
https://alive2.llvm.org/ce/z/7Gu3xX

**Test Commit**
[0b2f3cfb72a76fa90f3ec2a234caabe0d0712590](https://github.com/llvm/llvm-project/commit/0b2f3cfb72a76fa90f3ec2a234caabe0d0712590)

**Description**
When converting `memcpy` to `load`/`store`, the optimization reads more bytes than were initialized, causing poison to be loaded and stored. Related: https://github.com/llvm/llvm-project/issues/143527

**Steps to reproduce**
- Minimized test case, `input.ll`
```
define void @test(ptr %in, ptr %out, i1 %0) {
entry:
  br i1 %0, label %1, label %2

1: ; preds = %entry
  call void @llvm.memcpy.p0.p0.i64(ptr %out, ptr %in, i64 1, i1 false)
  br label %2

2:                                                ; preds = %1, %entry
  ret void
}

; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
declare void @llvm.memcpy.p0.p0.i64(ptr noalias writeonly captures(none), ptr noalias readonly captures(none), i64, i1 immarg) #0

attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }

```

**Output**
```

----------------------------------------
define void @test(ptr %in, ptr %out, i1 %#0) {
entry:
  br i1 %#0, label %#1, label %#2

#1:
  memcpy ptr %out align 1, ptr %in align 1, i64 1
  br label %#2

#2:
  ret void
}
=>
define void @test(ptr nocapture nowrite %in, ptr nocapture noread %out, i1 %#0) nofree willreturn memory(argmem: readwrite) {
entry:
  br i1 %#0, label %#1, label %#2

#1:
  %#3 = load i8, ptr nocapture nowrite %in, align 1
  store i8 %#3, ptr nocapture noread %out, align 1
  br label %#2

#2:
  ret void
}
Transformation doesn't verify!

ERROR: Mismatch in memory

Example:
ptr %in = pointer(non-local, block_id=1, offset=8, attrs=8) / Address=#x0a
ptr %out = pointer(non-local, block_id=1, offset=0, attrs=8) / Address=#x02
i1 %#0 = #x1 (1)

Source:
  >> Jump to %#1
  >> Jump to %#2

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

Block 2 >	size: 0	align: 1	alloc type: 0	alive: true	address: #x01
Contents:
2: poison
*: poison


Target:
  >> Jump to %#1
i8 %#3 = poison
  >> Jump to %#2

TARGET MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 >	size: 0	align: 1	alloc type: 0	alive: false	address: #x00
Block 1 >	size: 12	align: 2	alloc type: 4	alive: true	address: #x02
Contents:
8: pointer(non-local, block_id=0, offset=2), byte offset=2
2: poison
*: poison

Block 2 >	size: 0	align: 1	alloc type: 0	alive: true	address: #x01
Contents:
2: poison
*: poison


Mismatch in pointer(non-local, block_id=1, offset=0)
Source value: pointer(non-local, block_id=0, offset=2), byte offset=2
Target value: poison

Summary:
  0 correct transformations
  1 incorrect transformations
  0 failed-to-prove transformations
  0 Alive2 errors
```

_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to