Test source: git
Source: /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-early-exit.ll
-- 1. ModuleToFunctionPassAdaptor
-- 1. PassManager<Function> : Skipping NOP
-- 2. LoopVectorizePass
----------------------------------------
define i8 @test_early_exit_max_tc_less_than_16(ptr dereferenceable(16) %A) nofree {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%p.src = gep inbounds ptr dereferenceable(16) %A, 1 x i64 %iv
%l = load i8, ptr %p.src, align 1
%c = icmp eq i8 %l, 0
br i1 %c, label %exit, label %loop.latch
loop.latch:
%iv.next = add nsw i64 %iv, 1
%cmp = icmp eq i64 %iv.next, 16
br i1 %cmp, label %exit, label %loop.header
exit:
%res = phi i8 [ 0, %loop.header ], [ 1, %loop.latch ]
ret i8 %res
}
Transformation seems to be correct! (syntactically equal)
-- 3. LoopVectorizePass
----------------------------------------
define i8 @test_early_exit_max_tc_less_than_16(ptr dereferenceable(16) %A) nofree {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%p.src = gep inbounds ptr dereferenceable(16) %A, 1 x i64 %iv
%l = load i8, ptr %p.src, align 1
%c = icmp eq i8 %l, 0
br i1 %c, label %exit, label %loop.latch
loop.latch:
%iv.next = add nsw i64 %iv, 1
%cmp = icmp eq i64 %iv.next, 16
br i1 %cmp, label %exit, label %loop.header
exit:
%res = phi i8 [ 0, %loop.header ], [ 1, %loop.latch ]
ret i8 %res
}
=>
define i8 @test_early_exit_max_tc_less_than_16(ptr dereferenceable(16) %A) nofree {
entry:
br i1 0, label %scalar.ph, label %vector.ph
vector.ph:
br label %vector.body
vector.body:
%index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
%#0 = gep inbounds ptr dereferenceable(16) %A, 1 x i64 %index
%#1 = gep inbounds ptr %#0, 1 x i32 0
%wide.load = load <8 x i8>, ptr %#1, align 1
%#2 = icmp eq <8 x i8> %wide.load, { 0, 0, 0, 0, 0, 0, 0, 0 }
%index.next = add nuw i64 %index, 8
%#3 = reduce_or <8 x i1> %#2
%#4 = icmp eq i64 %index.next, 16
%#5 = or i1 %#3, %#4
br i1 %#5, label %middle.split, label %vector.body
middle.split:
br i1 %#3, label %vector.early.exit, label %middle.block
vector.early.exit:
br label %exit
middle.block:
br i1 1, label %exit, label %scalar.ph
scalar.ph:
%bc.resume.val = phi i64 [ 16, %middle.block ], [ 0, %entry ]
br label %loop.header
loop.header:
%iv = phi i64 [ %bc.resume.val, %scalar.ph ], [ %iv.next, %loop.latch ]
%p.src = gep inbounds ptr dereferenceable(16) %A, 1 x i64 %iv
%l = load i8, ptr %p.src, align 1
%c = icmp eq i8 %l, 0
br i1 %c, label %exit, label %loop.latch
loop.latch:
%iv.next = add nsw i64 %iv, 1
%cmp = icmp eq i64 %iv.next, 16
br i1 %cmp, label %exit, label %loop.header
exit:
%res = phi i8 [ 0, %loop.header ], [ 1, %loop.latch ], [ 1, %middle.block ], [ 0, %vector.early.exit ]
ret i8 %res
}
Transformation doesn't verify! (unsound)
ERROR: Source is more defined than target
Example:
ptr dereferenceable(16) %A = pointer(non-local, block_id=1, offset=0) / Address=#x0000000000000001
Source:
>> Jump to %loop.header
i64 %iv = #x0000000000000000 (0)
ptr %p.src = pointer(non-local, block_id=1, offset=0) / Address=#x0000000000000001
i8 %l = #x00 (0)
i1 %c = #x1 (1)
>> Jump to %exit
i8 %res = #x00 (0)
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 1 alloc type: 0 alive: false address: 0
Block 1 > size: 129 align: 1 alloc type: 0 alive: true address: 1
Contents:
0: #x00
6: #b0000000p
4: #b0000000p
3: #b0000000p
5: #b0000000p
7: #b0000000p
2: #b0000000p
1: #b0000000p
*: poison
Target:
>> Jump to %vector.ph
>> Jump to %vector.body
i64 %index = #x0000000000000000 (0)
ptr %#0 = pointer(non-local, block_id=1, offset=0) / Address=#x0000000000000001
ptr %#1 = pointer(non-local, block_id=1, offset=0) / Address=#x0000000000000001
<8 x i8> %wide.load = < #x00 (0), poison, poison, poison, poison, poison, poison, poison >
<8 x i1> %#2 = < #x1 (1), poison, poison, poison, poison, poison, poison, poison >
i64 %index.next = #x0000000000000008 (8)
i1 %#3 = poison
i1 %#4 = #x0 (0)
i1 %#5 = poison
UB triggered on br
Pass: LoopVectorizePass
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=loop-vectorize,verify<loops>' '-force-vector-width=8' '-force-vector-interleave=1' '-enable-early-exit-vectorization' '-S' '/bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-early-exit.ll' '-tv-smt-to=20000' '-tv-report-dir=/home/nlopes/alive2/build/logs' '-tv-smt-stats'
Wrote bitcode to: "/home/nlopes/alive2/build/logs/vector-loop-backedge-elimination-early-exit_vWtektm5_v1BM.bc"
------------------- SMT STATS -------------------
Num queries: 29
Num invalid: 0
Num skips: 0
Num trivial: 13 (31.0%)
Num timeout: 0 (0.0%)
Num errors: 0 (0.0%)
Num SAT: 22 (75.9%)
Num UNSAT: 7 (24.1%)
Alive2: Transform doesn't verify; aborting!
/home/nlopes/alive2/build/opt-alive.sh -passes='loop-vectorize,verify<loops>' -force-vector-width=8 -force-vector-interleave=1 -enable-early-exit-vectorization -S /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-early-exit.ll | /bitbucket/nlopes/llvm/build/bin/FileCheck --check-prefixes=VF8UF1 /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-early-exit.ll # RUN: at line 2 + /home/nlopes/alive2/build/opt-alive.sh '-passes=loop-vectorize,verify<loops>' -force-vector-width=8 -force-vector-interleave=1 -enable-early-exit-vectorization -S /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-early-exit.ll + /bitbucket/nlopes/llvm/build/bin/FileCheck --check-prefixes=VF8UF1 /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-early-exit.ll FileCheck error: '<stdin>' is empty. FileCheck command line: /bitbucket/nlopes/llvm/build/bin/FileCheck --check-prefixes=VF8UF1 /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/vector-loop-backedge-elimination-early-exit.ll