Skip to content

Commit

Permalink
[VAN-1446] use vector values in interpreter to properly handle vector…
Browse files Browse the repository at this point in the history
… returns (#142)

* update tests to keep original intent in light of better optimization
* also a random test fix
  • Loading branch information
tim-hoffman authored Jul 30, 2024
1 parent a24620d commit ccaa1c1
Show file tree
Hide file tree
Showing 14 changed files with 878 additions and 405 deletions.
553 changes: 352 additions & 201 deletions circom/tests/calls/arena_missing_val.circom

Large diffs are not rendered by default.

75 changes: 75 additions & 0 deletions circom/tests/calls/call_ret_arraymulti_nonzero.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
pragma circom 2.0.3;
// 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

function long_gt(a, b) {
for (var i = 1; i >= 0; i--) {
if (a[i] > b[i]) {
return 1;
}
if (a[i] < b[i]) {
return 2;
}
}
return 0;
}

function long_scalar_mult() {
return [[99, 88, 77], [66, 55, 44]];
}

template Test() {
var norm[2][3] = long_scalar_mult();
var out[1] = [long_gt(norm[0], norm[1])];
}

component main = Test();

// NOTE: With the constant arrays propagated through return and call,
// the long_gt() function is totally optimized away to the value '1'.

//CHECK-LABEL: define{{.*}} void @Test_{{[0-9]+}}_run([0 x i256]* %0){{.*}} {
//CHECK-NEXT: prelude:
//CHECK-NEXT: %lvars = alloca [7 x i256], align 8
//CHECK-NEXT: %subcmps = alloca [0 x { [0 x i256]*, i32 }], align 8
//CHECK-NEXT: br label %call1
//CHECK-EMPTY:
//CHECK-NEXT: call1:
//CHECK-NEXT: %[[ARENA:[0-9a-zA-Z_\.]+]] = alloca [12 x i256], align 8
//CHECK-NEXT: %[[T01:[0-9a-zA-Z_\.]+]] = bitcast [12 x i256]* %[[ARENA]] to i256*
//CHECK-NEXT: %[[T99:[0-9a-zA-Z_\.]+]] = call i256* @long_scalar_mult_{{[0-9a-zA-Z_\.]+}}(i256* %[[T01]])
//CHECK-NEXT: %[[T02:[0-9a-zA-Z_\.]+]] = getelementptr [7 x i256], [7 x i256]* %lvars, i32 0, i32 0
//CHECK-NEXT: %[[CPY_SRC_0:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T99]], i32 0
//CHECK-NEXT: %[[CPY_DST_0:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 0
//CHECK-NEXT: %[[CPY_VAL_0:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_0]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_0]], i256* %[[CPY_DST_0]], align 4
//CHECK-NEXT: %[[CPY_SRC_1:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T99]], i32 1
//CHECK-NEXT: %[[CPY_DST_1:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 1
//CHECK-NEXT: %[[CPY_VAL_1:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_1]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_1]], i256* %[[CPY_DST_1]], align 4
//CHECK-NEXT: %[[CPY_SRC_2:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T99]], i32 2
//CHECK-NEXT: %[[CPY_DST_2:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 2
//CHECK-NEXT: %[[CPY_VAL_2:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_2]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_2]], i256* %[[CPY_DST_2]], align 4
//CHECK-NEXT: %[[CPY_SRC_3:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T99]], i32 3
//CHECK-NEXT: %[[CPY_DST_3:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 3
//CHECK-NEXT: %[[CPY_VAL_3:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_3]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_3]], i256* %[[CPY_DST_3]], align 4
//CHECK-NEXT: %[[CPY_SRC_4:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T99]], i32 4
//CHECK-NEXT: %[[CPY_DST_4:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 4
//CHECK-NEXT: %[[CPY_VAL_4:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_4]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_4]], i256* %[[CPY_DST_4]], align 4
//CHECK-NEXT: %[[CPY_SRC_5:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T99]], i32 5
//CHECK-NEXT: %[[CPY_DST_5:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 5
//CHECK-NEXT: %[[CPY_VAL_5:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_5]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_5]], i256* %[[CPY_DST_5]], align 4
//CHECK-NEXT: br label %store2
//CHECK-EMPTY:
//CHECK-NEXT: store2:
//CHECK-NEXT: %[[T03:[0-9a-zA-Z_\.]+]] = getelementptr [7 x i256], [7 x i256]* %lvars, i32 0, i32 6
//CHECK-NEXT: store i256 1, i256* %[[T03]], align 4
//CHECK-NEXT: br label %prologue
//CHECK-EMPTY:
//CHECK-NEXT: prologue:
//CHECK-NEXT: ret void
//CHECK-NEXT: }
124 changes: 89 additions & 35 deletions circom/tests/controlflow/early_return_loop_with_unknown_if.circom
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,27 @@ function long_gt(a, b) {
if (a[i] > b[i]) {
return 1;
}
if (a[i] < b[i]) {
if (a[i] <= b[i]) {
return 0;
}
}
return 0;
}

function long_scalar_mult() {
var out[2];
function long_scalar_mult(in) {
var out[2] = in;
return out;
}

function long_div2(){
var norm[2] = long_scalar_mult();
function long_div2(in){
var norm[2] = long_scalar_mult(in);
var out[1] = [long_gt(norm, norm)];
return out;
}

template Test() {
var out[1] = long_div2();
signal input in[2];
var out[1] = long_div2(in);
}

component main = Test();
Expand All @@ -37,17 +38,20 @@ component main = Test();
//CHECK-NEXT: br label %store1
//CHECK-EMPTY:
//CHECK-NEXT: store1:
//CHECK-NEXT: %[[T01:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 0
//CHECK-NEXT: store i256 0, i256* %[[T01]], align 4
//CHECK-NEXT: br label %store2
//CHECK-EMPTY:
//CHECK-NEXT: store2:
//CHECK-NEXT: %[[T02:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 1
//CHECK-NEXT: store i256 0, i256* %[[T02]], align 4
//CHECK-NEXT: br label %return3
//CHECK-NEXT: %[[T01:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 2
//CHECK-NEXT: %[[T02:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 0
//CHECK-NEXT: %[[CPY_SRC_0:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 0
//CHECK-NEXT: %[[CPY_DST_0:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T01]], i32 0
//CHECK-NEXT: %[[CPY_VAL_0:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_0]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_0]], i256* %[[CPY_DST_0]], align 4
//CHECK-NEXT: %[[CPY_SRC_1:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 1
//CHECK-NEXT: %[[CPY_DST_1:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T01]], i32 1
//CHECK-NEXT: %[[CPY_VAL_1:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_1]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_1]], i256* %[[CPY_DST_1]], align 4
//CHECK-NEXT: br label %return2
//CHECK-EMPTY:
//CHECK-NEXT: return3:
//CHECK-NEXT: %[[T03:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 0
//CHECK-NEXT: return2:
//CHECK-NEXT: %[[T03:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 2
//CHECK-NEXT: ret i256* %[[T03]]
//CHECK-NEXT: }
//
Expand All @@ -71,7 +75,22 @@ component main = Test();
//CHECK-NEXT: br i1 %[[T99]], label %loop.body, label %loop.end
//CHECK-EMPTY:
//CHECK-NEXT: loop.body:
//CHECK-NEXT: br i1 false, label %if.then, label %if.else
//CHECK-NEXT: %[[T74:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 4
//CHECK-NEXT: %[[T75:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T74]], align 4
//CHECK-NEXT: %[[T91:[0-9a-zA-Z_\.]+]] = call i32 @fr_cast_to_addr(i256 %[[T75]])
//CHECK-NEXT: %[[T92:[0-9a-zA-Z_\.]+]] = mul i32 1, %[[T91]]
//CHECK-NEXT: %[[T93:[0-9a-zA-Z_\.]+]] = add i32 %[[T92]], 0
//CHECK-NEXT: %[[T76:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 %[[T93]]
//CHECK-NEXT: %[[T77:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T76]], align 4
//CHECK-NEXT: %[[T78:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 4
//CHECK-NEXT: %[[T79:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T78]], align 4
//CHECK-NEXT: %[[T97:[0-9a-zA-Z_\.]+]] = call i32 @fr_cast_to_addr(i256 %[[T79]])
//CHECK-NEXT: %[[T96:[0-9a-zA-Z_\.]+]] = mul i32 1, %[[T97]]
//CHECK-NEXT: %[[T95:[0-9a-zA-Z_\.]+]] = add i32 %[[T96]], 2
//CHECK-NEXT: %[[T80:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 %[[T95]]
//CHECK-NEXT: %[[T81:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T80]], align 4
//CHECK-NEXT: %[[T94:[0-9a-zA-Z_\.]+]] = call i1 @fr_gt(i256 %[[T77]], i256 %[[T81]])
//CHECK-NEXT: br i1 %[[T94]], label %if.then, label %if.else
//CHECK-EMPTY:
//CHECK-NEXT: loop.end:
//CHECK-NEXT: br label %return12
Expand All @@ -83,15 +102,30 @@ component main = Test();
//CHECK-NEXT: br label %if.merge
//CHECK-EMPTY:
//CHECK-NEXT: if.merge:
//CHECK-NEXT: br i1 false, label %if.then1, label %if.else2
//CHECK-EMPTY:
//CHECK-NEXT: if.then1:
//CHECK-NEXT: %[[T12:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 4
//CHECK-NEXT: %[[T13:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T12]], align 4
//CHECK-NEXT: %[[T27:[0-9a-zA-Z_\.]+]] = call i32 @fr_cast_to_addr(i256 %[[T13]])
//CHECK-NEXT: %[[T26:[0-9a-zA-Z_\.]+]] = mul i32 1, %[[T27]]
//CHECK-NEXT: %[[T25:[0-9a-zA-Z_\.]+]] = add i32 %[[T26]], 0
//CHECK-NEXT: %[[T14:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 %[[T25]]
//CHECK-NEXT: %[[T15:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T14]], align 4
//CHECK-NEXT: %[[T16:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 4
//CHECK-NEXT: %[[T17:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T16]], align 4
//CHECK-NEXT: %[[T24:[0-9a-zA-Z_\.]+]] = call i32 @fr_cast_to_addr(i256 %[[T17]])
//CHECK-NEXT: %[[T23:[0-9a-zA-Z_\.]+]] = mul i32 1, %[[T24]]
//CHECK-NEXT: %[[T22:[0-9a-zA-Z_\.]+]] = add i32 %[[T23]], 2
//CHECK-NEXT: %[[T18:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 %[[T22]]
//CHECK-NEXT: %[[T19:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T18]], align 4
//CHECK-NEXT: %[[T21:[0-9a-zA-Z_\.]+]] = call i1 @fr_le(i256 %[[T15]], i256 %[[T19]])
//CHECK-NEXT: br i1 %[[T21]], label %if.then4, label %if.else5
//CHECK-EMPTY:
//CHECK-NEXT: if.then4:
//CHECK-NEXT: ret i256 0
//CHECK-EMPTY:
//CHECK-NEXT: if.else2:
//CHECK-NEXT: br label %if.merge3
//CHECK-NEXT: if.else5:
//CHECK-NEXT: br label %if.merge6
//CHECK-EMPTY:
//CHECK-NEXT: if.merge3:
//CHECK-NEXT: if.merge6:
//CHECK-NEXT: %[[T04:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 4
//CHECK-NEXT: %[[T05:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 4
//CHECK-NEXT: %[[T06:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T05]], align 4
Expand All @@ -109,10 +143,20 @@ component main = Test();
//CHECK-NEXT: br label %call1
//CHECK-EMPTY:
//CHECK-NEXT: call1:
//CHECK-NEXT: %[[ARENA_1:[0-9a-zA-Z_\.]+]] = alloca [2 x i256], align 8
//CHECK-NEXT: %[[T01:[0-9a-zA-Z_\.]+]] = bitcast [2 x i256]* %[[ARENA_1]] to i256*
//CHECK-NEXT: %call.long_scalar_mult_[[$F_ID_1]] = call i256* @long_scalar_mult_[[$F_ID_1]](i256* %[[T01]])
//CHECK-NEXT: %[[T02:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 0
//CHECK-NEXT: %[[ARENA_1:[0-9a-zA-Z_\.]+]] = alloca [4 x i256], align 8
//CHECK-NEXT: %[[T50:[0-9a-zA-Z_\.]+]] = getelementptr [4 x i256], [4 x i256]* %[[ARENA_1]], i32 0, i32 0
//CHECK-NEXT: %[[T52:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 0
//CHECK-NEXT: %[[CPY_SRC_90:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T52]], i32 0
//CHECK-NEXT: %[[CPY_DST_90:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T50]], i32 0
//CHECK-NEXT: %[[CPY_VAL_90:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_90]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_90]], i256* %[[CPY_DST_90]], align 4
//CHECK-NEXT: %[[CPY_SRC_91:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T52]], i32 1
//CHECK-NEXT: %[[CPY_DST_91:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T50]], i32 1
//CHECK-NEXT: %[[CPY_VAL_91:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_91]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_91]], i256* %[[CPY_DST_91]], align 4
//CHECK-NEXT: %[[T01:[0-9a-zA-Z_\.]+]] = bitcast [4 x i256]* %[[ARENA_1]] to i256*
//CHECK-NEXT: %call.long_scalar_mult_[[$F_ID_1:[0-9a-zA-Z_\.]+]] = call i256* @long_scalar_mult_[[$F_ID_1]](i256* %[[T01]])
//CHECK-NEXT: %[[T02:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 2
//CHECK-NEXT: %[[CPY_SRC_0:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %call.long_scalar_mult_[[$F_ID_1]], i32 0
//CHECK-NEXT: %[[CPY_DST_0:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T02]], i32 0
//CHECK-NEXT: %[[CPY_VAL_0:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_0]], align 4
Expand All @@ -126,7 +170,7 @@ component main = Test();
//CHECK-NEXT: call2:
//CHECK-NEXT: %[[ARENA_2:[0-9a-zA-Z_\.]+]] = alloca [5 x i256], align 8
//CHECK-NEXT: %[[T03:[0-9a-zA-Z_\.]+]] = getelementptr [5 x i256], [5 x i256]* %[[ARENA_2]], i32 0, i32 0
//CHECK-NEXT: %[[T04:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 0
//CHECK-NEXT: %[[T04:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 2
//CHECK-NEXT: %[[CPY_SRC_01:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T04]], i32 0
//CHECK-NEXT: %[[CPY_DST_02:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T03]], i32 0
//CHECK-NEXT: %[[CPY_VAL_03:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_01]], align 4
Expand All @@ -136,7 +180,7 @@ component main = Test();
//CHECK-NEXT: %[[CPY_VAL_16:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_14]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_16]], i256* %[[CPY_DST_15]], align 4
//CHECK-NEXT: %[[T05:[0-9a-zA-Z_\.]+]] = getelementptr [5 x i256], [5 x i256]* %[[ARENA_2]], i32 0, i32 2
//CHECK-NEXT: %[[T06:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 0
//CHECK-NEXT: %[[T06:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 2
//CHECK-NEXT: %[[CPY_SRC_07:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T06]], i32 0
//CHECK-NEXT: %[[CPY_DST_08:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T05]], i32 0
//CHECK-NEXT: %[[CPY_VAL_09:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_07]], align 4
Expand All @@ -147,19 +191,19 @@ component main = Test();
//CHECK-NEXT: store i256 %[[CPY_VAL_112]], i256* %[[CPY_DST_111]], align 4
//CHECK-NEXT: %[[T07:[0-9a-zA-Z_\.]+]] = bitcast [5 x i256]* %[[ARENA_2]] to i256*
//CHECK-NEXT: %[[T97:[0-9a-zA-Z_\.]+]] = call i256 @long_gt_[[$F_ID_2]](i256* %[[T07]])
//CHECK-NEXT: %[[T08:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 3
//CHECK-NEXT: %[[T08:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 5
//CHECK-NEXT: store i256 %[[T97]], i256* %[[T08]], align 4
//CHECK-NEXT: br label %store3
//CHECK-EMPTY:
//CHECK-NEXT: store3:
//CHECK-NEXT: %[[T09:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 2
//CHECK-NEXT: %[[T10:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 3
//CHECK-NEXT: %[[T09:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 4
//CHECK-NEXT: %[[T10:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 5
//CHECK-NEXT: %[[T11:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T10]], align 4
//CHECK-NEXT: store i256 %[[T11]], i256* %[[T09]], align 4
//CHECK-NEXT: br label %return4
//CHECK-EMPTY:
//CHECK-NEXT: return4:
//CHECK-NEXT: %[[T12:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 2
//CHECK-NEXT: %[[T12:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %0, i32 4
//CHECK-NEXT: %[[T13:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[T12]], align 4
//CHECK-NEXT: ret i256 %[[T13]]
//CHECK-NEXT: }
Expand All @@ -171,8 +215,18 @@ component main = Test();
//CHECK-NEXT: br label %call1
//CHECK-EMPTY:
//CHECK-NEXT: call1:
//CHECK-NEXT: %[[ARENA_3:[0-9a-zA-Z_\.]+]] = alloca [4 x i256], align 8
//CHECK-NEXT: %[[T01:[0-9a-zA-Z_\.]+]] = bitcast [4 x i256]* %[[ARENA_3]] to i256*
//CHECK-NEXT: %[[ARENA_3:[0-9a-zA-Z_\.]+]] = alloca [6 x i256], align 8
//CHECK-NEXT: %[[T11:[0-9a-zA-Z_\.]+]] = getelementptr [6 x i256], [6 x i256]* %[[ARENA_3]], i32 0, i32 0
//CHECK-NEXT: %[[T12:[0-9a-zA-Z_\.]+]] = getelementptr [0 x i256], [0 x i256]* %0, i32 0, i32 0
//CHECK-NEXT: %[[CPY_SRC_0:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T12]], i32 0
//CHECK-NEXT: %[[CPY_DST_0:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T11]], i32 0
//CHECK-NEXT: %[[CPY_VAL_0:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_0]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_0]], i256* %[[CPY_DST_0]], align 4
//CHECK-NEXT: %[[CPY_SRC_1:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T12]], i32 1
//CHECK-NEXT: %[[CPY_DST_1:[0-9a-zA-Z_\.]+]] = getelementptr i256, i256* %[[T11]], i32 1
//CHECK-NEXT: %[[CPY_VAL_1:[0-9a-zA-Z_\.]+]] = load i256, i256* %[[CPY_SRC_1]], align 4
//CHECK-NEXT: store i256 %[[CPY_VAL_1]], i256* %[[CPY_DST_1]], align 4
//CHECK-NEXT: %[[T01:[0-9a-zA-Z_\.]+]] = bitcast [6 x i256]* %[[ARENA_3]] to i256*
//CHECK-NEXT: %[[T96:[0-9a-zA-Z_\.]+]] = call i256 @long_div2_[[$F_ID_3]](i256* %[[T01]])
//CHECK-NEXT: %[[T02:[0-9a-zA-Z_\.]+]] = getelementptr [1 x i256], [1 x i256]* %lvars, i32 0, i32 0
//CHECK-NEXT: store i256 %[[T96]], i256* %[[T02]], align 4
Expand Down
2 changes: 1 addition & 1 deletion circom/tests/subcmps/subcmps4.circom
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ component main = SubCmps4(3);
//CHECK-NEXT: ret void
//CHECK-NEXT: }
//
//CHECK-LABEL: define dso_local void @SubCmps4_1_run([0 x i256]* %0){{.*}} {
//CHECK-LABEL: define{{.*}} void @SubCmps4_1_run([0 x i256]* %0){{.*}} {
//CHECK-NEXT: prelude:
//CHECK-NEXT: %lvars = alloca [2 x i256], align 8
//CHECK-NEXT: %subcmps = alloca [2 x { [0 x i256]*, i32 }], align 8
Expand Down
29 changes: 29 additions & 0 deletions circom/tests/zzz/array_size_mismatch_return.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
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

// The circom compiler only gives a warning for this:
// warning[T3001]: Typing warning: Mismatched dimensions, assigning to an array an expression of smaller length, the remaining positions are assigned to 0.

function smaller() {
return [99, 98, 97, 96, 95];
}

template ImplicitExtension() {
signal output out[10];
var temp[10] = smaller();
out[0] <-- temp[0];
out[4] <-- temp[4];
out[5] <-- temp[5];
out[9] <-- temp[9];
}

component main = ImplicitExtension();

//CHECK-LABEL: define{{.*}} void @ImplicitExtension_{{[0-9]+}}_run([0 x i256]* %0){{.*}} {
//CHECK: store2:
//CHECK-NEXT: %[[T03:[0-9a-zA-Z_\.]+]] = getelementptr [0 x i256], [0 x i256]* %0, i32 0, i32 0
//CHECK-NEXT: store i256 99, i256* %[[T03]], align 4
//CHECK: store3:
//CHECK-NEXT: %[[T04:[0-9a-zA-Z_\.]+]] = getelementptr [0 x i256], [0 x i256]* %0, i32 0, i32 4
//CHECK-NEXT: store i256 95, i256* %[[T04]], align 4
25 changes: 25 additions & 0 deletions circom/tests/zzz/array_size_mismatch_store.circom
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
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

// The circom compiler only gives a warning for this:
// warning[T3001]: Typing warning: Mismatched dimensions, assigning to an array an expression of smaller length, the remaining positions are assigned to 0.

template ImplicitExtension() {
signal output out[10];
var temp[10] = [99, 98, 97, 96, 95];
out[0] <-- temp[0];
out[4] <-- temp[4];
out[5] <-- temp[5];
out[9] <-- temp[9];
}

component main = ImplicitExtension();

//CHECK-LABEL: define{{.*}} void @ImplicitExtension_{{[0-9]+}}_run([0 x i256]* %0){{.*}} {
//CHECK: store6:
//CHECK-NEXT: %[[T06:[0-9a-zA-Z_\.]+]] = getelementptr [0 x i256], [0 x i256]* %0, i32 0, i32 0
//CHECK-NEXT: store i256 99, i256* %[[T06]], align 4
//CHECK: store7:
//CHECK-NEXT: %[[T07:[0-9a-zA-Z_\.]+]] = getelementptr [0 x i256], [0 x i256]* %0, i32 0, i32 4
//CHECK-NEXT: store i256 95, i256* %[[T07]], align 4
Loading

0 comments on commit ccaa1c1

Please sign in to comment.