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