Test source: git
Source: <stdin>
-- 1. ModuleToFunctionPassAdaptor
-- 1. PassManager<Function> : Skipping NOP
-- 2. DSEPass
----------------------------------------
define ptr @foo(ptr noundef %ptr) {
#0:
%struct.alloca = alloca i64 16, align 8, dead
start_lifetime ptr %struct.alloca
%struct.byte.8 = gep inbounds ptr %struct.alloca, 1 x i64 8
memset ptr %struct.byte.8 align 4, i8 42, i64 8
store i32 43, ptr %struct.byte.8, align 4
%struct.byte.4 = gep inbounds ptr %struct.alloca, 1 x i64 4
store i32 44, ptr %struct.byte.4, align 4
%ret = load ptr, ptr %struct.byte.8, align 8
end_lifetime ptr %struct.alloca
ret ptr %ret
}
Transformation seems to be correct! (syntactically equal)
-- 3. DSEPass
----------------------------------------
define ptr @foo(ptr noundef %ptr) {
#0:
%struct.alloca = alloca i64 16, align 8, dead
start_lifetime ptr %struct.alloca
%struct.byte.8 = gep inbounds ptr %struct.alloca, 1 x i64 8
memset ptr %struct.byte.8 align 8, i8 42, i64 8
store i32 43, ptr %struct.byte.8, align 8
%struct.byte.4 = gep inbounds ptr %struct.alloca, 1 x i64 4
store i32 44, ptr %struct.byte.4, align 4
%ret = load ptr, ptr %struct.byte.8, align 8
end_lifetime ptr %struct.alloca
ret ptr %ret
}
=>
define ptr @foo(ptr noundef %ptr) {
#0:
%struct.alloca = alloca i64 16, align 8, dead
start_lifetime ptr %struct.alloca
%struct.byte.8 = gep inbounds ptr %struct.alloca, 1 x i64 8
%#1 = gep inbounds ptr %struct.byte.8, 1 x i64 4
memset ptr %#1 align 4, i8 42, i64 4
store i32 43, ptr %struct.byte.8, align 8
%ret = load ptr, ptr %struct.byte.8, align 8
end_lifetime ptr %struct.alloca
ret ptr %ret
}
Transformation seems to be correct!
-- 4. PassManager<Function> : Skipping NOP
-- 5. PassManager<Function> : Skipping NOP
-- 6. DSEPass
----------------------------------------
declare ptr @malloc(i64) noalias willreturn alloc-family(malloc) allockind(alloc, uninitialized)
declare void @readnone(ptr) nofree memory(none)
define ptr @foo_with_removable_malloc() {
#0:
%struct.alloca = alloca i64 16, align 8, dead
start_lifetime ptr %struct.alloca
%struct.byte.4 = gep inbounds ptr %struct.alloca, 1 x i64 4
%struct.byte.8 = gep inbounds ptr %struct.alloca, 1 x i64 8
%m2 = call ptr @malloc(noundef i64 4) nofree noundef nothrow noalias willreturn dereferenceable_or_null(4) alloc-family(malloc) allockind(alloc, uninitialized) allocsize(0) memory(inaccessiblemem: readwrite)
%m1 = call ptr @malloc(noundef i64 4) nofree noundef nothrow noalias willreturn dereferenceable_or_null(4) alloc-family(malloc) allockind(alloc, uninitialized) allocsize(0) memory(inaccessiblemem: readwrite)
store i32 0, ptr %struct.byte.8, align 4
store i32 0, ptr %struct.byte.8, align 4
store i32 123, ptr %m1, align 4
store i32 123, ptr %m2, align 4
memset ptr %struct.byte.8 align 4, i8 42, i64 8
store i32 43, ptr %struct.byte.8, align 4
store i32 44, ptr %struct.byte.4, align 4
%ret = load ptr, ptr %struct.byte.8, align 8
call void @readnone(ptr %struct.byte.4) nofree memory(none)
call void @readnone(ptr %struct.byte.8) nofree memory(none)
end_lifetime ptr %struct.alloca
ret ptr %ret
}
Transformation seems to be correct! (syntactically equal)
-- 7. DSEPass
----------------------------------------
declare ptr @malloc(i64) noalias willreturn alloc-family(malloc) allockind(alloc, uninitialized)
declare void @readnone(ptr) nofree memory(none)
define ptr @foo_with_removable_malloc() {
#0:
%struct.alloca = alloca i64 16, align 8, dead
start_lifetime ptr %struct.alloca
%struct.byte.4 = gep inbounds ptr %struct.alloca, 1 x i64 4
%struct.byte.8 = gep inbounds ptr %struct.alloca, 1 x i64 8
%m2 = call ptr @malloc(noundef i64 4) nofree noundef nothrow noalias willreturn dereferenceable_or_null(4) alloc-family(malloc) allockind(alloc, uninitialized) allocsize(0) memory(inaccessiblemem: readwrite)
%m1 = call ptr @malloc(noundef i64 4) nofree noundef nothrow noalias willreturn dereferenceable_or_null(4) alloc-family(malloc) allockind(alloc, uninitialized) allocsize(0) memory(inaccessiblemem: readwrite)
store i32 0, ptr %struct.byte.8, align 8
store i32 0, ptr %struct.byte.8, align 8
store i32 123, ptr %m1, align 8
store i32 123, ptr %m2, align 8
memset ptr %struct.byte.8 align 8, i8 42, i64 8
store i32 43, ptr %struct.byte.8, align 8
store i32 44, ptr %struct.byte.4, align 4
%ret = load ptr, ptr %struct.byte.8, align 8
call void @readnone(ptr %struct.byte.4) nofree memory(none)
call void @readnone(ptr %struct.byte.8) nofree memory(none)
end_lifetime ptr %struct.alloca
ret ptr %ret
}
=>
declare void @readnone(ptr) nofree memory(none)
define ptr @foo_with_removable_malloc() {
#0:
%struct.alloca = alloca i64 16, align 8, dead
start_lifetime ptr %struct.alloca
%struct.byte.4 = gep inbounds ptr %struct.alloca, 1 x i64 4
%struct.byte.8 = gep inbounds ptr %struct.alloca, 1 x i64 8
%#1 = gep inbounds ptr %struct.byte.8, 1 x i64 4
memset ptr %#1 align 4, i8 42, i64 4
store i32 43, ptr %struct.byte.8, align 8
%ret = load ptr, ptr %struct.byte.8, align 8
call void @readnone(ptr %struct.byte.4) nofree memory(none)
call void @readnone(ptr %struct.byte.8) nofree memory(none)
end_lifetime ptr %struct.alloca
ret ptr %ret
}
Transformation doesn't verify! (unsound)
ERROR: Source is more defined than target
Example:
Source:
ptr %struct.alloca = pointer(local, block_id=0, offset=0) / Address=#x140
ptr %struct.byte.4 = pointer(local, block_id=0, offset=4) / Address=#x144
ptr %struct.byte.8 = pointer(local, block_id=0, offset=8) / Address=#x148
ptr %m2 = pointer(local, block_id=1, offset=0) / Address=#x100
ptr %m1 = pointer(local, block_id=2, offset=0) / Address=#x120
ptr %ret = poison
void = function did not return!
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 4 alloc type: 0 alive: false address: 0
LOCAL BLOCKS:
Block 4 > size: 16 align: 8 alloc type: 1 alive: false address: 320
Block 5 > size: 8 align: 8 alloc type: 2 alive: true address: 256
Block 6 > size: 8 align: 8 alloc type: 2 alive: true address: 288
Target:
ptr %struct.alloca = pointer(local, block_id=0, offset=0) / Address=#x100
ptr %struct.byte.4 = pointer(local, block_id=0, offset=4) / Address=#x104
ptr %struct.byte.8 = pointer(local, block_id=0, offset=8) / Address=#x108
ptr %#1 = pointer(local, block_id=0, offset=12) / Address=#x10c
ptr %ret = poison
void = function did not return!
TARGET MEMORY STATE
===================
LOCAL BLOCKS:
Block 4 > size: 16 align: 8 alloc type: 1 alive: false address: 256
Pass: DSEPass
Command line: '/home/nlopes/llvm/build/bin/opt' '-load=/home/nlopes/alive2/build/tv/tv.so' '-load-pass-plugin=/home/nlopes/alive2/build/tv/tv.so' '-tv-exit-on-error' '-S' '-passes=dse' '-tv-smt-to=20000' '-tv-report-dir=/home/nlopes/alive2/build/logs' '-tv-smt-stats'
Wrote bitcode to: "/home/nlopes/alive2/build/logs/in_e9NCIWXT_yMfA.bc"
------------------- SMT STATS -------------------
Num queries: 25
Num invalid: 0
Num skips: 0
Num trivial: 15 (37.5%)
Num timeout: 0 (0.0%)
Num errors: 0 (0.0%)
Num SAT: 19 (76.0%)
Num UNSAT: 6 (24.0%)
Alive2: Transform doesn't verify; aborting!
RUN: at line 2: /home/nlopes/alive2/build/opt-alive.sh -S -passes=dse < /bitbucket/nlopes/llvm/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll | /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll + /home/nlopes/alive2/build/opt-alive.sh -S -passes=dse + /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll FileCheck error: '<stdin>' is empty. FileCheck command line: /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/DeadStoreElimination/batchaa-caching-new-pointers.ll