forked from iden3/circom
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* skip body extraction when the loop has 0 iterations * Modify interpreter to distinguish between circom functions and loop body functions * [VAN-676] duplicate extracted functions when flattening branch buckets * [VAN-670] generate and flatten subcmp counter/run * impl Debug for Env to be more friendly, expand on test case comment * remove debug println * fix: conditions not flattening in non-generated methods * [VAN-582] properly convert mapped to indexed when there are multiple versions of the subcomponent * fix XFAIL test outputs so they pass * add test cases * handle CallBucket return case in mapped_to_indexed * fix body_extractor assertion failure * fix segfault from improper GEP * use BucketId as key to speed up SimplificationPass * fix function name to reflect actual usage * Remove functions that cannot be reached from any template Co-authored-by: Daniel Dominguez <[email protected]>
- Loading branch information
1 parent
e6c4f14
commit 8cc3b56
Showing
54 changed files
with
4,084 additions
and
1,062 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
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 --enable-var-scope | ||
|
||
template Inner() { | ||
signal input in; | ||
signal output out; | ||
|
||
out <-- in & 1; | ||
} | ||
|
||
template Num2Bits(n) { | ||
signal input in; | ||
signal output out[n]; | ||
|
||
component c[n]; | ||
for (var i = 0; i < n; i++) { | ||
c[i] = Inner(); | ||
c[i].in <-- in; | ||
out[i] <-- c[i].out; | ||
} | ||
} | ||
|
||
component main = Num2Bits(3); | ||
|
||
//CHECK-LABEL: define void @..generated..loop.body.{{[0-9]+\.T}}([0 x i256]* %lvars, [0 x i256]* %signals, | ||
//CHECK-SAME: i256* %subfix_[[X1:[0-9]+]], i256* %fix_[[X2:[0-9]+]], i256* %subfix_[[X3:[0-9]+]], | ||
//CHECK-SAME: [0 x i256]* %sub_[[X3]], i256* %subc_[[X3]]){{.*}} { | ||
//CHECK-NEXT: ..generated..loop.body.[[$F_ID_1:[0-9]+\.T]]: | ||
//CHECK-NEXT: br label %store1 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: store1: | ||
//CHECK-NEXT: %0 = getelementptr [0 x i256], [0 x i256]* %signals, i32 0, i32 3 | ||
//CHECK-NEXT: %1 = load i256, i256* %0, align 4 | ||
//CHECK-NEXT: %2 = getelementptr i256, i256* %subfix_[[X1]], i32 0 | ||
//CHECK-NEXT: store i256 %1, i256* %2, align 4 | ||
//CHECK-NEXT: br label %store2 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: store2: | ||
//CHECK-NEXT: %3 = load i256, i256* %subc_[[X3]], align 4 | ||
//CHECK-NEXT: %call.fr_sub = call i256 @fr_sub(i256 %3, i256 1) | ||
//CHECK-NEXT: %4 = getelementptr i256, i256* %subc_[[X3]], i32 0 | ||
//CHECK-NEXT: store i256 %call.fr_sub, i256* %4, align 4 | ||
//CHECK-NEXT: br label %fold_true3 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: fold_true3: | ||
//CHECK-NEXT: call void @llvm.donothing() | ||
//CHECK-NEXT: call void @Inner_0_run([0 x i256]* %sub_[[X3]]) | ||
//CHECK-NEXT: br label %store4 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: store4: | ||
//CHECK-NEXT: %5 = getelementptr i256, i256* %subfix_[[X3]], i32 0 | ||
//CHECK-NEXT: %6 = load i256, i256* %5, align 4 | ||
//CHECK-NEXT: %7 = getelementptr i256, i256* %fix_[[X2]], i32 0 | ||
//CHECK-NEXT: store i256 %6, i256* %7, align 4 | ||
//CHECK-NEXT: br label %store5 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: store5: | ||
//CHECK-NEXT: %8 = getelementptr [0 x i256], [0 x i256]* %lvars, i32 0, i32 1 | ||
//CHECK-NEXT: %9 = load i256, i256* %8, align 4 | ||
//CHECK-NEXT: %call.fr_add = call i256 @fr_add(i256 %9, i256 1) | ||
//CHECK-NEXT: %10 = getelementptr [0 x i256], [0 x i256]* %lvars, i32 0, i32 1 | ||
//CHECK-NEXT: store i256 %call.fr_add, i256* %10, align 4 | ||
//CHECK-NEXT: br label %return6 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: return6: | ||
//CHECK-NEXT: ret void | ||
//CHECK-NEXT: } | ||
// | ||
//CHECK-LABEL: define void @Num2Bits_{{[0-9]+}}_run([0 x i256]* %0){{.*}} { | ||
//CHECK-NEXT: prelude: | ||
//CHECK-NEXT: %lvars = alloca [2 x i256], align 8 | ||
//CHECK-NEXT: %subcmps = alloca [3 x { [0 x i256]*, i32 }], align 8 | ||
//CHECK-NEXT: br label %store1 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: store1: | ||
//CHECK-NEXT: %1 = getelementptr [2 x i256], [2 x i256]* %lvars, i32 0, i32 0 | ||
//CHECK-NEXT: store i256 3, i256* %1, align 4 | ||
//CHECK-NEXT: br label %create_cmp2 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: create_cmp2: | ||
//CHECK-NEXT: %2 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 0 | ||
//CHECK-NEXT: call void @Inner_0_build({ [0 x i256]*, i32 }* %2) | ||
//CHECK-NEXT: %3 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 1 | ||
//CHECK-NEXT: call void @Inner_0_build({ [0 x i256]*, i32 }* %3) | ||
//CHECK-NEXT: %4 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 2 | ||
//CHECK-NEXT: call void @Inner_0_build({ [0 x i256]*, i32 }* %4) | ||
//CHECK-NEXT: br label %store3 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: store3: | ||
//CHECK-NEXT: %5 = getelementptr [2 x i256], [2 x i256]* %lvars, i32 0, i32 1 | ||
//CHECK-NEXT: store i256 0, i256* %5, align 4 | ||
//CHECK-NEXT: br label %unrolled_loop4 | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: unrolled_loop4: | ||
//CHECK-NEXT: %6 = bitcast [2 x i256]* %lvars to [0 x i256]* | ||
//CHECK-NEXT: %7 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 0, i32 0 | ||
//CHECK-NEXT: %8 = load [0 x i256]*, [0 x i256]** %7, align 8 | ||
//CHECK-NEXT: %9 = getelementptr [0 x i256], [0 x i256]* %8, i32 0 | ||
//CHECK-NEXT: %10 = getelementptr [0 x i256], [0 x i256]* %9, i32 0, i256 1 | ||
//CHECK-NEXT: %11 = getelementptr [0 x i256], [0 x i256]* %0, i32 0, i256 0 | ||
//CHECK-NEXT: %12 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 0, i32 0 | ||
//CHECK-NEXT: %13 = load [0 x i256]*, [0 x i256]** %12, align 8 | ||
//CHECK-NEXT: %14 = getelementptr [0 x i256], [0 x i256]* %13, i32 0 | ||
//CHECK-NEXT: %15 = getelementptr [0 x i256], [0 x i256]* %14, i32 0, i256 0 | ||
//CHECK-NEXT: %16 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 0, i32 0 | ||
//CHECK-NEXT: %17 = load [0 x i256]*, [0 x i256]** %16, align 8 | ||
//CHECK-NEXT: %18 = getelementptr [0 x i256], [0 x i256]* %17, i32 0 | ||
//CHECK-NEXT: %19 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 0, i32 1 | ||
//CHECK-NEXT: %20 = bitcast i32* %19 to i256* | ||
//CHECK-NEXT: call void @..generated..loop.body.[[$F_ID_1]]([0 x i256]* %6, [0 x i256]* %0, i256* %10, i256* %11, i256* %15, [0 x i256]* %18, i256* %20) | ||
//CHECK-NEXT: %21 = bitcast [2 x i256]* %lvars to [0 x i256]* | ||
//CHECK-NEXT: %22 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 1, i32 0 | ||
//CHECK-NEXT: %23 = load [0 x i256]*, [0 x i256]** %22, align 8 | ||
//CHECK-NEXT: %24 = getelementptr [0 x i256], [0 x i256]* %23, i32 0 | ||
//CHECK-NEXT: %25 = getelementptr [0 x i256], [0 x i256]* %24, i32 0, i256 1 | ||
//CHECK-NEXT: %26 = getelementptr [0 x i256], [0 x i256]* %0, i32 0, i256 1 | ||
//CHECK-NEXT: %27 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 1, i32 0 | ||
//CHECK-NEXT: %28 = load [0 x i256]*, [0 x i256]** %27, align 8 | ||
//CHECK-NEXT: %29 = getelementptr [0 x i256], [0 x i256]* %28, i32 0 | ||
//CHECK-NEXT: %30 = getelementptr [0 x i256], [0 x i256]* %29, i32 0, i256 0 | ||
//CHECK-NEXT: %31 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 1, i32 0 | ||
//CHECK-NEXT: %32 = load [0 x i256]*, [0 x i256]** %31, align 8 | ||
//CHECK-NEXT: %33 = getelementptr [0 x i256], [0 x i256]* %32, i32 0 | ||
//CHECK-NEXT: %34 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 1, i32 1 | ||
//CHECK-NEXT: %35 = bitcast i32* %34 to i256* | ||
//CHECK-NEXT: call void @..generated..loop.body.[[$F_ID_1]]([0 x i256]* %21, [0 x i256]* %0, i256* %25, i256* %26, i256* %30, [0 x i256]* %33, i256* %35) | ||
//CHECK-NEXT: %36 = bitcast [2 x i256]* %lvars to [0 x i256]* | ||
//CHECK-NEXT: %37 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 2, i32 0 | ||
//CHECK-NEXT: %38 = load [0 x i256]*, [0 x i256]** %37, align 8 | ||
//CHECK-NEXT: %39 = getelementptr [0 x i256], [0 x i256]* %38, i32 0 | ||
//CHECK-NEXT: %40 = getelementptr [0 x i256], [0 x i256]* %39, i32 0, i256 1 | ||
//CHECK-NEXT: %41 = getelementptr [0 x i256], [0 x i256]* %0, i32 0, i256 2 | ||
//CHECK-NEXT: %42 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 2, i32 0 | ||
//CHECK-NEXT: %43 = load [0 x i256]*, [0 x i256]** %42, align 8 | ||
//CHECK-NEXT: %44 = getelementptr [0 x i256], [0 x i256]* %43, i32 0 | ||
//CHECK-NEXT: %45 = getelementptr [0 x i256], [0 x i256]* %44, i32 0, i256 0 | ||
//CHECK-NEXT: %46 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 2, i32 0 | ||
//CHECK-NEXT: %47 = load [0 x i256]*, [0 x i256]** %46, align 8 | ||
//CHECK-NEXT: %48 = getelementptr [0 x i256], [0 x i256]* %47, i32 0 | ||
//CHECK-NEXT: %49 = getelementptr [3 x { [0 x i256]*, i32 }], [3 x { [0 x i256]*, i32 }]* %subcmps, i32 0, i32 2, i32 1 | ||
//CHECK-NEXT: %50 = bitcast i32* %49 to i256* | ||
//CHECK-NEXT: call void @..generated..loop.body.[[$F_ID_1]]([0 x i256]* %36, [0 x i256]* %0, i256* %40, i256* %41, i256* %45, [0 x i256]* %48, i256* %50) | ||
//CHECK-NEXT: br label %prologue | ||
//CHECK-EMPTY: | ||
//CHECK-NEXT: prologue: | ||
//CHECK-NEXT: ret void | ||
//CHECK-NEXT: } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
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 --enable-var-scope | ||
|
||
// References to the Inner subcmp use LocationRule::Mapped because of the 'i' parameter | ||
template Inner(i) { | ||
signal input in; | ||
signal output out; | ||
|
||
out <-- in & i; | ||
} | ||
|
||
template Num2Bits(n) { | ||
signal input in; | ||
signal output out[n]; | ||
|
||
component c[n]; | ||
for (var i = 0; i < n; i++) { | ||
c[i] = Inner(i); | ||
c[i].in <-- in; | ||
out[i] <-- c[i].out; | ||
} | ||
} | ||
|
||
component main = Num2Bits(3); | ||
|
||
//CHECK-LABEL: define void @Inner_{{[0-9]+}}_build({ [0 x i256]*, i32 }* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_ | ||
//CHECK-SAME: [[$RUN_1:[0-9]+]]_run([0 x i256]* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_{{[0-9]+}}_build({ [0 x i256]*, i32 }* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_ | ||
//CHECK-SAME: [[$RUN_2:[0-9]+]]_run([0 x i256]* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_{{[0-9]+}}_build({ [0 x i256]*, i32 }* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_ | ||
//CHECK-SAME: [[$RUN_3:[0-9]+]]_run([0 x i256]* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Num2Bits_{{[0-9]+}}_run([0 x i256]* %0){{.*}} { | ||
//CHECK: unrolled_loop{{[0-9]+}}: | ||
//CHECK: call void @Inner_[[$RUN_1]]_run([0 x i256]* % | ||
//CHECK: call void @Inner_[[$RUN_2]]_run([0 x i256]* % | ||
//CHECK: call void @Inner_[[$RUN_3]]_run([0 x i256]* % |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
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 --enable-var-scope | ||
|
||
// References to the Inner subcmp use LocationRule::Mapped because of the 'i' parameter | ||
template Inner(i,j) { | ||
signal input in; | ||
signal output out; | ||
|
||
out <-- (in >> i) & j; | ||
} | ||
|
||
template Num2Bits(n) { | ||
signal input in; | ||
signal output out[n]; | ||
|
||
component c[n]; | ||
for (var i = 0; i < n; i++) { | ||
c[i] = Inner(i, i+1); | ||
c[i].in <-- in; | ||
out[i] <-- c[i].out; | ||
} | ||
} | ||
|
||
component main = Num2Bits(3); | ||
|
||
//CHECK-LABEL: define void @Inner_{{[0-9]+}}_build({ [0 x i256]*, i32 }* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_ | ||
//CHECK-SAME: [[$RUN_1:[0-9]+]]_run([0 x i256]* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_{{[0-9]+}}_build({ [0 x i256]*, i32 }* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_ | ||
//CHECK-SAME: [[$RUN_2:[0-9]+]]_run([0 x i256]* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_{{[0-9]+}}_build({ [0 x i256]*, i32 }* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Inner_ | ||
//CHECK-SAME: [[$RUN_3:[0-9]+]]_run([0 x i256]* %0){{.*}} { | ||
// | ||
//CHECK-LABEL: define void @Num2Bits_{{[0-9]+}}_run([0 x i256]* %0){{.*}} { | ||
//CHECK: unrolled_loop{{[0-9]+}}: | ||
//CHECK: call void @Inner_[[$RUN_1]]_run([0 x i256]* % | ||
//CHECK: call void @Inner_[[$RUN_2]]_run([0 x i256]* % | ||
//CHECK: call void @Inner_[[$RUN_3]]_run([0 x i256]* % |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.