Test source: git
Source: <stdin> ---------------------------------------- define void @test_no_unswitch(* %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: call void @x() call void @x() call void @x() call void @x() br i1 %cond, label %loop_a, label %loop_b %loop_a: call void @a() br label %loop_latch %loop_b: call void @b() br label %loop_latch %loop_latch: %v = load i1, * %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret void } => define void @test_no_unswitch(* %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: call void @x() call void @x() call void @x() call void @x() br i1 %cond, label %loop_a, label %loop_b %loop_a: call void @a() br label %loop_latch %loop_b: call void @b() br label %loop_latch %loop_latch: %v = load i1, * %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret void } Transformation seems to be correct! (syntactically equal) ---------------------------------------- define void @test_unswitch(* %ptr, i1 %cond) { %entry: br label %loop_begin %loop_begin: call void @x() br i1 %cond, label %loop_a, label %loop_b %loop_a: call void @a() br label %loop_latch %loop_b: call void @b() br label %loop_latch %loop_latch: %v = load i1, * %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit %loop_exit: ret void } => define void @test_unswitch(* %ptr, i1 %cond) { %entry: br i1 %cond, label %entry.split.us, label %entry.split %entry.split: br label %loop_begin %loop_begin: call void @x() br label %loop_b %loop_b: call void @b() br label %loop_latch %loop_latch: %v = load i1, * %ptr, align 1 br i1 %v, label %loop_begin, label %loop_exit.split %loop_exit.split: br label %loop_exit %entry.split.us: br label %loop_begin.us %loop_begin.us: call void @x() br label %loop_a.us %loop_a.us: call void @a() br label %loop_latch.us %loop_latch.us: %v.us = load i1, * %ptr, align 1 br i1 %v.us, label %loop_begin.us, label %loop_exit.split.us %loop_exit.split.us: br label %loop_exit %loop_exit: ret void } Transformation doesn't verify! ERROR: Source is more defined than target Example: * %ptr = poison i1 %cond = poison Source: >> Jump to %loop_begin void = UB triggered! SOURCE MEMORY STATE =================== NON-LOCAL BLOCKS: Block 0 > size: 0 align: 1 alloc type: 0 Block 1 > align: 8 alloc type: 2 Block 2 > align: 1 alloc type: 2 Target: UB triggered on br ------------------- SMT STATS ------------------- Num queries: 5 Num invalid: 0 Num skips: 0 Num trivial: 0 (0.0%) Num timeout: 0 (0.0%) Num errors: 0 (0.0%) Num SAT: 5 (100.0%) Num UNSAT: 0 (0.0%) Alive2: Transform doesn't verify; aborting!
+ : 'RUN: at line 3' + /home/nuno/llvm/build/bin/FileCheck /home/nuno/llvm/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll + /home/nuno/alive2/build/opt-alive.sh '-passes=loop(simple-loop-unswitch<nontrivial>),verify<loops>' -unswitch-threshold=5 -S FileCheck error: '<stdin>' is empty. FileCheck command line: /home/nuno/llvm/build/bin/FileCheck /home/nuno/llvm/llvm/test/Transforms/SimpleLoopUnswitch/nontrivial-unswitch-cost.ll