Test source: git
Comments: LLVM PR57523
Source: <stdin> -- 1. ModuleToFunctionPassAdaptor -- 1. PassManager<Function> : Skipping NOP -- 2. IRCEPass ---------------------------------------- define void @multiple_access_no_preloop(ptr %arr_a, ptr %a_len_ptr, ptr %arr_b, ptr %b_len_ptr, i32 %n) { entry: %len.a = load i32, ptr %a_len_ptr, align 4 %len.a_range = !range i32 %len.a, i32 0, i32 2147483647 %len.b = load i32, ptr %b_len_ptr, align 4 %len.b_range = !range i32 %len.b, i32 0, i32 2147483647 %first.itr.check = icmp sgt i32 %n, 0 br i1 %first.itr.check, label %loop, label %exit loop: %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds.b ] %idx.next = add i32 %idx, 1 %abc.a = icmp slt i32 %idx, %len.a_range br i1 %abc.a, label %in.bounds.a, label %out.of.bounds in.bounds.a: %addr.a = gep ptr %arr_a, 4 x i32 %idx store i32 0, ptr %addr.a, align 4 %abc.b = icmp slt i32 %idx, %len.b_range br i1 %abc.b, label %in.bounds.b, label %out.of.bounds in.bounds.b: %addr.b = gep ptr %arr_b, 4 x i32 %idx store i32 4294967295, ptr %addr.b, align 4 %next = icmp slt i32 %idx.next, %n br i1 %next, label %loop, label %exit exit: ret void out.of.bounds: ret void } Transformation seems to be correct! (syntactically equal) -- 3. IRCEPass ---------------------------------------- define void @multiple_access_no_preloop(ptr %arr_a, ptr %a_len_ptr, ptr %arr_b, ptr %b_len_ptr, i32 %n) { entry: %len.a = load i32, ptr %a_len_ptr, align 4 %len.a_range = !range i32 %len.a, i32 0, i32 2147483647 %len.b = load i32, ptr %b_len_ptr, align 4 %len.b_range = !range i32 %len.b, i32 0, i32 2147483647 %first.itr.check = icmp sgt i32 %n, 0 br i1 %first.itr.check, label %loop, label %exit loop: %idx = phi i32 [ 0, %entry ], [ %idx.next, %in.bounds.b ] %idx.next = add i32 %idx, 1 %abc.a = icmp slt i32 %idx, %len.a_range br i1 %abc.a, label %in.bounds.a, label %out.of.bounds in.bounds.a: %addr.a = gep ptr %arr_a, 4 x i32 %idx store i32 0, ptr %addr.a, align 4 %abc.b = icmp slt i32 %idx, %len.b_range br i1 %abc.b, label %in.bounds.b, label %out.of.bounds in.bounds.b: %addr.b = gep ptr %arr_b, 4 x i32 %idx store i32 4294967295, ptr %addr.b, align 4 %next = icmp slt i32 %idx.next, %n br i1 %next, label %loop, label %exit exit: ret void out.of.bounds: ret void } => define void @multiple_access_no_preloop(ptr %arr_a, ptr %a_len_ptr, ptr %arr_b, ptr %b_len_ptr, i32 %n) { entry: %len.a = load i32, ptr %a_len_ptr, align 4 %len.a_range = !range i32 %len.a, i32 0, i32 2147483647 %len.b = load i32, ptr %b_len_ptr, align 4 %len.b_range = !range i32 %len.b, i32 0, i32 2147483647 %first.itr.check = icmp sgt i32 %n, 0 br i1 %first.itr.check, label %loop.preheader, label %exit loop.preheader: %smin = smin i32 %len.b_range, %len.a_range %smin1 = smin i32 %smin, %n %exit.mainloop.at = smax i32 %smin1, 0 %#0 = icmp slt i32 0, %exit.mainloop.at br i1 %#0, label %loop.preheader2, label %main.pseudo.exit loop.preheader2: br label %loop loop: %idx = phi i32 [ %idx.next, %in.bounds.b ], [ 0, %loop.preheader2 ] %idx.next = add nsw i32 %idx, 1 br i1 1, label %in.bounds.a, label %out.of.bounds.loopexit3 in.bounds.a: %addr.a = gep ptr %arr_a, 4 x i32 %idx store i32 0, ptr %addr.a, align 4 br i1 1, label %in.bounds.b, label %out.of.bounds.loopexit3 in.bounds.b: %addr.b = gep ptr %arr_b, 4 x i32 %idx store i32 4294967295, ptr %addr.b, align 4 %#1 = icmp slt i32 %idx.next, %exit.mainloop.at br i1 %#1, label %loop, label %main.exit.selector main.exit.selector: %idx.next.lcssa = phi i32 [ %idx.next, %in.bounds.b ] %#2 = icmp slt i32 %idx.next.lcssa, %n br i1 %#2, label %main.pseudo.exit, label %exit.loopexit out.of.bounds.loopexit3: br label %out.of.bounds main.pseudo.exit: %idx.copy = phi i32 [ 0, %loop.preheader ], [ %idx.next.lcssa, %main.exit.selector ] br label %postloop postloop: br label %loop.postloop loop.postloop: %idx.postloop = phi i32 [ %idx.next.postloop, %in.bounds.b.postloop ], [ %idx.copy, %postloop ] %idx.next.postloop = add i32 %idx.postloop, 1 %abc.a.postloop = icmp slt i32 %idx.postloop, %len.a_range br i1 %abc.a.postloop, label %in.bounds.a.postloop, label %out.of.bounds.loopexit in.bounds.a.postloop: %addr.a.postloop = gep ptr %arr_a, 4 x i32 %idx.postloop store i32 0, ptr %addr.a.postloop, align 4 %abc.b.postloop = icmp slt i32 %idx.postloop, %len.b_range br i1 %abc.b.postloop, label %in.bounds.b.postloop, label %out.of.bounds.loopexit in.bounds.b.postloop: %addr.b.postloop = gep ptr %arr_b, 4 x i32 %idx.postloop store i32 4294967295, ptr %addr.b.postloop, align 4 %next.postloop = icmp slt i32 %idx.next.postloop, %n br i1 %next.postloop, label %loop.postloop, label %exit.loopexit.loopexit exit.loopexit.loopexit: br label %exit.loopexit exit.loopexit: br label %exit exit: ret void out.of.bounds.loopexit: br label %out.of.bounds out.of.bounds: ret void } Transformation doesn't verify! (unsound) ERROR: Source is more defined than target Example: ptr %arr_a = poison ptr %a_len_ptr = pointer(non-local, block_id=2, offset=0) / Address=#x000000000c ptr %arr_b = poison ptr %b_len_ptr = pointer(non-local, block_id=4, offset=0) / Address=#x0000000004 i32 %n = #x00000002 (2) Source: i32 %len.a = #x00000000 (0) i32 %len.a_range = #x00000000 (0) i32 %len.b = #x80000010 (2147483664, -2147483632) i32 %len.b_range = poison i1 %first.itr.check = #x1 (1) >> Jump to %loop i32 %idx = #x00000000 (0) i32 %idx.next = #x00000001 (1) i1 %abc.a = #x0 (0) >> Jump to %out.of.bounds SOURCE MEMORY STATE =================== NON-LOCAL BLOCKS: Block 0 > size: 0 align: 4 alloc type: 0 alive: false address: 0 Block 1 > size: 1 align: 1 alloc type: 0 alive: true address: 2 Block 2 > size: 7 align: 4 alloc type: 0 alive: true address: 12 Contents: 0: #x00000000 *: poison Block 3 > size: 2 align: 1 alloc type: 0 alive: true address: 9 Block 4 > size: 5 align: 1 alloc type: 0 alive: true address: 4 Contents: *: #x80000010 Target: i32 %len.a = #x00000000 (0) i32 %len.a_range = #x00000000 (0) i32 %len.b = #x80000010 (2147483664, -2147483632) i32 %len.b_range = poison i1 %first.itr.check = #x1 (1) >> Jump to %loop.preheader i32 %smin = poison i32 %smin1 = poison i32 %exit.mainloop.at = poison i1 %#0 = poison UB triggered on br Pass: IRCEPass 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' '-verify-loop-info' '-passes=irce' '-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_kzUvvMAa_tI9y.bc" ------------------- SMT STATS ------------------- Num queries: 64 Num invalid: 0 Num skips: 0 Num trivial: 14 (17.9%) Num timeout: 0 (0.0%) Num errors: 0 (0.0%) Num SAT: 45 (70.3%) Num UNSAT: 19 (29.7%) Alive2: Transform doesn't verify; aborting!
RUN: at line 2: /home/nlopes/alive2/build/opt-alive.sh -verify-loop-info -passes=irce -S < /bitbucket/nlopes/llvm/llvm/test/Transforms/IRCE/multiple-access-no-preloop.ll | /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/IRCE/multiple-access-no-preloop.ll + /home/nlopes/alive2/build/opt-alive.sh -verify-loop-info -passes=irce -S + /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/IRCE/multiple-access-no-preloop.ll FileCheck error: '<stdin>' is empty. FileCheck command line: /bitbucket/nlopes/llvm/build/bin/FileCheck /bitbucket/nlopes/llvm/llvm/test/Transforms/IRCE/multiple-access-no-preloop.ll