| 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