Test source: git
Source: /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/trip-count-expansion-may-introduce-ub.ll
-- 1. ModuleToFunctionPassAdaptor
-- 1. PassManager<Function> : Skipping NOP
-- 2. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_1_exit_count_with_udiv_by_value_in_header(ptr %dst, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation seems to be correct! (syntactically equal)
-- 3. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_1_exit_count_with_udiv_by_value_in_header(ptr %dst, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
=>
define i64 @multi_exit_1_exit_count_with_udiv_by_value_in_header(ptr %dst, i64 %N) {
entry:
%smax = smax i64 %N, 0
%#0 = udiv i64 42, %N
%umin = umin i64 %smax, %#0
%#1 = add nsw nuw i64 %umin, 1
%min.iters.check = icmp ule i64 %#1, 4
br i1 %min.iters.check, label %scalar.ph, label %vector.ph
vector.ph:
%n.mod.vf = urem i64 %#1, 4
%#2 = icmp eq i64 %n.mod.vf, 0
%#3 = select i1 %#2, i64 4, i64 %n.mod.vf
%n.vec = sub i64 %#1, %#3
br label %vector.body
vector.body:
%index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
%#4 = add i64 %index, 0
%#5 = gep inbounds ptr %dst, 4 x i64 %#4
%#6 = gep inbounds ptr %#5, 4 x i32 0
store <4 x i32> { 1, 1, 1, 1 }, ptr %#6, align 4
%index.next = add nuw i64 %index, 4
%#7 = icmp eq i64 %index.next, %n.vec
br i1 %#7, label %middle.block, label %vector.body
middle.block:
br label %scalar.ph
scalar.ph:
%bc.resume.val = phi i64 [ %n.vec, %middle.block ], [ 0, %entry ]
br label %loop.header
loop.header:
%iv = phi i64 [ %bc.resume.val, %scalar.ph ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation doesn't verify! (not unsound)
ERROR: Timeout
-- 4. PassManager<Function> : Skipping NOP
-- 5. PassManager<Function> : Skipping NOP
-- 6. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_1_exit_count_with_udiv_by_constant_in_header(ptr %dst, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%d = udiv i64 %N, 42
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation seems to be correct! (syntactically equal)
-- 7. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_1_exit_count_with_udiv_by_constant_in_header(ptr %dst, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%d = udiv i64 %N, 42
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
=>
define i64 @multi_exit_1_exit_count_with_udiv_by_constant_in_header(ptr %dst, i64 %N) {
entry:
%smax = smax i64 %N, 0
%#0 = udiv i64 %N, 42
%umin = umin i64 %smax, %#0
%#1 = add nsw nuw i64 %umin, 1
%min.iters.check = icmp ule i64 %#1, 4
br i1 %min.iters.check, label %scalar.ph, label %vector.ph
vector.ph:
%n.mod.vf = urem i64 %#1, 4
%#2 = icmp eq i64 %n.mod.vf, 0
%#3 = select i1 %#2, i64 4, i64 %n.mod.vf
%n.vec = sub i64 %#1, %#3
br label %vector.body
vector.body:
%index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
%#4 = add i64 %index, 0
%#5 = gep inbounds ptr %dst, 4 x i64 %#4
%#6 = gep inbounds ptr %#5, 4 x i32 0
store <4 x i32> { 1, 1, 1, 1 }, ptr %#6, align 4
%index.next = add nuw i64 %index, 4
%#7 = icmp eq i64 %index.next, %n.vec
br i1 %#7, label %middle.block, label %vector.body
middle.block:
br label %scalar.ph
scalar.ph:
%bc.resume.val = phi i64 [ %n.vec, %middle.block ], [ 0, %entry ]
br label %loop.header
loop.header:
%iv = phi i64 [ %bc.resume.val, %scalar.ph ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%d = udiv i64 %N, 42
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation doesn't verify! (not unsound)
ERROR: Timeout
-- 8. PassManager<Function> : Skipping NOP
-- 9. PassManager<Function> : Skipping NOP
-- 10. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_2_exit_count_with_udiv_by_value_in_block_executed_unconditionally(ptr %A, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %continue
then:
store i32 1, ptr %gep, align 4
br label %continue
continue:
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %continue ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation seems to be correct! (syntactically equal)
-- 11. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_2_exit_count_with_udiv_by_value_in_block_executed_unconditionally(ptr %A, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %continue
then:
store i32 1, ptr %gep, align 4
br label %continue
continue:
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %continue ], [ 0, %loop.latch ]
ret i64 %p
}
=>
define i64 @multi_exit_2_exit_count_with_udiv_by_value_in_block_executed_unconditionally(ptr %A, i64 %N) {
entry:
%smax = smax i64 %N, 0
%#0 = udiv i64 42, %N
%umin = umin i64 %smax, %#0
%#1 = add nsw nuw i64 %umin, 1
%min.iters.check = icmp ule i64 %#1, 4
br i1 %min.iters.check, label %scalar.ph, label %vector.ph
vector.ph:
%n.mod.vf = urem i64 %#1, 4
%#2 = icmp eq i64 %n.mod.vf, 0
%#3 = select i1 %#2, i64 4, i64 %n.mod.vf
%n.vec = sub i64 %#1, %#3
br label %vector.body
vector.body:
%index = phi i64 [ 0, %vector.ph ], [ %index.next, %pred.store.continue6 ]
%#4 = add i64 %index, 0
%#5 = gep inbounds ptr %A, 4 x i64 %#4
%#6 = gep inbounds ptr %#5, 4 x i32 0
%wide.load = load <4 x i32>, ptr %#6, align 4
%#7 = icmp eq <4 x i32> %wide.load, { 10, 10, 10, 10 }
%#8 = extractelement <4 x i1> %#7, i32 0
br i1 %#8, label %pred.store.if, label %pred.store.continue
pred.store.if:
%#9 = gep inbounds ptr %A, 4 x i64 %#4
store i32 1, ptr %#9, align 4
br label %pred.store.continue
pred.store.continue:
%#10 = extractelement <4 x i1> %#7, i32 1
br i1 %#10, label %pred.store.if1, label %pred.store.continue2
pred.store.if1:
%#11 = add i64 %index, 1
%#12 = gep inbounds ptr %A, 4 x i64 %#11
store i32 1, ptr %#12, align 4
br label %pred.store.continue2
pred.store.continue2:
%#13 = extractelement <4 x i1> %#7, i32 2
br i1 %#13, label %pred.store.if3, label %pred.store.continue4
pred.store.if3:
%#14 = add i64 %index, 2
%#15 = gep inbounds ptr %A, 4 x i64 %#14
store i32 1, ptr %#15, align 4
br label %pred.store.continue4
pred.store.continue4:
%#16 = extractelement <4 x i1> %#7, i32 3
br i1 %#16, label %pred.store.if5, label %pred.store.continue6
pred.store.if5:
%#17 = add i64 %index, 3
%#18 = gep inbounds ptr %A, 4 x i64 %#17
store i32 1, ptr %#18, align 4
br label %pred.store.continue6
pred.store.continue6:
%index.next = add nuw i64 %index, 4
%#19 = icmp eq i64 %index.next, %n.vec
br i1 %#19, label %middle.block, label %vector.body
middle.block:
br label %scalar.ph
scalar.ph:
%bc.resume.val = phi i64 [ %n.vec, %middle.block ], [ 0, %entry ]
br label %loop.header
loop.header:
%iv = phi i64 [ %bc.resume.val, %scalar.ph ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %continue
then:
store i32 1, ptr %gep, align 4
br label %continue
continue:
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %continue ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation doesn't verify! (not unsound)
ERROR: Timeout
-- 12. PassManager<Function> : Skipping NOP
-- 13. PassManager<Function> : Skipping NOP
-- 14. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_2_exit_count_with_udiv_by_constant_in_block_executed_unconditionally(ptr %A, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %continue
then:
store i32 1, ptr %gep, align 4
br label %continue
continue:
%d = udiv i64 %N, 42
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %continue ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation seems to be correct! (syntactically equal)
-- 15. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_2_exit_count_with_udiv_by_constant_in_block_executed_unconditionally(ptr %A, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %continue
then:
store i32 1, ptr %gep, align 4
br label %continue
continue:
%d = udiv i64 %N, 42
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %continue ], [ 0, %loop.latch ]
ret i64 %p
}
=>
define i64 @multi_exit_2_exit_count_with_udiv_by_constant_in_block_executed_unconditionally(ptr %A, i64 %N) {
entry:
%smax = smax i64 %N, 0
%#0 = udiv i64 %N, 42
%umin = umin i64 %smax, %#0
%#1 = add nsw nuw i64 %umin, 1
%min.iters.check = icmp ule i64 %#1, 4
br i1 %min.iters.check, label %scalar.ph, label %vector.ph
vector.ph:
%n.mod.vf = urem i64 %#1, 4
%#2 = icmp eq i64 %n.mod.vf, 0
%#3 = select i1 %#2, i64 4, i64 %n.mod.vf
%n.vec = sub i64 %#1, %#3
br label %vector.body
vector.body:
%index = phi i64 [ 0, %vector.ph ], [ %index.next, %pred.store.continue6 ]
%#4 = add i64 %index, 0
%#5 = gep inbounds ptr %A, 4 x i64 %#4
%#6 = gep inbounds ptr %#5, 4 x i32 0
%wide.load = load <4 x i32>, ptr %#6, align 4
%#7 = icmp eq <4 x i32> %wide.load, { 10, 10, 10, 10 }
%#8 = extractelement <4 x i1> %#7, i32 0
br i1 %#8, label %pred.store.if, label %pred.store.continue
pred.store.if:
%#9 = gep inbounds ptr %A, 4 x i64 %#4
store i32 1, ptr %#9, align 4
br label %pred.store.continue
pred.store.continue:
%#10 = extractelement <4 x i1> %#7, i32 1
br i1 %#10, label %pred.store.if1, label %pred.store.continue2
pred.store.if1:
%#11 = add i64 %index, 1
%#12 = gep inbounds ptr %A, 4 x i64 %#11
store i32 1, ptr %#12, align 4
br label %pred.store.continue2
pred.store.continue2:
%#13 = extractelement <4 x i1> %#7, i32 2
br i1 %#13, label %pred.store.if3, label %pred.store.continue4
pred.store.if3:
%#14 = add i64 %index, 2
%#15 = gep inbounds ptr %A, 4 x i64 %#14
store i32 1, ptr %#15, align 4
br label %pred.store.continue4
pred.store.continue4:
%#16 = extractelement <4 x i1> %#7, i32 3
br i1 %#16, label %pred.store.if5, label %pred.store.continue6
pred.store.if5:
%#17 = add i64 %index, 3
%#18 = gep inbounds ptr %A, 4 x i64 %#17
store i32 1, ptr %#18, align 4
br label %pred.store.continue6
pred.store.continue6:
%index.next = add nuw i64 %index, 4
%#19 = icmp eq i64 %index.next, %n.vec
br i1 %#19, label %middle.block, label %vector.body
middle.block:
br label %scalar.ph
scalar.ph:
%bc.resume.val = phi i64 [ %n.vec, %middle.block ], [ 0, %entry ]
br label %loop.header
loop.header:
%iv = phi i64 [ %bc.resume.val, %scalar.ph ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %continue
then:
store i32 1, ptr %gep, align 4
br label %continue
continue:
%d = udiv i64 %N, 42
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %continue ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation doesn't verify! (not unsound)
ERROR: Timeout
-- 16. PassManager<Function> : Skipping NOP
-- 17. PassManager<Function> : Skipping NOP
-- 18. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_3_exit_count_with_udiv_by_value_in_block_executed_conditionally(ptr %A, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %loop.latch
then:
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
store i32 1, ptr %gep, align 4
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %then ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation seems to be correct! (syntactically equal)
-- 19. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_3_exit_count_with_udiv_by_value_in_block_executed_conditionally(ptr %A, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %loop.latch
then:
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
store i32 1, ptr %gep, align 4
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %then ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation seems to be correct! (syntactically equal)
-- 20. PassManager<Function> : Skipping NOP
-- 21. PassManager<Function> : Skipping NOP
-- 22. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_3_exit_count_with_udiv_by_constant_in_block_executed_conditionally(ptr %A, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %loop.latch
then:
%d = udiv i64 %N, 42
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
store i32 1, ptr %gep, align 4
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %then ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation seems to be correct! (syntactically equal)
-- 23. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_3_exit_count_with_udiv_by_constant_in_block_executed_conditionally(ptr %A, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp eq i32 %l, 10
br i1 %c.2, label %then, label %loop.latch
then:
%d = udiv i64 %N, 42
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.latch, label %exit
loop.latch:
store i32 1, ptr %gep, align 4
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %then ], [ 0, %loop.latch ]
ret i64 %p
}
=>
define i64 @multi_exit_3_exit_count_with_udiv_by_constant_in_block_executed_conditionally(ptr %A, i64 %N) {
entry:
%d = udiv i64 %N, 42
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %A, 4 x i64 %iv
%l = load i32, ptr %gep, align 4
%c.2 = icmp ne i32 %l, 10
%c.1 = icmp slt i64 %iv, %d
%or.cond = select i1 %c.2, i1 1, i1 %c.1
br i1 %or.cond, label %loop.latch, label %exit
loop.latch:
store i32 1, ptr %gep, align 4
%iv.next = add i64 %iv, 1
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.header, label %exit
exit:
%p = phi i64 [ 0, %loop.latch ], [ 1, %loop.header ]
ret i64 %p
}
Transformation seems to be correct!
-- 24. PassManager<Function> : Skipping NOP
-- 25. PassManager<Function> : Skipping NOP
-- 26. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch(ptr %dst, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation seems to be correct! (syntactically equal)
-- 27. LoopVectorizePass
----------------------------------------
define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch(ptr %dst, i64 %N) {
entry:
br label %loop.header
loop.header:
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
=>
define i64 @multi_exit_4_exit_count_with_udiv_by_value_in_latch(ptr %dst, i64 %N) {
entry:
%smax = smax i64 %N, 0
%#0 = udiv i64 42, %N
%umin = umin i64 %smax, %#0
%#1 = add nsw nuw i64 %umin, 1
%min.iters.check = icmp ule i64 %#1, 4
br i1 %min.iters.check, label %scalar.ph, label %vector.ph
vector.ph:
%n.mod.vf = urem i64 %#1, 4
%#2 = icmp eq i64 %n.mod.vf, 0
%#3 = select i1 %#2, i64 4, i64 %n.mod.vf
%n.vec = sub i64 %#1, %#3
br label %vector.body
vector.body:
%index = phi i64 [ 0, %vector.ph ], [ %index.next, %vector.body ]
%#4 = add i64 %index, 0
%#5 = gep inbounds ptr %dst, 4 x i64 %#4
%#6 = gep inbounds ptr %#5, 4 x i32 0
store <4 x i32> { 1, 1, 1, 1 }, ptr %#6, align 4
%index.next = add nuw i64 %index, 4
%#7 = icmp eq i64 %index.next, %n.vec
br i1 %#7, label %middle.block, label %vector.body
middle.block:
br label %scalar.ph
scalar.ph:
%bc.resume.val = phi i64 [ %n.vec, %middle.block ], [ 0, %entry ]
br label %loop.header
loop.header:
%iv = phi i64 [ %bc.resume.val, %scalar.ph ], [ %iv.next, %loop.latch ]
%gep = gep inbounds ptr %dst, 4 x i64 %iv
store i32 1, ptr %gep, align 4
%c.0 = icmp slt i64 %iv, %N
br i1 %c.0, label %loop.latch, label %exit
loop.latch:
%iv.next = add i64 %iv, 1
%d = udiv i64 42, %N
%c.1 = icmp slt i64 %iv, %d
br i1 %c.1, label %loop.header, label %exit
exit:
%p = phi i64 [ 1, %loop.header ], [ 0, %loop.latch ]
ret i64 %p
}
Transformation doesn't verify! (unsound)
ERROR: Source is more defined than target
Example:
ptr %dst = pointer(non-local, block_id=1, offset=0) / Address=#x0000000000000004
i64 %N = #x0000000000000000 (0)
Source:
>> Jump to %loop.header
i64 %iv = #x0000000000000000 (0)
ptr %gep = pointer(non-local, block_id=1, offset=0) / Address=#x0000000000000004
i1 %c.0 = #x0 (0)
>> Jump to %exit
i64 %p = #x0000000000000001 (1)
SOURCE MEMORY STATE
===================
NON-LOCAL BLOCKS:
Block 0 > size: 0 align: 4 alloc type: 0 alive: false address: 0
Block 1 > size: 8 align: 1 alloc type: 0 alive: true address: 4
Target:
i64 %smax = #x0000000000000000 (0)
i64 %#0 = UB triggered!
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' '-p' 'loop-vectorize' '-force-vector-width=4' '-S' '/bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/trip-count-expansion-may-introduce-ub.ll' '-tv-smt-to=20000' '-tv-report-dir=/home/nlopes/alive2/build/logs' '-tv-smt-stats'
Wrote bitcode to: "/home/nlopes/alive2/build/logs/trip-count-expansion-may-introduce-ub_2OKPvoNS_zuKo.bc"
------------------- SMT STATS -------------------
Num queries: 57
Num invalid: 0
Num skips: 0
Num trivial: 11 (16.2%)
Num timeout: 4 (7.0%)
Num errors: 0 (0.0%)
Num SAT: 40 (70.2%)
Num UNSAT: 13 (22.8%)
Alive2: Transform doesn't verify; aborting!
RUN: at line 2: /home/nlopes/alive2/build/opt-alive.sh -p loop-vectorize -force-vector-width=4 -S /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/trip-count-expansion-may-introduce-ub.ll | /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/trip-count-expansion-may-introduce-ub.ll + /home/nlopes/alive2/build/opt-alive.sh -p loop-vectorize -force-vector-width=4 -S /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/trip-count-expansion-may-introduce-ub.ll + /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/trip-count-expansion-may-introduce-ub.ll remark: <unknown>:0:0: loop not vectorized: could not determine number of loop iterations remark: <unknown>:0:0: loop not vectorized: could not determine number of loop iterations FileCheck error: '<stdin>' is empty. FileCheck command line: /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/LoopVectorize/trip-count-expansion-may-introduce-ub.ll