Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VAN-1446] use vector values in interpreter to properly handle vector returns #142

Merged
merged 3 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading