diff --git a/circom/tests/loops/fib_input.circom b/circom/tests/loops/fib_input.circom index ac8362253..6b664f2e6 100644 --- a/circom/tests/loops/fib_input.circom +++ b/circom/tests/loops/fib_input.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template Fibonacci() { signal input nth_fib; @@ -11,7 +11,7 @@ template Fibonacci() { var next = 0; var counter = nth_fib; - while (counter > 2) { + while (counter > 2) { // unknown iteration count next = a + b; a = b; b = next; @@ -22,4 +22,14 @@ template Fibonacci() { out <-- (nth_fib == 0) ? 0 : (nth_fib == 1 ? 1 : a + b); } -component main = Fibonacci(); \ No newline at end of file +component main = Fibonacci(); + +//// Use the block labels to check that the loop is NOT unrolled +//CHECK-LABEL: define void @Fibonacci_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: loop.cond{{.*}}: +//CHECK: loop.body{{.*}}: +//CHECK: loop.end{{.*}}: +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: } diff --git a/circom/tests/loops/fib_template.circom b/circom/tests/loops/fib_template.circom index e6dc16a7b..c3ee4e755 100644 --- a/circom/tests/loops/fib_template.circom +++ b/circom/tests/loops/fib_template.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template FibonacciTmpl(N) { signal output out; @@ -10,7 +10,7 @@ template FibonacciTmpl(N) { var next = 0; var counter = N; - while (counter > 2) { + while (counter > 2) { // known iteration count next = a + b; a = b; b = next; @@ -27,4 +27,20 @@ template FibonacciTmpl(N) { } } -component main = FibonacciTmpl(5); \ No newline at end of file +component main = FibonacciTmpl(5); + +//CHECK-LABEL: define void @FibonacciTmpl_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//// Use the block labels to check that the loop is unrolled +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//CHECK: unrolled_loop{{.*}}: +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//// Check that final value stored to 'out' is computed correctly via unrolling +//CHECK: store{{[0-9]+}}: +//CHECK: %[[T:[0-9]+]] = getelementptr [0 x i256], [0 x i256]* %{{.*}}[[ARG]], i32 0, i32 0 +//CHECK: store i256 5, i256* %{{.*}}[[T]], align 4 +//CHECK: } diff --git a/circom/tests/loops/for_known.circom b/circom/tests/loops/for_known.circom index 3508ba4ae..77b7f14ae 100644 --- a/circom/tests/loops/for_known.circom +++ b/circom/tests/loops/for_known.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template ForKnown(N) { signal output out; @@ -13,4 +13,20 @@ template ForKnown(N) { out <-- acc; } -component main = ForKnown(10); \ No newline at end of file +component main = ForKnown(10); + +//CHECK-LABEL: define void @ForKnown_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//// Use the block labels to check that the loop is unrolled +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//CHECK: unrolled_loop{{.*}}: +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//// Check that final value stored to 'out' is computed correctly via unrolling +//CHECK: store{{[0-9]+}}: +//CHECK: %[[T:[0-9]+]] = getelementptr [0 x i256], [0 x i256]* %{{.*}}[[ARG]], i32 0, i32 0 +//CHECK: store i256 55, i256* %{{.*}}[[T]], align 4 +//CHECK: } diff --git a/circom/tests/loops/for_unknown.circom b/circom/tests/loops/for_unknown.circom index a93572610..888061553 100644 --- a/circom/tests/loops/for_unknown.circom +++ b/circom/tests/loops/for_unknown.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template ForUnknown() { signal input in; @@ -14,4 +14,14 @@ template ForUnknown() { out <-- acc; } -component main = ForUnknown(); \ No newline at end of file +component main = ForUnknown(); + +//// Use the block labels to check that the loop is NOT unrolled +//CHECK-LABEL: define void @ForUnknown_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: loop.cond{{.*}}: +//CHECK: loop.body{{.*}}: +//CHECK: loop.end{{.*}}: +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: } diff --git a/circom/tests/loops/for_unknown_index.circom b/circom/tests/loops/for_unknown_index.circom index 495e4b1ca..87bde3fbb 100644 --- a/circom/tests/loops/for_unknown_index.circom +++ b/circom/tests/loops/for_unknown_index.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template ForUnknownIndex() { signal input in; @@ -17,4 +17,14 @@ template ForUnknownIndex() { out <-- arr[acc]; } -component main = ForUnknownIndex(); \ No newline at end of file +component main = ForUnknownIndex(); + +//// Use the block labels to check that the loop is NOT unrolled +//CHECK-LABEL: define void @ForUnknownIndex_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: loop.cond{{.*}}: +//CHECK: loop.body{{.*}}: +//CHECK: loop.end{{.*}}: +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: } diff --git a/circom/tests/loops/inner_loops.circom b/circom/tests/loops/inner_loops.circom index d1b80e98f..7205dfb5f 100644 --- a/circom/tests/loops/inner_loops.circom +++ b/circom/tests/loops/inner_loops.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template InnerLoops(n) { signal input a[n]; @@ -8,9 +8,74 @@ template InnerLoops(n) { for (var i = 0; i < n; i++) { for (var j = 0; j <= i; j++) { - b[i] = a[i - j]; + b[i] += a[i - j]; } } } -component main = InnerLoops(2); \ No newline at end of file +component main = InnerLoops(2); +// +//ARG = { a[0], a[1] } +//lvars = { n, b[0], b[1], i, j } +//unrolled code: +// b[0] = b[0] + a[0 - 0 = 0]; +// b[1] = b[1] + a[1 - 0 = 1]; +// b[1] = b[1] + a[1 - 1 = 0]; +// +// +//CHECK-LABEL: define void @InnerLoops_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//// Use the block labels to check that the loop is unrolled and check the unrolled body +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//CHECK: unrolled_loop{{.*}}: +// // j = 0 +//CHECK-NEXT: %[[T01:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 4 +//CHECK-NEXT: store i256 0, i256* %{{.*}}[[T01]], align 4 +// // b[0] = b[0] + a[0] +//CHECK-NEXT: %[[T02:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 1 +//CHECK-NEXT: %[[T03:[[:alnum:]_.]+]] = load i256, i256* %{{.*}}[[T02]], align 4 +//CHECK-NEXT: %[[T04:[[:alnum:]_.]+]] = getelementptr [0 x i256], [0 x i256]* %{{.*}}[[ARG]], i32 0, i32 0 +//CHECK-NEXT: %[[T05:[[:alnum:]_.]+]] = load i256, i256* %{{.*}}[[T04]], align 4 +//CHECK-NEXT: %[[T06:[[:alnum:]_.]+]] = call i256 @fr_add(i256 %{{.*}}[[T03]], i256 %{{.*}}[[T05]]) +//CHECK-NEXT: %[[T07:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 1 +//CHECK-NEXT: store i256 %{{.*}}[[T06]], i256* %{{.*}}[[T07]], align 4 +// // j = 1 +//CHECK-NEXT: %[[T08:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 4 +//CHECK-NEXT: store i256 1, i256* %{{.*}}[[T08]], align 4 +// // i = 1 +//CHECK-NEXT: %[[T09:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 3 +//CHECK-NEXT: store i256 1, i256* %{{.*}}[[T09]], align 4 +// // j = 0 +//CHECK-NEXT: %[[T10:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 4 +//CHECK-NEXT: store i256 0, i256* %{{.*}}[[T10]], align 4 +// // b[1] = b[1] + a[1] +//CHECK-NEXT: %[[T11:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 2 +//CHECK-NEXT: %[[T12:[[:alnum:]_.]+]] = load i256, i256* %{{.*}}[[T11]], align 4 +//CHECK-NEXT: %[[T13:[[:alnum:]_.]+]] = getelementptr [0 x i256], [0 x i256]* %{{.*}}[[ARG]], i32 0, i32 1 +//CHECK-NEXT: %[[T14:[[:alnum:]_.]+]] = load i256, i256* %{{.*}}[[T13]], align 4 +//CHECK-NEXT: %[[T15:[[:alnum:]_.]+]] = call i256 @fr_add(i256 %{{.*}}[[T12]], i256 %{{.*}}[[T14]]) +//CHECK-NEXT: %[[T16:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 2 +//CHECK-NEXT: store i256 %{{.*}}[[T15]], i256* %{{.*}}[[T16]], align 4 +// // j = 1 +//CHECK-NEXT: %[[T17:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 4 +//CHECK-NEXT: store i256 1, i256* %{{.*}}[[T17]], align 4 +// // b[1] = b[1] + a[0] +//CHECK-NEXT: %[[T18:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 2 +//CHECK-NEXT: %[[T19:[[:alnum:]_.]+]] = load i256, i256* %{{.*}}[[T18]], align 4 +//CHECK-NEXT: %[[T20:[[:alnum:]_.]+]] = getelementptr [0 x i256], [0 x i256]* %{{.*}}[[ARG]], i32 0, i32 0 +//CHECK-NEXT: %[[T21:[[:alnum:]_.]+]] = load i256, i256* %{{.*}}[[T20]], align 4 +//CHECK-NEXT: %[[T22:[[:alnum:]_.]+]] = call i256 @fr_add(i256 %{{.*}}[[T19]], i256 %{{.*}}[[T21]]) +//CHECK-NEXT: %[[T23:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 2 +//CHECK-NEXT: store i256 %{{.*}}[[T22]], i256* %{{.*}}[[T23]], align 4 +// // j = 2 +//CHECK-NEXT: %[[T24:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 4 +//CHECK-NEXT: store i256 2, i256* %{{.*}}[[T24]], align 4 +// // i = 2 +//CHECK-NEXT: %[[T25:[[:alnum:]_.]+]] = getelementptr [5 x i256], [5 x i256]* %lvars, i32 0, i32 3 +//CHECK-NEXT: store i256 2, i256* %{{.*}}[[T25]], align 4 +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//CHECK: } diff --git a/circom/tests/loops/inner_loops2.circom b/circom/tests/loops/inner_loops2.circom index c9f5fecc6..fe405a82f 100644 --- a/circom/tests/loops/inner_loops2.circom +++ b/circom/tests/loops/inner_loops2.circom @@ -32,4 +32,4 @@ template InnerLoops(n) { i++; // 5 } -component main = InnerLoops(5); \ No newline at end of file +component main = InnerLoops(5); diff --git a/circom/tests/loops/inner_loops3.circom b/circom/tests/loops/inner_loops3.circom index bf735f369..9c193f329 100644 --- a/circom/tests/loops/inner_loops3.circom +++ b/circom/tests/loops/inner_loops3.circom @@ -23,4 +23,4 @@ template InnerLoops(n) { } } -component main = InnerLoops(5); \ No newline at end of file +component main = InnerLoops(5); diff --git a/circom/tests/loops/inner_loops4.circom b/circom/tests/loops/inner_loops4.circom index 0f636e23f..a85aa859b 100644 --- a/circom/tests/loops/inner_loops4.circom +++ b/circom/tests/loops/inner_loops4.circom @@ -13,4 +13,4 @@ template InnerLoops(n) { } } -component main = InnerLoops(2); \ No newline at end of file +component main = InnerLoops(2); diff --git a/circom/tests/loops/known_function.circom b/circom/tests/loops/known_function.circom new file mode 100644 index 000000000..65b837850 --- /dev/null +++ b/circom/tests/loops/known_function.circom @@ -0,0 +1,48 @@ +pragma circom 2.0.0; +// REQUIRES: circom +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s + +function funWithLoop(n) { + var acc = 0; + for (var i = 1; i <= n; i++) { + acc += i; + } + return acc; +} + +template KnownFunctionArgs() { + signal output out[3]; + + out[0] <-- funWithLoop(4); // 0 + 1 + 2 + 3 + 4 = 10 + out[1] <-- funWithLoop(5); // 0 + 1 + 2 + 3 + 4 + 5 = 15 + + var acc = 1; + for (var i = 2; i <= funWithLoop(3); i++) { + acc *= i; + } + out[2] <-- acc; // 1 * 2 * 3 * 4 * 5 * 6 = 720 +} + +component main = KnownFunctionArgs(); + +//CHECK-LABEL: define void @KnownFunctionArgs_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//// Check storing initial constant values to 'out' +//CHECK: store{{[0-9]+}}: +//CHECK: %[[T1:[0-9]+]] = getelementptr [0 x i256], [0 x i256]* %{{.*}}[[ARG]], i32 0, i32 0 +//CHECK: store i256 10, i256* %{{.*}}[[T1]], align 4 +//CHECK: store{{[0-9]+}}: +//CHECK: %[[T2:[0-9]+]] = getelementptr [0 x i256], [0 x i256]* %{{.*}}[[ARG]], i32 0, i32 1 +//CHECK: store i256 15, i256* %{{.*}}[[T2]], align 4 +//// Use the block labels to check that the loop is unrolled +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//CHECK: unrolled_loop{{.*}}: +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//// Check that final value stored to 'out' is computed correctly via unrolling +//CHECK: store{{[0-9]+}}: +//CHECK: %[[T3:[0-9]+]] = getelementptr [0 x i256], [0 x i256]* %{{.*}}[[ARG]], i32 0, i32 2 +//CHECK: store i256 720, i256* %{{.*}}[[T3]], align 4 diff --git a/circom/tests/loops/known_signal_value.circom b/circom/tests/loops/known_signal_value.circom new file mode 100644 index 000000000..6038f1785 --- /dev/null +++ b/circom/tests/loops/known_signal_value.circom @@ -0,0 +1,39 @@ +pragma circom 2.0.0; +// REQUIRES: circom +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s + +template accumulate() { + signal input i; + signal output o; + var r = 0; + while (r < i) { + r++; + } + o <-- r; +} + +template KnownLoopViaSignal() { + signal output y; + + component a = accumulate(); + a.i <-- 5; + y <-- a.o; +} + +component main = KnownLoopViaSignal(); + +//// Use the block labels to check that the loop is NOT unrolled +//CHECK-LABEL: define void @accumulate_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: loop.cond{{.*}}: +//CHECK: loop.body{{.*}}: +//CHECK: loop.end{{.*}}: +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: } + +//// Use the block labels to check that no loop related blocks are present +//CHECK-LABEL: define void @KnownLoopViaSignal_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: {{.*}}loop{{.*}}: +//CHECK: } diff --git a/circom/tests/loops/unknown_local_array_index.circom b/circom/tests/loops/unknown_local_array_index.circom index fae97a25b..77b690851 100644 --- a/circom/tests/loops/unknown_local_array_index.circom +++ b/circom/tests/loops/unknown_local_array_index.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template ForUnknownIndex() { signal input in; @@ -20,4 +20,14 @@ template ForUnknownIndex() { out <-- arr2[acc % 10]; } -component main = ForUnknownIndex(); \ No newline at end of file +component main = ForUnknownIndex(); + +//// Use the block labels to check that the loop is NOT unrolled +//CHECK-LABEL: define void @ForUnknownIndex_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: loop.cond{{.*}}: +//CHECK: loop.body{{.*}}: +//CHECK: loop.end{{.*}}: +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: } diff --git a/circom/tests/loops/unknown_loop_component.circom b/circom/tests/loops/unknown_loop_component.circom index 6dbbe60f8..e20626b59 100644 --- a/circom/tests/loops/unknown_loop_component.circom +++ b/circom/tests/loops/unknown_loop_component.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template nbits() { signal input in; @@ -23,4 +23,20 @@ template UnknownLoopComponent() { bits <-- nb.out; } -component main = UnknownLoopComponent(); \ No newline at end of file +component main = UnknownLoopComponent(); + +//// Use the block labels to check that the loop is NOT unrolled +//CHECK-LABEL: define void @nbits_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: loop.cond{{.*}}: +//CHECK: loop.body{{.*}}: +//CHECK: loop.end{{.*}}: +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: } + +//// Use the block labels to check that no loop related blocks are present +//CHECK-LABEL: define void @UnknownLoopComponent_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: {{.*}}loop{{.*}}: +//CHECK: } diff --git a/circom/tests/loops/unknown_loop_index.circom b/circom/tests/loops/unknown_loop_index.circom index 357841e32..b9656b80f 100644 --- a/circom/tests/loops/unknown_loop_index.circom +++ b/circom/tests/loops/unknown_loop_index.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template Num2Bits(n) { signal input in; @@ -64,4 +64,38 @@ template UnknownLoopIndex(n) { out <-- choices[c.out]; } -component main = UnknownLoopIndex(100); \ No newline at end of file +component main = UnknownLoopIndex(100); + +//// Use the block labels to check that the loop is unrolled +//CHECK-LABEL: define void @Num2Bits_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//CHECK: unrolled_loop{{.*}}: +//CHECK-NOT: loop.cond{{.*}}: +//CHECK-NOT: loop.body{{.*}}: +//CHECK-NOT: loop.end{{.*}}: +//CHECK: } + +//// Use the block labels to check that no loop related blocks are present +//CHECK-LABEL: define void @LessThan_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: {{.*}}loop{{.*}}: +//CHECK: } + +//// Use the block labels to check that the loop is NOT unrolled +//CHECK-LABEL: define void @CountDown_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: loop.cond{{.*}}: +//CHECK: loop.body{{.*}}: +//CHECK: loop.end{{.*}}: +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: } + +//// Use the block labels to check that no loop related blocks are present +//CHECK-LABEL: define void @UnknownLoopIndex_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: {{.*}}loop{{.*}}: +//CHECK: } diff --git a/circom/tests/loops/unknown_loop_oob.circom b/circom/tests/loops/unknown_loop_oob.circom index 5fed384d3..d167fb514 100644 --- a/circom/tests/loops/unknown_loop_oob.circom +++ b/circom/tests/loops/unknown_loop_oob.circom @@ -1,6 +1,6 @@ pragma circom 2.0.0; // REQUIRES: circom -// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s +// RUN: rm -rf %t && mkdir %t && %circom --llvm -o %t %s | sed -n 's/.*Written successfully:.* \(.*\)/\1/p' | xargs cat | FileCheck %s template accumulate() { signal input i; @@ -22,4 +22,20 @@ template UnknownLoopOOB() { y <-- n[a.o]; } -component main = UnknownLoopOOB(); \ No newline at end of file +component main = UnknownLoopOOB(); + +//// Use the block labels to check that the loop is NOT unrolled +//CHECK-LABEL: define void @accumulate_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: loop.cond{{.*}}: +//CHECK: loop.body{{.*}}: +//CHECK: loop.end{{.*}}: +//CHECK-NOT: unrolled_loop{{.*}}: +//CHECK: } + +//// Use the block labels to check that no loop related blocks are present +//CHECK-LABEL: define void @UnknownLoopOOB_{{[0-9]+}}_run +//CHECK-SAME: ([0 x i256]* %[[ARG:[0-9]+]]) +//CHECK-NOT: {{.*}}loop{{.*}}: +//CHECK: }