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

[Bug] if ... else if chain yields code of size quadratic in the number of conditions #28386

Closed
mikebenfield opened this issue Oct 9, 2024 · 0 comments · Fixed by #28392
Closed
Labels
bug Something isn't working

Comments

@mikebenfield
Copy link
Collaborator

🐛 Bug Report

This Leo code:

program order_exp.aleo {
    transition main(public a: field) -> u32 {
        if a == 0field {
            return 0u32;
        } else if a == 1field {
            return 1u32;
        } else if a == 2field {
            return 2u32;
        } else if a == 3field {
            return 3u32;
        } else if a == 4field {
            return 4u32;
        } else if a == 5field {
            return 5u32;
        } else if a == 6field {
            return 6u32;
        } else {
            return 7u32;
        }
    }
}

Yields this aleo code:

program order_exp.aleo;



function main:
    input r0 as field.public;
    is.eq r0 0field into r1;
    is.eq r0 1field into r2;
    is.eq r0 2field into r3;
    is.eq r0 3field into r4;
    is.eq r0 4field into r5;
    is.eq r0 5field into r6;
    is.eq r0 6field into r7;
    not r1 into r8;
    not r2 into r9;
    and r8 r9 into r10;
    not r3 into r11;
    and r10 r11 into r12;
    not r4 into r13;
    and r12 r13 into r14;
    not r5 into r15;
    and r14 r15 into r16;
    not r6 into r17;
    and r16 r17 into r18;
    and r18 r7 into r19;
    ternary r19 6u32 7u32 into r20;
    not r1 into r21;
    not r2 into r22;
    and r21 r22 into r23;
    not r3 into r24;
    and r23 r24 into r25;
    not r4 into r26;
    and r25 r26 into r27;
    not r5 into r28;
    and r27 r28 into r29;
    and r29 r6 into r30;
    ternary r30 5u32 r20 into r31;
    not r1 into r32;
    not r2 into r33;
    and r32 r33 into r34;
    not r3 into r35;
    and r34 r35 into r36;
    not r4 into r37;
    and r36 r37 into r38;
    and r38 r5 into r39;
    ternary r39 4u32 r31 into r40;
    not r1 into r41;
    not r2 into r42;
    and r41 r42 into r43;
    not r3 into r44;
    and r43 r44 into r45;
    and r45 r4 into r46;
    ternary r46 3u32 r40 into r47;
    not r1 into r48;
    not r2 into r49;
    and r48 r49 into r50;
    and r50 r3 into r51;
    ternary r51 2u32 r47 into r52;
    not r1 into r53;
    and r53 r2 into r54;
    ternary r54 1u32 r52 into r55;
    ternary r1 0u32 r55 into r56;
    output r56 as u32.private;
@mikebenfield mikebenfield added the bug Something isn't working label Oct 9, 2024
mikebenfield added a commit that referenced this issue Oct 10, 2024
Specifically two changes are made:

1. Cache Anded together chains of conditionals for early returns.
This prevents quadratic code being generated in the face of a chain
of ifs like

```
if a { return 0u32; } else if b { return 1u32 } else if ...
```

2. Take into account early returns for asserts.

Fixes #28386, 28387
mikebenfield added a commit that referenced this issue Oct 10, 2024
Specifically two changes are made:

1. Cache Anded together chains of conditionals for early returns.
This prevents quadratic code being generated in the face of a chain
of ifs like

```
if a { return 0u32; } else if b { return 1u32 } else if ...
```

2. Take into account early returns for asserts.

Fixes #28386, #28387
mikebenfield added a commit that referenced this issue Oct 10, 2024
Specifically two changes are made:

1. Cache Anded together chains of conditionals for early returns.
This prevents quadratic code being generated in the face of a chain
of ifs like

```
if a { return 0u32; } else if b { return 1u32 } else if ...
```

2. Take into account early returns for asserts.

Fixes #28386, #28387
mikebenfield added a commit that referenced this issue Oct 10, 2024
Specifically two changes are made:

1. Cache Anded together chains of conditionals for early returns.
This prevents quadratic code being generated in the face of a chain
of ifs like

```
if a { return 0u32; } else if b { return 1u32 } else if ...
```

2. Take into account early returns for asserts.

Fixes #28386, #28387
mikebenfield added a commit that referenced this issue Oct 17, 2024
Specifically three changes are made:

1. Cache Anded together chains of conditionals for early returns.
This prevents quadratic code being generated in the face of a chain
of ifs like

```
if a { return 0u32; } else if b { return 1u32 } else if ...
```

2. Take into account early returns for asserts, and cache the
when reconstructing the assert, as with caching them for early returns.

Fixes #28386, #28387
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant