Test source: git
Source: <stdin> -- 1. ModuleToFunctionPassAdaptor -- 1. PassManager<Function> : Skipping NOP -- 2. GVNPass ---------------------------------------- declare i32 @use(ptr) nofree memory(none) declare void @somecall() declare i1 @cond() nofree memory(none) define i32 @loadpre_opportunity(ptr %arg, i1 %arg1, i1 %arg2, i1 %arg3) { bb: %i = load ptr, ptr %arg, align 8 br label %bb5 bb5: %i6 = call i32 @use(ptr %i) nofree memory(none) br label %bb11 bb11: %i12 = phi i32 [ %i6, %bb5 ], [ %i10, %bb7 ] br i1 %arg1, label %bb7, label %bb13 bb13: call void @somecall() br i1 %arg2, label %bb14, label %bb17 bb14: br label %bb15 bb15: br i1 %arg3, label %bb16, label %bb15 bb16: br label %bb17 bb17: %i18 = call i1 @cond() nofree memory(none) br i1 %i18, label %bb7, label %bb19 bb7: %i8 = load ptr, ptr %arg, align 8 %i10 = call i32 @use(ptr %i8) nofree memory(none) br label %bb11 bb19: ret i32 %i12 } Transformation seems to be correct! (syntactically equal) -- 3. GVNPass ---------------------------------------- declare i32 @use(ptr) nofree memory(none) declare void @somecall() declare i1 @cond() nofree memory(none) define i32 @loadpre_opportunity(ptr %arg, i1 %arg1, i1 %arg2, i1 %arg3) { bb: %i = load ptr, ptr %arg, align 8 br label %bb5 bb5: %i6 = call i32 @use(ptr %i) nofree memory(none) br label %bb11 bb11: %i12 = phi i32 [ %i6, %bb5 ], [ %i10, %bb7 ] br i1 %arg1, label %bb7, label %bb13 bb13: call void @somecall() br i1 %arg2, label %bb14, label %bb17 bb14: br label %bb15 bb15: br i1 %arg3, label %bb16, label %bb15 bb16: br label %bb17 bb17: %i18 = call i1 @cond() nofree memory(none) br i1 %i18, label %bb7, label %bb19 bb7: %i8 = load ptr, ptr %arg, align 8 %i10 = call i32 @use(ptr %i8) nofree memory(none) br label %bb11 bb19: ret i32 %i12 } => declare i32 @use(ptr) nofree memory(none) declare void @somecall() declare i1 @cond() nofree memory(none) define i32 @loadpre_opportunity(ptr %arg, i1 %arg1, i1 %arg2, i1 %arg3) { bb: %i = load ptr, ptr %arg, align 8 %i6 = call i32 @use(ptr %i) nofree memory(none) br label %bb11 bb11: %i81 = phi ptr [ %i, %bb ], [ %i8, %bb7 ] %i12 = phi i32 [ %i6, %bb ], [ %i10, %bb7 ] br i1 %arg1, label %bb7, label %bb13 bb13: call void @somecall() br i1 %arg2, label %bb14, label %bb17 bb14: br label %bb15 bb15: br i1 %arg3, label %bb16, label %bb15 bb16: br label %bb17 bb17: %i18 = call i1 @cond() nofree memory(none) br i1 %i18, label %bb17.bb7_crit_edge, label %bb19 bb17.bb7_crit_edge: %i8.pre = load ptr, ptr %arg, align 8 br label %bb7 bb7: %i8 = phi ptr [ %i8.pre, %bb17.bb7_crit_edge ], [ %i81, %bb11 ] %i10 = call i32 @use(ptr %i8) nofree memory(none) br label %bb11 bb19: ret i32 %i12 } Transformation doesn't verify! (unsound) ERROR: Source is more defined than target Example: ptr %arg = pointer(non-local, block_id=1, offset=0) i1 %arg1 = #x0 (0) i1 %arg2 = #x0 (0) i1 %arg3 = #x0 (0) Source: ptr %i = null >> Jump to %bb5 i32 %i6 = #x00000000 (0) >> Jump to %bb11 i32 %i12 = #x00000000 (0) >> Jump to %bb13 Function @somecall returned >> Jump to %bb17 i1 %i18 = #x1 (1) >> Jump to %bb7 ptr %i8 = pointer(non-local, block_id=2, offset=100) i32 %i10 = function did not return! SOURCE MEMORY STATE =================== NON-LOCAL BLOCKS: Block 0 > size: 0 align: 8 alloc type: 0 alive: false address: 0 Block 1 > size: 8 align: 1 alloc type: 0 alive: true address: 8 Contents: *: poison Block 2 > size: 1 align: 8 alloc type: 2 alive: false address: 240 Contents: *: pointer(non-local, block_id=2, offset=100), byte offset=0 Block 3 > size: 8 align: 8 alloc type: 0 alive: true Contents: *: pointer(non-local, block_id=2, offset=100), byte offset=0 Target: ptr %i = null i32 %i6 = #x00000000 (0) UB triggered on br Pass: GVNPass 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' '-passes=gvn' '-gvn-max-block-speculations=1' '-S' '-tv-smt-to=20000' '-tv-report-dir=/home/nlopes/alive2/build/logs' '-tv-smt-stats' Wrote bitcode to: "/home/nlopes/alive2/build/logs/in_dcEvmbt3_ugwx.bc" ------------------- SMT STATS ------------------- Num queries: 50 Num invalid: 0 Num skips: 0 Num trivial: 11 (18.0%) Num timeout: 0 (0.0%) Num errors: 0 (0.0%) Num SAT: 36 (72.0%) Num UNSAT: 14 (28.0%) Alive2: Transform doesn't verify; aborting!
RUN: at line 2: /home/nlopes/alive2/build/opt-alive.sh < /bitbucket/nlopes/llvm/llvm/test/Transforms/GVN/loadpre-missed-opportunity.ll -passes=gvn -gvn-max-block-speculations=1 -S | /bitbucket/nlopes/llvm/build/bin/FileCheck -check-prefix=PRE /bitbucket/nlopes/llvm/llvm/test/Transforms/GVN/loadpre-missed-opportunity.ll + /home/nlopes/alive2/build/opt-alive.sh -passes=gvn -gvn-max-block-speculations=1 -S + /bitbucket/nlopes/llvm/build/bin/FileCheck -check-prefix=PRE /bitbucket/nlopes/llvm/llvm/test/Transforms/GVN/loadpre-missed-opportunity.ll FileCheck error: '<stdin>' is empty. FileCheck command line: /bitbucket/nlopes/llvm/build/bin/FileCheck -check-prefix=PRE /bitbucket/nlopes/llvm/llvm/test/Transforms/GVN/loadpre-missed-opportunity.ll